Tool schemas are an API design problem, not a prompt problem
When an agent calls the wrong tool or invents a parameter, the fix usually isn't a better prompt — it's a better schema. Here's how to design tools agents actually use correctly.
When an agent picks the wrong tool, or calls the right tool with a hallucinated parameter, the instinct is to fix it in the prompt: add a warning, add an example, add “IMPORTANT: only use this when…”. That works for a day and quietly breaks again next week. The actual bug usually isn’t in the prompt — it’s in the tool schema. You shipped an API with ambiguous names, overlapping responsibilities, or no validation, and you’re asking the model to guess its way around a bad interface. Models are good at using clear tools and bad at reading your mind.
Treat the tool list like a public API, because it is one
Every tool you register is a function some non-deterministic caller will invoke with arguments it generates itself. That caller can’t read your source code, can’t ask a teammate what a field means, and can’t step through a debugger when it’s confused. The schema — name, description, parameter types, examples — is the entire interface. If it’s ambiguous to a human skimming it, it’s ambiguous to the model choosing it under a full context window.
Two rules do most of the work:
- One tool, one job.
get_orderandupdate_order_statusbeat oneorder_action(action, ...)tool with a mode flag. Overloaded tools force the model to pick the right mode from your description, and that’s exactly the kind of judgment call it gets wrong under pressure. - Names and descriptions carry the routing logic. The model chooses a tool primarily from its
name and description, not your system prompt.
search_refund_policywill get called correctly far more often thanquery(index, filters).
Narrow beats broad, every time
The temptation is to wrap an entire internal API as one flexible tool and let the model figure out the right call. It’s less code to write, and it fails constantly — the model has too much freedom and too little context to use it well. Agents with small, precisely scoped tool sets consistently outperform agents with broad, general-purpose wrappers on both accuracy and governance, because a narrow tool can only be called in a bounded number of wrong ways.
Bad: crm_api(method, endpoint, params) -> the model improvises a REST call
Good: get_contact(id), update_contact_email(id, email), list_open_deals(contact_id)
The narrow version is more upfront work. It also means every tool call is reviewable, loggable, and
individually permissioned — you can let an agent call get_contact freely and require approval on
update_contact_email without touching a single line of prompt.
Validate at the boundary, not in the model’s head
A schema with strict types, required fields, and enums where they apply catches a hallucinated argument before it reaches your database — a malformed date, a status value that doesn’t exist, an id in the wrong format. Don’t rely on the model to self-police; validate every call the way you’d validate an untrusted client, because that’s what it is. Reject with a specific, actionable error (“status must be one of: open, closed, pending” — not “invalid input”) and most models self-correct on the very next turn.
Write the description for the tool-picking moment
The description isn’t documentation for a human maintainer — it’s read at the exact instant the model is deciding what to call next, alongside a dozen other tool descriptions. State what the tool does, when to use it, and when not to (the sibling tool it’s often confused with). One good example call in the description beats three sentences of prose.
The prompt is not where reliability comes from
None of this replaces a good system prompt — it just moves the weight where it belongs. A prompt can tell an agent why it’s doing a task; it shouldn’t have to tell it how to hold a badly shaped tool. Fix the schema first. If the agent still misuses a clean, narrow, validated tool, that’s a real prompt problem — but by then it’s the exception, not the default failure mode.
We design and register tools this way in every agent we build, including inside Hive: narrow scope, strict schemas, boundary validation, and a description written for the moment a model is choosing between ten options and has one shot to pick right.
Want something like this built for your team?
Get a quote →