Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Enhancement-overlay skill — the DECISION + WIRING layer for LM observability that the single-backend skills [[langsmith]], [[phoenix]], [[mlflow]] do NOT cover. Each of those installs one backend; none of them help you DECIDE which backend fits your stack/scale/budget, nor give you a one-line autolog that turns it on fast. Use when starting any LM project, before the first deploy, or the moment someone asks "why did it do that?" and there are no traces to answer with. The skill picks a backend b
.claude/skills/agentsope-agentsop-observability-setup/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-09 | ✗→✓ | ▲ Improved | 141% | 0% |
| case-01 | ✗→✓ | ▲ Improved | 49% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 707% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 373% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 156% | 0% |
> "Instrument before you need it. The cheapest debugging session is a trace you already have."
This is an ENHANCE overlay. The local skills langsmith]], phoenix]] and mlflow]] each teach one backend deeply. This skill sits one level up: it answers the question those skills cannot — which one, and how do I turn it on in a single line right now — then hands off to the chosen backend's own skill for depth.
Activate at one of three moments — earlier is always cheaper:
| Trigger | Signal | |---|---| | Starting any LM project | First dspy.LM / ChatOpenAI / LlamaIndex / agent graph in the repo, and no tracing wired yet | | Before first deploy | About to ship an LM feature to real users with no trace UI — the AP-15 trap (§6) | | "Why did it do that?" with no traces | A bug surfaced, you reach for history, and there is nothing recorded — you are debugging blind | | Multi-component pipeline | Retriever + reranker + LLM + tools; per-call printing (agentsop-prompt-history-inspect]]) is no longer enough | | Cost / latency regression | Need aggregate token & latency dashboards across runs, not a single printout |
Do NOT activate when:
The relationship to agentsop-prompt-history-inspect]]: that skill is the reactive first move (dump one prompt, no setup). This skill is the proactive layer — wire persistent tracing so the next "why" is answered by a trace that already exists, not a frantic re-run.
Instrument BEFORE you need it
───────────────────────────────────────────────
pick backend one-line verify add eval
by constraints → autolog turns → a trace → hooks (judge,
(stack/scale/ it on actually datasets,
budget) (~1 line) landed alerts)
───────────────────────────────────────────────
cost of skipping each stage compounds: a missing trace at deploy
becomes a multi-hour blind-debug later (AP-15, §6).Three load-bearing ideas:
(langsmith env vars, px.launch_app(), mlflow.<framework>.autolog()). The real cost is picking the one that won't lock you in or under-serve you at scale (§4 decision table, §5 cases).
near-zero; reconstructing one after a production bug costs hours and may be impossible (no repro).
standardize on it, and let OpenTelemetry GenAI semantics keep you portable if you outgrow it (§7).
A five-step path. Each step gates the next.
Run the decision table in §4 (OP-1). Inputs: stack (is it LangChain/LangGraph? OSS-only? already on MLflow?), scale (dev-only vs high-volume production), budget/hosting (managed-OK vs must-self-host). Output: exactly one backend.
Wire the single call/env-var for the chosen backend (OP-2). Resist building a custom tracing layer first — autolog gets you a trace today; you can refine later.
Run one real LM call, then open the trace UI and confirm the call appears with inputs, outputs, latency, and token counts (OP-3). A backend that is "configured" but shows no traces is the #1 silent failure (wrong project name, env var not exported, sampling at 0).
Once raw traces flow, attach what makes them actionable: an LLM-as-judge or rule evaluator, a dataset built from real traces for regression testing, and basic cost/latency alerts (OP-4). This is what turns "we have logs" into "we catch regressions before users do."
Hand off to the chosen backend's own skill (langsmith]] / phoenix]] / mlflow]]) for the deep API once tracing and evals are flowing (OP-6).
Step gating, explicitly. Do not start Step n+1 until Step n is observably true. The most common failure is jumping from Step 2 (wired) straight to Step 4 (evals) without Step 3 (verify) — you build evaluators on top of a trace stream that was silently empty the whole time. Each step has a one-line proof: Step 1 → a backend name written down; Step 2 → an autolog call in the code; Step 3 → one trace visible in the UI with token counts; Step 4 → one evaluator firing on that trace. If any proof is missing, you are not at that step yet.
| If your situation is… | Choose | Why | Tie-breaker / caveat | |---|---|---|---| | Stack is LangChain / LangGraph (or LlamaIndex) and managed SaaS is acceptable | LangSmith → langsmith]] | First-class, zero-glue integration; "same team builds both" so tracing is native (R1] swarnendu.de / langgraph AP-15) | Vendor lock-in; pricing scales with trace volume — see Case B (§5) | | OSS-only / local-first, want OpenTelemetry, no vendor lock-in | Phoenix (Arize) → phoenix]] | OTel-based, self-hosted with SQLite/Postgres, framework-agnostic (R1] phoenix SKILL frontmatter) | Self-host = you run the infra; managed Arize Cloud exists if you outgrow it | | You are an ML-shop already running MLflow (model registry, experiments) | MLflow → mlflow]] | One pane of glass: LLM traces alongside existing runs/registry; mlflow.<fw>.autolog() (R1] mlflow SKILL; dspy-sop deploy line) | LLM-trace UI is younger than purpose-built LLM tools; fine if MLflow is already your hub | | Must self-host a purpose-built LLM-observability product (data-residency, privacy) | Langfuse | Self-hostable LLM-native tracing + evals; the common DSPy/CrewAI bolt-on (R1] dspy-sop "LangFuse-style traces"; crewai obs) | Not a local skill here — install per Langfuse docs; OTel-compatible | | Mixed stack, want maximum portability, framework churn expected | OpenTelemetry GenAI semantics under any of the above | Standard span schema → swap backends without re-instrumenting | More wiring; pick a concrete backend (Phoenix is OTel-native) to actually view spans |
references/R1-source-evidence.md.python # LangSmith — env vars only, no code change (auto-traces LangChain/LangGraph): # export LANGSMITH_TRACING=true # export LANGSMITH_API_KEY=... export LANGSMITH_PROJECT=my-app # (raw SDK / non-LangChain: wrap calls with langsmith.wrappers.wrap_openai or @traceable)
# Phoenix — launch local app + auto-instrument: import phoenix as px; px.launch_app() from phoenix.otel import register register(auto_instrument=True) # picks up installed framework instrumentors
# MLflow — one autolog call per framework: import mlflow mlflow.set_tracking_uri("http://localhost:5000") mlflow.dspy.autolog() # or mlflow.langchain / mlflow.openai / mlflow.crewai
mlflow.dspy.log_model deploy line; prompt-history-inspect op-001 (mlflow.dspy.autolog).px localhost / MLflow :5000), confirm the run shows inputs + outputs + latency + token count. If empty: check project name, that the env var is exported in this process, and that sampling ≠ 0.references/R2).query + retrieved_nodes + scores + index_id; for agents: tool name + args + observation).Quick decision: how much to capture. Default to the minimum payload above on every span, plus full request/response bodies on errors and a sampled fraction of successes. Capturing full bodies on 100% of high-volume traffic is the over-instrumenting trap (§6) and the cost driver in Case B. Capturing less than the minimum recreates AP-15 in slow motion — you have traces, but they cannot answer the "why."
Situation: A team building on LangGraph wants tracing before launch. LangSmith is one env-var away and natively integrated; Phoenix is OSS/OTel but needs self-hosting. Tension: Speed-to-trace + native integration (LangSmith) vs no vendor lock-in + data control (Phoenix). The langgraph-sop is explicit that LangSmith integration is first-class — "the same team builds both" (R1] AP-15). Resolution: If you are LangChain/LangGraph-first and SaaS is acceptable, take LangSmith now — the integration tax of Phoenix is real and AP-15 warns against shipping with no tracing far more loudly than against the lock-in. If data must stay in-house or you have a mixed/OSS stack, take Phoenix and accept the self-host cost. The wrong move is to dither and ship with neither (AP-15). Either choice beats no choice; OTel semantics (§7) keep migration possible.
Situation: A product graduates from dev to high traffic. Per-trace pricing on a managed backend turns "nice dashboards" into a line item that scales linearly with users; full-fidelity tracing of every call becomes both expensive and noisy. Tension: Full observability vs cost & signal-to-noise at production volume. High-volume LLM products (the Replit-class case — agent products generating millions of LM calls) cannot afford to trace 100% on a metered SaaS plan, but turning tracing off recreates AP-15. Resolution: Don't binary-choose between "trace all" and "trace none." (1) Sample — full-fidelity on errors and a small % of successes; (2) move to a self-hosted backend (Phoenix / Langfuse) where marginal cost is infra, not per-trace fees, once volume crosses the break-even; (3) keep eval datasets curated from sampled traces so regression coverage survives the sampling. Decide the sampling/hosting policy before the bill or the noise forces a panicked migration — instrument before you need it, but scale the instrumentation deliberately.
Anti-patterns
trace UI. "Replaying a checkpoint locally only goes so far; production needs the trace UI" (R1] langgraph-sop AP-15). Symptom: a user hits a bug, you have nothing to inspect, and you cannot reproduce it. Fix: this skill's Stage 1–3 before deploy.
as a span, or building a bespoke tracing layer before trying one-line autolog. Cost: noise, double bills, maintenance burden. Fix: one backend, autolog first, add detail only where a real question demands it.
(OP-3). The env var wasn't exported in the running process, the project name is wrong, or sampling is 0 — and you discover it only when you need a trace and there is none.
bugs live in the response and the upstream nodes, not the prompt (OP-5).
Boundaries (when this skill is the wrong tool)
| Backend | Hosting | Stack fit | One-line turn-on | Lock-in | Local skill | |---|---|---|---|---|---| | LangSmith | Managed SaaS (self-host enterprise) | LangChain / LangGraph / LlamaIndex first-class | export LANGSMITH_TRACING=true (+ key + project) | High (proprietary) | langsmith]] | | Phoenix (Arize) | Self-host (SQLite/Postgres) or Arize Cloud | OSS / any framework via OTel | px.launch_app() + register(auto_instrument=True) | Low (OSS, OTel) | phoenix]] | | MLflow | Self-host / managed (Databricks) | ML-shops; framework-agnostic, registry + runs | mlflow.<framework>.autolog() | Low (Apache-2.0) | mlflow]] | | Langfuse | Self-host (LLM-native) or cloud | DSPy / CrewAI bolt-on; privacy/data-residency | from langfuse import Langfuse + framework callback | Low (OSS) | (no local skill — per docs) | | OpenTelemetry GenAI | Backend-agnostic span schema | Any — portability layer under the above | Instrument with OTel GenAI conventions, export to chosen backend | None | (standard, not a product) |
Reading the table: pick by the dominant constraint, not a feature checklist. Stack-coupling (LangSmith), OSS/lock-in aversion (Phoenix), existing-MLflow-investment (MLflow), and hosting/privacy (Langfuse) are the four forces; OpenTelemetry is the escape hatch that keeps any choice reversible. Then hand off to the matching local skill for depth.
Overlay note: this skill intentionally stops at decision + one-line wiring + verification + eval hooks. For backend-specific APIs (custom evaluators, dataset management, dashboards, alerting), defer to langsmith]], phoenix]], mlflow]]. For the reactive single-prompt dump, see agentsop-prompt-history-inspect]].
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-22 | pass→pass | 12,752 | 7,028 | -45% | 1 | 1 | 0% | 1,994 | 5,493 | +175% | 0 | 0 | — |
case-09 | fail→pass | 15,396 | 7,819 | -49% | 1 | 1 | 0% | 2,392 | 5,755 | +141% | 0 | 0 | — |
case-19 | pass→pass | 18,206 | 9,238 | -49% | 1 | 1 | 0% | 2,565 | 5,859 | +128% | 0 | 0 | — |
case-20 | pass→pass | 13,555 | 10,551 | -22% | 1 | 1 | 0% | 2,118 | 6,109 | +188% | 0 | 0 | — |
case-01 | fail→pass | 24,116 | 12,778 | -47% | 1 | 1 | 0% | 4,251 | 6,345 | +49% | 0 | 0 | — |
case-02 | pass→pass | 13,258 | 8,394 | -37% | 1 | 1 | 0% | 2,093 | 5,898 | +182% | 0 | 0 | — |
case-03 | pass→pass | 14,423 | 6,154 | -57% | 1 | 1 | 0% | 2,476 | 5,458 | +120% | 0 | 0 | — |
case-04 | fail→fail | 24,172 | 20,010 | -17% | 1 | 1 | 0% | 4,609 | 8,387 | +82% | 0 | 0 | — |
case-05 | fail→pass | 4,195 | 5,632 | +34% | 1 | 1 | 0% | 654 | 5,279 | +707% | 0 | 0 | — |
case-06 | pass→pass | 4,703 | 4,416 | -6% | 1 | 1 | 0% | 879 | 5,207 | +492% | 0 | 0 | — |
case-07 | pass→pass | 18,257 | 8,385 | -54% | 1 | 1 | 0% | 3,000 | 5,865 | +96% | 0 | 0 | — |
case-08 | pass→pass | 29,832 | 10,360 | -65% | 1 | 1 | 0% | 2,553 | 6,275 | +146% | 0 | 0 | — |
case-10 | fail→pass | 31,992 | 9,028 | -72% | 1 | 1 | 0% | 1,252 | 5,918 | +373% | 0 | 0 | — |
case-11 | fail→pass | 19,779 | 19,404 | -2% | 1 | 1 | 0% | 2,977 | 7,622 | +156% | 0 | 0 | — |
case-12 | pass→pass | 15,545 | 10,355 | -33% | 1 | 1 | 0% | 2,253 | 6,029 | +168% | 0 | 0 | — |
case-13 | fail→pass | 14,711 | 10,050 | -32% | 1 | 1 | 0% | 2,172 | 6,025 | +177% | 0 | 0 | — |
case-14 | pass→pass | 15,028 | 15,087 | +0% | 1 | 1 | 0% | 2,436 | 6,978 | +186% | 0 | 0 | — |
case-21 | fail→pass | 14,402 | 10,879 | -24% | 1 | 1 | 0% | 2,103 | 6,124 | +191% | 0 | 0 | — |
case-15 | pass→pass | 3,573 | 3,326 | -7% | 1 | 1 | 0% | 518 | 5,035 | +872% | 0 | 0 | — |
case-16 | fail→pass | 4,664 | 3,790 | -19% | 1 | 1 | 0% | 827 | 5,069 | +513% | 0 | 0 | — |
case-17 | fail→pass | 5,593 | 5,471 | -2% | 1 | 1 | 0% | 938 | 5,338 | +469% | 0 | 0 | — |
case-18 | fail→pass | 17,199 | 5,869 | -66% | 1 | 1 | 0% | 3,037 | 5,478 | +80% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 21 counted toward the lift figure. The other 1 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +45 percentage points is the difference between those two pass rates over the 21 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.