Claude 能够与外部客户端工具和函数交互,允许您使用自己的自定义工具来装备 Claude,以执行更广泛的任务。

现在,对于使用 Anthropic Messages API、Amazon Bedrock 和 Google Vertex AI 的开发人员,工具使用功能已在整个 Claude 3 模型系列中普遍可用!请继续使用此表单分享您的想法和建议。

以下是如何使用 Messages API 为 Claude 提供工具的示例:

curl https://api.anthropic.com/v1/messages \
  -H "content-type: application/json" \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -d '{
    "model": "claude-3-opus-20240229",
    "max_tokens": 1024,
    "tools": [
      {
        "name": "get_weather",
        "description": "获取给定位置的当前天气",
        "input_schema": {
          "type": "object",
          "properties": {
            "location": {
              "type": "string",
              "description": "城市和州,例如旧金山,加利福尼亚州"
            }
          },
          "required": ["location"]
        }
      }
    ],
    "messages": [
      {
        "role": "user",
        "content": "旧金山的天气如何?"
      }
    ]
  }'

工具使用的工作原理

使用 Claude 的工具涉及以下步骤:

  1. 为 Claude 提供工具和用户提示:(API 请求)
    • 定义您希望 Claude 访问的工具集,包括它们的名称、描述和输入模式。
    • 提供一个用户提示,可能需要使用一个或多个这些工具来回答,例如”旧金山的天气如何?“。
  2. Claude 使用工具:(API 响应)
    • Claude 评估用户提示,并决定是否有任何可用工具可以帮助回答用户的查询或任务。如果是,它还会决定使用哪些工具以及使用什么输入。
    • Claude 构造格式正确的工具使用请求。
    • API 响应将具有 stop_reasontool_use,表示 Claude 想要使用外部工具。
  3. 提取工具输入,运行代码并返回结果:(API 请求)
    • 在客户端,您应该从 Claude 的工具使用请求中提取工具名称和输入。
    • 在客户端运行实际的工具代码。
    • 通过使用包含 tool_result 内容块的新 user 消息继续对话,将结果返回给 Claude。
  4. Claude 使用工具结果来制定响应:(API 响应)
    • 在收到工具结果后,Claude 将使用该信息来制定对原始用户提示的最终响应。

步骤 (3) 和 (4) 是可选的 - 对于某些工作流,Claude 使用工具就是您需要的所有信息,您可能不需要将工具结果返回给 Claude。

所有工具都是用户提供的

需要注意的是,Claude 无法访问任何内置的服务器端工具。所有工具都必须由您(用户)在每个 API 请求中明确提供。这使您可以完全控制和灵活地使用 Claude 可以使用的工具。


指定工具

工具在 API 请求的 tools 顶级参数中指定。每个工具定义包括:

  • name:工具的名称。必须匹配正则表达式 ^[a-zA-Z0-9_-]{1,64}$
  • description:对工具功能、何时使用以及如何运作的详细纯文本描述。
  • input_schema:定义工具预期参数的 JSON Schema 对象。

以下是一个简单的工具定义示例:

JSON
{
  "name": "get_weather",
  "description": "获取给定位置的当前天气",
  "input_schema": {
    "type": "object",
    "properties": {
      "location": {
        "type": "string",
        "description": "城市和州,例如旧金山,加利福尼亚州"
      },
      "unit": {
        "type": "string",
        "enum": ["celsius", "fahrenheit"],
        "description": "温度单位,'celsius' 或 'fahrenheit'"
      }
    },
    "required": ["location"]
  }
}

这个名为 get_weather 的工具需要一个输入对象,其中包含一个必需的 location 字符串和一个可选的 unit 字符串,该字符串必须是 “celsius” 或 “fahrenheit”。

工具定义的最佳实践

要在使用工具时获得 Claude 的最佳性能,请遵循以下准则:

  • 提供极其详细的描述。 这是工具性能中最重要的因素。您的描述应该解释工具的每个细节,包括:
    • 工具的功能
    • 何时应该使用(以及何时不应该使用)
    • 每个参数的含义以及它如何影响工具的行为
    • 任何重要的注意事项或限制,例如如果工具名称不明确,工具不会返回哪些信息 您可以为 Claude 提供有关工具的更多上下文,它就会更好地决定何时以及如何使用它们。每个工具描述至少要有 3-4 个句子,如果工具很复杂,则更多。
  • 优先考虑描述而不是示例。 虽然您可以在工具描述或附带的提示中包含如何使用工具的示例,但这不如对工具的目的和参数进行清晰全面的解释重要。只有在充分阐述描述之后才添加示例。

以下是一个好的工具描述示例:

JSON
{
  "name": "get_stock_price",
  "description": "检索给定股票代码的当前股价。股票代码必须是在纽约证券交易所或纳斯达克等主要美国证券交易所上市的公司的有效代码。该工具将以美元返回最新交易价格。当用户询问特定股票的当前或最近价格时,应使用它。它不会提供有关股票或公司的任何其他信息。",
  "input_schema": {
    "type": "object",
    "properties": {
      "ticker": {
        "type": "string",
        "description": "股票代码,例如 Apple Inc. 的 AAPL"
      }
    },
    "required": ["ticker"]
  }
}

相比之下,以下是一个不好的工具描述示例:

JSON
{
  "name": "get_stock_price",
  "description": "获取股票代码的股价。",
  "input_schema": {
    "type": "object",
    "properties": {
      "ticker": {
        "type": "string"
      }
    },
    "required": ["ticker"]
  }
}

好的描述清楚地解释了工具的功能、何时使用、返回的数据以及 ticker 参数的含义。不好的描述过于简短,让 Claude 对工具的行为和用法有许多未解答的问题。


工具使用和工具结果内容块

当 Claude 决定使用您提供的工具之一时,它将返回一个 stop_reasontool_use 的响应,并在 API 响应中包含一个或多个 tool_use 内容块,其中包括:

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

以下是包含 tool_use 内容块的 API 响应示例:

JSON
{
  "id": "msg_01Aq9w938a90dw8q",
  "model": "claude-3-opus-20240229",
  "stop_reason": "tool_use",
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "<thinking>我需要使用 get_weather,用户想要 SF,这可能是旧金山,加利福尼亚州。</thinking>"
    },
    {
      "type": "tool_use",
      "id": "toolu_01A09q90qw90lq917835lq9",
      "name": "get_weather",
      "input": {"location": "San Francisco, CA", "unit": "celsius"}
    }
  ]
}

当您收到工具使用响应时,您应该:

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

以下是返回成功工具结果的示例:

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

content 中也支持图像:

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

以下是返回错误结果的示例:

JSON
{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01A09q90qw90lq917835lq9",
      "content": "ConnectionError: 天气服务 API 不可用(HTTP 500)",
      "is_error": true
    }
  ]
}

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

您还可以返回一个没有错误的工具结果,其中 content 为空,表示工具成功运行而没有任何输出:

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

与其他 API 的差异

您可能熟悉其他 API,它们将工具使用作为与模型主要输出分开的内容返回,或者使用特殊用途的 toolfunction 消息 role

相比之下,Anthropic 的模型和 API 围绕交替的 userassistant 消息构建,其中每条消息都是丰富内容块的数组:textimagetool_usetool_result

在此格式中,user 消息表示客户端和用户/人工管理的内容,assistant 消息表示服务器端和 AI 管理的内容。因此,没有特殊的 toolfunction 消息 role,您应该在 user 消息的 content 中包含 tool_result 块。


强制工具使用

在某些情况下,即使 Claude 认为它可以在不使用工具的情况下提供答案,您也可能希望 Claude 使用特定工具来回答用户的问题。您可以通过在 tool_choice 字段中指定工具来做到这一点,如下所示:

tool_choice = {"type": "tool", "name": "get_weather"}

通过明确告诉 Claude 使用 get_weather 工具,您可以鼓励它使用您想要的工具。这种技术对于测试和调试您的工具集成或者当您知道无论输入如何都应该始终使用该工具时非常有用。

您还可以通过 {"type": "any"} 告诉 Claude 使用任何提供的工具。默认的 tool_choice{"type": "auto"},它允许 Claude 决定是否使用工具。

请注意,当您将 tool_choice 设置为 anytool 时,我们将预填助手消息以强制使用工具。这意味着即使明确要求模型这样做,它也不会在 tool_use 内容块之前发出思维链 text 内容块。我们的测试表明,这不应降低性能。如果您仍然希望在请求模型使用特定工具的同时保留思维链(特别是使用 Opus),您可以将 tool_choice 设置为 {"type": "auto"} (默认值),并在 user 消息中添加明确的指令。例如:“伦敦的天气如何?在你的回答中使用 get_weather 工具。”


JSON 输出

工具不一定需要是客户端函数 - 只要您希望模型返回符合提供的模式的 JSON 输出,就可以使用工具。例如,您可以使用具有特定模式的 record_summary 工具。有关完整的工作示例,请参阅工具使用示例


错误处理

在使用 Claude 的工具时可能会发生几种不同类型的错误:

工具执行错误

如果工具本身在执行过程中抛出错误(例如获取天气数据时的网络错误),您可以在 content 中返回错误消息以及 "is_error": true

JSON
{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01A09q90qw90lq917835lq9",
      "content": "ConnectionError: 天气服务 API 不可用(HTTP 500)",
      "is_error": true
    }
  ]
}

然后 Claude 会将此错误纳入其对用户的响应中,例如”对不起,我无法检索当前天气,因为天气服务 API 不可用。请稍后再试。”

超过最大令牌数

如果由于达到 max_tokens 限制而截断了 Claude 的响应,并且截断的响应包含不完整的工具使用块,则需要使用更高的 max_tokens 值重试请求以获取完整的工具使用。

无效的工具使用

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

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

JSON
{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01A09q90qw90lq917835lq9",
      "content": "错误:缺少必需的 'location' 参数",
      "is_error": true
    }
  ]
}

思维链工具使用

在使用工具时,Claude 通常会展示其”思维链”,即它用来分解问题并决定使用哪些工具的逐步推理。如果 tool_choice 设置为 auto(这是默认值,请参阅强制工具使用),Claude 3 Opus 模型将执行此操作,Sonnet 和 Haiku 可以通过提示来执行此操作。

例如,给定提示”旧金山现在的天气如何,那里现在几点了?“,Claude 可能会回答:

JSON
{
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "<thinking>要回答这个问题,我将:1. 使用 get_weather 工具获取旧金山当前的天气。2. 使用 get_time 工具获取覆盖旧金山的 America/Los_Angeles 时区的当前时间。</thinking>"
    },
    {
      "type": "tool_use",
      "id": "toolu_01A09q90qw90lq917835lq9",
      "name": "get_weather",
      "input": {"location": "San Francisco, CA"}
    }
  ]
}

这个思维链可以洞察 Claude 的推理过程,并可以帮助您调试意外行为。

对于 Claude 3 Sonnet 模型,默认情况下思维链不太常见,但您可以通过在用户消息或系统提示中添加类似”在回答之前,请在标签中逐步解释你的推理。“来提示 Claude 展示其推理。有关更深入的示例,请参阅思维链工具使用示例

需要注意的是,虽然 <thinking> 标签是 Claude 用来表示其思维链的常见约定,但确切的格式(例如这个 XML 标签的名称)可能会随时间而改变。您的代码应该将思维链视为任何其他助手生成的文本,而不是依赖于 <thinking> 标签的存在或特定格式。


工具使用最佳实践和限制

在使用 Claude 的工具时,请记住以下限制和最佳实践:

  • 使用 Claude 3 Opus 来处理复杂的工具使用,如果处理简单的工具则使用 Haiku:与其他模型相比,Opus 能够同时处理最多的工具,并且在捕获缺失参数方面更好。在参数未明确给出或可能不需要工具来完成用户请求的模糊情况下,它更有可能要求澄清。Haiku 默认尝试更频繁地使用工具(即使与查询无关),如果未明确给出参数,它将推断缺失的参数。
  • 工具数量:即使使用数百个简单工具,所有 Claude 3 模型仍可保持 >90% 的准确性,以及少量复杂工具。“复杂”工具是指具有大量参数或具有复杂模式(例如嵌套对象)的参数的工具。
  • 复杂和深度嵌套的工具:就像人类一样,Claude 可以更好地使用更简单的接口和更简单的工具。如果 Claude 难以正确使用您的工具,请尝试将输入模式从深度嵌套的 JSON 对象扁平化,并减少输入的数量。
  • 顺序工具使用:Claude 通常更喜欢一次使用一个工具,然后使用该工具的输出来指导其下一个操作。虽然您可以通过仔细设计提示和工具来提示 Claude 并行使用多个工具,但这可能会导致 Claude 为依赖于早期工具使用结果的参数填充虚拟值。为获得最佳结果,请设计您的工作流程和工具,以引出并使用来自 Claude 的一系列顺序工具。
  • 重试:如果 Claude 的工具使用请求无效或缺少必需参数,您可以返回错误响应,Claude 通常会使用填充了缺失信息的请求重试。但是,在 2-3 次失败尝试后,Claude 可能会放弃并向用户返回道歉,而不是进一步重试。
  • 调试:在调试意外的工具使用行为时,请注意 Claude 的思维链输出(如果有),以了解它为什么做出这些选择。您还可以尝试提示 Claude 使用特定工具,看看是否会导致预期的行为。如果 Claude 误用工具,请仔细检查您的工具描述和模式是否清晰明确。
  • <search_quality_reflection> 标签:有时在使用搜索工具时,模型可能会在其响应中返回 <search_quality_reflection> XML 标签和搜索质量分数。要阻止模型这样做,请在提示的末尾添加句子”不要在你的回答中反映返回的搜索结果的质量。“。

通过牢记这些限制和准则,您可以设计有效的工具和主动编排,显著扩展 Claude 的能力以处理各种任务。


Beta 版本历史(旧版)

截至 2024 年 5 月 30 日,工具使用不再处于 beta 阶段,已普遍可用。

  • tools-2024-05-16
    • 系统提示更改为 Opus,以更好地处理在单个轮次中可能需要多次工具使用的场景
  • tools-2024-04-04:工具使用的初始 beta 版本

后续步骤

工具使用是一种强大的技术,通过将 Claude 连接到外部数据源和功能来扩展其能力。使用设计良好的工具集,您可以使 Claude 能够处理大量仅凭其基础知识无法完成的任务。

一些可能的后续步骤包括:

  • 浏览我们的工具使用手册:探索我们的现成工具使用代码示例库,例如:
  • 提高工具使用质量和可靠性:迭代和改进您的工具描述和提示,以从 Claude 引出更可靠和准确的工具使用
  • 扩展 Claude 的能力
    • 尝试不同的工具和模式,看看 Claude 如何处理不同类型的输入和输出格式。
    • 将多个工具链接在一起,将复杂的任务分解为一系列更简单的步骤。
    • 构建主动编排,让 Claude 可以像助手一样端到端地完成各种任务。
    • 探索复杂的工具使用架构,例如为 Claude 提供工具以进行 RAG 搜索,或调用较小的模型子代理(如 Haiku)代表它执行任务

在您使用工具构建时,我们很乐意听取您的反馈并了解您的创作!加入我们的开发者 Discord,与其他开发者分享您的项目并讨论技巧和技术。

我们很高兴看到您如何使用工具使用来突破 Claude 的可能性界限。祝您构建愉快!