---
title: "Claude Tool Use Patterns: Sequential, Parallel, and Nested Tool Calls"
description: "Master Claude's tool calling patterns including sequential chains, parallel execution, nested tool calls, forced tool use, and auto vs any mode for complex agent orchestration."
canonical: https://callsphere.ai/blog/claude-tool-use-patterns-sequential-parallel-nested
category: "Learn Agentic AI"
tags: ["Claude", "Tool Use", "Agent Patterns", "Orchestration", "Python"]
author: "CallSphere Team"
published: 2026-03-17T00:00:00.000Z
updated: 2026-05-06T01:02:42.268Z
---

# Claude Tool Use Patterns: Sequential, Parallel, and Nested Tool Calls

> Master Claude's tool calling patterns including sequential chains, parallel execution, nested tool calls, forced tool use, and auto vs any mode for complex agent orchestration.

## Understanding Claude Tool Call Patterns

Claude does not just call one tool at a time. Depending on the task, it may invoke multiple tools in parallel, chain tool calls sequentially across turns, or use the output of one tool as input to another. Understanding these patterns is critical for building efficient and reliable agents.

The three core patterns are sequential (one tool per turn, results feed forward), parallel (multiple tools in a single turn), and nested (a tool call triggers another agent or sub-workflow). Each pattern has different performance, cost, and reliability characteristics.

## Sequential Tool Calls

Sequential calls happen naturally when each step depends on the previous result. Claude calls one tool, receives the result, reasons about it, then calls the next tool.

```mermaid
flowchart TD
    USER(["User message"])
    LLM["LLM call
with tools schema"]
    DECIDE{"Model wants
to call a tool?"}
    EXEC["Execute tool
sandboxed runtime"]
    RESULT["Append tool_result
to messages"]
    GUARD{"Output passes
guardrails?"}
    DONE(["Final reply"])
    BLOCK(["Refuse and log"])
    USER --> LLM --> DECIDE
    DECIDE -->|Yes| EXEC --> RESULT --> LLM
    DECIDE -->|No| GUARD
    GUARD -->|Yes| DONE
    GUARD -->|No| BLOCK
    style LLM fill:#4f46e5,stroke:#4338ca,color:#fff
    style EXEC fill:#ede9fe,stroke:#7c3aed,color:#1e1b4b
    style GUARD fill:#f59e0b,stroke:#d97706,color:#1f2937
    style DONE fill:#059669,stroke:#047857,color:#fff
    style BLOCK fill:#dc2626,stroke:#b91c1c,color:#fff
```

```python
import anthropic
import json

client = anthropic.Anthropic()

tools = [
    {
        "name": "get_user",
        "description": "Fetch user details by user ID",
        "input_schema": {
            "type": "object",
            "properties": {
                "user_id": {"type": "string", "description": "The user ID"}
            },
            "required": ["user_id"]
        }
    },
    {
        "name": "get_orders",
        "description": "Fetch recent orders for a user email address",
        "input_schema": {
            "type": "object",
            "properties": {
                "email": {"type": "string", "description": "User email"}
            },
            "required": ["email"]
        }
    },
]

# Claude will first call get_user, then use the returned email
# to call get_orders — a natural sequential chain
```

Claude decides the ordering automatically. If it needs user email before fetching orders, it calls `get_user` first and extracts the email from the result.

## Parallel Tool Calls

When tools are independent, Claude calls them simultaneously in a single response. This reduces round trips and speeds up the agent loop.

```python
# Claude will call both tools in ONE response when the
# information requests are independent
tools = [
    {
        "name": "get_weather",
        "description": "Get current weather for a city",
        "input_schema": {
            "type": "object",
            "properties": {
                "city": {"type": "string"}
            },
            "required": ["city"]
        }
    },
    {
        "name": "get_exchange_rate",
        "description": "Get currency exchange rate",
        "input_schema": {
            "type": "object",
            "properties": {
                "from_currency": {"type": "string"},
                "to_currency": {"type": "string"}
            },
            "required": ["from_currency", "to_currency"]
        }
    },
]

# "What's the weather in Tokyo and the USD to JPY rate?"
# Claude returns TWO tool_use blocks in a single response
```

When processing parallel tool calls, you must return a `tool_result` for every `tool_use` block, matching them by `tool_use_id`:

```python
def process_parallel_tools(response):
    tool_results = []
    for block in response.content:
        if block.type == "tool_use":
            result = execute_tool(block.name, block.input)
            tool_results.append({
                "type": "tool_result",
                "tool_use_id": block.id,
                "content": json.dumps(result),
            })
    return tool_results
```

## Controlling Tool Use with tool_choice

The `tool_choice` parameter controls whether and how Claude uses tools:

```python
# Let Claude decide (default)
response = client.messages.create(
    model="claude-sonnet-4-20250514",
    max_tokens=1024,
    tools=tools,
    tool_choice={"type": "auto"},
    messages=messages,
)

# Force Claude to use ANY tool (must call at least one)
response = client.messages.create(
    model="claude-sonnet-4-20250514",
    max_tokens=1024,
    tools=tools,
    tool_choice={"type": "any"},
    messages=messages,
)

# Force Claude to use a SPECIFIC tool
response = client.messages.create(
    model="claude-sonnet-4-20250514",
    max_tokens=1024,
    tools=tools,
    tool_choice={"type": "tool", "name": "get_weather"},
    messages=messages,
)
```

Use `"any"` when you know the user's request requires a tool call but you want Claude to pick which one. Use `"tool"` with a specific name when you need deterministic behavior — for example, always extracting structured data before reasoning about it.

## Nested Tool Calls with Sub-Agents

Nested patterns emerge when a tool itself runs another Claude agent. This creates a hierarchy where a top-level agent delegates specialized tasks:

```python
def research_tool(query: str) -> dict:
    """This tool runs a sub-agent to do deep research."""
    sub_agent_tools = [web_search_tool, summarize_tool]

    messages = [{"role": "user", "content": f"Research: {query}"}]

    # Sub-agent loop
    while True:
        response = client.messages.create(
            model="claude-sonnet-4-20250514",
            max_tokens=4096,
            system="You are a research specialist. Search and summarize.",
            tools=sub_agent_tools,
            messages=messages,
        )

        if response.stop_reason == "end_turn":
            return {"research_summary": response.content[0].text}

        # Process sub-agent tool calls
        messages.append({"role": "assistant", "content": response.content})
        results = process_parallel_tools(response)
        messages.append({"role": "user", "content": results})
```

The outer agent sees `research_tool` as a single tool, unaware that it internally runs a full agent loop with its own tools.

## Error Handling in Tool Results

Always return errors gracefully in tool results. Claude can reason about errors and retry or try alternative approaches:

```python
def execute_tool(name: str, inputs: dict) -> dict:
    try:
        result = TOOL_REGISTRY[name](**inputs)
        return {"status": "success", "data": result}
    except KeyError:
        return {"status": "error", "message": f"Unknown tool: {name}"}
    except Exception as e:
        return {"status": "error", "message": str(e)}
```

When Claude receives an error result, it often tries a different approach or asks the user for clarification rather than failing silently.

## FAQ

### When does Claude choose parallel vs sequential tool calls?

Claude calls tools in parallel when they are independent — neither tool's input depends on the other's output. If the user asks "What is the weather in Tokyo and New York?", Claude will issue two parallel `get_weather` calls. If the user asks "Get user 123's email and then their orders," Claude will call `get_user` first and `get_orders` second.

### Can I disable parallel tool calls?

There is no direct SDK parameter to disable parallel calls. However, you can structure your tool descriptions to imply dependencies, or process them sequentially on your side even if Claude sends them in parallel. In practice, parallel calls are usually desirable because they reduce latency.

### What happens if a tool_result is missing for a tool_use block?

The API will return an error. Every `tool_use` block in Claude's response must have a corresponding `tool_result` in the next user message. If a tool fails, return an error message as the content rather than omitting the result entirely.

---

#Claude #ToolUse #AgentPatterns #Orchestration #Python #AgenticAI #LearnAI #AIEngineering

---

Source: https://callsphere.ai/blog/claude-tool-use-patterns-sequential-parallel-nested
