Claude Platform Docs
Messages工具

并行工具使用

启用、格式化和禁用并行工具调用,并提供消息历史指导和故障排除。

默认情况下,Claude 可能会在单个响应中调用多个工具。本页介绍如何运行这些调用、如何格式化消息历史以保持并行性正常工作,以及在需要时如何禁用"parallel tool use"(并行工具使用)。有关单次调用流程,请参阅处理工具调用。

执行语义

当 Claude 调用工具时,响应的 stop_reason 为 tool_use,并且可以在单个助手轮次中包含多个 tool_use 块。如何运行这些调用由您决定。API 不规定执行顺序:您可以并发运行这些调用(Promise.all、asyncio.gather),按它们出现的顺序依次运行,或者采用任何适合您工具的组合方式。

请根据您的工具的功能选择策略。独立的只读操作通常可以安全地并行运行,以降低"latency"(延迟)。具有副作用、共享状态或顺序要求的工具可能更适合依次运行。

无论您使用哪种策略,都要为每个 tool_use 块返回一个 tool_result,并将它们全部放在下一条用户消息中。使用 tool_use_id 将每个结果与其调用匹配,并将每个 tool_result 块放在该消息中任何文本内容之前。有关完整的格式规则,请参阅处理工具调用。如果您选择不运行某个特定调用(例如,因为您依次运行了该批次而较早的调用失败了),仍然要为其返回一个带有 is_error: true 和简短说明的 tool_result。

{
  "type": "tool_result",
  "tool_use_id": "toolu_02",
  "is_error": true,
  "content": "Not executed: the preceding write_file call failed."
}

计算机使用工具和浏览器使用工具的要求更为严格。当 Claude 在一个轮次中返回多个其成员工具调用(批量操作)时,请按它们出现的顺序依次运行,并在第一次失败时停止;每个工具都定义了针对您跳过的调用应返回的确切文本。

测试并行工具调用

以下脚本发送一个应触发并行工具调用的请求,验证响应中包含这些调用,并格式化工具结果以保持并行性正常工作。请在环境中设置 ANTHROPIC_API_KEY 后运行它:

client = Anthropic()

# 定义工具
tools = [
    {
        "name": "get_weather",
        "description": "Get the current weather in a given location",
        "input_schema": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "The city and state, e.g. San Francisco, CA",
                }
            },
            "required": ["location"],
        },
    },
    {
        "name": "get_time",
        "description": "Get the current time in a given timezone",
        "input_schema": {
            "type": "object",
            "properties": {
                "timezone": {
                    "type": "string",
                    "description": "The timezone, e.g. America/New_York",
                }
            },
            "required": ["timezone"],
        },
    },
]

# 测试包含并行工具调用的对话
messages = [
    {
        "role": "user",
        "content": "What's the weather in SF and NYC, and what time is it there?",
    }
]

# 发起初始请求
print("Requesting parallel tool calls...")
response = client.messages.create(
    model="claude-opus-5-5", max_tokens=1024, messages=messages, tools=tools
)

# 检查是否存在并行工具调用
tool_uses = [block for block in response.content if block.type == "tool_use"]
print(f"\n✓ Claude made {len(tool_uses)} tool calls")

if len(tool_uses) > 1:
    print("✓ Parallel tool calls detected!")
    for tool in tool_uses:
        print(f"  - {tool.name}: {tool.input}")
else:
    print("✗ No parallel tool calls detected")

# 模拟工具执行并正确格式化结果
tool_results = []
for tool_use in tool_uses:
    if tool_use.name == "get_weather":
        if "San Francisco" in str(tool_use.input):
            result = "San Francisco: 68°F, partly cloudy"
        else:
            result = "New York: 45°F, clear skies"
    else:  # get_time
        if "Los_Angeles" in str(tool_use.input):
            result = "2:30 PM PST"
        else:
            result = "5:30 PM EST"

    tool_results.append(
        {"type": "tool_result", "tool_use_id": tool_use.id, "content": result}
    )

# 使用工具结果继续对话
messages.extend(
    [
        {"role": "assistant", "content": response.content},
        {"role": "user", "content": tool_results},  # All results in one message!
    ]
)

# 获取最终响应
print("\nGetting final response...")
final_response = client.messages.create(
    model="claude-opus-5-5", max_tokens=1024, messages=messages, tools=tools
)

final_text = next(
    block.text for block in final_response.content if block.type == "text"
)
print(f"\nClaude's response:\n{final_text}")

# 验证格式
print("\n--- Verification ---")
print(f"✓ Tool results sent in single user message: {len(tool_results)} results")
print("✓ No text before tool results in content array")
print("✓ Conversation formatted correctly for future parallel tool use")

末尾的摘要行重申了保持并行性正常工作的两条格式规则:所有工具结果都在单条用户消息中返回,并且该消息中工具结果之前不出现任何文本内容。

最大化并行工具使用

当请求能从多个工具中受益时,Claude 4 及更高版本的模型默认会进行并行工具调用。对于所有模型,您都可以通过有针对性的提示来提高并行工具调用的可能性:

禁用并行工具使用

并行工具使用默认开启。要关闭它,请在 tool_choice 对象内设置 disable_parallel_tool_use: true。它不是顶层请求参数。其效果取决于 tool_choice 的类型。

最多一次工具调用

当 tool_choice 类型为 auto(默认值)时,设置 disable_parallel_tool_use: true 意味着 Claude 每个响应最多调用一个工具。Claude 仍然可以不调用任何工具而以纯文本回答。高亮显示的行是与标准工具使用请求相比唯一的变化:

client = Anthropic()

response = client.messages.create(
    model="claude-opus-5-5",
    max_tokens=1024,
    tools=[
        {
            "name": "get_weather",
            "description": "Get the current weather in a given location",
            "input_schema": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "The city and state, e.g. San Francisco, CA",
                    }
                },
                "required": ["location"],
            },
        }
    ],
    tool_choice={"type": "auto", "disable_parallel_tool_use": True},
    messages=[
        {
            "role": "user",
            "content": "What is the weather in San Francisco and New York?",
        }
    ],
)
print(response.content)

恰好一次工具调用

当 tool_choice 类型为 any 或 tool 时,设置 disable_parallel_tool_use: true 意味着 Claude 恰好调用一个工具。Claude Opus 5.5、Claude Sonnet 5.5、Claude Fable 5.1 和 Claude Mythos 5.1 不支持这些 tool_choice 类型(请参阅强制工具使用)。以下示例使用 any。同一字段也适用于 tool:

client = Anthropic()

response = client.messages.create(
    model="claude-opus-5",
    max_tokens=1024,
    tools=[
        {
            "name": "get_weather",
            "description": "Get the current weather in a given location",
            "input_schema": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "The city and state, e.g. San Francisco, CA",
                    }
                },
                "required": ["location"],
            },
        }
    ],
    tool_choice={"type": "any", "disable_parallel_tool_use": True},
    messages=[
        {
            "role": "user",
            "content": "What is the weather in San Francisco and New York?",
        }
    ],
)
print(response.content)

故障排除

如果 Claude 没有按预期进行并行工具调用,请检查以下常见问题:

1. 工具结果格式不正确

最常见的问题是在对话历史中错误地格式化工具结果。这会"教会" Claude 避免并行调用。

具体针对并行工具使用:

  • 错误: 为每个工具结果使用单独的用户消息
  • 正确: 所有工具结果一起放在单条用户消息中
// Wrong: separate user messages reduce parallel tool use
[
  {"role": "assistant", "content": [tool_use_1, tool_use_2]},
  {"role": "user", "content": [tool_result_1]},
  {"role": "user", "content": [tool_result_2]}  // Separate message
]

// Correct: one user message with all results maintains parallel tool use
[
  {"role": "assistant", "content": [tool_use_1, tool_use_2]},
  {"role": "user", "content": [tool_result_1, tool_result_2]}  // Single message
]

有关其他格式规则,请参阅处理工具调用。

2. 提示力度不足

默认提示可能不够。请使用最大化并行工具使用中更强的系统提示。

3. 衡量并行工具使用情况

要验证并行工具调用是否正常工作:

messages = []  # Message objects returned by client.messages.create across your run

tool_call_messages = [
    msg for msg in messages if any(block.type == "tool_use" for block in msg.content)
]
total_tool_calls = sum(
    len([block for block in msg.content if block.type == "tool_use"])
    for msg in tool_call_messages
)
avg_tools_per_message = (
    total_tool_calls / len(tool_call_messages) if tool_call_messages else 0.0
)
print(f"Average tools per message: {avg_tools_per_message}")
# 如果并行调用正常工作,该值应 > 1.0

4. 批次中的调用似乎相互依赖

执行顺序由您选择。如果您的工具存在顺序依赖,依次运行该批次并在第一次失败时停止是一种有效的策略(也是计算机使用和浏览器使用工具所要求的策略):对于您未运行的任何调用,返回 is_error: true。如果您并行运行,而某个调用因其前置条件尚未完成而失败,请返回 is_error: true 并附上自然的错误消息。Claude 将在下一轮次重新发出该调用。要减少相互依赖的调用一起出现的情况,请将以下内容添加到您的系统提示中:"Only batch tool calls that are independent of each other."

后续步骤

使用 SDK 的 Tool Runner 抽象来自动处理智能体循环、错误包装和类型安全。

解析 tool_use 块、格式化 tool_result 响应,并使用 is_error 处理错误。

指定工具模式、编写有效的描述,并控制 Claude 何时调用您的工具。

Was this page helpful?