本文根據 Claude API 官方文檔的 Tool use 系列頁面整理,核對日期 2026-10-07。示例代碼基於官方 get_weather 示例改寫。
適用於誰
- 想讓 Claude 查數據庫、調用內部接口、發電郵,也就是「讓模型調用我的函數」的開發者;
- 搜「claude tool use」「claude function calling example」的人;
- 遇到報錯「tool_use ids were found without tool_result blocks immediately after」的人。
基礎調用方式詳見本站《Claude API Python 入門:安裝 SDK、第一個請求、流式輸出與多輪對話》。
結論先說
- 模型自己從不執行任何東西:它只會返回一個結構化的「我要調用某某工具、參數是這些」的請求(
tool_use塊),由你的代碼去執行,再把結果用tool_result塊發回去。 - 工具定義三要素:
name(名稱)、description(說明)、input_schema(JSON Schema 格式的參數)。官方說描述寫得詳細是影響效果的最重要因素,每個工具建議至少寫 3~4 句。 - 標準循環:只要響應的
stop_reason是"tool_use",就執行工具、把結果發回、繼續請求;變成"end_turn"等其他值時結束。 tool_result必須緊跟在對應的tool_use之後,並且在用戶消息裏排在最前面;每個tool_use都要有一個對應的tool_result。違反這兩條就會出現上面那個報錯。- 不想自己寫循環,可以用 SDK 的 tool runner(beta);網頁搜尋、代碼執行等伺服器工具由 Anthropic 執行,你不用寫
tool_result。
一、三類工具
| 類型 | 誰定義 schema | 誰執行 | 例子 |
|---|---|---|---|
| 自定義工具 | 你 | 你的代碼 | 查訂單、調內部 API |
| Anthropic 定義 schema 的客戶端工具 | Anthropic | 你的代碼 | memory、bash、text_editor、computer use、browser use |
| 伺服器工具 | Anthropic | Anthropic | web_search、web_fetch、code_execution、tool_search |
第二類的好處是:模型針對這些固定的工具簽名專門訓練過,調用更可靠。
二、定義一個工具
json
{
"name": "get_weather",
"description": "查詢指定城市當前的天氣。當用戶詢問某地現在的天氣、氣溫時使用。只返回當前天氣,不提供預報。",
"input_schema": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "城市名,例如:上海"},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"], "description": "溫度單位"}
},
"required": ["location"]
}
}
name只能用字母、數字、下劃線和短橫線,最長 128 個字符;- 官方的寫法建議:說清楚工具做什麼、什麼時候用(以及什麼時候不用)、每個參數的含義、有什麼限制;相關操作合併成少量工具(用一個
action參數區分),而不是一個動作一個工具;跨多個服務時給工具名加前綴(如github_list_prs);工具返回只給 Claude 需要的高價值資訊; - 想保證參數一定符合 schema,可以在工具定義裏加
strict: true(嚴格工具調用)。
三、完整的調用循環(Python)
python
import json
import anthropic
client = anthropic.Anthropic()
tools = [{
"name": "get_weather",
"description": "查詢指定城市當前的天氣。當用戶詢問某地現在的天氣、氣溫時使用。",
"input_schema": {
"type": "object",
"properties": {"location": {"type": "string", "description": "城市名"}},
"required": ["location"],
},
}]
def get_weather(location: str) -> str:
# 這裏換成你真實的天氣接口
return json.dumps({"location": location, "temperature": "22°C", "condition": "多雲"}, ensure_ascii=False)
messages = [{"role": "user", "content": "杭州現在天氣怎麼樣?"}]
while True:
response = client.messages.create(
model="claude-opus-5-5",
max_tokens=1024,
tools=tools,
messages=messages,
)
# 1. 把助手這一輪的完整回覆(含 tool_use 塊)加入歷史
messages.append({"role": "assistant", "content": response.content})
if response.stop_reason != "tool_use":
break # end_turn / max_tokens 等:結束循環
# 2. 執行每一個 tool_use,收集 tool_result
results = []
for block in response.content:
if block.type == "tool_use":
try:
output = get_weather(**block.input)
results.append({"type": "tool_result", "tool_use_id": block.id, "content": output})
except Exception as e:
results.append({"type": "tool_result", "tool_use_id": block.id,
"content": f"查詢失敗:{e},請換個說法或稍後再試", "is_error": True})
# 3. 把所有結果放在同一條 user 消息裏發回去
messages.append({"role": "user", "content": results})
print("".join(b.text for b in response.content if b.type == "text"))
循環的關鍵點(官方要求):
tool_use塊裏有三樣東西:id(用來對應結果)、name、input(符合你 schema 的參數);tool_result裏填tool_use_id、content(字符串,或文本 / 圖片 / 文檔內容塊列表),出錯時加"is_error": true;- Claude 一次可能並行調用多個工具:要把多個
tool_result放在同一條 user 消息裏發回,而不是一條結果一輪; - 同一條 user 消息裏如果還想附加文字,文字必須放在所有
tool_result之後。
四、出錯了怎麼告訴 Claude
工具執行失敗時,把錯誤訊息放進 content 並設 is_error: true,Claude 會據此給用戶解釋或換個方式重試。官方建議錯誤訊息寫得有指導性:不要只寫「失敗」,而是寫清楚出了什麼問題、下一步該怎麼做(例如「超出頻率限制,60 秒後重試」)。
參數缺失之類的無效調用,也可以用帶 is_error 的結果告訴它缺了什麼,官方說明 Claude 通常會修正後再試 2~3 次。
五、讓 SDK 幫你跑循環:tool runner
Python SDK 提供了 tool runner(beta),用裝飾器從函數簽名和文檔字符串自動生成 schema,並自動處理調用循環:
python
import json
from anthropic import Anthropic, beta_tool
client = Anthropic()
@beta_tool
def get_weather(location: str, unit: str = "celsius") -> str:
"""查詢指定城市當前的天氣。
Args:
location: 城市名,例如 上海
unit: 溫度單位,celsius 或 fahrenheit
"""
return json.dumps({"temperature": "20°C", "condition": "晴"}, ensure_ascii=False)
runner = client.beta.messages.tool_runner(
model="claude-opus-5-5",
max_tokens=1024,
tools=[get_weather],
messages=[{"role": "user", "content": "巴黎現在天氣如何?"}],
)
for message in runner:
print(message)
需要人工審批、自定義日誌或按條件執行時,官方建議還是用第三節的手寫循環。
六、伺服器工具:不用寫 tool_result
以網頁搜尋為例,只要在 tools 裏聲明,Anthropic 會在伺服器上執行搜尋並把結果融進回答:
python
response = client.messages.create(
model="claude-opus-5-5",
max_tokens=1024,
tools=[{"type": "web_search_20260209", "name": "web_search"}],
messages=[{"role": "user", "content": "火星車最近有什麼新進展?"}],
)
響應裏會出現 server_tool_use 塊記錄它做了什麼。伺服器工具有內部循環次數上限,達到上限時 stop_reason 會是 "pause_turn",把對話(含這次的響應)原樣再發一次即可讓它繼續。伺服器工具除了 token 費用,還可能按使用次數另外計費(如網頁搜尋按搜尋次數),見官方定價。
七、控制 Claude 用不用工具
- 預設
tool_choice是{"type": "auto"}:Claude 自己判斷。想讓它更積極地用工具,可以在系統提示裏寫「回答前先用工具調查」;想更剋制,寫「自行判斷是否需要調用工具」; {"type": "none"}:本次不用工具;{"type": "any"}或{"type": "tool", "name": "..."}:強制調用工具。注意官方說明在 Opus 5.5、Sonnet 5.5、Fable 5.1 等新模型上強制調用會返回 400 錯誤,開啟手動擴展思考時也不支持;這些情況下改用auto加嚴格工具調用,或用結構化輸出。
用戶沒給全必填參數時,官方提到 Opus 更傾向於反問,Sonnet 有時會自己推測一個值——對關鍵參數,最好在描述裏寫明「缺少時先問用戶」。
常見問題
Q:報錯「tool_use ids were found without tool_result blocks immediately after」?
官方給出的原因有兩個:有的 tool_use id 沒有對應的 tool_result(並行調用了多個工具,你只回了一個);或者 tool_result 不是 user 消息裏的第一個內容塊(前面放了文字)。解決:給助手回覆裏的每一個 tool_use 都返回一個 tool_result,並把它們都放在文字之前;兩條消息之間也不能插入其他消息。
Q:工具調用會多花錢嗎?
會。tools 參數裏的名稱、描述、schema,以及 tool_use、tool_result 塊都算輸入 token;使用工具時 API 還會自動加一段工具調用專用的系統提示(官方頁面列有各模型的 token 數)。
Q:Claude 選錯工具或亂編參數?
官方排查建議:把工具描述寫得更具體(何時用、何時不用);參數格式複雜的可以加 input_examples 示例;需要保證格式時用 strict: true。
Q:工具返回的內容安全嗎?
工具結果往往來自網頁、電郵、用戶上載等你控制不了的來源,可能藏有「提示詞注入」。官方建議把這類不可信內容放在 tool_result 裏,而不是放進 system 提示或普通用戶文本。
Q:想做能自己讀文件、跑命令的智能體?
可以直接用 Claude Agent SDK,它內置了這些工具和循環,詳見本站《Claude Agent SDK 入門:是什麼、怎麼裝、第一個智能體(Python / TypeScript)》。要接入現成的外部工具,也可以看 MCP,詳見本站《MCP 是什麼:Model Context Protocol 入門,以及在 Claude 裏怎麼用》。
參考資料
- Tool use with Claude(官方):https://platform.claude.com/docs/en/agents-and-tools/tool-use/overview
- How tool use works(官方):https://platform.claude.com/docs/en/agents-and-tools/tool-use/how-tool-use-works
- Define tools(官方):https://platform.claude.com/docs/en/agents-and-tools/tool-use/define-tools
- Handle tool calls(官方):https://platform.claude.com/docs/en/agents-and-tools/tool-use/handle-tool-calls
- Tool runner (SDK)(官方):https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-runner
- Troubleshooting tool use(官方):https://platform.claude.com/docs/en/agents-and-tools/tool-use/troubleshooting-tool-use
0 條評論
還沒有評論,來搶沙發~