← Blog

Claude Tool Use Best Practices for Reliable Agents

2026-09-15 · 5 min read · SubToAPI Team

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": "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:

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:

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

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.

Turn your Claude access into an HTTPS API

SubToAPI gives you application API keys, streaming, tool use and usage insights on top of your existing Claude access — set up in minutes.

Start free  Read the quickstart →