The single-tool loop is a teaching device; production agents present Claude with several tools at once and let the model choose. Structurally nothing changes — you still call, inspect tool_use blocks, execute, inject results, repeat — but three concerns that were trivial with one tool become real engineering: routing, parallel invocations, and state.
Routing: from tool name to implementation
Each tool_use block names the tool the model wants. Your loop needs a dispatch layer that maps that name to an implementation, and the boring solution is the right one: a registry — a dictionary from tool name to a handler plus its schema — rather than a chain of if statements. The registry gives you one place to enforce cross-cutting policy: argument validation against the schema, per-tool authorization ("this user may query orders but not refund them"), timeouts, and structured logging of every invocation. An unknown tool name should produce an error result sent back to the model, not an exception; misrouted calls are recoverable if the model learns the tool didn't exist.
Two design pressures pull against each other. More tools give the model more capability, but every tool definition rides in the prompt on every iteration and costs tokens (the pricing documentation quantifies both the tool-use system prompt overhead and per-tool definition costs). Curate the toolbox per task where you can: an agent resolving billing questions does not need the deployment tools in context.
Parallel invocations
A single Claude response can contain more than one tool_use block — the model batching independent lookups it wants done together. Your loop must handle this shape correctly:
Execute independently, gather completely. If the calls are independent (they usually are — that is why the model batched them), run them concurrently: asyncio.gather in Python, Promise.all in TypeScript. Wall-clock latency of the turn drops to the slowest tool instead of the sum.
Return one result per request, matched to its call. Every requested tool call gets exactly one tool-result block in the next user message, matched to the request it answers. Skipping a failed one is an error — encode the failure as that call's result.
Keep the assistant turn intact. Append the assistant's content unmodified before the results. On reasoning-enabled models the tool-requesting turn can carry a thinking block that must be returned exactly as received; thinking blocks are signature-verified and altered ones are rejected.
State across a multi-turn session
The conversation history is the model's state: every prior tool result it should remember must be in the messages you send. That has two operational consequences. First, context growth — everything counts toward the context window, including tool definitions, tool results, and (on models that preserve them) prior thinking blocks. Current 1M-token context windows on the newer models buy a lot of headroom, but agents that pull large documents through tools can still fill it; summarize or truncate bulky tool results before injecting them where fidelity allows. Second, cost — a growing prefix re-sent every iteration is the textbook case for prompt caching, which is available on all four platforms and prices cache reads at a tenth of the base input rate.
Keep application state out of the transcript. Database handles, user identity, accumulated side effects belong in your session object, keyed by your own session ID; the transcript should carry only what the model needs to reason with.
When to graduate to managed orchestration
Everything above is you running the loop. Anthropic also offers Claude Managed Agents — agents, sessions, environments, and memory stores run on Anthropic's side — currently available in beta on the first-party API and Claude Platform on AWS only, not on Bedrock, Vertex AI, or Foundry. One documented difference on Claude Platform on AWS: a session can run autonomously for at most 6 hours before requiring a user event to reauthenticate. If your platform is Bedrock or Vertex AI, the self-built loop described here remains the standard pattern.
Where to go next
Sharpen the contract side with tool schema definition, then make the loop testable with mocking and VCR cassettes.