Claude API
Tool Use(函数调用)
让 Claude 调用外部函数 — 工具定义、调用流程、并行工具与最佳实践
概述
Tool Use 允许 Claude 请求和使用外部函数,是构建与数据库、API 等外部系统交互的 Agent 的关键能力。
定义工具
每个工具需要 name、description 和 input_schema(JSON Schema):
tools = [
{
"name": "get_weather",
"description": "获取指定位置的当前天气",
"input_schema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "城市名称,如 北京、上海"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "温度单位(默认: celsius)"
}
},
"required": ["location"]
}
},
{
"name": "calculate",
"description": "执行数学计算",
"input_schema": {
"type": "object",
"properties": {
"operation": {
"type": "string",
"enum": ["add", "subtract", "multiply", "divide"]
},
"a": {"type": "number"},
"b": {"type": "number"}
},
"required": ["operation", "a", "b"]
}
}
]完整调用流程
Tool Use 是一个 4 步流程:
import anthropic
import json
client = anthropic.Anthropic()
tools = [
{
"name": "get_weather",
"description": "获取当前天气",
"input_schema": {
"type": "object",
"properties": {
"location": {"type": "string"}
},
"required": ["location"]
}
}
]
# 第 1 步:发送带工具的消息
response = client.messages.create(
model="claude-opus-4-6",
max_tokens=1024,
tools=tools,
messages=[
{"role": "user", "content": "巴黎现在天气怎么样?"}
]
)
# 第 2 步:检查 Claude 是否要调用工具
for block in response.content:
if block.type == "tool_use":
tool_name = block.name
tool_input = block.input
tool_use_id = block.id
# 第 3 步:执行工具(这里模拟)
tool_result = f"{tool_input['location']}天气:22°C,晴"
# 第 4 步:将工具结果返回给 Claude
response = client.messages.create(
model="claude-opus-4-6",
max_tokens=1024,
tools=tools,
messages=[
{"role": "user", "content": "巴黎现在天气怎么样?"},
{"role": "assistant", "content": response.content},
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": tool_use_id,
"content": tool_result
}
]
}
]
)
print(response.content[0].text)自动工具循环
处理多步工具调用的完整循环:
import anthropic
import json
client = anthropic.Anthropic()
def execute_tool(name: str, input: dict):
"""根据工具名执行对应函数"""
if name == "get_weather":
return {"temperature": 22, "condition": "晴"}
elif name == "calculate":
ops = {"add": lambda a, b: a + b, "subtract": lambda a, b: a - b,
"multiply": lambda a, b: a * b, "divide": lambda a, b: a / b}
return ops[input["operation"]](input["a"], input["b"])
return f"未知工具: {name}"
messages = [
{"role": "user", "content": "旧金山天气怎样?另外算一下 5 + 3"}
]
response = client.messages.create(
model="claude-opus-4-6", max_tokens=1024,
tools=tools, messages=messages
)
# 循环处理,直到 Claude 不再调用工具
while response.stop_reason == "tool_use":
tool_results = []
for block in response.content:
if block.type == "tool_use":
result = execute_tool(block.name, block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": json.dumps(result)
})
messages.append({"role": "assistant", "content": response.content})
messages.append({"role": "user", "content": tool_results})
response = client.messages.create(
model="claude-opus-4-6", max_tokens=1024,
tools=tools, messages=messages
)
# 输出最终回复
for block in response.content:
if hasattr(block, 'text'):
print(block.text)并行工具调用
Claude 可以在单次响应中同时调用多个工具:
response = client.messages.create(
model="claude-opus-4-6",
max_tokens=1024,
tools=tools,
messages=[
{"role": "user", "content": "查一下巴黎和纽约的天气,以及那里现在几点?"}
]
)
# Claude 可能在一次响应中调用多个工具
tool_calls = [b for b in response.content if b.type == "tool_use"]
print(f"Claude 并行调用了 {len(tool_calls)} 个工具")
for tc in tool_calls:
print(f" - {tc.name}: {tc.input}")tool_choice 控制
通过 tool_choice 参数控制 Claude 的工具使用行为:
| 值 | 行为 |
|---|---|
"auto" | Claude 自行决定(默认) |
"any" | 强制使用某个工具 |
{"type": "tool", "name": "xxx"} | 强制使用指定工具 |
"none" | 禁止使用工具 |
最佳实践
- 详细描述:清楚说明工具的功能、适用场景和限制
- 清晰的 Schema:使用描述性属性名,包含默认值
- 错误处理:工具失败时返回有意义的错误信息
- Streaming 保持:使用流式输出时,将 thinking blocks 原样传回
- Strict 模式:关键工作流使用
"strict": true保证输入合规