Agent Observability

An LLM agent is a distributed system whose components are a stochastic model, a set of tools that may call anything, and a state that evolves with each call. Debugging without traces is guesswork. The difference between teams that ship reliable agents and teams that don't is usually visible in whether they log every model call and tool call as a span from day one.

This page is what to log, how to structure it, and which tools are worth adopting.

The three observability layers

Agents need the same three layers as any distributed system — metrics, logs, traces — but the semantics differ.

LayerHTTP serviceLLM agent
Metricsreq/s, error rate, p50/p95 latencytask success rate, cost per task, tool validity rate, token throughput
Logsstructured app logsstructured app logs + full LLM inputs/outputs (sampled)
Tracesone span per service hopone span per LLM call and one per tool dispatch, nested under a per-task trace

Metrics tell you that something's wrong. Traces tell you what and where. Logs contain the prompts you need to reproduce. You need all three.

The canonical trace

One trace per agent task, with spans at every step. Minimum span shape:

{
  "trace_id": "task_4f2e...",
  "span_id": "step_3_llm",
  "parent_span_id": "step_3",
  "name": "model.chat",
  "start_ts": ...,
  "end_ts": ...,
  "attributes": {
    "agent_version": "v2.3.1",
    "model": "claude-sonnet-4-6",
    "input_tokens": 2451,
    "output_tokens": 312,
    "cached_tokens": 2100,
    "cost_usd": 0.0091,
    "temperature": 0.0,
    "stop_reason": "tool_use",
    "tool_calls": ["cancel_subscription"],
    "validation_ok": true
  }
}

Every tool call gets its own span, nested under the step:

{
  "trace_id": "task_4f2e...",
  "span_id": "step_3_tool_cancel",
  "parent_span_id": "step_3",
  "name": "tool.cancel_subscription",
  "attributes": {
    "tool_input_hash": "...",
    "tool_output_hash": "...",
    "tool_duration_ms": 412,
    "tool_status": "ok"
  }
}

The attribute set matters more than the trace format. You will query this data constantly; design for the queries you'll actually run.

Questions the telemetry needs to answer

Work backwards from these:

If any of these takes more than a minute to answer with your current telemetry, you have an observability gap.

Sampling: what to keep, what to drop

LLM call logs are verbose. A 20-step agent with 30k-token contexts produces ~600k tokens of span data per task. At 1 task/s, that's 2 TB/month. You'll want to sample.

Reasonable policy:

Raise the success-task sampling rate to 100% during incidents, then drop it back.

Cost tracking

LLM cost is a primary dimension, not a footnote. Log per-call:

Aggregate to dashboards:

See LlmTokenEconomicsAndPricing for the accounting specifics.

The tools worth using

ToolStrengthsWhen to pick
LangSmithDeep LangChain/LangGraph integration, excellent UI for trace exploration, built-in eval workflowYou're on LangChain; you want the lowest-friction option
LangfuseOpen source, model-agnostic, OpenTelemetry-ish, self-hostableYou want self-hosted or you're not on LangChain
OpenLLMetryOpenTelemetry instrumentation for LLM frameworks; exports to your existing OTel stackYou already run Datadog/Honeycomb/Jaeger and want LLM data in the same pane
Arize PhoenixOpen source, eval-centric, strong on embedding drift detectionYou care about eval-in-prod more than trace browsing
Homegrown PostgresTotal control, simple queries, no vendor lock-inSmall team, simple needs, doesn't mind building the UI yourself

Strong opinion: start with Langfuse or OpenLLMetry. Both are open source and model-agnostic. The commercial tools add polish but lock you in; the self-hosted ones give you the data.

Alerting

Real alerts, pager-worthy:

Nice-to-have:

Debugging workflow, concretely

A user reports the agent did something wrong. Ideal path:

  1. Find the user's task in the trace UI by user ID + timestamp.
  2. Open the full trace. See every LLM call, every tool call, every state transition.
  3. Click the failing step. See the full prompt sent, the full response, the tool validation result.
  4. Copy the prompt into a playground, reproduce the issue, iterate on a fix.
  5. The fix gets added to the rollout eval set — see AgentTesting.

Without telemetry this cycle is "I can't reproduce it." That's the gap observability closes.

Privacy and compliance

Full-prompt logging captures everything users said. That has compliance implications:

Instrumentation minimum (if you start today)

Every LLM call:          input, output, model, tokens, cost, latency, cache stats
Every tool call:         name, input, output, duration, error, idempotency key
Every task:              user_id, goal, final_state, total_steps, total_cost, terminal_reason
Sampled full transcripts: 1-5% of successes, 100% of failures
One trace ID:            correlates everything above

Three hours of work; years of saved debugging time.

Further reading