AI Tool Pipelines — Automate Your WorkflowsAI Tool Pipelines

How to Debug AI Agent Tool-Routing Decisions

7 min read · Updated Aug 5, 2026

A person monitoring multiple screens in an industrial control room

You debug a wrong tool-routing decision the same way you debug any nondeterministic system: capture the full context that produced it (the exact system prompt, the tool schemas the model saw, and its raw output before your code parsed it), reproduce it at temperature 0 to rule out randomness, then check whether two of your tool descriptions are actually distinguishable to a model that has never seen your codebase, only the text you gave it. Most misrouting bugs turn out to be a naming or description problem, not a model capability problem.

Key takeaways

  • Log the full routing decision, not just the outcome: the system prompt, the tool schemas offered, and the model’s raw tool-call output, before your code does anything with it.
  • Reproduce at temperature 0 first. If the same input produces different routing on different runs, you are debugging randomness, not a logic bug, and the fix is different.
  • Most misrouting comes down to two tool descriptions that are too similar for the model to distinguish reliably, not a limitation of the model itself.
  • Build a small golden set of representative inputs and their correct tool choice, and re-run it after every prompt or tool-description change.
  • For ambiguous or high-stakes routing decisions, add a confidence check or a human-in-the-loop confirmation step rather than trusting every routing decision blindly.

"It picked the wrong tool" is not enough to debug

That sentence alone gives you nothing to act on. It picked the wrong tool compared to what expectation. Given what exact prompt. Was it close (a genuinely similar tool) or nowhere close (a sign of a broken schema or a missing tool entirely). Every one of those distinctions changes what you do next, and none of them are answerable after the fact if you only logged which tool ended up getting called.

Capture the full decision, not just the outcome

Log the exact system prompt, the full tool schema array as sent, and the model’s raw response before any of your own parsing touches it. This is the single highest-leverage change most teams can make to their agent pipelines, and most have not made it.

javascript
async function routeWithLogging(systemPrompt, tools, userMessage) {
  const response = await llm.chat({
    system: systemPrompt,
    tools,
    messages: [{ role: 'user', content: userMessage }],
    temperature: 0,
  });

  await routingLog.insert({
    timestamp: new Date().toISOString(),
    systemPrompt,
    toolNames: tools.map((t) => t.name),
    userMessage,
    rawResponse: response, // before parsing, this is what saves you
  });

  return response;
}
Logging the full routing decision before it is parsed or acted on.
Two technicians operating machinery in a modern industrial control room

Rule out randomness first

Run the exact same input, same prompt, same tools, at temperature 0 a handful of times. If the routing decision stays consistent, the bug is in your prompt or tool descriptions, and rewriting a tool description is the right fix. If it flips between runs even at temperature 0 (some providers still have minor nondeterminism at temperature 0 due to floating-point and batching effects), the issue may be that the two candidate tools are close enough in score that noise decides the outcome, which points you toward making the distinction between them sharper rather than debugging either tool description in isolation.

The two tools that were basically the same tool

In January 2025, a support-routing agent I built kept calling escalate_to_human instead of create_refund_request on roughly one in six genuinely refundable requests, almost always the ones phrased as a complaint before mentioning money. I spent close to a full day assuming it was a model limitation before actually reading the two tool descriptions side by side. escalate_to_human read "use for customer complaints requiring human attention." create_refund_request read "use when a customer requests a refund." A message that led with frustration and mentioned a refund halfway through matched both descriptions about equally well from the model’s point of view, because both were true. Rewriting escalate_to_human to explicitly exclude any message mentioning a refund dropped the misroute rate to roughly one in forty on the same test set, with no change to the model, the prompt structure, or anything else.

Build a golden set before you touch the prompt again

A golden set is a small, fixed collection of representative inputs paired with the tool each one should trigger. Without one, every prompt or tool-description edit is a guess you validate by eyeballing a handful of manual test messages and hoping nothing else broke.

A slice of what a routing golden set looks like in practice.
Input excerptExpected toolWhy it is tricky
"This is ridiculous, I want my money back"create_refund_requestFrustration phrased first, refund intent is still clear
"Can someone actually help me, nothing here works"escalate_to_humanNo refund mentioned at all, pure complaint
"Charged twice, need this fixed today"create_refund_requestUrgency language could read as an escalation on its own
Abstract visualization of digital circuit blocks with vibrant LED lights

When to add a confidence check instead of trusting the routing

For low-stakes routing, a wrong call is an inconvenience. For anything destructive or financial, a wrong call is an incident. Ask the model to state which other tool it considered and how close the decision was, or check whether two tools scored similarly if your provider exposes that, and route anything below a confidence threshold to a human confirmation step instead of executing automatically. This is not a substitute for fixing ambiguous tool descriptions, it is a safety net for the cases that stay genuinely ambiguous even after you have.

I think most "the AI agent made a bad decision" postmortems misdiagnose the problem as a model-capability issue when it is actually a specification issue. Read your own tool descriptions as if you were a competent contractor who joined the project this morning, with no access to the code behind them, only the schema text. Most of the ambiguity a model struggles with, a genuinely new team member reading the same descriptions would struggle with too.

Anthropic’s own tool-use documentation (2024) makes this exact point directly: it recommends writing tool descriptions as if they were doc-comments for a new engineer joining the team, since the model has no access to your source code or your mental model of the system, only the text you put in the schema.

“An agent does not misread your intent. It reads exactly what you wrote, and what you wrote was ambiguous enough for two answers to both look right.”

Frequently asked questions

Frequently asked questions

Why does an AI agent sometimes call the wrong tool?

Most often because two or more of the available tool descriptions are similar enough that the model cannot reliably distinguish which one applies to a given input, especially when the input plausibly matches both. This is a specification problem far more often than a model capability problem.

How do I debug a nondeterministic routing decision?

Capture the full context (system prompt, tool schemas, raw model output) for the failing case, then reproduce it at temperature 0 across several runs. Consistent output points to a prompt or tool-description problem, inconsistent output points to two tools scoring too closely for noise to be ruled out.

What should I log to debug tool-routing decisions later?

The exact system prompt used, the full tool schema array sent to the model, and the model’s raw, unparsed response. Logging only the final action taken removes any ability to inspect why the decision happened after the fact.

What is a golden set and why do I need one for routing?

A fixed collection of representative inputs paired with their correct tool choice, used as a regression test suite. Without one, every prompt or tool-description edit is validated by manual spot-checking, which reliably misses cases that used to work and quietly broke.

Does lowering the temperature fix misrouting?

It removes randomness as a variable so you can tell whether a misroute is consistent or intermittent, which is essential for debugging. It does not fix the underlying ambiguity in your tool descriptions on its own, that still needs to be rewritten.

Should I always trust an agent’s tool-routing decision?

For low-stakes actions, usually yes. For destructive or financial actions, add a confidence check or a human confirmation step for decisions that fall below a reasonable threshold, rather than executing every routing decision automatically regardless of how ambiguous the input was.