Claude Tool Use (工具调用)
Tool Use 让 Claude 能够调用你定义的工具/函数,是构建 AI Agent 的核心能力。
把它当成“让 AI 学会按流程调用企业内工具”的能力。
模型负责理解意图和填参数,业务系统仍由你掌控执行与权限。
什么是 Tool Use?
Tool Use 让 Claude 能够:
- 理解用户意图
- 决定使用哪个工具
- 提取工具参数
- 等待工具结果并生成回复
用户: "北京今天天气怎么样?"
↓
Claude: 需要使用 get_weather 工具,参数 city="北京"
↓
你的代码: 调用天气 API,返回结果
↓
Claude: "北京今天晴朗,气温 25°C,适合户外活动。"
读者导向:建议实践顺序
- 先做单工具闭环(请求 -> tool_use -> tool_result -> 最终回复)。
- 再做多工具路由和并行调用。
- 最后补权限、审计、失败重试与幂等策略。
基础用法
定义工具
tools = [
{
"name": "get_weather",
"description": "获取指定城市的当前天气信息",
"input_schema": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,如:北京、上海、深圳"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "温度单位,默认摄氏度"
}
},
"required": ["city"]
}
}
]
调用 API
import anthropic
import json
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
tools=tools,
messages=[
{"role": "user", "content": "北京天气怎么样?"}
]
)
# 检查响应类型
for block in response.content:
if block.type == "tool_use":
print(f"工具: {block.name}")
print(f"参数: {block.input}")
print(f"ID: {block.id}")
执行工具并返回结果
def get_weather(city: str, unit: str = "celsius") -> str:
"""模拟天气 API"""
return f"{city}今天晴,气温 25°C"
# 1. 第一次调用 - 获取工具调用请求
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
tools=tools,
messages=[{"role": "user", "content": "北京天气怎么样?"}]
)
# 2. 检查并执行工具
messages = [{"role": "user", "content": "北京天气怎么样?"}]
messages.append({"role": "assistant", "content": response.content})
for block in response.content:
if block.type == "tool_use":
# 执行工具
result = get_weather(**block.input)
# 添加工具结果
messages.append({
"role": "user",
"content": [{
"type": "tool_result",
"tool_use_id": block.id,
"content": result
}]
})
# 3. 获取最终回复
final_response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
tools=tools,
messages=messages
)
print(final_response.content[0].text)
多工具定义
tools = [
{
"name": "get_weather",
"description": "获取城市天气",
"input_schema": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "城市名"}
},
"required": ["city"]
}
},
{
"name": "search_web",
"description": "搜索网络信息",
"input_schema": {
"type": "object",
"properties": {
"query": {"type": "string", "description": "搜索关键词"}
},
"required": ["query"]
}
},
{
"name": "send_email",
"description": "发送邮件",
"input_schema": {
"type": "object",
"properties": {
"to": {"type": "string", "description": "收件人邮箱"},
"subject": {"type": "string", "description": "邮件主题"},
"body": {"type": "string", "description": "邮件内容"}
},
"required": ["to", "subject", "body"]
}
}
]
控制工具使用
tool_choice 参数
# 自动决定(默认)
tool_choice = {"type": "auto"}
# 强制使用特定工具
tool_choice = {"type": "tool", "name": "get_weather"}
# 强制使用任意一个工具
tool_choice = {"type": "any"}
# 禁止使用工具
tool_choice = {"type": "none"} # 或不传 tools 参数
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
tools=tools,
tool_choice=tool_choice,
messages=[...]
)
常见误区
- 把工具 schema 写得过于宽松,导致参数不稳定
- 工具执行失败只返回“失败”,不返回结构化错误信息
- 忽略权限边界,让模型可触达不该调用的高风险接口
一句轻松提醒:
Tool Use 像给 AI 发工作证,权限开太大,出事概率会同步放大。
并行工具调用
Claude 可以同时请求多个工具:
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
tools=tools,
messages=[
{"role": "user", "content": "北京和上海的天气分别怎么样?"}
]
)
# 可能返回多个 tool_use blocks
tool_calls = [block for block in response.content if block.type == "tool_use"]
print(f"需要调用 {len(tool_calls)} 个工具")
for tc in tool_calls:
print(f"- {tc.name}: {tc.input}")
处理并行调用
def process_tool_calls(response, available_functions):
"""处理所有工具调用"""
tool_results = []
for block in response.content:
if block.type == "tool_use":
func = available_functions.get(block.name)
if func:
result = func(**block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": str(result)
})
return tool_results
# 使用
available_functions = {
"get_weather": get_weather,
"search_web": search_web,
"send_email": send_email
}
tool_results = process_tool_calls(response, available_functions)
完整示例:AI 助手
import anthropic
import json
client = anthropic.Anthropic()
# 工具定义
tools = [
{
"name": "get_weather",
"description": "获取城市天气信息",
"input_schema": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "城市名"}
},
"required": ["city"]
}
},
{
"name": "calculate",
"description": "数学计算",
"input_schema": {
"type": "object",
"properties": {
"expression": {"type": "string", "description": "数学表达式"}
},
"required": ["expression"]
}
}
]
# 工具实现
def get_weather(city: str) -> str:
weather_data = {
"北京": "晴,25°C",
"上海": "多云,28°C",
}
return weather_data.get(city, f"{city}天气数据暂不可用")
def calculate(expression: str) -> str:
try:
return str(eval(expression))
except:
return "计算错误"
available_functions = {
"get_weather": get_weather,
"calculate": calculate
}
def chat(user_message: str):
messages = [{"role": "user", "content": user_message}]
while True:
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
tools=tools,
messages=messages
)
# 检查是否有工具调用
tool_uses = [b for b in response.content if b.type == "tool_use"]
if not tool_uses:
# 没有工具调用,返回文本响应
text_blocks = [b for b in response.content if b.type == "text"]
return text_blocks[0].text if text_blocks else ""
# 处理工具调用
messages.append({"role": "assistant", "content": response.content})
tool_results = []
for tool_use in tool_uses:
func = available_functions.get(tool_use.name)
if func:
result = func(**tool_use.input)
print(f"[调用] {tool_use.name}({tool_use.input}) -> {result}")
tool_results.append({
"type": "tool_result",
"tool_use_id": tool_use.id,
"content": result
})
messages.append({"role": "user", "content": tool_results})
# 测试
print(chat("北京天气怎么样?"))
print(chat("123 * 456 等于多少?"))
print(chat("北京天气如何?另外帮我算一下 15 的平方"))
工具结果格式
成功结果
{
"type": "tool_result",
"tool_use_id": "toolu_xxx",
"content": "北京今天晴,25°C"
}
错误结果
{
"type": "tool_result",
"tool_use_id": "toolu_xxx",
"content": "错误:无法获取天气数据",
"is_error": True
}
图片结果
{
"type": "tool_result",
"tool_use_id": "toolu_xxx",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/png",
"data": "base64_encoded_data"
}
},
{
"type": "text",
"text": "生成的图表"
}
]
}
最佳实践
1. 清晰的工具描述
# ❌ 不够清晰
"description": "获取数据"
# ✅ 清晰明确
"description": "获取指定城市的实时天气信息,包括温度、湿度和天气状况。支持中国主要城市。"
2. 详细的参数说明
"properties": {
"date": {
"type": "string",
"description": "查询日期,格式为 YYYY-MM-DD,如 2024-01-15。不填则查询今天。"
}
}
3. 使用枚举限制选项
"status": {
"type": "string",
"enum": ["pending", "approved", "rejected"],
"description": "订单状态"
}
4. 错误处理
def safe_tool_call(func, **kwargs):
try:
return func(**kwargs)
except Exception as e:
return f"工具执行错误: {str(e)}"
与 OpenAI Function Calling 的区别
| 特性 | Claude Tool Use | OpenAI Function Calling |
|---|---|---|
| 参数名 | input_schema | parameters |
| 工具类型 | 直接定义 | type: "function" 包装 |
| 结果格式 | tool_result | function role |
| 控制参数 | tool_choice | tool_choice |
下一步
- Vision - 图像理解
- Prompt Caching - 缓存优化
- Batch API - 批量处理
提示:Tool Use 是构建 AI Agent 的基础,结合多个工具可以实现复杂的自动化任务。