CloudCodeTree LogoCloudCodeTree
AI NewsTutorialsAbout
CloudCodeTree Logo
CloudCodeTree
  • AI News
  • Tutorials
  • About
← Back to AI News
Fetch Multiple Data Points in One Claude Response: Parallel Tool Calls With asyncio.gather

Fetch Multiple Data Points in One Claude Response: Parallel Tool Calls With asyncio.gather

Chris Harper

3 min read

Aug 10, 2026 · 20:03 UTC

AI
Tutorial
Agents
Best Practices

Claude 4 and later return multiple independent tool calls in a single response — dispatch them with asyncio.gather to cut latency by N× instead of running sequential round trips.

What you'll be able to do after this:

  • Understand how Claude signals parallel tool intent in a single response
  • Dispatch multiple tool calls concurrently with asyncio.gather and return all results in one user message
  • Know when to disable parallel tool use for sequential, side-effectful workflows

The serial trap

Most agents are written as a simple while loop: call the API, get a tool request, execute it, return the result, repeat. If your agent needs to fetch a user profile, look up their orders, AND check their billing status, that is three sequential round trips — the total latency is T₁ + T₂ + T₃. Claude doesn't need them to be sequential; your code forces it.

How Claude signals parallel intent

Claude 4 and later models return multiple tool_use blocks in a single assistant message when the calls are independent:

# Claude returns ONE assistant message containing N tool_use blocks
response.content = [
    ToolUseBlock(id="toolu_01", name="get_user_profile", input={"user_id": "u123"}),
    ToolUseBlock(id="toolu_02", name="get_orders",       input={"user_id": "u123"}),
    ToolUseBlock(id="toolu_03", name="get_billing",      input={"user_id": "u123"}),
]

Your responsibility: run all three, then return ALL results in a single user message before calling the API again.

The parallel dispatch pattern

import asyncio
import anthropic

client = anthropic.Anthropic()

async def dispatch_parallel(tool_calls, tool_map):
    """Run all tool calls concurrently; return tool_result blocks."""
    tasks = [tool_map[tc.name](**tc.input) for tc in tool_calls]
    results = await asyncio.gather(*tasks, return_exceptions=True)
    return [
        {
            "type": "tool_result",
            "tool_use_id": tc.id,   # match by id, not by position
            "content": str(r) if not isinstance(r, Exception) else f"Error: {r}",
            "is_error": isinstance(r, Exception),
        }
        for tc, r in zip(tool_calls, results)
    ]

async def agent_loop(prompt, tools, tool_map):
    messages = [{"role": "user", "content": prompt}]
    while True:
        resp = client.messages.create(
            model="claude-sonnet-5-20250901",
            max_tokens=1024,
            tools=tools,
            messages=messages,
        )
        if resp.stop_reason == "end_turn":
            return next(b.text for b in resp.content if hasattr(b, "text"))

        tool_calls = [b for b in resp.content if b.type == "tool_use"]

        # 1. Append the full assistant message (keeps tool_use blocks intact)
        messages.append({"role": "assistant", "content": resp.content})

        # 2. Dispatch all calls in parallel
        results = await dispatch_parallel(tool_calls, tool_map)

        # 3. Return ALL results in a single user message
        messages.append({"role": "user", "content": results})

Two rules that catch most bugs

Match by tool_use_id, not list position. Claude doesn't guarantee which tool appears first. Always pair calls and results by id.

Append response.content in full — never strip tool_use blocks. The next API call expects to see Claude's own requests echoed back. Stripping them causes an API error.

Disable for sequential workflows

If your tools have side effects or ordering dependencies (e.g., create_invoice must succeed before send_confirmation):

client.messages.create(
    ...,
    tool_choice={"type": "auto", "disable_parallel_tool_use": True},
)

Sources: Parallel tool use — Claude Platform Docs · Implement tool use — Claude Platform Docs · Build a tool-using agent — Claude Platform Docs