以下是一些代码示例,演示了各种工具使用模式和技术。为了简洁起见,这些工具是简单的工具,工具描述也比理想情况下要短,以确保最佳性能。有关更多信息,请参阅指定工具

单一工具

此示例展示了一个基本的单工具情况,使用了一个 get_weather 工具。

curl https://api.anthropic.com/v1/messages \
     --header "x-api-key: $ANTHROPIC_API_KEY" \
     --header "anthropic-version: 2023-06-01" \
     --header "content-type: application/json" \
     --data \
'{
    "model": "claude-3-opus-20240229",
    "max_tokens": 1024,
    "tools": [{
        "name": "get_weather",
        "description": "获取给定位置的当前天气",
        "input_schema": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "城市和州,例如 San Francisco, CA"
                },
                "unit": {
                    "type": "string",
                    "enum": ["celsius", "fahrenheit"],
                    "description": "温度单位,\"celsius\" 或 \"fahrenheit\""
                }
            },
            "required": ["location"]
        }
    }],
    "messages": [{"role": "user", "content": "旧金山的天气如何?"}]
}'

Claude 将返回类似以下的响应:

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

然后,您需要使用提供的输入执行 get_weather 函数,并在新的 user 消息中返回结果:

curl https://api.anthropic.com/v1/messages \
     --header "x-api-key: $ANTHROPIC_API_KEY" \
     --header "anthropic-version: 2023-06-01" \
     --header "content-type: application/json" \
     --data \
'{
    "model": "claude-3-opus-20240229",
    "max_tokens": 1024,
    "tools": [
        {
            "name": "get_weather",
            "description": "获取给定位置的当前天气",
            "input_schema": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "城市和州,例如 San Francisco, CA"
                    },
                    "unit": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"],
                        "description": "温度单位,\"celsius\" 或 \"fahrenheit\""
                    }
                },
                "required": ["location"]
            }
        }
    ],
    "messages": [
        {
            "role": "user",
            "content": "旧金山的天气如何?"
        },
        {
            "role": "assistant",
            "content": [
                {
                    "type": "text",
                    "text": "<thinking>我需要使用 get_weather,用户想要的是旧金山,可能是指加利福尼亚州的旧金山。</thinking>"
                },
                {
                    "type": "tool_use",
                    "id": "toolu_01A09q90qw90lq917835lq9",
                    "name": "get_weather",
                    "input": {
                        "location": "San Francisco, CA",
                        "unit": "celsius"
                    }
                }
            ]
        },
        {
            "role": "user",
            "content": [
                {
                    "type": "tool_result",
                    "tool_use_id": "toolu_01A09q90qw90lq917835lq9",
                    "content": "15 度"
                }
            ]
        }
    ]
}'

这将打印 Claude 的最终响应,包含天气数据:

JSON
{
  "id": "msg_01Aq9w938a90dw8q",
  "model": "claude-3-opus-20240229",
  "stop_reason": "stop_sequence",
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "旧金山目前的天气是 15 摄氏度(59 华氏度)。这是海湾城市一个凉爽的日子!"
    }
  ]
}

缺少信息

如果用户的提示没有包含足够的信息来填充工具所需的所有参数,Claude 3 Opus 更有可能意识到缺少参数并询问。Claude 3 Sonnet 可能会询问,特别是在提示它在输出工具请求之前进行思考时。但它也可能会尽最大努力推断出一个合理的值。

例如,使用上面的 get_weather 工具,如果你问 Claude “天气如何?“而没有指定位置,Claude,特别是 Claude 3 Sonnet,可能会猜测工具输入:

JSON
{
  "type": "tool_use",
  "id": "toolu_01A09q90qw90lq917835lq9",
  "name": "get_weather", 
  "input": {"location": "New York, NY", "unit": "fahrenheit"}
}

这种行为并不能保证,特别是对于更模糊的提示和比 Claude 3 Opus 智能程度低的模型。如果 Claude 3 Opus 没有足够的上下文来填充所需的参数,它更有可能用一个澄清的问题来回应,而不是进行工具调用。


多个工具

您可以在单个请求中为 Claude 提供多个工具供其选择。下面是一个同时使用 get_weatherget_time 工具的示例,以及一个询问两者的用户查询。

curl https://api.anthropic.com/v1/messages \
     --header "x-api-key: $ANTHROPIC_API_KEY" \
     --header "anthropic-version: 2023-06-01" \
     --header "content-type: application/json" \
     --data \
'{
    "model": "claude-3-opus-20240229",
    "max_tokens": 1024,
    "tools": [{
        "name": "get_weather",
        "description": "获取给定位置的当前天气",
        "input_schema": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "城市和州,例如 San Francisco, CA"
                },
                "unit": {
                    "type": "string",
                    "enum": ["celsius", "fahrenheit"],
                    "description": "温度单位,'celsius' 或 'fahrenheit'"
                }
            },
            "required": ["location"]
        }
    },
    {
        "name": "get_time",
        "description": "获取给定时区的当前时间",
        "input_schema": {
            "type": "object",
            "properties": {
                "timezone": {
                    "type": "string",
                    "description": "IANA 时区名称,例如 America/Los_Angeles"
                }
            },
            "required": ["timezone"]
        }
    }],
    "messages": [{
        "role": "user",
        "content": "现在纽约的天气如何?那里现在几点了?"
    }]
}'

在这种情况下,Claude 很可能会尝试使用两个独立的工具,一次一个 —— get_weather 然后是 get_time —— 以完全回答用户的问题。但是,它有时也会一次输出两个 tool_use 块,特别是如果它们彼此不依赖。您需要执行每个工具,并在单个 user 消息中的单独 tool_result 块中返回它们的结果。


顺序工具

某些任务可能需要按顺序调用多个工具,使用一个工具的输出作为另一个工具的输入。在这种情况下,Claude 将一次调用一个工具。如果提示一次调用所有工具,Claude 可能会为下游工具猜测参数,如果它们依赖于上游工具的工具结果。

下面是一个使用 get_location 工具获取用户位置,然后将该位置传递给 get_weather 工具的示例:

curl https://api.anthropic.com/v1/messages \
     --header "x-api-key: $ANTHROPIC_API_KEY" \
     --header "anthropic-version: 2023-06-01" \
     --header "content-type: application/json" \
     --data \
'{
    "model": "claude-3-opus-20240229",
    "max_tokens": 1024,
    "tools": [
        {
            "name": "get_location",
            "description": "根据用户的 IP 地址获取当前用户位置。此工具没有参数或参数。",
            "input_schema": {
                "type": "object",
                "properties": {}
            }
        },
        {
            "name": "get_weather",
            "description": "获取给定位置的当前天气",
            "input_schema": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "城市和州,例如 San Francisco, CA"
                    },
                    "unit": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"],
                        "description": "温度单位,'celsius' 或 'fahrenheit'"
                    }
                },
                "required": ["location"]
            }
        }
    ],
    "messages": [{
        "role": "user",
        "content": "我这里的天气如何?"
    }]
}'

在这种情况下,Claude 会首先调用 get_location 工具获取用户的位置。在您在 tool_result 中返回位置后,Claude 会使用该位置调用 get_weather 以获得最终答案。

完整的对话可能如下所示:

角色内容
用户我这里的天气如何?
助手<thinking>要回答这个问题,我首先需要使用 get_location 工具确定用户的位置。然后我可以将该位置传递给 get_weather 工具,找到那里的当前天气。</thinking>[get_location 的工具使用]
用户[get_location 的工具结果,带有匹配的 id 和 San Francisco, CA 的结果]
助手[get_weather 的工具使用,带有以下输入]{ “location”: “San Francisco, CA”, “unit”: “fahrenheit” }
用户[get_weather 的工具结果,带有匹配的 id 和 “59°F (15°C),多云” 的结果]
助手根据您当前在加利福尼亚州旧金山的位置,现在的天气是 59°F (15°C),多云。如果您要出门,可能需要带一件轻薄的夹克。

这个例子演示了 Claude 如何将多个工具调用串联起来,以回答需要从不同来源收集数据的问题。关键步骤是:

  1. Claude 首先意识到它需要用户的位置来回答天气问题,所以它调用了 get_location 工具。
  2. 用户(即客户端代码)执行实际的 get_location 函数,并在 tool_result 块中返回结果 “San Francisco, CA”。
  3. 现在已知位置,Claude 继续调用 get_weather 工具,将 “San Francisco, CA” 作为 location 参数传入(以及一个猜测的 unit 参数,因为 unit 不是必需参数)。
  4. 用户再次使用提供的参数执行实际的 get_weather 函数,并在另一个 tool_result 块中返回天气数据。
  5. 最后,Claude 将天气数据合并到一个自然语言响应中,回答原始问题。

思维链工具使用

默认情况下,Claude 3 Opus 被提示在回答工具使用查询之前进行思考,以最好地确定是否需要工具、使用哪个工具以及适当的参数。Claude 3 Sonnet 和 Claude 3 Haiku 被提示尽可能多地使用工具,更有可能调用不必要的工具或推断缺失的参数。为了提示 Sonnet 或 Haiku 在进行工具调用之前更好地评估用户查询,可以使用以下提示:

思维链提示

使用相关工具(如果有)回答用户的请求。在调用工具之前,在 \<thinking>\</thinking> 标签内进行一些分析。首先,考虑提供的工具中哪个是回答用户请求的相关工具。其次,检查相关工具的每个必需参数,确定用户是否直接提供或给出了足够的信息来推断一个值。在决定是否可以推断参数时,仔细考虑所有上下文,看它是否支持特定值。如果所有必需参数都存在或可以合理推断,关闭思考标签并继续工具调用。但是,如果缺少必需参数的值之一,不要调用函数(即使使用缺失参数的填充),而是要求用户提供缺失的参数。如果未提供可选参数的更多信息,请不要询问。


JSON 模式

您可以使用工具让 Claude 生成遵循模式的 JSON 输出,即使您无意通过工具或函数运行该输出。

使用这种方式使用工具时:

  • 您通常希望提供一个单一工具
  • 您应该设置 tool_choice(参见强制工具使用)来指示模型明确使用该工具
  • 请记住,模型将把 input 传递给工具,因此工具的名称和描述应该从模型的角度来看。

以下使用 record_summary 工具以特定格式描述图像。

#!/bin/bash
IMAGE_URL="https://upload.wikimedia.org/wikipedia/commons/a/a7/Camponotus_flavomarginatus_ant.jpg"
IMAGE_MEDIA_TYPE="image/jpeg"
IMAGE_BASE64=$(curl "$IMAGE_URL" | base64)

curl https://api.anthropic.com/v1/messages \
     --header "content-type: application/json" \
     --header "x-api-key: $ANTHROPIC_API_KEY" \
     --header "anthropic-version: 2023-06-01" \
     --data \
'{
    "model": "claude-3-sonnet-20240229",
    "max_tokens": 1024,
    "tools": [{
        "name": "record_summary",
        "description": "使用结构良好的 JSON 记录图像摘要。",
        "input_schema": {
            "type": "object",
            "properties": {
                "key_colors": {
                    "type": "array",
                    "items": {
                        "type": "object",
                        "properties": {
"r": { "type": "number", "description": "红色值 [0.0, 1.0]" },
"g": { "type": "number", "description": "绿色值 [0.0, 1.0]" },
"b": { "type": "number", "description": "蓝色值 [0.0, 1.0]" },
"name": { "type": "string", "description": "人类可读的蛇形命名法颜色名称,例如 \"olive_green\" 或 \"turquoise\"" }
                        },
                        "required": [ "r", "g", "b", "name" ]
                    },
                    "description": "图像中的关键颜色。限制在四个以下。"
                },
                "description": {
                    "type": "string",
                    "description": "图像描述。最多一到两句话。"
                },
                "estimated_year": {
                    "type": "integer",
                    "description": "如果是照片,估计图像拍摄的年份。仅在图像看起来是非虚构的情况下设置此项。粗略估计是可以的!"
                }
            },
            "required": [ "key_colors", "description" ]
        }
    }],
    "tool_choice": {"type": "tool", "name": "record_summary"},
    "messages": [
        {"role": "user", "content": [
            {"type": "image", "source": {
                "type": "base64",
                "media_type": "'$IMAGE_MEDIA_TYPE'",
                "data": "'$IMAGE_BASE64'"
            }},
            {"type": "text", "text": "描述这张图片。"}
        ]}
    ]
}'