GuidesAgents
用 Claude API Tool Use 调用外部工具
在 Messages API 里声明客户工具,处理 tool_use,再回传 tool_result,跑通 Claude 的外部工具闭环。
基于 Anthropic Docs 整理 · 官方资料 ↗
Claude 的 tool use 让模型在对话中调用你定义的函数,或使用 Anthropic 托管的 server tools。客户工具在你的应用里执行;server tools(如 web_search)在 Anthropic 侧执行,你直接在同一响应里看到结果。
这篇聚焦客户工具闭环:声明带 input_schema 的工具 → 读取 tool_use → 本地执行 → 用 tool_result 回传 → 再请求一次拿到最终文本。示例沿用官方 get_weather。
先把这一轮 round trip 跑稳,再扩展并行工具、server tools 或更复杂的编排。
客户工具和 server tools 差在哪
客户工具(含你自定义的工具,以及 bash、text_editor 这类由你执行的工具)会让 Claude 以 stop_reason: "tool_use" 结束,并返回一个或多个 tool_use 块。你负责执行,再发 tool_result。
Server tools(如 web_search、web_fetch、code_execution)在 Anthropic 基础设施上执行。你通常在同一次响应里看到结果,不必自己跑检索。例外是它与客户工具出现在同一批并行调用里时,仍要按 stop reason 处理。
最小学习路径先走客户工具:协议完整,也最接近你把内部 API 接到 Claude 的真实做法。
声明一个带 input_schema 的工具
每个客户工具需要 name、description 和 input_schema(JSON Schema)。description 决定 Claude 何时调用;schema 决定它能填哪些参数。
安装 Anthropic Python SDK
pip install -U anthropic
export ANTHROPIC_API_KEY=...官方 get_weather 工具定义
import json
import anthropic
client = anthropic.Anthropic()
tools = [
{
"name": "get_weather",
"description": "Get the current weather for a given location.",
"input_schema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City and state, e.g. San Francisco, CA",
}
},
"required": ["location"],
},
}
]第一次请求:拿到 tool_use
调用 messages.create,传入 tools 与用户问题。官方示例用 tool_choice 限制为每轮最多一个工具调用,便于把闭环看清楚。
官方:触发 get_weather
messages = [{"role": "user", "content": "What's the weather in San Francisco?"}]
response = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
tools=tools,
tool_choice={"type": "auto", "disable_parallel_tool_use": True},
messages=messages,
)
tool_use = next(block for block in response.content if block.type == "tool_use")
print(f"Claude called {tool_use.name} with {json.dumps(tool_use.input)}")
print(response.stop_reason)官方文档示例模型为 claude-opus-5。若不可用,换成当前支持 tool use 的 Claude 模型。成功时你应看到 name 为 get_weather,input 含 location。
执行工具并回传 tool_result
把助手 content(含 tool_use)追加为 assistant 消息。再发一条 user 消息,content 里放 type: "tool_result",tool_use_id 对齐刚才的 id,content 为工具输出字符串。
官方:回传 tool_result 并取最终文本
weather = "15 degrees Celsius, partly cloudy" # 换成你的真实查询结果
messages += [
{"role": "assistant", "content": response.content},
{
"role": "user",
"content": [
{"type": "tool_result", "tool_use_id": tool_use.id, "content": weather}
],
},
]
followup = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
tools=tools,
tool_choice={"type": "auto", "disable_parallel_tool_use": True},
messages=messages,
)
final_text = next(block for block in followup.content if block.type == "text")
print(final_text.text)示例里的 weather 字符串只是占位。接到真实系统时,在这里调用你的 API,并把原始结果或摘要放进 tool_result。
对照:server tool 长什么样
若只需 Anthropic 托管的联网搜索,可声明 server tool,不必自己执行。官方最小示例如下:
官方 web_search server tool 示例
response = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
tools=[{"type": "web_search_20260209", "name": "web_search"}],
messages=[{"role": "user", "content": "What's the latest on the Mars rover?"}],
)
print(response.content)客户工具与 server tools 可以组合,但排障时先单独验证一种,避免并行调用把 stop reason 搅在一起。
闭环验收清单
- 第一次响应出现 type=tool_use 的块
- stop_reason 为 tool_use(客户工具路径)
- tool_result.tool_use_id 与 tool_use.id 一致
- 第二次响应出现 text,并基于工具结果作答
生产代码还应处理多个 tool_use、工具失败(向 Claude 返回错误信息让它改策略),以及权限与超时。先把单工具同步闭环做对,再加这些分支。
最容易踩的坑
找不到 tool_use 块
打印 response.content 与 stop_reason;确认 tools 已传入,问题确实需要该工具;检查模型是否支持 tool use。
第二次请求报 tool_use_id 相关错误
必须先 append 完整的 assistant content;tool_result.tool_use_id 必须等于对应 tool_use.id。
工具执行失败后模型行为怪异
仍返回 tool_result,在 content 里说明错误,让 Claude 决定重试或换策略;不要静默吞掉失败。
模型名不可用
官方示例使用 claude-opus-5。换成账号可用且支持 tool use 的 Claude 模型。
官方资料
Anthropic Docs
Tool use with Claude ↗