
Designing Tool Errors for Agents
When a tool fails, the error is the only instruction the agent gets for what to do next. How to write errors that lead to a correction instead of a retry loop, and what to keep out of them.
Tag archive

When a tool fails, the error is the only instruction the agent gets for what to do next. How to write errors that lead to a correction instead of a retry loop, and what to keep out of them.

An agent re-reads the same instructions, tools and history on every step, and pays full price each time unless the prompt is built for caching. Where the boundary belongs, which TTL fits which gap, and how to read a hit rate honestly.

Restarting a failed agent run from step one doesn't just waste the work already done — the second attempt can take a different path and contradict the first. Durable execution saves state after each step, so a crashed, deployed or paused run resumes at the next step instead.

An agent that remembers everything soon remembers it wrong — stale facts and one-off details included. Memory earns its keep only when what to store, when to write it, and when to delete it are designed decisions, not defaults.

When an agent gives a wrong answer, the final text is the one part of the run you don't need to debug. A trace — one run broken into timed steps for every model call, tool call and retrieval — turns "it failed" into the exact step where it failed, and what that step was looking at when it did.

A timeout after a write tells you nothing about whether the write happened. Agents retry anyway, through frameworks, queues and restarts as well as their own loops, so every action with a side effect needs a stable key, a record of what it did, and a reconciliation path for the systems that offer neither.

Multi-agent systems earn their cost in one shape of work — breadth-first, read-heavy, loosely coupled — and lose it in another. The evidence from the teams and researchers who have measured them points to the same dividing line: fan out for reading, keep writing and deciding in one thread.

We asked the same twelve business questions of the same data stored two ways, a clean demo schema and a legacy one, across three production models and two datasets. On the larger legacy database the best score was 3 of 12. Every failure clustered on facts the schema never states, and the fixes the post recommends lifted every model to 8 or better.

A deployment rarely fails in the build. It fails earlier, in the opening weeks, when the brief's version of the problem goes unchallenged. Five heuristics for the embed phase: find the real problem, the real data and the real owner before the build locks in.

Swapping the model is a one-line edit. Proving the replacement still does your job — on your prompts, your data, your awkward edge cases — is a release: an inventory, an eval replay by slice, a shadow run, a canary, and a rollback that only works while the old model still exists.

An agent with a shell inherits everything the shell can reach — your files, your keys, your network. A sandbox replaces per-command permission prompts with an enforced boundary: a short list of files, hosts and credentials the code can touch, and nothing else.

Schema-constrained generation guarantees the shape of a model's answer — every required field present, every type right, every enum legal. It says nothing about whether the values are true. Production systems still need semantic validation, bounded repair, and a reject path.