Why Your AI Agent Calls the Wrong Tool
An AI agent calls the wrong tool mostly because two or more of your tools plausibly match the same request, not because you have too many tools. The published thresholds (Claude's tool selection degrades past 30 to 50 tools, OpenAI advises staying under 20) describe context dilution at scale, but the wrong-tool calls most operators hit happen at six to twelve tools and are overlap failures. The fix is an explicit do-not-use boundary in every tool description plus an escape-hatch tool for requests nothing covers.
Your AI agent calls the wrong tool because two or more of your tools plausibly answer the same request, not because you gave it too many. The model never sees your code. It sees a list of names, descriptions, and parameter names, and it picks the one that reads like the best match. When two entries on that list read the same way, it guesses. Fix the overlap and the wrong calls mostly stop, no matter how long the list is.
The published tool-count thresholds are real and probably not your problem
Both major vendors publish a ceiling. Anthropic's documentation for the tool search tool states plainly that Claude's ability to pick the right tool degrades once you exceed 30 to 50 available tools. OpenAI's function calling guide advises aiming for fewer than 20 functions available at the start of a turn, calling it a soft suggestion and telling you to evaluate at different counts yourself.
Those numbers describe a dilution effect. Load enough definitions into the context window and attention spreads thin across all of them. Anthropic's own example is five MCP servers (GitHub, Slack, Sentry, Grafana, and Splunk) totaling 58 tools and roughly 55,000 tokens of definitions before the model does any work. At that scale, narrowing the candidate pool is the fix, and the measured gains are real: Anthropic reports Opus 4.5 improving from 79.5 percent to 88.1 percent on its internal MCP evaluations with tool search enabled, and Opus 4 going from 49 percent to 74 percent.
Here is the part that gets skipped. Almost no small-business agent has 58 tools. The ones we build and inherit run six to twelve. And they still call the wrong tool. Quoting a 30-to-50 threshold at an agent with nine tools is a diagnosis that does not fit the patient, and it sends people off to prune a list that was never too long.
Count overlap, not tools
The number that predicts wrong tool calls is not how many tools you have. It is how many of your tools could plausibly match a single request.
Run this in a spreadsheet. It takes about half an hour and needs no code.
- Pull the 20 most common requests your agent actually receives. Take them from real transcripts, not from your imagination. Real ones are messier and shorter than the examples you would write.
- Make one row per request and one column per tool.
- For each row, mark the one tool that should fire.
- Then, reading only the tool name and description, mark every other tool that a reasonable person could argue should fire for that request. Be generous. You are simulating a model that has no context beyond the text.
- Count the rows with two or more marks. That number is your overlap count, and it is the thing to drive to zero.
Every row with two marks is a description bug, and it is your bug, not the model's. An agent with nine tools and six ambiguous rows will misfire constantly. An agent with 30 tools and zero ambiguous rows will be nearly perfect. This is why "just use fewer tools" so often fails to help: it reduces the list without reducing the ambiguity, and the ambiguous pairs usually survive the cut because they both look important.
Six ways an agent lands on the wrong tool
Once you have the grid, sort each failure into one of these. The fix is different in every row, which is why a single generic answer like "write better descriptions" does not get you there.
| What you see | What is actually happening | The fix |
|---|---|---|
The broad tool fires when a specific one exists (search_orders instead of get_order_by_id) | The broad tool's description matches more requests, so it wins on surface similarity nearly every time | Add an exclusion line to the broad tool that names the specific one and the case it owns |
| The agent calls a tool name that does not exist | Nothing in the list matched, so the model completed the pattern instead of stopping | Add an escape-hatch tool, and return a readable error rather than a silent failure |
| Right tool, arguments borrowed from a different tool's schema | Parameter names repeat across tools (id, email, query) and blur together | Rename parameters to be unambiguous (customer_email, invoice_id) and add a worked example to the description |
| The agent skips a required first step (updates a ticket without fetching it) | Both steps are exposed as independent tools and nothing states the ordering | Consolidate the pair into one tool, or state the prerequisite in the description of the second |
| A request nothing covers gets the nearest-fit tool | The model has no way to decline, so declining is not an option it can express | Escape-hatch tool, plus explicit do-not-use lines on the tools that keep absorbing these |
One catch-all tool (run_query, search, api_call) absorbs traffic from everything | Maximum surface overlap by design; it matches every request by construction | Delete it, or describe it as a last resort and say which tools take precedence |
The bottom row deserves a warning. A generic run_query or api_call tool feels efficient when you build it, because it saves you writing five specific tools. It is the single most reliable way to wreck tool selection, and it is also the access-control problem we wrote about in how much access to give an AI agent. A tool that can do anything will be chosen for everything.
Give every description an exclusion line
Most tool descriptions state a purpose. A purpose tells the model when a tool applies. It gives the model nothing to rule the tool out with. That asymmetry is why the broad tool keeps winning.
OpenAI's guidance says to use the system prompt to describe when and when not to use each function. Anthropic's tool-writing guidance says to write for a new hire and make implicit knowledge explicit, and notes that overlapping tools distract agents from efficient strategies. Both point at the same missing sentence. Write descriptions in three lines:
- Use when: the specific trigger condition, in the words a customer would use.
- Do not use when: the neighboring case that this tool keeps stealing.
- Use instead: the exact name of the tool that owns that neighboring case.
Concretely. Before: "Searches customer orders." After: "Searches customer orders by date range, status, or product when the customer has not given an order number. Do not use when the request includes a specific order number or confirmation code. Use get_order_by_id for that."
That is one added sentence per tool, and in our experience it clears most of the ambiguous rows in the grid. Namespacing helps on top of it. Anthropic recommends grouping related tools under common prefixes, like asana_projects_search and asana_users_search, which draws visible boundaries between clusters of tools that would otherwise read as interchangeable.
The tool your agent does not have
Look at the tool list of an agent that keeps misfiring and you will usually notice something missing: there is no way for it to say no.
Every tool in the list is an action. The model is asked to choose one. When a request arrives that none of them covers, and a customer asking a support bot about a refund policy you never wired up is exactly that case, the model does not have a "none of these" option available. So it picks the closest thing. That is not a hallucination. It is the only move the interface allows.
Add an explicit escape hatch. Call it escalate_to_human or no_matching_action, give it a description like "Call this when no other tool applies to the request, or when you are not confident which tool applies," and route it to a human queue or a canned reply. This converts a class of silent wrong actions into visible handoffs, and it doubles as a monitoring signal: if that tool starts firing 15 percent of the time, you have found the feature your agent is missing. Pair it with the approval boundaries in when to require human approval so the escalation lands somewhere a person actually reads.
Two more structural moves are worth knowing about, but only after the overlap is gone. Consolidating tools that are always called in sequence is recommended by both vendors, and it removes an entire failure mode: one schedule_event tool cannot be called out of order the way list_users, list_events, and create_event can. And splitting a large toolset across sub-agents narrows the candidate pool per decision, though that only pays when the pool is genuinely large, which we covered in single vs multi-agent AI. If your overlapping pair ends up inside the same sub-agent, the split bought you nothing. Whether you needed a tool-choosing model at all is the prior question we work through in do you need an MCP server.
What to do this week
Take the last request where your agent did the wrong thing. Copy your tool names and descriptions into a plain chat window, paste that request underneath, and ask the model which tool it would call and why. It will explain what it read into each description, and the ambiguity you are hunting for is usually visible in the first answer. That test costs five minutes and no instrumentation, and it is a better first move than adding logging or swapping models.
Then build the grid, count the ambiguous rows, add an exclusion line to each tool involved, and add the escape hatch. Re-run the same 20 requests. If you are building an AI assistant that has to pick correctly among real business actions and you would rather not discover the overlap through customer complaints, that is the kind of design work we do at custom software platforms. Send us your tool list and the request that went wrong at contact, and we will tell you which of the six rows you are in.
Frequently Asked Questions
SOURCES & CITATIONS
- Tool search tool — Anthropichttps://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-search-tool
- Introducing advanced tool use on the Claude Developer Platform — Anthropichttps://www.anthropic.com/engineering/advanced-tool-use
- Function calling — OpenAIhttps://developers.openai.com/api/docs/guides/function-calling
- Writing effective tools for AI agents — Anthropichttps://www.anthropic.com/engineering/writing-tools-for-agents
About Alexey Yushkin
Alexey is the founder of GENERAL INFORMATICS LLC. He designs and ships AI and automation systems for businesses and operators across the US.
Related reading
Want this kind of system in your business?
We build practical AI and automation systems for operators. Send us your current workflow and we will show you what to automate first.
Request a Workflow Review