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.
Often 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: while building their agent for SWE-bench, 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_accounts_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. Example input: {\"account_id\": \"acct_1234\"}.",
"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 even small refinements to tool descriptions can yield dramatic improvements, and credits precise description changes with helping Claude Sonnet 3.5 reach state-of-the-art results on SWE-bench Verified.
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 Japanese manufacturing term for error-proofing: shaping the process so the mistake is hard or impossible to make.
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, limits MCP tool output to 25,000 tokens by default (configurable with
MAX_MCP_OUTPUT_TOKENS) and warns when output passes 10,000 tokens.
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-10. 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 breaks prompt caching. On Claude, tool definitions are the first part of the cached prefix, so editing them invalidates the whole cache. OpenAI's caching guide likewise says to keep tool definitions, their order and their schemas stable.
To control which tools can run at a given step without editing the list:
- OpenAI: use
tool_choice. Set it to"none"to turn tools off, or use theallowed_toolstype to limit the model to a subset while thetoolslist stays the same. - Claude:
tool_choicecan force one specific tool or turn tools off, but it can't limit the model to a subset. Changing it also re-processes the cached messages, though the tools and system prompt stay cached. 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?
FAQ
How do I stop my AI agent from calling the wrong tool?
Cut overlapping tools and give each one a clear, distinct purpose. Anthropic recommends merging endpoint-style tools into workflow tools, such as one schedule_event tool in place of list_users, list_events and create_event.
How long should a tool description be?
Long enough that a new teammate could use the tool correctly from the description alone. Anthropic's tool-use docs suggest at least 3 to 4 sentences per tool, covering what it does, when to use it and how it behaves.
What is the default MCP tool output limit in Claude Code?
Claude Code limits MCP tool output to 25,000 tokens by default and shows a warning above 10,000 tokens. You can change the limit with the MAX_MCP_OUTPUT_TOKENS environment variable.
Does changing the tool list break prompt caching?
Yes. On Claude, tools are the first part of the cached prefix, so editing tool definitions invalidates the whole cache. OpenAI's caching guide says to keep the tools list stable and use tool_choice to control which tools can run.
Sources
- Anthropic, Writing effective tools for AI agents (2025)
- Anthropic, Building effective agents (2024)
- OpenAI, Prompt caching guide
- Anthropic, Define tools (Claude API documentation)
- Anthropic, Prompt caching (Claude API documentation)
- Anthropic, Connect Claude Code to tools via MCP (Claude Code documentation)
- Lean Enterprise Institute, Poka-yoke