AI Agent Tool Use: Design Patterns That Hold Up in Production
Design AI agent tools with explicit schemas, error handling, parallel execution rules, and controls for side effects.
Tools let an AI system read databases, call APIs, send emails, and create records. Each tool needs a clear schema, permission checks, and failure handling, especially when a call changes external state.
What Tool Use Actually Is
When a language model "calls a tool," it is generating structured output — typically a JSON object — that specifies a function name and arguments. The orchestration layer then actually executes that function and passes the result back to the model. The model uses that result to decide what to do next.
The model does not run code. It makes decisions about what to call and what to pass. The reliability of tool use depends heavily on how clearly you define the tools and how defensively you implement the functions behind them.
Core Principles for AI Agent Tool Use Design
Design Schemas as Communication
The tool schema — name, description, parameter names, parameter descriptions — is the primary interface between the language model and your function. The model uses it to decide whether and how to call the tool. Treat schema design with the same rigor as an API contract.
Common mistakes:
- Vague names like
process_requestinstead ofcreate_support_ticket - Missing or generic descriptions that do not tell the model when to use the tool
- Optional parameters that are actually conditionally required
- Parameters that accept free-form strings when they should be enums
A well-designed schema reduces the rate at which the model calls the wrong tool, passes the wrong arguments, or tries to synthesize information it should be retrieving.
Separate Read Tools from Write Tools
Tools that read from external systems are low-risk. Tools that write to external systems carry consequences. Separate them clearly in both naming and schema structure.
Read tools: get_customer, search_knowledge_base, fetch_order_status
Write tools: update_order_status, submit_refund, send_email
This separation makes it easier to apply different authorization levels to each class and easier for reviewers (human or automated) to identify when the agent is about to take an action with side effects.
Every Write Must Be Idempotent
If a write tool is called twice with the same inputs, the result must be the same as calling it once. This is non-negotiable. Networks fail, timeouts happen, and agents retry. Without idempotency, you ship with a class of bugs that are hard to detect and painful for users.
Implement idempotency keys at the tool level. Generate a unique key per workflow run or per logical action. Pass it to the underlying system, which uses it to deduplicate.
Return Structured Results, Not Prose
Tools should return structured data, not natural language strings. A tool that returns "Refund processed successfully for order 12345, amount $49.00, confirmation REF-98712" is harder for the agent to parse and reason over than a tool that returns:
status: "success"
order_id: "12345"
amount: 49.00
confirmation_id: "REF-98712"
Structured returns let the model extract specific fields reliably and reduce the risk of the model misinterpreting a result.
Design Error Returns for Agent Consumption
When a tool fails, the error it returns is read by the language model. That error needs to be interpretable enough that the agent can respond intelligently — either retrying with different parameters, explaining the situation to the user, or escalating.
Good error: "Order 12345 is not eligible for a refund because it was delivered more than 30 days ago."
Bad error: "Error 422: validation failed"
The first error gives the agent everything it needs to generate a helpful response. The second leaves it guessing.
Advanced Patterns
Parallel Tool Calling
Most major LLM providers support calling multiple tools in a single inference step. Use this when you have independent lookups that can happen simultaneously. Fetching customer profile, order history, and recent tickets can all happen in parallel rather than sequentially. This cuts latency on multi-step retrievals significantly.
Be careful with parallel write calls. Parallel writes to the same resource create race conditions that are difficult to debug.
Confirmation Before Irreversible Actions
For tools that take irreversible actions — deleting records, sending bulk communications, charging payment methods — add a confirmation step. The agent proposes the action and its parameters. A human or a policy checker confirms before the function executes.
Tool Caching
If a read tool is called multiple times in a single workflow with the same inputs, cache the result rather than hitting the upstream API each time. This reduces latency, reduces cost, and prevents rate-limiting issues on the underlying API.
Cache at the tool call level, keyed on the function name and serialized input parameters. Invalidate on writes that could affect the cached data.
Limiting the Tool Set
A large tool set can make selection harder, especially when descriptions overlap. Test tool selection accuracy on representative tasks as you add tools.
If you have a large library of tools, consider presenting a subset relevant to the current workflow context rather than exposing everything at once. Tool selection can itself be a model decision — but keep it bounded.
The Hidden Cost of Poorly Designed Tools
Ambiguous schemas and error messages can lead to unnecessary calls or retry loops. Track tool-call counts, retries, and cost per completed workflow to identify these failures.
Include tool schemas, authorization, and retry behavior in design reviews and tests.