Parallel tool use and result pairing
One assistant message can request several tools. How you return the results decides whether it ever does so again.
3 min read · Lesson 3 of 12 in this domain
When several tool calls do not depend on each other, Claude will often request them all at once in a single assistant message rather than one per turn. This is a large latency win — three lookups become one round trip instead of three. But it depends on a convention: the model learns from the shape of the conversation whether parallel calls actually get handled well. If your harness returns results in a shape that implies the calls were processed one at a time, the model adapts and stops batching them.
- Parallel tool use is on by default — a single assistant message may contain multiple
tool_useblocks. - Execute them concurrently, then return all
tool_resultblocks in a single user message. - Splitting results across multiple user messages silently trains Claude to stop making parallel calls, quietly destroying your concurrency.
- A failed tool still gets a result block, with
is_error: trueand an informative message. Never drop it. - To force at most one tool per response, set
disable_parallel_tool_use: trueinsidetool_choice.
The failure mode is silent. Claude requests get_weather, get_traffic and get_events in one message. Your code awaits all three, then appends three separate user messages, one result each. Nothing errors — the answer is correct. But you have just modelled a conversation in which those three calls were resolved sequentially. Over subsequent turns the model drifts toward requesting one tool at a time, and your parallelism quietly disappears with no failure to debug. The fix is one user message containing all three tool_result blocks.
"Return them in completion order, one message each" sounds tidy and is exactly the anti-pattern.
Claude returns three tool_use blocks. How do you return the results?
Splitting results across messages trains the model to stop batching parallel calls.
A tool in a parallel batch fails. What do you send?
Never drop the block — an omission breaks the turn, and an empty string looks like a successful empty result.
Practise this domain with 27%%-weighted questions in the study app.
Open in study appSource: Claude Docs — Tool use overview · Independent study aid, not affiliated with or endorsed by Anthropic.