A practitioner's guide to tracing, evaluating, and debugging LLM agents in production with the tools that actually earn their keep.
Debugging a plain web service is mostly about reading a stack trace. Debugging an agent is not. When an agent quietly returns a wrong answer, there is no exception to catch. The model called four tools, retried one, summarized the results, and produced fluent nonsense. Everything "worked." That gap is why agent observability has become its own discipline, separate from the APM stack you already run.
If you are still designing the agent itself, start with our building AI agents guide. This post assumes you have something running and now need to see inside it.
A traditional request is one hop. An agent run is a tree. A single user message fans out into planning steps, tool calls, sub-agent invocations, and retries, sometimes dozens deep. Five properties make this hard:
Your Datadog dashboard shows the HTTP 200. It cannot show you that step 3 hallucinated a customer ID.
The unit of observability for agents is the trace tree, not the log line. For every run, capture:
With that in place, a debugging session becomes reading a tree top to bottom instead of guessing.
LangSmith: the framework-native option if you live in LangChain or LangGraph. Instrumentation is nearly automatic, the trace view maps cleanly onto graph nodes, and evals plus dataset management are built in. You pay for that convenience with a hosted, LangChain-flavored workflow. If your stack is already LangGraph, this is the path of least resistance.
Langfuse: the open-source workhorse. Self-hostable, framework-agnostic, and it bundles tracing, evals, and prompt management in one place. Teams that want their trace data on their own infrastructure, or who are wary of vendor lock-in, tend to land here. The SDK is unobtrusive and the prompt-versioning feature alone justifies adoption for many.
Arize Phoenix: eval-first and rooted in the broader ML observability world. It speaks OpenInference and is strong on retrieval and embedding analysis, so RAG-heavy agents benefit most. Phoenix runs locally or self-hosted and pairs well with a separate tracing backend if you already have one.
OpenTelemetry GenAI + OpenLLMetry: the standards-based route. The OpenTelemetry GenAI semantic conventions define how to name spans and attributes for LLM calls, and OpenLLMetry (from Traceloop) emits them from popular SDKs. Instrument once, export to any OTel-compatible backend. This is the choice when you want agent traces sitting next to the rest of your telemetry rather than in a walled garden.
Helicone: proxy-based, so you point your model client at it and get cost, latency, and caching metrics without touching application code. It is the fastest way to answer "where is the token spend going" and a reasonable gateway layer, though it sees calls rather than the full agent tree.
For a wider field including the pure LLM-monitoring vendors, see our best LLM observability tools comparison.
Tracing tells you what happened. Evals tell you whether it was any good. Three modes matter:
All four tools above support some slice of this. LangSmith and Langfuse make the dataset-plus-judge loop first-class; Phoenix leans into eval templates.
As agents move to the Model Context Protocol, the interesting failures live at the tool boundary. The trick is correlation ids: propagate the trace id and span id into the MCP call metadata so the tool server's spans stitch back into the agent's trace tree. Without that, you get two disconnected halves and no way to see that the slow step was the tool server, not the model. Most OTel-based instrumentation will carry context automatically if you pass it through; verify it end to end rather than assuming.
The mechanics are usually a few lines. Here is the shape with Langfuse:
from langfuse import observe, get_client
langfuse = get_client()
@observe(name="support-agent")
def run_agent(user_msg: str) -> str:
result = agent.invoke({"input": user_msg})
langfuse.update_current_trace(
input=user_msg,
output=result["output"],
metadata={"tool_calls": result["intermediate_steps"]},
)
return result["output"]
The decorator opens a trace, nested tool and LLM spans attach automatically, and the update call records inputs, outputs, and cost. Swap the import and it is roughly the same story in LangSmith or an OTel setup.
Match the tool to your real constraint, not the feature matrix.
These are not exclusive. A common pattern is Helicone at the gateway for cost, plus Langfuse or LangSmith for traces and evals.
For most teams shipping agents in 2026, self-hosted Langfuse for tracing, prompt management, and evals, with OpenLLMetry as the instrumentation layer so you are not locked to one vendor's SDK. It keeps trace data in your control, covers the full agent tree, and slots into an OTel pipeline you may already run. Reach for LangSmith instead only if you are all-in on LangGraph and value the native integration over portability. Start with tracing on day one; add evals the moment you have a prompt worth protecting from silent drift.
Get the latest tutorials, guides, and insights on AI, DevOps, Cloud, and Infrastructure delivered directly to your inbox.
MCP is an open standard that gives AI agents one consistent way to reach external tools and data instead of bespoke glue.
A practitioner's tour of the reusable patterns for building reliable LLM agents, and when each one earns its keep.
Explore more articles in this category
Small language models now handle most agent steps at a fraction of the cost, so pick per step instead of defaulting to a frontier model.
AI agents went from demos to production this year. This is the map: the frameworks, the protocol tying them together, and the patterns that actually ship.
A practitioner's tour of the reusable patterns for building reliable LLM agents, and when each one earns its keep.
Evergreen posts worth revisiting.