Here is a pattern anyone who has watched agent traces will recognize. The agent needs order history. Your API has query_api, get_data, and fetch_records — three names that could all plausibly do it. It picks one, guesses at nine optional parameters, gets back either a 10,000-row JSON dump that floods its context or Error 500 with no hint of what to change, retries the identical call twice, and wanders off to reconstruct order history from a different tool entirely. Twelve calls, four thousand tokens, one piece of information. Then we look at the trace and conclude the model needs to be smarter.
The model was fine. The interface was hostile. Anthropic’s engineering team made this point bluntly in their guide to writing tools for agents: tools are not an API wrapper, they are part of the prompt — every name, description, parameter, and response is text a language model must interpret under uncertainty. Function-calling benchmarks like BFCL show even frontier models losing double-digit accuracy when tool definitions get ambiguous or overlapping — the same model, the same task, different interface, very different agent.
And the long-horizon lens makes it compound. In the evaluation post I argued that small per-step differences explode over hundreds of steps. Tool ergonomics are that per-step difference: a 5% tool-selection error rate is invisible in a demo and fatal at step 200.
01The seven sins of tool design
Each sin below produces a specific, observable behavior in the trace — which means each one is diagnosable from the metrics you already collect, and fixable without touching the model.
| Sin | Trace symptom | Fix |
|---|---|---|
| 1 · Ambiguous names | get_data vs fetch_records — wrong tool picked, or dithering between twins | Verb_noun names that state intent: search_orders, refund_payment. One tool per job; delete the twins |
| 2 · No usage contract | Right tool, wrong situations — used where another tool was meant | Description says when to use it and when not to, and names the alternative |
| 3 · Kitchen-sink parameters | Hallucinated arguments, invalid enum values, missing required fields | ≤3 required params; enums over free strings; split mega-tools into focused ones |
| 4 · Unbounded responses | One call floods the context; the agent forgets its own plan | Default limits, pagination, and a response_format: concise|detailed knob |
| 5 · Dead-end errors | Identical retry, identical failure — the doom loop’s favorite food | Errors are prompts: say what was wrong and what to try instead (“user_id not found — did you mean search_users first?”) |
| 6 · Opaque identifiers | UUIDs copied wrong, hallucinated IDs, joins the agent can’t follow | Return names and human-readable context alongside (or instead of) raw IDs |
| 7 · Unmarked side effects | Agent “checks” something by mutating it; retries double-charge | Annotate read-only vs destructive vs idempotent — and make retries safe by design |
› Go deeper: why “a tool definition is a prompt” is literally true
Every tool schema is serialized into the model’s context verbatim — name, description, parameter docs, all of it. The model chooses tools by reading that text, exactly as it reads your system prompt. Which means everything we know about prompt quality transfers: be specific, state the contract, give an example, bound the output. The difference is leverage — you write the system prompt once, but the agent re-reads the tool text at every decision point. A one-line improvement to a tool description is a prompt improvement applied hundreds of times per task.
02The grader: score a tool definition, live
The rubric below runs in your browser and re-scores on every keystroke. It checks the eight things a tool review should check: is the name an intent, does the description carry a contract, are the parameters few and documented, is the response bounded, do errors teach, is there an example, are side effects declared. Load the sinful tool, read its scores, then load the redeemed version — same underlying API, different interface.
Tool definition (JSON)
Two honest notes about what you just saw. The redeemed tool is longer — good tool text usually is; you are spending tokens on the definition to save multiples of them at call time. And the rubric is heuristic: it reads the text the way a reviewer would, not the way a model does. The ground truth is always an agent-in-the-loop eval — which is Section 04.
03Responses are prompts too
Half of tool design happens after the call returns. The response lands in the same context window as your carefully-tuned system prompt — and can bury it. Four rules cover most of it:
- Budget the payload. Default to the concise form; make verbosity opt-in (
response_format). Anthropic’s team found token-efficient responses were one of the highest-impact changes across their internal tools. - Return meaning, not plumbing.
{"name": "Acme Corp", "status": "overdue"}beats{"cust_ref": "9f3ab..."}— the agent reasons over words, and every opaque ID is a hallucination invitation. - Make errors instructional. The error string is the one piece of your system guaranteed to be read at the exact moment the agent is deciding what to do next. “date must be YYYY-MM-DD; you sent 07/22/2026” converts a doom loop into a one-step recovery.
- Paginate by default. If a response can be huge, someday it will be — at step 180 of a 200-step task, right on top of the plan.
04Close the loop: evaluate tools like you evaluate agents
Tool quality is measurable with the same trace metrics from the long-horizon eval framework, sliced per tool instead of per agent: selection accuracy (was this the right tool for the step?), call-error rate (schema violations, bad params), retries per successful call, and tokens per successful call. Run your eval suite, rank tools by these, and fix the worst one — it’s usually obvious once you look. Then repeat, because the second-worst tool is now the worst.
And use the loop’s best trick: let the agent rewrite the tool docs. Give a strong model the failing traces plus the current tool definition and ask what confused it. Anthropic reports Claude-optimized tool descriptions beating hand-written ones on their internal benchmarks — the agent is, after all, the native speaker of the language your tools are written in.
The framing I’d push
Treat your tool surface like a product with one very unusual user: read the traces as user research, fix the top confusion, ship, re-measure. Prompt engineering got a decade of attention; interface engineering for agents is the same leverage, mostly unclaimed.
05Where better tools don’t save you
· Perfect tools can’t fix a missing capability. If the model can’t plan a refund flow, renaming refund_payment won’t teach it. Interface fixes recover leaked capability — diagnose with an oracle run (hand the agent the correct tool sequence; if it still fails, the gap is the model, not the tools).
· The rubric is gameable, the eval isn’t. You can write descriptions that ace the grader and still confuse agents in practice. The grader is a code-review aid; agent-in-the-loop metrics are the ground truth.
· More tools is its own sin. A hundred beautifully-designed tools still burn context and split the agent’s attention. Consolidate aggressively; the best tool count is the smallest one that covers the workflows.
Takeaways
- A tool definition is a prompt — re-read at every decision point. Edit it with the same care as your system prompt, and expect more leverage.
- Names are decisions. If two tools could plausibly do the job, the interface — not the model — just created an error rate.
- Bound every response and teach in every error. Context is the agent’s working memory; a hostile payload is memory corruption.
- Declare side effects. Read-only vs destructive vs idempotent is the difference between a safe retry and a double refund.
- Measure per-tool, fix the worst, repeat — selection accuracy, call-error rate, retries, tokens per success.
- Let the agent edit the docs. It’s the native speaker.
On a long-horizon task the agent will touch your tools a thousand times. Every one of those touches is either compounding for you or against you.