Skip to content
The Operon Library

Volume IV · Chapter 3

Tools Are APIs for Agents

Tool design as the new interface design: naming, granularity, error surfaces, token cost of tool results.2026-07-12 · 9 min read

A team building an internal harness for its own codebase makes what looks like the disciplined choice: instead of shipping a dozen bespoke tools, they give the agent one — run_shell_command — and let it do everything a shell can do. It searches with grep, inspects history with git log, restarts a service with a deploy script, all through the same door. The surface area is minimal. There is nothing to maintain, no schema to keep in sync with the codebase, no decision about which operations deserve their own name. On paper, this is the harness equivalent of handing a new hire root and a terminal: maximal capability, zero abstraction tax.

What actually happens is that the agent spends a meaningful share of every session reconstructing shell invocations from scratch, and reconstructing them inconsistently. One session searches with grep -rn and remembers the file-type filter; the next forgets it, greps the .git directory and node_modules along with the source, and then has to read through several thousand irrelevant lines to find the one it wanted. A command that fails returns whatever the shell returns — a bare non-zero exit code and a stderr line written for a human who already knows the codebase, not a model deciding what to attempt next. And nothing about the tool’s name or signature signals that git push --force or rm -rf are different in kind from ls or cat. The harness has delegated the judgment about which shell commands are dangerous to a model reconstructing the command fresh every time, from a blank slate, under no structural constraint at all.

What the tool call actually costs

The previous chapter named the shape of the agent loop — gather context, act, observe, repeat — without dwelling on what “act” actually is. For nearly everything an agent does beyond producing text, acting means calling a tool: a discrete, named operation the harness exposes, with a schema describing what it accepts and a contract, implicit or explicit, about what it returns. run_shell_command is technically a tool by that definition, but it does no work on the agent’s behalf — it is a pipe. A well-designed tool, by contrast, does real cognitive work for the agent before the agent ever calls it: it has already decided what a safe, correctly formed request looks like, and it already knows what the caller is likely to need back. The gap between those two things is not a matter of taste. It shows up as tokens spent reconstructing boilerplate, as retries after malformed commands, and as failure modes a better-designed tool would have made unreachable in the first place.

Tools are APIs for agents

This volume’s third chapter argued that a prompt is an interface, not an incantation — that the vocabulary of affordances, constraints, and error states built for user-interface and API design applies wholesale to how an instruction is written, independent of tone. The same argument extends one layer down, to the tools a harness exposes for the agent to call. A tool is, structurally, exactly what an API endpoint is: a named operation with a schema, invoked by a party that has to infer what a valid request looks like from the name, the parameter list, and whatever documentation is attached to it. The only unusual thing about this particular API is its caller. A conventional API’s caller is a compiler or a strongly typed client that refuses to compile a malformed request. A tool’s caller is a language model inferring what a well-formed call looks like the same way it infers anything else — from pattern and context, not an enforced contract. That does not make interface design less important for tools. It makes the interface do more of the work, because no compiler stands behind the caller to reject a bad guess before it executes.

A run_shell_command tool is an API with no schema, no docs, and a caller that has read a thousand shell tutorials and none of them describe this codebase.

Naming is the first and most visible dimension of that interface, and it functions the way a signifier functions in a physical interface: a perceptible cue about what an object permits, read before the object is used. A tool called run signifies nothing about what it is for; a model deciding whether to reach for it has no information beyond a parameter that is just a string. A tool called search_files or run_tests signifies its purpose in the name itself, and a model choosing among several candidate tools is, in effect, pattern-matching against those names the way a person scanning a toolbar pattern-matches against icons. Anthropic’s own guidance here is concrete rather than aesthetic: it recommends namespacing — grouping related tools under a shared prefix or suffix, so asana_search and jira_search stay distinguishable rather than shipping two identically named search tools — and reports that even the choice between prefix- and suffix-based namespacing measurably changed evaluation results, the kind of finding that only turns up once someone tests naming empirically instead of treating it as cosmetic.

Granularity is the second dimension, and it is the one plain intuition gets wrong most often, because the obvious fix for “too broad” looks like “many narrow tools,” and that is not reliably an improvement. A tool that requires the model to correctly assemble a complex, multi-step shell pipeline every time is too broad — the run_shell_command failure above. But ten narrow tools that each do one small thing — list_users, list_events, create_event — force the model to chain them correctly, in the right order, every time, with every intermediate result round-tripped through the context window. Anthropic’s guidance argues for a middle path: consolidate the operations an agent would naturally chain into a single tool shaped like the task, not like the underlying data model — schedule_event instead of the three-tool chain, get_customer_context instead of separately fetching a customer record, their transactions, and their notes. It is the same discipline Roy Fielding formalized for REST APIs two decades earlier: an interface is a coordinated set of constraints on components and data, not a friendlier wrapper around whatever the backend exposes. Match the tool to the unit of work a caller needs, and a whole category of chaining error becomes structurally unreachable rather than merely unlikely.

Error surfaces are the third dimension, and they matter because a tool call fails constantly in ordinary use — a file does not exist, a query times out, a permission is denied — and what comes back from that failure determines whether the agent can recover in the same turn or has to guess. A raw stack trace or an opaque error code is information a human debugging the codebase can use and a model mid-session largely cannot; it burns a turn’s worth of tokens rendering a traceback that names no next step. Anthropic’s guidance treats this explicitly as a writing problem, not a logging problem: an error response can be engineered to name what went wrong and suggest a specific, actionable correction — narrow the search, use pagination — the same way a well-designed form rejects a malformed submission by naming which field failed, and why. Jakob Nielsen’s decades-old heuristic for error prevention was never written with language models in mind, but “the best designs carefully prevent problems from occurring in the first place” describes exactly what a schema-validated, well-scoped tool does that a generic shell pipe cannot: it makes a whole class of malformed request impossible to construct, rather than possible to construct and then apologize for.

The fourth dimension is the one most likely to be invisible to whoever designed the tool, because it does not surface as a bug — it surfaces as a context budget quietly spent on the wrong things. A tool that returns an entire file when the model asked a question answerable from one function is not wrong, exactly; it is expensive, in precisely the sense the prior volume’s argument about context rot describes: every token a tool result adds to the window competes for the same finite attention budget as everything else in it, and the model then has to do the filtering work a better tool would have done first. Anthropic’s own comparison of a verbose and a curated response format for the same underlying data found the concise version costing roughly a third of the tokens of the detailed one — retaining the identifiers a follow-up call would need while dropping low-signal fields, UUIDs, raw image URLs, MIME types, that a human skimming an API response tolerates and a model paying for every token should not have to.

Four dimensions of tool design

Put together, the four dimensions form a checklist a harness’s tool roster can be audited against — not unlike the interface checklist the previous chapter applied to prompts, aimed one layer further down, at the tools those prompts eventually cause the agent to call.

Design dimensionWhat a poorly designed tool doesWhat a well-designed tool does
NamingA generic label (run, execute, do_task) that signifies nothing about purpose or scopeA specific, namespaced label (search_files, run_tests, schedule_event) a model can pattern-match against without reading documentation
GranularityOne broad tool the model must assemble complex, error-prone requests for, or many narrow tools that must be chained in exact orderOne tool shaped like the unit of work a caller actually needs, consolidating the steps a task naturally chains together
Error surfacesA raw stack trace, an opaque status code, or a silent failure with no signal about what to try nextA specific, actionable message naming what went wrong and suggesting a concrete next step
Token cost of resultsA full, unfiltered payload — entire files, entire logs, every field a backend happens to returnA curated, right-sized result with sensible defaults for pagination, filtering, and verbosity, exposed as caller options rather than assumed

What Anthropic found when it measured

None of this is presented, in Anthropic’s own published guidance, as best practice meant to be intuited correctly on the first attempt. The recommendation is explicitly empirical: prototype a tool, wire it into a working agent, and run it against dozens of realistic evaluation tasks before treating the design as settled — tasks specific and multi-step enough to resemble production use, not a single happy-path call. A tool that reads as well designed to the engineer who wrote it can still be systematically misused by a model in ways that only surface once real tasks are run against it and the transcripts are read, the same way a form that looks intuitive to its designer can still produce malformed submissions once real users touch it. The guidance goes further than most engineering advice usually bothers to: it describes letting an agent read its own evaluation transcripts and propose fixes to the tool definitions, finding measurable improvements beyond what the humans who wrote the “expert” version of the same tools had achieved by hand. Whether or not a given team adopts that specific practice, the underlying claim is the one worth taking seriously: tool quality is measurable, not merely arguable, and a roster should be evaluated the way any other system component is — against real tasks, with metrics, not a reviewer’s sense of what looks clean.

A tool that looks well-designed to the engineer who wrote it can still be systematically misused by a model. That gap only closes by running real tasks against it and reading what came back.

On Anthropic’s guidance for evaluating agent tools

What a tool-usage audit should surface

Most harnesses do not currently instrument their own tool roster well enough to answer basic questions about it — which tools consume the most context per call, which ones get retried most often after a malformed first attempt, which ones return payloads the model visibly never uses in full. That is not a criticism specific to any one team; it is the same instrumentation gap Volume I named at the session level, one layer further down, at the level of the individual tool call.

The roster is not fixed

None of the four dimensions above are properties a harness inherits passively from whichever operations happened to be easy to wire up first. A tool roster is a designed artifact, in the same sense a prompt library or a permission model is a designed artifact — and treating it as an afterthought, the leftover surface between “what the backend exposes” and “what the agent needs,” produces exactly the failure this chapter opened with: a generic pipe standing in for a dozen tools never built, because building them looked like unnecessary abstraction. It is not. The next two chapters take up what sits directly on top of this decision — which actions get auto-approved and which get gated behind a human, and how far a mistake’s blast radius is allowed to reach — and both questions get easier to answer once the tool roster has already made entire classes of request impossible to make badly. It is the same throughline Anthropic’s own guidance on long-running agent harnesses keeps returning to: an agent’s reliability over a long session is inseparable from the scaffolding around it, and the tools are not its least important piece — they are the vocabulary the loop is written in.

For Discussion

  1. Pull the five tools your harness calls most often. How many have a name specific enough that a new engineer could guess their purpose without reading the schema?
  2. The last time a tool call failed mid-session, what came back — a stack trace, or a message that told the agent what to try next?
  3. If you audited a week of tool-call token usage, would you expect the cost to concentrate in a handful of overly verbose tools, or spread evenly across the roster?

References

  1. establishedWriting effective tools for agents — namespacing, consolidation, actionable errors, response-format curation, and empirical evaluation harnessesAnthropic engineering · 2025-09-11
  2. establishedEffective context engineering for AI agents — context as a finite, curated resourceAnthropic engineering · 2025-09-29
  3. establishedEffective harnesses for long-running agentsAnthropic engineering · 2025-11-26
  4. establishedContext Rot: how models use context, evaluated across 18 modelsChroma Research · 2025-07
  5. establishedThe Design of Everyday Things (Revised and Expanded Edition) — affordances and signifiersDon Norman, Basic Books · 2013
  6. establishedArchitectural Styles and the Design of Network-based Software Architectures (doctoral dissertation) — architectural style as a coordinated set of constraints; origin of RESTRoy T. Fielding, University of California, Irvine · 2000
  7. establishedTen Usability Heuristics for User Interface Design — error preventionJakob Nielsen, Nielsen Norman Group · 1994