Why Your Agent Calls the Wrong Tool (and How to Fix It)
A debugging checklist for tool-calling agents: overlapping tools, vague descriptions, ambiguous parameters, noisy responses and unhelpful errors, with a fix for each.
Most tool-calling failures look like model failures. The agent searched when it should have fetched, passed a name where an ID belonged, or looped on the same call until it ran out of turns. The natural reaction is to rewrite the system prompt or try a bigger model.
Usually the problem is the tools. A model only knows what a tool does from its name, its description, its parameters and what it returns. If those are unclear to someone who has never seen your codebase, they are unclear to the model too. Anthropic's engineers made the same point in Building effective agents: on one of their coding agents, they spent more time improving the tools than the overall prompt.
Here is a checklist of the causes that come up most often, roughly in the order worth checking them.
First, classify the failure
Pull a few failing transcripts and sort each failure into one of these buckets:
- Wrong tool: the agent picked a tool that cannot do the job.
- Right tool, wrong arguments: the call was sensible but the inputs were malformed or mismatched.
- Right call, misread result: the tool worked but the agent drew the wrong conclusion from its output.
- Stuck: the agent repeated a call, gave up, or stopped before finishing.
The bucket points to the fix. Wrong-tool failures usually mean the tool set or descriptions are confusing. Wrong-argument failures point at parameter design. Misread results point at response format. Getting stuck often traces back to error messages.
Cause 1: Too many overlapping tools
A common pattern is to wrap every API endpoint as its own tool. The agent then sees list_users, get_user, search_users and find_user_by_email, and has to guess which one you meant.
Anthropic's post Writing effective tools for AI agents recommends building fewer tools around whole workflows instead. Their examples:
- Replace
list_users,list_eventsandcreate_eventwith oneschedule_eventtool that finds availability and books the slot. - Replace
read_logswithsearch_logs, which returns only the relevant lines. - Replace
get_customer_by_id,list_transactionsandlist_noteswithget_customer_context.
Fix: list your tools and, for each pair, ask whether a new teammate could tell from the names alone which one to use. Merge any pair where the answer is no. Each tool should have one clear purpose that no other tool shares.
Cause 2: Names that do not separate
Once an agent has tools from several services, names collide. Is search for the wiki, the ticket tracker or the codebase?
Fix: namespace by service and resource, for example jira_issues_search and confluence_pages_search. The Anthropic tools post notes that prefix versus suffix naming had measurable effects in their evals and that the best choice varied by model, so if you have an eval suite, test both.
Cause 3: Descriptions written for people who already know the system
A description like "Gets account data" makes sense to the person who wrote the endpoint. It tells the model nothing about what an account is, what data comes back or when to prefer another tool.
Fix: write the description the way you would explain the tool to a new hire. Include:
- What it does and what it returns, in one or two sentences.
- When to use it, and when to use a different tool instead.
- Any terms of art, formats or limits ("dates are ISO 8601", "returns at most 50 results").
- One short example call.
Before:
{
"name": "get_account",
"description": "Gets account data.",
"input_schema": {
"type": "object",
"properties": { "account": { "type": "string" } }
}
}
After:
{
"name": "billing_account_get",
"description": "Look up one billing account and return its plan, status, renewal date and the last 5 invoices. Use this when you already know the account ID. To find an account from a company name or email, call billing_accounts_search first.",
"input_schema": {
"type": "object",
"properties": {
"account_id": {
"type": "string",
"description": "Billing account ID, formatted like 'acct_1234'. Not the company name."
}
},
"required": ["account_id"]
}
}
The second version answers the questions the model would otherwise guess at. The Anthropic post reports that small refinements to tool descriptions produced large gains on their own benchmarks.
Cause 4: Parameters that invite mistakes
user could be a name, an email or an ID. date could be a day, a timestamp or "next Tuesday". Every ambiguous parameter is a coin flip.
Fix: make the wrong input hard to send.
- Name parameters by what they hold:
user_id, notuser. - Use enums for any field with a fixed set of values.
- Mark required fields as required.
- Choose formats that leave no room for error.
The Building effective agents post has a good example of that last point. Their coding agent made mistakes with relative file paths after it moved out of the root directory. They changed the tool to require absolute paths, and the errors went away. They call this poka-yoke, a term from manufacturing for designs that prevent errors instead of detecting them.
Cause 5: Responses full of noise
If a tool returns a 3,000-token JSON blob of internal fields, the agent has to dig through all of it to find the one value it needs, and that blob sits in context for the rest of the conversation.
Fix: return what the agent needs to make its next decision, in a form it can use.
- Prefer human-readable identifiers. The Anthropic tools post found that resolving UUIDs to names or short numeric IDs improved retrieval precision and reduced hallucinations.
- Drop low-level fields the agent will never act on, like MIME types or thumbnail URLs.
- Offer a
response_formatparameter withconciseanddetailedoptions. In their example, the concise response used about a third of the tokens of the detailed one. - Paginate or truncate large results, and say so in the response: "Showing 20 of 312 results. Narrow the query or request the next page." Claude Code, for reference, caps tool responses at 25,000 tokens by default.
Cause 6: Errors the agent cannot act on
When a call fails with Error 400 or a stack trace, the agent has nothing to work with. It retries the same call, or it gives up.
Fix: write error messages that tell the agent what to do next.
Bad: ValidationError: invalid value
Good: start_date must be YYYY-MM-DD, for example 2026-11-12. You sent "next Tuesday".
Resolve relative dates before calling this tool.
A good error message turns a dead end into a one-step correction.
Cause 7: The tool set changes between turns
Some agents add and remove tools as the conversation moves, to keep the list short. This can confuse the model when earlier turns refer to tools that no longer exist, and it also defeats prompt caching, since tool definitions sit at the very start of the prompt. If you need to restrict which tools can run at a given step, both the Claude and OpenAI APIs offer a tool_choice setting, and OpenAI's caching guide suggests restricting tools that way instead of editing the list. More on that in prompt caching for AI agents.
How to know you fixed it
Guessing is how tool problems come back. Build a small set of tasks that each require a specific tool or sequence, run them a few times, and track:
- Pass rate on the tasks.
- Number of tool calls per task.
- Number of tool errors per task.
- Tokens per task.
Then change one thing at a time: a description, a name, a merged tool. If the numbers move the right way, keep the change. If you have not set up evals yet, this starter guide covers the basics.
Quick checklist
- Can a new teammate tell every tool apart by name and description alone?
- Does each description say when not to use the tool?
- Is every parameter named for what it holds, with enums and required fields set?
- Do responses use readable identifiers and skip internal fields?
- Are large results paginated, with a note saying so?
- Do errors explain how to fix the call?
- Is the tool list stable across the conversation?
Sources
- Anthropic, Writing effective tools for AI agents (2025)
- Anthropic, Building effective agents (2024)
- OpenAI, Prompt caching guide