ByHeartAI
Advanced8 min read

Tool, Retrieval, and Agent Traces

An agent trace is a waterfall: retrieve, plan, tool, answer — each a child span with ids, timings, and status. You debug "wrong tool" or "empty retrieval" by clicking the guilty row, not by rereading the final chat.

Explain like I'm new to AI

A wrong answer has stages. If you only store the final paragraph, you cannot tell missed retrieval from ignored chunk from bad tool args from looping. Nested spans make the stages visible.

trace_id=7f3a · click a span

in=1280 out=220 ttft=380ms cited=false invented=§4.2

Here is the bug: context had the truth, the final span still invented a section. Observability found the stage; eval would have scored it.

Nested spans: retrieve, tools, each model call. The waterfall shows which stage failed — not just that the answer was wrong.

What to record (minimum):

  • Retrieve: query (or hash), k, hit ids, optional scores. Not always the full chunk text.
  • LLM: model, tokens, finish_reason, tool names it requested.
  • Tool / MCP: name, hashed args, status, duration, result size. Raw results often hold secrets — default off.
  • Loop: iteration index, stop reason (done / cap / error).

Mental model

A kitchen pass: ticket in, grill, sauce, plate. If the plate is wrong you look at which station timestamped last — not only the complaint at the table.

How it works

Parent span = user turn (or agent run). Children = each retrieve, embed, rerank, model, tool. MCP calls are tool spans with server name as an attribute (the protocol is still "a tool ran").

Empty retrieve vs wrong retrieve: hits=0 vs hits=8 but none of the gold ids. That's the same split as RAG evaluation, live.

Wrong tool: the llm.plan span shows tool=refund with args hash; you compare to policy. Excessive agency (Security, next category) is this span with a destructive name you should have gated.

Cap max iterations in the runtime and alert when traces hit the cap. Observability without a cap just documents a money fire.

Multi-turn: session_id on the parent so you can see memory and prior tools, but each turn still has its own tree.

Real-world example

User: "cancel my order." Final text is polite. Trace: tool.delete_account ran. The chat UI lied; the waterfall didn't. Grade trajectories, not only the last sentence (eval category said the same — traces are how you capture the trajectory).

Technical explanation

Span events can mark "token stream started" without storing the stream. For RAG, store chunk ids so you can join to the index version (retriever_version on the span — next lesson).

Don't nest 200 tiny spans per token; nest semantic operations. Cardinality of span names should be a short enum, not the user query.

Tail-sample traces with loop_count > 3 or tool_error always kept.

Common mistakes

Common mistake

One timer around "the agent." You will know it was slow and never which child.

  • Logging full tool JSON (API keys, account dumps).
  • No retrieve ids — you cannot replay what the model saw.

When to use it

  • Any tool-using or RAG system in production. Multi-agent: one trace per handoff, linked by parent id.

When NOT to use it

  • Don't flatten to a single "LLM call" span "to keep it simple." That's how you go back to superstition.
  • Don't store every retrieved paragraph in the trace store by default.

Alternatives

  • Application debugger on your laptop — not the fleet. Eval sets catch average quality; they won't show this morning's delete_account.

Quick quiz

Question 1 of 3

Why nest retrieve / llm / tool as child spans?

Question 2 of 3

The final message is polite but delete_account ran. What catches that?

Question 3 of 3

True or false: you should log full tool JSON by default for easier debugging.

Related concepts

  • Tracing, Logging, and MetricsTraces are the request tree, logs are events on that tree, metrics are fleet aggregates — join them with a trace id, and sample the expensive and failing calls.
  • How to Evaluate RAGRAG evaluation measures retrieval quality (context precision/recall) and generation quality (faithfulness, answer relevance) separately to find and fix failures.
  • What is MCP?MCP is an open protocol that lets any AI app discover and use tools, files, and prompts from external systems through a shared client-server language.
  • Tool Abuse and Excessive AgencyIf the model can call a powerful tool, injection can try to. Shrink the kit, validate args, and require humans for irreversible actions.
NextPrompt Versioning and Evaluation Traces

Last reviewed: 2026-09-04 · Written by ByHeart AI · Reviewed by ByHeart AI