Production observability and cost engineering
Tracing, structured logs, per-tenant cost attribution, and the dashboards that keep the bill knowable.
Why this matters
The most common reason agent products fail in production is opacity and runaway cost, not bad models. The skill of "I can debug, attribute, and shrink the bill" makes you the senior engineer the team relies on.
This lesson is the production-focused expansion of Lesson 3.5 β same tools, deeper patterns.
Learning objectives
- Stand up a LangSmith + Langfuse + OpenTelemetry/Phoenix stack and pick the right one.
- Tag traces with
tenant_id,user_id,feature,versionfor surgical debugging. - Build a cost dashboard segmented by feature.
- Apply the cost optimisation pyramid end-to-end.
- Set SLOs and alarms.
1. Observability stack picks for 2026
| Tool | Strengths | Pick when |
|---|---|---|
| LangSmith | Best UX for LangChain/LangGraph; experiments + datasets. Hosted. | You use LangChain and want zero ops. |
| Langfuse | OSS, self-hostable, similar UX to LangSmith. | Privacy or air-gapped. |
| Arize Phoenix | OSS; ML/embedding drift, RAG monitoring. | Need embedding/ retrieval drift. |
| Datadog LLM Observability | Plugs into existing Datadog APM. | Enterprise already on Datadog. |
| OpenTelemetry + Tempo/Jaeger | Vendor-neutral; OpenInference semantic conventions. | Big org with existing OTel stack. |
| Helicone | Proxy-style; lowest setup. | Single-LLM-vendor app. |
In 2026 most stacks are: LangSmith for dev/experiments + OTel+Phoenix or Langfuse for prod.
2. The 6 fields you must tag on every trace
Senior agents always tag:
tenant_id(ororg_id) β the customer.user_idβ the human.request_idβ UUID for cross-system correlation.featureβchat,summarise,code_review, etc.versionβ your app/service version.modelandprovider.
Use LangSmith metadata or LangChain RunnableConfig:
config = {"metadata": {"tenant_id": tid, "user_id": uid, "feature":"chat",
"version": APP_VERSION},
"tags": [f"v{APP_VERSION}", f"tenant:{tid}", "feature:chat"]}
chain.invoke(input, config=config)In OTel:
from opentelemetry import trace
trace.get_current_span().set_attributes({
"tenant.id": tid, "user.id": uid, "feature":"chat",
"service.version": APP_VERSION,
})Now you can slice metrics by any tag in dashboards.
3. Three dashboards every agent needs
Dashboard A β health
- Requests / minute (per feature).
- Error rate (per node, per tool).
- p50/p95/p99 latency (per feature).
- Token throughput.
- "I do not know" rate.
Dashboard B β quality
- Online task-success rate (judged on sampled traffic).
- RAG faithfulness (sampled).
- Refusal rate.
- Adversarial bucket hit count.
Dashboard C β cost
- USD / 1k requests by feature.
- Token mix (input vs output) by model.
- Cache hit rate.
- Cost share between models.
- Forecast vs budget.
A single Grafana repo with these three dashboards in JSON is interview gold.
4. Cost optimisation pyramid (production version)
From Lesson 1.5, expanded for prod:
- Right-size the model. Run a real eval; pick smallest that meets quality SLO.
- Prompt caching. Anthropic 90% off; OpenAI auto cache when shared prefix > 1024 tokens.
- Semantic cache for FAQ-style queries.
- Output budgets. Strict
max_tokens. Stop sequences for templated outputs. - Context compression. LLMLingua-2 for large doc QA; chunk + retrieve instead.
- Cascade. Try cheap β escalate to expensive only on low confidence.
- Batch APIs (50% off) for nightly evals, embeddings, summarisations.
- Self-host with vLLM when daily volume justifies (Lesson 5.5).
- Move retrieval/rerank off the LLM when classical algorithms suffice (BM25, cosine).
Document each one's win in your README. "Prompt caching cut input cost 73% on the help-bot feature" is exactly the line a hiring manager wants to see.
5. SLOs and alarms
Define service-level objectives explicitly:
- 99.5% requests succeed (no 5xx).
- p95 latency < 4s.
- "I do not know" rate < 8%.
- Cost per request < $0.02 (chat); < $0.20 (deep-agent).
- Faithfulness β₯ 0.85 weekly average.
Alert on trend, not just single thresholds:
- 7-day rolling task-success drops > 5% β page on-call.
- Cost / 1k rises > 25% week-over-week β investigate.
- New 4xx error pattern (
unknown_tool) > 1/hour β investigate.
Use Grafana / Datadog Monitors / Prometheus Alertmanager.
6. Trace-driven debugging workflow
Real production debugging:
- User reports a bad answer. They send
request_id. - Open LangSmith / Langfuse β search by
request_id. - View the full trace tree: which retriever returned what, which chunks survived rerank, which tools were called with what args, which LLM call produced the bad reply.
- Replay the run with one variable changed (different model, different chunk size, different system prompt). Compare results side-by-side.
- Add a test case to your golden set so the bug never returns.
This loop β observe β replay β fix β add test β is the senior workflow. Practice it on your own projects.
7. Privacy in observability (the rule that gets violated)
You must redact before the trace leaves your perimeter:
- PII (Presidio / regex).
- Secrets (regex; deny-list known prefixes).
- Customer business secrets.
Most platforms support a redaction callback; otherwise wrap your client to scrub inputs/outputs before the trace upload.
A common 2026 pattern: store full traces internally (Phoenix or Langfuse self-hosted) and a redacted summary externally.
Hands-on lab (5 hours)
Add to your agent stack:
- LangSmith metadata on every run with the 6 standard tags.
- Phoenix OSS instance via Docker, instrumented via OpenInference.
- Prometheus + Grafana with the 3 dashboards above.
- Cost meter middleware that emits
agent_cost_usd_total{feature=...}. - Alertmanager rules:
alert if rate(agent_errors_total[5m]) > 5,alert if avg(agent_cost_usd_total[1h]) > 0.05. - PII redactor in the trace upload path.
Acceptance:
- Trigger a load test; dashboards populate live.
- Trip an alarm intentionally; receive the notification.
- README screenshots all three dashboards.
Common pitfalls
- No tagging. You cannot slice by feature when it matters most.
- Storing raw PII. Redact at the source, not "later."
- Single threshold alerts. They fire forever or never. Use rate-of-change alarms.
- Tracing only LLM calls. Trace the whole request including retrieval and tools.
- Tracking cost in the API console. Always have a per-feature meter in your code.
Self-check
- Why is
tenant_idnon-negotiable for B2B agents? - How does prompt caching show up in
usagefields? - Two ways to detect retrieval drift in production.
- Why do trend-based alerts beat single-threshold alerts?
- How would you reduce a feature's cost by 50% if budgets force it?
References
Sign in to save your progress and earn badges.