Claude Tool Use Best Practices for Reliable Agents
Claude's tool use (function calling) lets the model call your code — databases, APIs, calculators, search — instead of guessing answers. The best practices that actually move the needle are: write tight, unambiguous tool schemas, give the model just enough tools (not all of them), handle errors as structured tool results rather than exceptions, and design your prompt so Claude knows when not to call a tool.
This guide covers the concrete patterns that separate a demo that works once from a tool-using agent that holds up in production.
Design Tool Schemas Like API Contracts
Claude reads your input_schema the same way a junior developer would read documentation — literally, and only once per call. Vague schemas produce vague or malformed calls.
- Name tools by verb + object:
get_weather,search_orders,create_invoice. Avoid generic names likerunorexecute. - Write descriptions for the model, not for humans skimming docs. State what the tool does, when to use it, and what it returns.
- Mark required fields explicitly and avoid optional parameters that silently change behavior.
- Use enums for constrained values. If a
statusparameter only acceptspending,shipped, orcancelled, say so in the schema — don't leave it as a free-text string.
{
"name": "get_order_status",
"description": "Look up the current status of a customer order by order ID. Returns status, tracking number, and estimated delivery date. Use this only when the user asks about an existing order, not for placing new orders.",
"input_schema": {
"type": "object",
"properties": {
"order_id": {
"type": "string",
"description": "The order ID, e.g. ORD-48213"
}
},
"required": ["order_id"]
}
}
Vague descriptions like "gets order info" cause Claude to either skip the tool or call it with malformed arguments. Specificity is cheaper than debugging.
Limit the Toolset per Request
Claude performs better with fewer, well-chosen tools than with a large catalog "just in case." If you're building an agent with 30+ possible tools, filter them per-request based on context — retrieve only the 3–5 tools relevant to the current task before sending the request. This reduces ambiguity and cuts token overhead on every turn since tool definitions are re-sent with each request in the conversation.
Handle Tool Errors as Data, Not Exceptions
When a tool call fails — a timeout, a 404, invalid input — don't drop the turn. Return a tool_result block with an error message and let Claude decide how to recover (retry with different arguments, ask the user for clarification, or fall back to another tool).
{
"type": "tool_result",
"tool_use_id": "toolu_01A2...",
"content": "Error: order_id ORD-48213 not found. Did you mean ORD-48312?",
"is_error": true
}
Claude generally handles this gracefully if the error message is informative. A bare "500 Internal Server Error" gives it nothing to work with; a message that hints at the likely fix often gets a useful retry.
Use Parallel Tool Calls Where It Makes Sense
Claude can request multiple tool calls in a single turn when the tasks are independent — for example, fetching weather for three cities at once. Structure your tool schemas so independent lookups can be batched, and make sure your execution layer actually runs them concurrently rather than serially. If your tools have side effects (writes, payments, sends), be explicit in the description that they should be called one at a time, or Claude may parallelize calls that shouldn't run together.
Control When Claude Should NOT Call a Tool
A common failure mode is Claude calling a tool for something it could answer directly, or refusing to answer without a tool it doesn't have. Two levers help:
- System prompt guidance: "Only use the
search_docstool when the user asks about something not in your training knowledge or that may have changed recently." tool_choicecontrol: you can force Claude to use a specific tool, force any tool use, or let it decide (auto). Useautofor conversational agents, and forced tool choice for structured extraction tasks where you always want a specific tool called.
Keep Tool Results Concise
Large JSON dumps returned as tool results burn context and can distract the model from the actual task. Trim tool outputs to the fields Claude actually needs. If a database query returns 40 columns, return the 5 relevant ones. This also reduces latency and cost on multi-turn tool conversations.
Test the Full Loop, Not Just the Schema
A schema that validates isn't the same as a schema that produces correct calls. Test with:
- Ambiguous user phrasing ("what's it doing outside?" instead of "what's the weather in Paris?")
- Multi-tool scenarios where the model has to pick the right one
- Sequential dependencies (tool B needs the output of tool A)
- Deliberately malformed or missing data to check error-recovery behavior
Log actual tool calls in staging before shipping. Patterns you didn't anticipate — like Claude re-calling a tool with slightly different arguments after a partial failure — are easier to catch in logs than in a support ticket.
Simplifying the Infrastructure Side
Most of the reliability problems teams hit aren't about the model — they're about the plumbing around it: streaming partial tool-call JSON correctly, tracking token usage per tool call across a team, and giving each service its own API key instead of sharing one credential.
SubToAPI turns your existing Claude access into a standard HTTPS API with per-application keys (sub_live_...), built-in streaming, and usage metadata per request — so you can focus on tool schemas and prompt logic instead of managing raw connections. The tool use docs cover the request format, and streaming docs show how partial tool-call chunks arrive during generation. Plans start at Solo €9/month with a free trial at signup; see pricing for team and scale tiers.
A Quick Checklist
- [ ] Tool names and descriptions are specific enough for a stranger to use correctly
- [ ] Required vs. optional parameters are marked accurately
- [ ] Only relevant tools are sent per request, not the full catalog
- [ ] Errors return as structured
tool_resultblocks with actionable messages - [ ] Side-effect tools are documented as non-parallel
- [ ] Tool outputs are trimmed to essential fields
- [ ] Full conversational loops are tested, not just individual schemas
FAQ
Should I give Claude access to every tool I have available? No. Filter to the 3–5 tools relevant to the current request. Large toolsets increase the chance of the wrong tool being called or malformed arguments.
How should I handle a tool that times out or fails? Return a tool_result with is_error: true and a clear message describing what went wrong. Claude can usually retry, ask for clarification, or fall back — but only if the error message is informative.
Can Claude call multiple tools at once? Yes, for independent tasks in a single turn. Make sure your execution layer runs them concurrently, and clearly mark tools with side effects as sequential-only in their descriptions.