📚 Domain 2 · Task Statement 2.3

Distribute Tools Appropriately Across Agents and Configure tool_choice

📊 Domain Weight: 18% 🎯 Difficulty: Core Concept 🔗 Scenarios: Multi-Agent Research Pipelines

In multi-agent systems, giving every agent every tool is an anti-pattern. Each agent should receive exactly the tools it needs — no more, no less. This guide covers the Principle of Least Privilege for tools, the four tool_choice modes, and how coordinator vs. subagent tool sets differ by design.

📋 Contents

  1. Real-World Analogy: The Surgical Team
  2. Principle of Least Privilege for Tools
  3. Coordinator vs. Subagent Tool Sets
  4. The Four tool_choice Modes
  5. Diagram: Tool Distribution in a Research Pipeline
  6. When to Force vs. Auto: Decision Guide
  7. Code Examples: Configuring tool_choice
  8. Anti-Patterns to Avoid
  9. Exam Readiness & Key Takeaways

🏥 Real-World Analogy: The Surgical Team

🩹 Analogy — Roles, Tools, and Scope

In an operating room, the surgeon has a scalpel, sutures, and clamps — not a blood pressure monitor or IV pump. The anesthesiologist has the drug dispensary and vital monitoring equipment — not surgical instruments. The scrub nurse maintains the sterile instrument tray and hands tools to the surgeon on request.

Each role has exactly the tools for their function. Giving the surgeon an IV pump would create confusion and risk. Giving the anesthesiologist a scalpel adds no value and increases scope for error.

In multi-agent systems: the coordinator agent is the surgeon directing the operation. Subagents are specialists. The tool distributor (your architecture) is the scrub nurse — ensuring each agent only holds the tools they need for their specific task.

🔒 Principle of Least Privilege for Tools

The Principle of Least Privilege (PoLP) — borrowed from security engineering — states that every agent should have access to only the tools required to perform its designated function, and nothing more.

Why Tool Scope Matters

If You Give Too Many ToolsIf You Scope Tools Correctly
Claude may choose incorrect tools for the task, leading to unexpected side effectsClaude deterministically selects from a small, relevant set
Token budget wasted on tool descriptions Claude never usesContext window used efficiently; more space for actual task data
Security risk: write/delete tools accessible where only read is neededWrite operations gated to agents explicitly designed for mutation
Harder to audit what each agent is capable of doingClear blast radius per agent; easier to reason about failure modes
Tool selection ambiguity causes Claude to ask clarifying questionsUnambiguous tool set leads to more decisive, autonomous execution
🎯 Exam Focus — Token Cost of Tool Descriptions

Each tool definition in the API request consumes tokens from the context window. A tool schema with a detailed description, parameter definitions, and examples can cost 100–300 tokens. In a system with 20 tools, that’s 2,000–6,000 tokens consumed before any task content. Scoping tools per agent directly reduces this overhead and leaves more context for actual work.

🔨 Coordinator vs. Subagent Tool Sets

In a multi-agent system, the coordinator and each subagent have fundamentally different responsibilities — and therefore fundamentally different tool sets.

Agent TypeTypical ToolsTools it Should NOT Have
Coordinator spawn_subagent, delegate_task
aggregate_results, check_status
High-level orchestration verbs only
Low-level execution tools (web_search, file_write)
Domain-specific data tools (payments_api, db_query)
— it delegates these, not executes them
Research Subagent web_search, fetch_url
read_document, search_knowledge_base
write_file, send_email
update_database — read-only scope
Synthesis Subagent read_text, format_report
write_file (final output only)
web_search — synthesis uses provided data, not new fetches
spawn_subagent — not its role to orchestrate
Execution Subagent run_command, update_database
send_notification
web_search — it executes, not researches
spawn_subagent — execution is terminal, not orchestrating
💡 Design Rule: Match Tool Verbs to Agent Responsibility

Coordinator agents use orchestration verbs: spawn, delegate, aggregate, route, check. Subagent tools use execution verbs: search, read, write, send, run. If a coordinator needs an execution verb tool, it’s a design smell — that work should be delegated to a subagent.

🎮 The Four tool_choice Modes

The tool_choice parameter controls whether and how Claude decides to use tools in a given API call. It has four distinct modes, each with specific use cases:

🤖 Auto

tool_choice: auto

Claude decides whether to call a tool or respond in text. Default behavior. Best for open-ended agentic tasks where Claude should use judgment.

📺 Any

tool_choice: any

Claude MUST call at least one tool, but can choose which one. Prevents pure text responses when a tool call is required by the workflow.

🎯 Tool

tool_choice: {type: "tool", name: "X"}

Claude MUST call the specific named tool. Used to force a particular structured output format, data extraction, or mandatory action.

⛔ None

tool_choice: none

Claude cannot call any tools. Forces a plain text response even if tools are present in the request. Used for pure summarization or explanation steps.

ModeUse CaseWhen to Use
autoOpen-ended agentic tasksWhen Claude should autonomously decide the best approach
anyForcing structured interactionWhen any tool call is acceptable but text-only is not (e.g., data must be fetched)
toolMandatory structured outputExtracting JSON-structured data via a schema-tool; guaranteed call to a specific tool
nonePure text generationSummarization, explanation, or reasoning steps where no side effects should occur
🎯 Exam Focus — tool_choice: tool for Structured Output

A key exam pattern: using tool_choice: {"type": "tool", "name": "extract_data"} combined with a JSON schema tool definition to guarantee structured output. Claude is forced to call the tool, producing a validated JSON response every time. This is more reliable than asking Claude to “respond in JSON” in free text, because the tool schema enforces field types at the API level.

🕐 Diagram: Tool Distribution in a Research Pipeline

Figure 1 — Multi-Agent Tool Distribution (Research Pipeline)
Coordinator Agent tools: [spawn_subagent, aggregate_results, route_output] Research Subagent tool_choice: auto web_search fetch_url search_knowledge_base Extraction Subagent tool_choice: {tool: extract_schema} extract_schema (forced) Guarantees structured JSON output every call Synthesis Subagent tool_choice: none (first pass) write_report (final step) No web_search allowed No spawn_subagent Coordinator: aggregate_results Merges outputs; delivers final response Key: Each agent holds only tools for its role. Coordinator: orchestration only. Research: read tools. Extraction: forced schema tool. Synthesis: write + no-tool reasoning.

🎯 When to Force vs. Auto: Decision Guide

Choosing the right tool_choice mode requires understanding what the agent step needs to guarantee:

SituationCorrect ModeReasoning
Agent must autonomously complete a multi-step taskautoClaude needs full discretion to choose tools or respond based on context
Workflow step must always produce a tool call (not text)anyEnsures Claude doesn’t skip a required data-fetch step with a text response
Extracting structured data that must match a JSON schematool (specific)Guarantees schema adherence; Claude forced to populate defined fields
Summarization, reasoning, or explanation step (no side effects)nonePrevents accidental tool calls during pure reasoning steps
Onboarding/confirmation step before taking irreversible actionnoneForces explicit text response before proceeding to execution tools
⚠️ Anti-Pattern: Always Using Auto

Defaulting to tool_choice: auto for every agent step is the most common mistake. For extraction steps, Claude may choose to respond in text rather than calling the schema tool, producing unstructured output. For synthesis steps, it may call a web_search tool unnecessarily, going beyond its intended scope. Match tool_choice to the guarantee you need for that specific step.

💻 Code Examples: Configuring tool_choice

Python — Forced Structured Extraction with tool_choice: tool
# Define a schema tool for structured extraction
extract_tool = {
    "name": "extract_company_data",
    "description": "Extract structured company information from the provided text.",
    "input_schema": {
        "type": "object",
        "properties": {
            "company_name": {"type": "string"},
            "founded_year": {"type": "integer"},
            "revenue_usd_millions": {"type": "number"},
            "headquarters_country": {"type": "string"}
        },
        "required": ["company_name", "founded_year"]
    }
}

# Force Claude to ALWAYS call extract_company_data
response = client.messages.create(
    model="claude-opus-4-5",
    max_tokens=1024,
    tools=[extract_tool],            # Only this tool in scope
    tool_choice={                    # FORCE this specific tool
        "type": "tool",
        "name": "extract_company_data"
    },
    messages=[{"role": "user", "content": document_text}]
)

# Response is GUARANTEED to be a tool_use block with valid JSON
extracted = response.content[0].input  # Always a dict matching schema
Python — Research Subagent with Scoped tool_choice: auto
# Research subagent: scoped to read-only tools, auto choice
research_tools = [
    {"name": "web_search", "description": "Search the web for information", ...},
    {"name": "fetch_url", "description": "Fetch content from a URL", ...},
    {"name": "search_knowledge_base", "description": "Search internal KB", ...}
]
# NOTE: write_file, send_email etc. deliberately excluded

response = client.messages.create(
    model="claude-opus-4-5",
    max_tokens=4096,
    tools=research_tools,
    tool_choice={"type": "auto"},  # Claude decides which to call
    system="You are a research agent. Search for information as needed.",
    messages=messages
)
Python — Synthesis Subagent: tool_choice: none for Reasoning Pass
# Synthesis phase 1: Pure reasoning, no tools allowed
synthesis_response = client.messages.create(
    model="claude-opus-4-5",
    max_tokens=2048,
    tools=[write_report_tool],        # Tool available but...
    tool_choice={"type": "none"},      # ...cannot be called yet
    system="Analyze the research findings below and identify key themes.",
    messages=[{"role": "user", "content": aggregated_research}]
)
# Returns pure text reasoning - no tool calls possible
themes = synthesis_response.content[0].text

# Synthesis phase 2: Now allow write tool to produce final output
final_response = client.messages.create(
    model="claude-opus-4-5",
    max_tokens=4096,
    tools=[write_report_tool],
    tool_choice={"type": "tool", "name": "write_report"},  # Force final output
    messages=[..., {"role": "user", "content": f"Based on themes: {themes}. Write the report."}]
)

Anti-Patterns to Avoid

⛔ Tool Dump: All Tools to All Agents

Passing the entire tool registry to every agent. Wastes tokens, creates security risk, and introduces ambiguity. Each agent should receive a purpose-built tool subset.

⛔ Coordinator Executing Work

Giving the coordinator web_search or write_file. Coordinators orchestrate, they don’t execute domain work. This creates a single point of failure and prevents proper task specialization.

⛔ Always Auto tool_choice

Using auto for extraction steps. Claude may produce free text instead of the required structured JSON. Extraction must use forced tool_choice: tool for reliability.

⛔ Write Access in Read-Only Agents

Giving a research subagent a write_file or send_email tool. Accidental execution of write operations during research can cause unintended side effects.

⛔ Missing tool_choice: none for Reasoning

Allowing tool access during a pure reasoning or summarization pass. Claude may invoke tools unnecessarily, extending latency and consuming budget on unneeded operations.

⛔ Subagents With Spawn Power

Giving a leaf subagent the ability to spawn further subagents. This creates uncontrolled recursive delegation and breaks the coordinator’s ability to track and manage execution.

✓ Build Per-Role Tool Sets

Define tool lists for each agent role: coordinator tools, research tools, extraction tools, synthesis tools. Never share a single list across all roles.

✓ Match tool_choice to Step Guarantee

Ask: “What must this step guarantee?” Structured output → forced tool. Any tool call required → any. Reasoning only → none. Open-ended task → auto.

✓ Read-Only Tools for Gathering Agents

All agents that gather information (research, search, fetch) should have exclusively read-only tool sets. Mutation tools only for execution agents.

Exam Readiness & Key Takeaways

🎓 Exam Scenario — Multi-Agent Research Pipeline

Scenario: A multi-agent research pipeline has a coordinator, a web research subagent, and a report synthesis subagent. Which tool_choice should the coordinator use when delegating to the research subagent? Which should the synthesis subagent use when producing its first reasoning pass?

Answer: Coordinator uses auto when delegating (Claude decides if/how to use delegation tools). Research subagent uses auto (Claude chooses which search tools to call and when). Synthesis subagent first pass uses none (pure reasoning, no tool calls), then tool_choice: tool for write_report in final step.

Common distractor: “Use tool_choice: any for the synthesis subagent” — wrong. any forces some tool call but doesn’t prevent the wrong tool from being called (e.g., web_search). The synthesis agent should have no web_search in its tool set at all.

1
Principle of Least Privilege applies to tools. Every agent receives only the tools needed for its specific function. No tool sharing across roles without explicit design justification. Tool scope = security boundary + context efficiency.
2
Coordinators have orchestration tools only. spawn_subagent, delegate_task, aggregate_results. Never execution tools like web_search or write_file. Coordinators direct; they do not execute domain work themselves.
3
Four tool_choice modes — memorize all four: auto (Claude decides), any (must use some tool), tool (must use this specific tool), none (no tools allowed). Each serves a distinct guarantee requirement.
4
Use tool_choice: tool for structured extraction. Forces Claude to call a named schema tool, guaranteed to produce JSON matching the defined schema. More reliable than asking for JSON in free text, which Claude may not follow.
5
Use tool_choice: none for reasoning/summarization passes. Prevents unintended tool calls during pure text reasoning steps. Useful as a first pass before allowing write operations in a two-phase pattern.
6
Each tool definition costs tokens. Tool schemas consume context. Scoping tool sets per agent reduces this overhead, leaving more context for actual task content and improving performance.
7
No subagent should have spawn_subagent. Delegation authority belongs to coordinators. Giving subagents the ability to spawn further agents creates uncontrolled recursion and breaks the coordinator’s oversight of the system.