What you’ll be able to do
- Write tool names and descriptions for the selection moment, not the implementation
- Keep parameter schemas tight enough that invalid calls are structurally impossible
- Recognize when two tools overlap and should be merged or clearly partitioned
- Design for a model choosing among many tools, not calling the one tool you tested
What you need to know
A tool description is read at the wrong time to explain itself
By the time a tool's description matters, the model has already committed to reading it as a decision aid: does this tool do what I need, right now, given this request? A description that explains internals — "queries the v2 inventory microservice" — answers a question nobody asked at that moment. A description that explains effect and scope — "look up current stock for a single SKU by exact ID" — answers the actual question.
This distinction gets harder, not easier, as an application grows. A single well-described tool is forgiving; ten tools with vague, overlapping descriptions turn every call into a coin flip the architect can't debug from the outside, because the failure isn't in the tool's code — it's in which tool got picked.
Tight schemas remove a whole failure class
A parameter schema is not documentation. It's an enforcement boundary. Every value the schema doesn't rule out is a value your handler has to defend against at runtime — and defending at runtime means the failure surfaces as a confusing tool error instead of never happening.
The architectural point: an enum, a bounded number range, or a fixed date format isn't extra ceremony — it converts an entire category of bug from "discovered in production when the handler mishandles it" to "impossible to construct in the first place."
Overlap is a selection-time bug, not a code smell
Two tools can each be individually well-written and still break the system together, if their descriptions both plausibly cover the same request. get_customer_by_email and search_customers with a filter on email look redundant to a human skimming the code, but the actual failure mode is worse than redundancy: the model has no reliable way to know which one you intended for the ambiguous case, and it will pick inconsistently across otherwise-identical requests.
The fix is architectural, not textual — merge the overlapping pair into one tool with a parameter, or partition their descriptions so the boundary between them is unambiguous ("use this only when you already have the exact ID"). A better sentence in one description while the other tool still overlaps doesn't remove the ambiguity; it just moves it.
Key concept
A tool schema is a contract for a reader that can’t ask a follow-up question. Everything the schema doesn’t constrain becomes a runtime defense; everything the description doesn’t disambiguate becomes a selection error.
When a scenario describes a model "calling the wrong tool" or "constructing an invalid call," the fix under test is almost always schema or description design, not a smarter model or a longer prompt.
Practice scenario
update_order, modify_order, and edit_order_details — added over time by different engineers, each doing a slightly different subset of the same underlying update. Calls to the wrong one are now a recurring bug report.Work it through, then open this
The bug isn’t in any single tool’s code — it’s that three descriptions cover overlapping ground with no disambiguating signal. The fix is consolidation: one update_order tool with parameters covering the full range of what the three used to split apart, and a schema that makes invalid combinations of those parameters unconstructable. Renaming the three tools without merging them would not fix this; the ambiguity is structural, not lexical.
Build exercise — Audit a tool for selection ambiguity
Intermediate · 25 min
What you’ll learn
- Reading a tool description the way a selecting model reads it
- Finding parameter fields that don’t structurally rule out invalid values
- Spotting a second tool that silently competes for the same requests
-
Take a tool your application already exposes and list every other tool whose description could plausibly also handle the same sample request.
- Why: Overlap is invisible from inside a single tool’s code — it only shows up when you compare descriptions side by side.
- You should see: Either a clean partition, or two tools that would both look reasonable to a model receiving the same request.
-
For each parameter, ask whether an invalid value can currently be constructed. Convert free-text fields with a small fixed set of valid values into an
enum.- Why: Every unconstrained parameter is a defense your handler has to write and a failure mode your handler has to explain.
- You should see: A shorter list of “things the handler must validate” and a schema that now does that work instead.
Exam traps
Naming a tool after its internal implementation instead of its effect
A name like query_v2_service tells the model nothing about when to use it. Names should describe effect and scope.
Writing a description for a human maintainer instead of the calling model
The audience at call time is the model deciding whether this tool fits the current request — not a future engineer reading the source.
Leaving a parameter’s format unconstrained when only a few values are valid
An unconstrained field pushes validation into the handler and turns a preventable error into a runtime one.
Shipping two tools whose descriptions could both plausibly apply to the same request
This is a selection-time bug, not a documentation issue. Merge or clearly partition them.
Assuming a working demo with one tool proves the schema at ten tools
Overlap and ambiguity are invisible with a single tool and only appear once there’s something to be confused with.
Making a required field optional to be “flexible”
It reintroduces the invalid states the schema existed to rule out, in exchange for convenience nobody asked for.