处理工具调用

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


本页介绍工具调用的生命周期:从 Claude 的响应中读取 tool_use 块,在回复中格式化 tool_result 块,以及发出错误信号。有关自动处理此过程的 SDK 抽象,请参阅工具运行器

Note

使用工具运行器更简单:本页描述的手动工具处理由工具运行器自动管理。当你需要对工具执行进行自定义控制时使用本页。

Claude 的响应根据使用的是客户端工具还是服务器端工具而有所不同。

处理客户端工具的结果

响应的 stop_reasontool_use,并包含一个或多个 tool_use 内容块,其中包括:

  • id:此特定工具使用块的唯一标识符。稍后将用于匹配工具结果。
  • name:正在使用的工具名称。
  • input:传递给工具的输入对象,符合工具的 input_schema

包含 tool_use 内容块的 API 响应示例

{
  "id": "msg_01Aq9w938a90dw8q",
  "model": "claude-opus-4-7",
  "stop_reason": "tool_use",
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "I'll check the current weather in San Francisco for you."
    },
    {
      "type": "tool_use",
      "id": "toolu_01A09q90qw90lq917835lq9",
      "name": "get_weather",
      "input": { "location": "San Francisco, CA", "unit": "celsius" }
    }
  ]
}

当你收到客户端工具的工具使用响应时,你应该:

  1. tool_use 块中提取 nameidinput
  2. 在代码库中运行与该工具名称对应的实际工具,传入工具 input
  3. 通过发送一个 roleuser 的新消息来继续对话,消息包含 tool_result 类型的 content 块和以下信息:
    • tool_use_id:此结果对应的工具使用请求的 id
    • content(可选):工具的结果,可以是字符串(例如 "content": "15 degrees")、嵌套内容块列表(例如 "content": [{"type": "text", "text": "15 degrees"}])或文档块列表(例如 "content": [{"type": "document", "source": {"type": "text", "media_type": "text/plain", "data": "15 degrees"}}])。这些内容块可以使用 textimagedocument 类型。
    • is_error(可选):如果工具执行导致错误,设置为 true
Note

重要的格式要求

  • 工具结果块必须在消息历史记录中紧跟其对应的工具使用块。你不能在助手的工具使用消息和用户的工具结果消息之间包含任何消息。
  • 在包含工具结果的用户消息中,tool_result 块必须位于 content 数组的第一位。任何文本必须在所有工具结果之后。

例如,这会导致 400 错误:

{
  "role": "user",
  "content": [
    { "type": "text", "text": "Here are the results:" }, // ❌ Text before tool_result
    { "type": "tool_result", "tool_use_id": "toolu_01" /* ... */ }
  ]
}

这是正确的:

{
  "role": "user",
  "content": [
    { "type": "tool_result", "tool_use_id": "toolu_01" /* ... */ },
    { "type": "text", "text": "What should I do next?" } // ✅ Text after tool_result
  ]
}

如果你收到类似 "tool_use ids were found without tool_result blocks immediately after" 的错误,请检查你的工具结果格式是否正确。

成功的工具结果示例

{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01A09q90qw90lq917835lq9",
      "content": "15 degrees"
    }
  ]
}

包含图像的工具结果示例

{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01A09q90qw90lq917835lq9",
      "content": [
        { "type": "text", "text": "15 degrees" },
        {
          "type": "image",
          "source": {
            "type": "base64",
            "media_type": "image/jpeg",
            "data": "/9j/4AAQSkZJRg..."
          }
        }
      ]
    }
  ]
}

空工具结果示例

{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01A09q90qw90lq917835lq9"
    }
  ]
}

包含文档的工具结果示例

{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01A09q90qw90lq917835lq9",
      "content": [
        { "type": "text", "text": "The weather is" },
        {
          "type": "document",
          "source": {
            "type": "text",
            "media_type": "text/plain",
            "data": "15 degrees"
          }
        }
      ]
    }
  ]
}

收到工具结果后,Claude 将使用该信息继续生成对原始用户提示的响应。

处理服务器端工具的结果

Claude 在内部执行工具,并将结果直接整合到其响应中,无需额外的用户交互。

Tip

与其他 API 的区别

与分离工具使用或使用 toolfunction 等特殊角色的 API 不同,Claude API 将工具直接集成到 userassistant 消息结构中。

消息包含 textimagetool_usetool_result 块的数组。user 消息包含客户端内容和 tool_result,而 assistant 消息包含 AI 生成的内容和 tool_use

使用 is_error 处理错误

使用 Claude 工具时可能出现几种不同类型的错误:

工具执行错误

如果工具本身在执行期间抛出错误(例如,获取天气数据时的网络错误),你可以在 content 中返回错误消息,并附带 "is_error": true

{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01A09q90qw90lq917835lq9",
      "content": "ConnectionError: the weather service API is not available (HTTP 500)",
      "is_error": true
    }
  ]
}

Claude 然后会将此错误整合到其对用户的响应中。例如:"抱歉,我无法获取当前天气,因为天气服务 API 不可用。请稍后再试。"

Tip

编写具有指导性的错误消息。不要使用通用的错误(如 "failed"),而是包含出了什么问题以及 Claude 应该尝试什么,例如 "Rate limit exceeded. Retry after 60 seconds." 这给 Claude 提供了恢复或调整所需的上下文,而无需猜测。

无效的工具名称

如果 Claude 尝试使用的工具无效(例如,缺少必需的参数),通常意味着没有足够的信息让 Claude 正确使用该工具。在开发期间最好的做法是在工具定义中使用更详细的 description 值重试请求。

但是,你也可以通过指示错误的 tool_result 继续对话,Claude 将尝试使用填写了缺失信息的工具再次使用:

{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01A09q90qw90lq917835lq9",
      "content": "Error: Missing required 'location' parameter",
      "is_error": true
    }
  ]
}

如果工具请求无效或缺少参数,Claude 会重试 2-3 次并进行更正,然后向用户道歉。

Tip

要完全消除无效的工具调用,请在工具定义上使用 strict: true严格工具使用。这保证工具输入将始终与你的 schema 完全匹配,防止缺少参数和类型不匹配。

服务器端工具错误

当服务器端工具遇到错误(例如,Web Search 的网络问题)时,Claude 会透明地处理这些错误,并尝试向用户提供替代响应或解释。与客户端工具不同,你不需要为服务器端工具处理 is_error 结果。

对于网络搜索,可能的错误代码包括:

  • too_many_requests:超出速率限制
  • invalid_input:无效的搜索查询参数
  • max_uses_exceeded:超出最大网络搜索工具使用次数
  • query_too_long:查询超出最大长度
  • unavailable:发生内部错误

后续步骤