audit-langfuse-llm — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited audit-langfuse-llm (Agent Skill) and scored it 45/100 (orange). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 1 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 flagged
A base64 string of 128+ characters appears in a documentation file. Encoded prompt injection hides the hostile instruction in base64 — invisible to keyword filters — and relies on the agent's ability to decode it at runtime. There is no normal authoring reason to embed a multi-hundred-byte base64 blob in skill docs.
*.sig, SIGNATURES) outside the documentation.Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Automated PDCA audit for LLM/AI features: trace completeness, prompt quality, cost efficiency, eval health, grounding accuracy, and end-to-end pipeline verification. Works with any project — auto-detects Langfuse setup from the codebase.
NEVER skip the auto-detect phase. Every project configures Langfuse differently.
Research before judging. Use Firecrawl to find current LLM best practices so recommendations are evidence-based, not opinion.
Verify live, not just statically. Trigger AI features via Playwright and confirm traces land in Langfuse — static code analysis alone misses runtime issues.
Use concrete numbers. "Costs seem high" is not an audit finding. "GPT-4o used for intent classification at $0.03/call when GPT-4o-mini at $0.001/call achieves equivalent accuracy" is.
Always use the `browser-anti-stall` protocol when using Playwright browser MCP tools.
Search for environment variables and config files (in order):
.env, .env.local, .env.production — look for LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY, LANGFUSE_BASE_URL, LANGFUSE_HOSTlangfuse.config.ts, langfuse.config.js — dedicated config filesinstrumentation.ts / instrumentation.js — Next.js instrumentation with LangfuseGlob("**/supabase/functions/**/index.ts") and search for Langfuse importsGrep(pattern: "LANGFUSE_PUBLIC_KEY|LANGFUSE_SECRET_KEY|LANGFUSE_BASE_URL|LANGFUSE_HOST", glob: ".env*")
Grep(pattern: "langfuse|Langfuse|@langfuse", glob: "*.{ts,js,tsx,jsx,py,rb,go}")Record:
LANGFUSE_HOST (cloud or self-hosted URL)LANGFUSE_PUBLIC_KEY (identifies the project)LANGFUSE_PUBLIC_KEY and LANGFUSE_SECRET_KEY in the environment)Grep(pattern: "openai|OpenAI|anthropic|Anthropic|@google/generative-ai|gemini|cohere|mistral|groq|together|replicate", glob: "*.{ts,js,py}")
Grep(pattern: "langchain|LangChain|@langchain|vercel/ai|ai/core|createOpenAI|createAnthropic", glob: "*.{ts,js,py}")Record:
gpt-4o, claude-3, gemini-pro)SemanticSearch(query: "Where are LLM/AI features called in the codebase?", target_directories: [])Build a feature map:
| Feature | File(s) | Provider | Model | Traced? |
|---|---|---|---|---|
| _e.g. Chat_ | app/api/chat/route.ts | OpenAI | gpt-4o | Yes |
Grep(pattern: "createScore|langfuse.score|annotation|eval|judge|dataset", glob: "*.{ts,js,py}")
Grep(pattern: "getPrompt|langfuse.prompt|fetchPrompt|compilePrompt", glob: "*.{ts,js,py}")Record:
Before auditing, establish the current state of the art so findings are grounded in evidence.
CallMcpTool(server: "user-firecrawl", toolName: "firecrawl_search", arguments: {
"query": "LLM observability best practices production monitoring [current year]",
"limit": 5
})CallMcpTool(server: "user-firecrawl", toolName: "firecrawl_search", arguments: {
"query": "prompt engineering evaluation scoring hallucination detection [current year]",
"limit": 5
})CallMcpTool(server: "user-firecrawl", toolName: "firecrawl_search", arguments: {
"query": "LLM cost optimization token usage model selection production [current year]",
"limit": 5
})Scrape the top 2-3 most relevant results for detailed guidance:
CallMcpTool(server: "user-firecrawl", toolName: "firecrawl_scrape", arguments: {
"url": "<BEST_RESULT_URL>",
"formats": ["markdown"]
})Research Langfuse-specific features relevant to the detected setup:
CallMcpTool(server: "user-firecrawl", toolName: "firecrawl_search", arguments: {
"query": "site:langfuse.com docs tracing prompts evaluation scores",
"limit": 5
})If the project uses a specific LLM framework (LangChain, Vercel AI SDK, etc.), also fetch its Langfuse integration docs.
If detected in Phase 0b, fetch the framework-specific documentation:
CallMcpTool(server: "context7", toolName: "resolve-library-id", arguments: {
"libraryName": "<DETECTED_FRAMEWORK e.g. langchain or vercel-ai>"
})Then query for integration patterns:
CallMcpTool(server: "context7", toolName: "query-docs", arguments: {
"libraryId": "<RESOLVED_ID>",
"query": "Langfuse integration tracing observability"
})All commands below use the Langfuse CLI via the Shell tool. Ensure the environment has LANGFUSE_PUBLIC_KEY and LANGFUSE_SECRET_KEY set (from .env or exported).
npx langfuse-cli api traces list --limit 50For each AI feature identified in Phase 0c, verify:
Red flags:
npx langfuse-cli api prompts listFor each prompt:
npx langfuse-cli api prompts get --name "<PROMPT_NAME>"Evaluate:
production label? Are there staging/experiment labels for A/B testing?{{variables}} not string concatenation?If prompts are hardcoded in source code instead of managed via Langfuse:
Grep(pattern: "You are|system.*message|systemPrompt|SYSTEM_PROMPT", glob: "*.{ts,js,py}")Flag hardcoded prompts as a finding — they should be migrated to Langfuse for versioning and A/B testing.
From trace data, analyze:
npx langfuse-cli api traces list --limit 50For each trace, check the generation details (model, usage tokens, latency, cost).
Build a cost table:
| Feature | Model | Avg Input Tokens | Avg Output Tokens | Avg Latency | Est. Cost/Call |
|---|
Red flags:
npx langfuse-cli api scores list --limit 50Evaluate:
Red flags:
npx langfuse-cli api sessions list --limit 20Verify:
npx langfuse-cli api datasets listEvaluate:
For each AI feature identified in Phase 0c, use browser MCP tools to trigger it live.
Important: Apply the browser-anti-stall protocol — set 15-second timeouts, skip browser_wait_for on navigation, use browser_snapshot to detect ready state.
CallMcpTool(server: "user-playwright", toolName: "browser_navigate", arguments: {
"url": "<APP_URL>"
})Navigate to the feature, interact with it (fill form, click button, send message), and capture:
browser_snapshot)browser_console_messages) — look for errorsbrowser_network_requests) — look for failed API callsAfter triggering each feature, wait 5-10 seconds, then verify the trace landed:
npx langfuse-cli api traces list --limit 5Check:
If a trace is missing after triggering a feature → pipeline break (critical finding).
CallMcpTool(server: "plugin-sentry-sentry", toolName: "search_issues", arguments: {
"organizationSlug": "<ORG_SLUG>",
"projectSlug": "<PROJECT_SLUG>",
"query": "is:unresolved ai OR llm OR openai OR anthropic OR langfuse OR completion OR embedding"
})Check for:
If the project stores AI outputs in the database:
CallMcpTool(server: "plugin-supabase-supabase", toolName: "list_tables", arguments: {
"project_id": "<PROJECT_ID>"
})Find tables that store AI outputs and verify data landed:
CallMcpTool(server: "plugin-supabase-supabase", toolName: "execute_sql", arguments: {
"project_id": "<PROJECT_ID>",
"query": "SELECT id, created_at, <ai_output_column> FROM <table> ORDER BY created_at DESC LIMIT 5"
})For features where the AI should reference source data (RAG, summarization, data extraction):
execute_sql)Red flags:
Generate a structured report with the following sections.
═══════════════════════════════════════════════════════
LANGFUSE LLM QUALITY AUDIT REPORT
Project: <PROJECT_NAME>
Date: <DATE>
Langfuse Host: <HOST_URL>
═══════════════════════════════════════════════════════
## 1. TRACE COVERAGE
| Feature | Traced? | Generations? | Input/Output? | Metadata? | Status |
|---------|---------|-------------|---------------|-----------|--------|
| ... | ... | ... | ... | ... | ✅/❌ |
Coverage: X/Y features traced (Z%)
Missing instrumentation: [list features with no traces]
## 2. PROMPT QUALITY
| Prompt | Version | Label | System Msg | Few-Shot | Guardrails | Variables | Score |
|--------|---------|-------|------------|----------|------------|-----------|-------|
| ... | ... | ... | ... | ... | ... | ... | A-F |
Hardcoded prompts found: [list files with inline prompts]
Recommendations: [specific improvements per prompt]
## 3. COST EFFICIENCY
| Feature | Model | Avg Tokens (in/out) | Avg Latency | Est. Cost/Call | Recommendation |
|---------|-------|---------------------|-------------|----------------|----------------|
| ... | ... | ... | ... | ... | ... |
Monthly estimate: $X (at current usage rate)
Savings opportunity: $Y (by implementing recommendations)
## 4. EVAL HEALTH
| Metric | Status | Details |
|------------------|-----------|----------------------------------|
| Automated evals | ✅/❌ | [count and types] |
| Manual reviews | ✅/❌ | [annotation queue status] |
| Score distribution| ✅/❌ | [healthy spread vs clustered] |
| Datasets | ✅/❌ | [count, freshness, coverage] |
| Regression tests | ✅/❌ | [dataset run frequency] |
## 5. PIPELINE INTEGRITY
| Step | Status | Evidence |
|-------------------------|--------|-------------------------------------|
| FE triggers AI feature | ✅/❌ | [Playwright observation] |
| API receives request | ✅/❌ | [network request captured] |
| LLM call executes | ✅/❌ | [trace generation exists] |
| Trace lands in Langfuse | ✅/❌ | [CLI verification] |
| Result stored in DB | ✅/❌ | [Supabase query result] |
| Result displayed in FE | ✅/❌ | [Playwright snapshot] |
| Eval score recorded | ✅/❌ | [score attached to trace] |
## 6. GROUNDING & HALLUCINATION
| Feature | Source Data | AI Output Match | Hallucinations | Score |
|---------|-------------|-----------------|----------------|-------|
| ... | ... | ... | ... | A-F |
## 7. SENTRY LLM ERRORS
| Issue | Error Type | Events | Impact | Fix Needed |
|-------|------------|--------|--------|------------|
| ... | ... | ... | ... | ... |
## 8. CRITICAL FINDINGS (Action Required)
P0 — Must fix immediately:
1. [finding with evidence]
P1 — Should fix this sprint:
1. [finding with evidence]
P2 — Improvement opportunity:
1. [finding with evidence]
## 9. RECOMMENDATIONS
| # | Category | Current State | Recommended State | Effort | Impact |
|---|----------|---------------|-------------------|--------|--------|
| 1 | ... | ... | ... | S/M/L | S/M/L |
## 10. PDCA IMPROVEMENT RESULTS
| Prompt | Baseline Score | Iter 1 Score | Iter 2 Score | Iter 3 Score | Final Score | Action Taken |
|--------|---------------|-------------|-------------|-------------|-------------|--------------|
| ... | ... | ... | ... | ... | ... | Promoted / Rolled back / Needs manual |
## Further reading
- [Improvement Details and more](references/details.md)~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.