'Gets Data' Is Too Vague: How to Write Tool Descriptions That Work
▶ Watch on YouTube & subscribe to The Stack Underflow
You register a tool called get_data. The description field says, literally, “gets data.” It compiles fine, the schema validates, the demo works when you call it directly — and then in production the agent calls it at the wrong moments, ignores it when it’s the right tool, or confuses it with a similarly-named tool three lines down in the same server. Nobody touched the code. The bug is the sentence you didn’t write.
The one-sentence version: A tool description isn’t documentation for your teammates — it’s the only specification the model ever reads, so it has to say what the tool does, when to use it, what each argument means, and show an example.
The question
A tool’s description is just gets data, and the agent keeps misusing it — calling it when it shouldn’t, or skipping it when it should. What’s the best practice for writing tool descriptions?
- A) Keep them short to save tokens
- B) Write them FOR THE MODEL: what it does, when to use it, each arg, and an example
- C) Leave them blank
- D) Duplicate the function name
Pause here and pick an answer before you scroll.
The answer
The correct answer is B — write the description for the model: what the tool does, when to use it, what each argument is for, and an example call.
The mechanism is simpler than it sounds, and it’s easy to forget once you’re deep in backend code: the model never sees your function body, your docstrings, your internal comments, or your variable names. At tool-selection time, the only thing in its context is the tool’s name, its description string, and its JSON schema. That text block is the API, in the same sense that a REST endpoint’s OpenAPI spec is the API for a client that’s never read the server source.
WHAT THE MODEL ACTUALLY SEES AT SELECTION TIME
────────────────────────────────────────────────
Your codebase Model's context
┌─────────────────────┐ ┌─────────────────────────────┐
│ def get_data(...): │ │ tool: get_data │
│ # fetches records │ ✗ never │ description: "gets data" │
│ # from the orders │──sent───▶ │ params: { query: string } │
│ # table, retries 3x │ │ │
│ ... │ │ ← this is the ENTIRE spec. │
└─────────────────────┘ │ No comments. No source. │
└─────────────────────────────┘
BEFORE AFTER
┌───────────────────────────┐ ┌────────────────────────────────────┐
│ "gets data" │ │ WHAT: Looks up a customer's order │
│ │ ──▶ │ history from the orders DB. │
│ (agent guesses: web search? │ │ WHEN: Use when the user asks about │
│ file lookup? DB query?) │ │ past purchases or order │
│ │ │ status. Do NOT use for │
│ selector wavers / picks │ │ inventory or shipping ETAs. │
│ wrong tool, or skips it │ │ ARGS: customer_id (string, req.) │
└───────────────────────────┘ │ EX: get_data(customer_id="C-882") │
└────────────────────────────────────┘
selector snaps to correct tool
A well-formed tool description does four jobs in one string:
- WHAT — the plain function of the tool, in a sentence a non-engineer could parse.
- WHEN TO USE — the trigger condition, and just as important, when not to use it (this is what disambiguates it from a similarly-named neighbor).
- ARGS — what each parameter means in domain terms, not just its type (the JSON schema carries the type; the description carries the meaning).
- EXAMPLE — one concrete call, which anchors the model’s own generation the same way a few-shot example anchors a completion.
This is a selection-time problem, not a runtime problem. The model doesn’t run your tool to find out what it does — it reads the description, compares it against the user’s request and every other available tool’s description, and picks based on that text alone. Vague text produces vague, inconsistent selection even when the underlying implementation is flawless.
Why the other options fail
- A) Keep them short to save tokens. Tool descriptions are a few dozen to a couple hundred tokens, loaded once per turn as part of the tool list. Compare that to the cost of a wrong tool call: a wasted round trip, a bad result the model has to notice and recover from, sometimes a hallucinated correction on top of it. Optimizing token count on the one field that determines whether the call happens correctly at all is optimizing the wrong line item.
- C) Leave them blank. A blank description doesn’t make the model ask a clarifying question — it makes the model guess from the tool name alone, which is exactly the failure mode in the diagram above. Names are rarely self-disambiguating (
get_datavs.fetch_datavs.data_lookupall plausibly mean the same thing to a selector with no other signal). - D) Duplicate the function name. A description like
"get_data: gets data"restates the name in prose without adding any of the four things the model actually needs — the when, the args-in-context, or the example. It looks like documentation and functions like nothing.
The concept behind it
Zoom out from this one question and the underlying idea generalizes to most of tool design: everything the model uses to decide and to act has to be legible from inside its context window — nothing you know from reading the source code transfers for free. That’s true of the description (this question), the JSON schema (Q2 in this practice set — typing tool parameters), and the error payload a tool returns (Q3 — designing an error contract). In every case, the fix is the same shape: stop assuming implicit context and write the explicit spec the model can actually read.
For descriptions specifically, a few patterns hold up across most tool catalogs:
| Bad pattern | Why it fails | Better pattern |
|---|---|---|
"gets data" | No disambiguation from other tools | State the domain: “looks up order history from the orders DB” |
"searches" on two similar tools | Selector can’t tell them apart | Name the boundary: “for the public web,” “for internal docs only” |
| No WHEN clause | Model calls it at the wrong turn, or never | Add an explicit trigger: “use when the user asks about X” |
| Args typed but not explained | Model passes technically-valid but semantically-wrong values | Explain each arg’s meaning and constraints in plain language |
| No example | Model’s own call format drifts | Show one realistic call as an anchor |
This also scales downward into a governance concern once a catalog grows past a handful of tools: at 40+ tools, vague descriptions compound, because now the model isn’t just deciding whether to use a tool — it’s ranking many similar-sounding candidates against each other. That’s a related but distinct failure mode covered in scoping tools per agent: fixing the description helps one tool; fixing the count and grouping helps the whole catalog.
One more nuance worth internalizing for the exam: “write it for the model” is a voice instruction, not a length instruction. A tight, well-scoped description that nails WHAT / WHEN / ARGS / EXAMPLE in three sentences beats a rambling paragraph that never states the trigger condition. The test isn’t “how many words” — it’s “could a system with no other context correctly decide whether and how to call this.”
FAQ
Does the tool description length actually affect Claude’s accuracy, or is this overstated? It affects accuracy through content, not raw length. A short description that clearly states what/when/args performs better than a long one that’s vague on all three. The failure mode in this question isn’t “too few words” — it’s zero disambiguating information. Length only becomes a real problem if you’re padding with irrelevant detail that dilutes the signal (implementation notes, internal ticket numbers, etc.) rather than adding decision-relevant content.
Should the tool description or the JSON schema carry the parameter constraints?
Both, for different jobs. The schema (type, format, enum) is the machine-enforced guardrail — it’s what makes a malformed call impossible to emit in the first place. The description is where you explain meaning: why a field exists, when it matters, and what a correct value looks like in context. See typing tool parameters for the schema side of this same split.
Is there a real token cost to writing longer, better descriptions? Yes, a small one — every tool’s name, description, and schema is loaded into context on every turn where tools are available, so a catalog of dozens of verbose tools does add up. But the fix for that cost is scoping which tools are loaded per agent, not shrinking each individual description back to the point of ambiguity. Treat the description’s completeness and the catalog’s size as two separate levers.
Where do I verify current CCA exam details like format and passing score? This page is study material, not the exam. As of mid-2026 the publicly cited logistics are Pearson VUE delivery, a $125 fee with retakes available, 60 questions in 120 minutes, and a passing scaled score of 720 out of 1000 across five domains — but verify the current numbers on Anthropic’s official certification pages before you register, since logistics like this change without much notice.
Where this fits in the CCA series
This is question 7 of 10 in the Domain 2 (Tool Design & MCP Integration) practice set, worth roughly 18% of the exam. If tool selection keeps failing even after you fix the description, the next thing to check is whether the schema is doing its job — see the model sends “next Tuesday,” not a date. If the failure is downstream, at the point a tool call errors out, see designing a tool error contract. And if the real problem is that you have too many tools for any description to save you, see scoping tools per agent.
For the full protocol context — why the description-as-API problem exists at all, and how MCP standardizes tool exposure — see MCP explained on one diagram. And for the full five-domain map of the exam, start with the Claude Certified Architect exam guide.
Not affiliated with, authorized, or endorsed by Anthropic. “Claude” and “Claude Certified Architect” are trademarks of Anthropic. These are original practice questions for study, not real exam content — verify current exam details on Anthropic’s official pages.
Browse all tutorials for the rest of the series.
Found this useful? The deep version lives on YouTube — new breakdowns of how AI dev tools actually work, weekly.
Subscribe on YouTube →