Security

Splitting One Broad Agent Tool Into Narrow Tools

Antonio Evans11 min read

A top-down view of a workbench where one large grey toolbox labelled ACTION spills loose parts toward six small labelled trays, each holding one part type and a short schema card.
Key points

Key points

  1. 1Inventory the actions your catch-all tool actually performs by reading call logs, then group them by side effect and by the fields the model must supply.
  2. 2Replace the free-form action string with closed schemas: an enum when the group is small, a separate tool when inputs or side effects genuinely differ.
  3. 3Rewrite the prompt so the model selects a named tool instead of constructing an action, and state preconditions next to each tool.
  4. 4Split tool selection evals from argument correctness evals, because the two failures have different fixes and different owners.

Why a catch-all tool fails quietly

A tool that takes an action string and a loose parameter bag looks efficient. One definition covers read, write, search and export, so the tool registry stays short. The cost shows up in the arguments. When the schema is a bag, the model has to infer from the request which fields matter for which action. A search needs a query and maybe a limit. An export needs a format, a date range and a destination. A deletion needs an identifier plus a reason. Give the model one untyped map and it will populate plausible-looking fields for the wrong action, and your handler has to guess what was meant.

Anthropic's guidance on writing tools for agents frames the problem precisely: a tool is a contract between a deterministic system and a non-deterministic agent, which is different from a function contract between two programs, and tools therefore have to be designed to be ergonomic for the model that will call them Writing effective tools for agents. A catch-all tool is ergonomic for the developer who writes one handler, not for the model that must choose a branch inside a string field.

The same source is blunt about naming: namespacing tools to define clear boundaries in functionality is one of the principles it lands on after running tool evaluations. A single namespace that swallows every verb defines no boundary at all.

There is also a security dimension you should name explicitly in the design doc. Tool misuse and exploitation sits high on the OWASP Top 10 for Agentic Applications, and the pattern it describes is an agent staying inside its permissions while chaining tools in a hazardous way Demystifying OWASP Top 10 for Agentic AI. A broad tool with a write-capable parameter bag is the cheapest possible way to reproduce that risk, because a single misread field turns a lookup into a mutation.

Step 1: inventory the actions the broad tool really performs

You cannot group what you have not listed. Pull the last few thousand recorded calls and tabulate them. For each call, record the action string the model emitted, the argument keys it supplied, which keys the handler actually read, whether the call mutated state, and whether it succeeded.

Expect three findings, and write them down as counts:

  • Orphan actions. Values the model invented that the handler never recognized. These are silent failures that your error rate hides, because the handler probably returned a generic message.
  • Overlapping actions. Strings that mean the same thing with different phrasing ("fetch", "get", "lookup", "retrieve"). These inflate your enum without adding behavior.
  • Unused parameters. Keys the model supplies habitually because they appear in the schema, even when the action never reads them.

The count matters because it sets your split target. If the log shows 40 distinct action strings but only 11 distinct behaviors, you are not splitting a 40-way tool; you are collapsing noise and then splitting 11 real actions. This inventory pass is the same discipline red teamers apply when they map an agent's capabilities before testing it: enumerate every tool the agent can call and every external system it can reach, because that defines the blast radius Complete Guide to Agentic AI Red Teaming.

Annotation is where practitioners underinvest. Have the person who owns the downstream system label each row as read, write, destructive or financial, before you look at the grouping. A grouping made by the tool's author tends to preserve the author's mental model, which is the model that produced the catch-all in the first place.

Step 2: group by side effect first, input shape second

Sort the real actions into groups using two keys, in this order.

First key: side effect class. Read-only, reversible write, irreversible write, and financial or externally visible action. This ordering is not stylistic. Least privilege guidance for agents is consistent that read and write access are different risks and should be granted independently, and the same logic applies to the tool boundary Access Management for AI Agents. Two actions that differ only in whether they change state should never share an authorization path if you can avoid it.

Second key: input shape. Within a side effect class, ask whether two actions require materially different required fields. If yes, they want separate schemas, because that is exactly the inference burden you are trying to remove. If the required fields are identical or near-identical, they can share a tool with an enum.

Here is the decision rule as a table you can paste into a design review.

ConditionMove
Actions share a side effect class and require the same fields, differing only in modeOne tool, action as enum
Actions differ in side effect class (read vs write, reversible vs irreversible)Separate tools, always
Actions require different required fields or different resource identifiersSeparate tools
Actions differ only by a label the model cannot infer from the request textDo not split; merge or drop
Action is destructive or financialOwn tool, plus human approval gate
Action has never been observed in logs and no owner claims itDelete it

The last two rows do the most work in practice, and the fourth is the one teams get wrong. If two candidate tools are distinguishable only by a word that never appears in a user's request, splitting them gives the model a coin flip with an audit trail. Merge them behind one enum and let the handler dispatch, or drop the distinction entirely.

Microsoft's guidance on scoping agent permissions reinforces the structural point underneath this table: access controls belong around the action, not only around the identity that performs it How to implement least privilege for AI agents. One tool per side effect class is how you make that enforceable at the tool registry rather than inside a prompt.

Step 3: write one closed schema per group

A closed schema means every field is declared, required fields are actually required, and free-form strings are replaced with enums or typed values wherever the valid set is finite. Start with the read-only group, because it is the least dangerous and the fastest to validate.

Before schema, one broad tool:

{
  "name": "run_action",
  "description": "Run an action against the workspace.",
  "parameters": {
    "type": "object",
    "properties": {
      "action": { "type": "string" },
      "params": { "type": "object" }
    }
  }
}

After the split, the read group keeps a small closed enum, and every other group becomes its own tool:

{
  "name": "search_records",
  "description": "Find records matching a text query. Read-only. Use this before any tool that needs a record id.",
  "parameters": {
    "type": "object",
    "additionalProperties": false,
    "required": ["query"],
    "properties": {
      "query": { "type": "string", "minLength": 2 },
      "scope": { "type": "string", "enum": ["owned", "shared", "all"] },
      "limit": { "type": "integer", "minimum": 1, "maximum": 50 }
    }
  }
}
{
  "name": "update_record_status",
  "description": "Change the status of one record. Reversible. Requires a record id from search_records.",
  "parameters": {
    "type": "object",
    "additionalProperties": false,
    "required": ["record_id", "status", "reason"],
    "properties": {
      "record_id": { "type": "string" },
      "status": { "type": "string", "enum": ["open", "pending", "closed"] },
      "reason": { "type": "string", "maxLength": 280 }
    }
  }
}
}

Three details carry most of the reliability gain. additionalProperties: false stops the model from inventing keys. required lists every field the handler truly needs, which removes the "did they mean to send this" branch inside your code. And the enum on status converts an argument-correctness problem into a validation error you can see.

Practitioner guidance on tool design converges on the same preferences: narrow, job-specific tools with clear input and output schemas outperform broad API wrappers, and typed schema validation on every tool input and output is not optional for production AI Agent Tool Use Best Practices for Practitioners. The same source offers a useful tripwire: if an agent has more than eight tools registered at once, treat that as a design problem rather than a capability gap.

Descriptions are part of the schema, not decoration. Anthropic notes that tool descriptions and specs are themselves a prompt-engineering surface, and that tools should return meaningful context to the agent rather than bare status codes Writing effective tools for agents. Put the precondition in the description text, as in the update_record_status example above, and your prompt has less to carry.

Step 4: change the prompt so the model selects, not constructs

The old prompt told the model how to build an action string. The new prompt must teach selection. Delete every instruction of the form "set action to fetch, get or lookup depending on", because that sentence is what you just removed from the interface.

Replace it with a catalogue in prose that mirrors the tool list, organized by side effect, with the sequencing rules stated as positive requirements. A structure that holds up in review:

  1. Name the tools and their side effect class in one line each.
  2. State the precondition chain explicitly. If a tool needs an id, say that the id comes from search_records and must never be invented.
  3. State what each tool refuses to do, once, and do not repeat it.
  4. State the escalation rule for destructive and financial actions.

That last point matters more than it looks. Guidance on agent permissions is consistent that standing permission for an agent to send email, move funds or modify production systems should be replaced with explicit human-in-the-loop approval, and that this is a structural control rather than a UX preference AI Agent Tool Use Best Practices for Practitioners. A prompt that says "ask before anything irreversible" is a reminder; a separate tool that your orchestrator refuses to execute without an approval token is a control. Use the prompt for the reminder and the harness for the control.

One rewrite lesson from a documented production refactor is worth borrowing: accumulated "DO NOT" directives are scar tissue, and replacing them with positive specifications of what to do, alongside thinner routing, cut token consumption substantially in that system From Prompt Spaghetti to Structured Multi-Agent Systems. When you split the tool, spend the reclaimed tokens on preconditions, not on more prohibitions.

Step 5: split the evals, then read the numbers

This is the step that decides whether the refactor worked, and the step most often skipped. Build two eval sets and keep their scores separate.

EvalWhat it asksTypical failure it catches
Tool selectionGiven this request, did the agent call the right tool?Picks a write tool for a question phrased as a lookup
Argument correctnessGiven the right tool, were the required fields present and valid?Invents a record id, omits reason, sends a status outside the enum
SequencingDid it search before updating?Acts on an id it never resolved
Refusal and escalationDid it stop and ask where the policy requires it?Performs an irreversible action unattended
Injection resistanceDoes retrieved content change the selected tool?A document tells it to export instead of summarize

Report tool selection as a single accuracy number and argument correctness as a per-field validity rate. If selection accuracy is high and field validity is poor, your schemas are still too loose or your descriptions do not state preconditions. If selection accuracy is poor while field validity is high, you split something the model could not observe, and the fix is merging two tools, not another prompt revision.

For the injection row, borrow structure rather than building from scratch. Agentic red teaming distinguishes a reasoning layer, where goals get redirected, from an action layer, where tool calls and parameters get manipulated, and it treats inter-agent messages as a third surface Complete Guide to Agentic AI Red Teaming. Your tool-split eval maps cleanly onto the action layer. Microsoft's red teaming tooling makes the same split, scoring attack success rate across probes and logging results for comparison over time AI Red Teaming Agent.

One number from published research should shape how you weight the injection probes: roleplay-based prompt injection achieved an attack success rate of about 89.6 percent in a study of attack techniques, well ahead of logic traps and encoding tricks AI Agent Red Teaming. If your catch-all tool had a send or export branch reachable from a free-form parameter, that is the class of attack most likely to find it. After the split, re-run those probes against the new registry and confirm which tool the payload now selects.

Worked example: 11 behaviors, three tools, and a decision

Take a support agent whose workspace tool accepted an action string and a parameter bag. The log inventory shows 40 distinct action strings mapping to 11 real behaviors plus nine orphans. Three behaviors mutate state, one is externally visible (sending a customer email), and seven are read-only.

Applying the table:

  • Seven read-only behaviors require largely the same fields (a query, a scope, a limit). They become one search_* tool family with a closed enum, or two tools if the resource shape differs enough.
  • The three reversible writes each need a distinct record id plus a status or owner field. They become three tools, or one tool per resource, each with its own required fields.
  • The customer email becomes its own tool with a human approval gate, because it is externally visible and irreversible once sent.
  • The nine orphans are deleted, and each deletion is announced to the teams that relied on them.

Result: three to five tools instead of one, all under the eight-tool tripwire, with the destructive path isolated behind an approval requirement. The measured gain you should expect is not "better answers" in general but a lower rate of wrong-field calls and a clean audit trail of which side-effect class was invoked, which is precisely the visibility that least-agency governance asks for Least Agency: Why Least Privilege Isn't Enough to Secure AI Agents.

If you are running this across several agents and want one place to compare model behavior for the eval step, Quanta Inference puts text, image, audio and embedding models behind one API key so you can swap the model under the same eval set without rewriting clients. When the split spans multiple teams and each needs its own approval policy for the write and send tools, a consulting call is the faster path to a scoped registry than rebuilding it per squad.

When splitting stops helping

Splitting pays off when the model's argument errors come from having to infer which fields matter. It stops paying off under two conditions you can check cheaply.

The first is unobservable labels. If every candidate tool requires the same fields and the only difference is a name the request text never mentions, the split converts an argument problem into a selection problem and adds latency. Merge them behind an enum and let your handler dispatch.

The second is registry bloat. Every tool you add consumes context and gives the model another way to be wrong; the practitioner ceiling of roughly eight registered tools is a reasonable guardrail for a single agent AI Agent Tool Use Best Practices for Practitioners. If grouping honestly produces fifteen tools, the answer is usually fewer agents rather than more tools, which is the neighboring decision that follows this one.

Finally, treat the tool registry as an inventory you govern, not a file you edit. Security teams are being pushed hard in this direction: inventorying agents and mapping their permitted tools is now a first-class control, because you cannot bound what you have not listed Agent Inventory for SaaS AI Agents. A split tool set is only better than a catch-all if you can still enumerate it, diff it in review, and revoke one entry without breaking the rest. OWASP's agentic guidance makes the same demand at the application level, tying tool boundaries to concrete technical controls rather than prompt wording Securing Agentic Applications Guide 1.0.

FAQ

FAQ

Does splitting always improve tool selection accuracy?

No. Selection accuracy improves when the new tools differ in ways the model can see in the request, such as a needed identifier or a side effect the user described. It can degrade when tools differ only by an internal label, because you have replaced one inference with another. Measure selection accuracy and argument validity separately and merge any pair the eval cannot tell apart.

How many tools should one agent have?

Keep the registry small enough that the model can hold every description in context and your team can review the list in one sitting. A common practitioner guardrail is to treat more than eight registered tools on a single agent as a design signal rather than a capability gap AI Agent Tool Use Best Practices for Practitioners. If honest grouping exceeds that, reduce the agent's scope rather than the schema's strictness.

Should destructive actions be separate tools or just a flag?

Separate tools, with the approval requirement enforced in the orchestrator. Permissions guidance repeatedly warns that standing permission for sending, moving funds or modifying production systems should be replaced with explicit human-in-the-loop approval, and that prompt-based reminders are not a substitute How to implement least privilege for AI agents. A flag inside a shared tool gives the model the option to skip the gate.

What do I do with actions that never appear in the logs?

Delete them. An action with no observed calls and no owning team is either dead code or a latent path that no eval covers. Removing it shrinks the blast radius of a prompt injection and removes a schema branch nobody maintains. If a caller does need it, it returns as its own typed tool with an owner attached.

How do I test that retrieved content cannot switch the selected tool?

Add eval cases where a document, ticket or email contains an instruction to call a specific write or export tool. Record which tool the agent actually invoked and score it as a failure if the selection changed. This targets the action layer that agentic red teaming identifies as distinct from the reasoning layer, and it is cheap to run on every registry change AI Agent Red Teaming.

Sources

Sources

  1. Writing effective tools for AI agents, using AI agents - Anthropic
  2. Demystifying OWASP Top 10 for Agentic AI - Medium
  3. Complete Guide to Agentic AI Red Teaming | DeepTeam
  4. Access Management for AI Agents: Scope What They Touch
  5. How to implement least privilege for AI agents - Okta
  6. AI Agent Tool Use Best Practices for Practitioners - MLflow
  7. From Prompt Spaghetti to Structured Multi-Agent Systems
  8. AI Red Teaming Agent - Microsoft Foundry
  9. AI Agent Red Teaming: Techniques and Attack Surfaces | Fiddler AI Blog
  10. Least Agency: Why Least Privilege Isn't Enough to Secure AI Agents - Zenity
  11. Agent Inventory for SaaS AI Agents
  12. Securing Agentic Applications Guide 1.0 - OWASP Gen AI Security Project
About the author

About the author

Antonio Evans
Antonio Evans

Antonio Evans is the founder of Quanta Intelligence and a fractional CTO who builds HIPAA-ready AI systems for health and life-science companies. Before that he was technical co-founder of FriendsEAT for twenty years, CEO of Socialdraft, and a data engineer at IBM. Antonio lives with his dog Santino in Lisbon, Portugal.

All articles