工具執行器會處理代理迴圈、錯誤包裝和型別安全,讓您無需自行處理。當您需要人工介入核准、自訂日誌記錄或條件式執行時,請改用手動迴圈。
工具執行器會自動執行以下操作,而不需要手動處理工具呼叫、工具結果和對話管理:
使用 SDK 輔助工具定義工具,然後使用工具執行器來執行它們。
根據 SDK 的工具簽章,工具會以字串或內容區塊(文字、圖片或文件區塊)的形式回傳結果,因此工具可以回傳多模態結果。回傳的字串會成為單一文字內容區塊。若要回傳結構化資料(例如 JSON 物件或數字),請先將其編碼為字串。
使用 @beta_tool 裝飾器搭配型別提示和 docstring 來定義工具。
import json
from anthropic import Anthropic, beta_tool
client = Anthropic()
@beta_tool
def get_weather(location: str, unit: str = "fahrenheit") -> str:
"""Get the current weather in a given location.
Args:
location: The city and state, e.g. San Francisco, CA
unit: Temperature unit, either 'celsius' or 'fahrenheit'
"""
return json.dumps({"temperature": "20°C", "condition": "Sunny"})
@beta_tool
def calculate_sum(a: int, b: int) -> str:
"""Add two numbers together.
Args:
a: First number
b: Second number
"""
return str(a + b)
runner = client.beta.messages.tool_runner(
model="claude-opus-5",
max_tokens=1024,
tools=[get_weather, calculate_sum],
messages=[
{
"role": "user",
"content": "What's the weather like in Paris? Also, what's 15 + 27?",
}
],
)
for message in runner:
print(message)@beta_tool 裝飾器會檢查函式引數和 docstring,為您推導出 JSON schema。
工具執行器是一個可迭代物件,會產生來自 Claude 的訊息。在每次迭代時,執行器會檢查 Claude 是否請求了工具使用。如果是,它會執行該工具並自動將結果傳回給 Claude,然後產生來自 Claude 的下一則訊息以繼續您的迴圈。
您可以在任何迭代中使用 break 陳述式結束迴圈。執行器會持續迴圈,直到 Claude 回傳不含工具使用的訊息,或者如果您設定了 max_iterations,則直到達到該值為止。
如果您不需要中間訊息,可以直接取得最終訊息:
使用 runner.until_done() 取得最終訊息。
client = anthropic.Anthropic()
runner = client.beta.messages.tool_runner(
model="claude-opus-5",
max_tokens=1024,
tools=[get_weather, calculate_sum],
messages=[
{
"role": "user",
"content": "What's the weather like in Paris? Also, what's 15 + 27?",
}
],
)
final_message = runner.until_done()
for block in final_message.content:
if block.type == "text":
print(block.text)在迴圈內,您可以讀取每則回應訊息,並在下一次 API 呼叫之前修改執行器的狀態。每次迭代都遵循以下生命週期:
預設情況下,執行器會為您管理對話狀態:在每個工具呼叫回合之後,它會將助理訊息和任何工具結果附加到自己的訊息歷史記錄中。當您想要重試一個回合(捨棄回應並重新發送)、注入後續訊息或自行建構工具結果時,您可以接管訊息歷史記錄。
您可以透過在迴圈主體內修改執行器的訊息來接管。確切的方法取決於 SDK。請參閱後面的各語言分頁。
當您在某次迭代中接管時,執行器不會附加該回合的助理訊息或工具結果。您需要負責保持對話的有效性:自行附加助理訊息和工具結果(如果您希望該回合計入)、有條件地修改狀態以便迴圈在沒有工具呼叫時仍能結束,並傳遞 max_iterations 來限制迴圈。所有七個 SDK 都支援 max_iterations。
使用 generate_tool_call_response() 來檢查或計算工具結果。在迴圈內呼叫 append_messages() 會告訴執行器您正在自行管理歷史記錄,因此請在您附加的內容中包含助理訊息和工具結果。
runner = client.beta.messages.tool_runner(
model="claude-opus-5",
max_tokens=1024,
max_iterations=10,
tools=[get_weather],
messages=[{"role": "user", "content": "What's the weather in San Francisco?"}],
)
for message in runner:
tool_response = runner.generate_tool_call_response()
if tool_response is not None:
# append_messages() 會將狀態標記為已修改,因此 runner 會跳過
# 本次迭代的自動附加。請自行附加 assistant 訊息與
# tool result,以及任何後續內容。
runner.append_messages(
message,
tool_response,
{"role": "user", "content": "Please be concise."},
)
# 若沒有工具呼叫,則保持狀態不變以便迴圈結束。若要在不接管訊息歷史記錄的情況下變更請求參數(例如 max_tokens),請使用 set_messages_params()。執行器仍會自動附加助理訊息和工具結果。
for message in runner:
runner.set_messages_params(lambda params: {**params, "max_tokens": 2048})對於長時間執行的代理任務,Python、TypeScript 和 Ruby 工具執行器支援自動壓縮,當 token 使用量超過閾值時會產生摘要,讓對話能夠超越上下文視窗限制繼續進行。這三個 SDK 都已棄用此客戶端選項,改用伺服器端的上下文編輯,該功能在每個 SDK 中都可用。Go、Java、C# 和 PHP 工具執行器不包含客戶端壓縮。
當工具拋出例外時,工具執行器會捕捉它,並以帶有 is_error: true 的工具結果將錯誤回傳給 Claude。工具結果帶有例外的訊息(在 Python 中為其型別和訊息),而非完整的堆疊追蹤。
SDK 記錄的內容因語言而異。每當工具引發未處理的例外時,Python SDK 會透過標準 logging 模組記錄完整的例外,包括其堆疊追蹤。Python、TypeScript 和 Java SDK 會讀取 ANTHROPIC_LOG 環境變數來開啟 SDK 的日誌記錄,其中包括請求和回應的詳細資訊:
# 以 info 層級記錄日誌
export ANTHROPIC_LOG=info
# 以 debug 層級記錄日誌以取得更詳細的輸出
export ANTHROPIC_LOG=debugGo、Ruby、C# 和 PHP SDK 不會讀取 ANTHROPIC_LOG。除了 Python 之外,沒有任何 SDK 會記錄失敗的工具:若要查看工具失敗的原因,請在工具函式內捕捉並記錄例外,然後再返回或重新拋出它。
預設情況下,工具錯誤會傳回給 Claude,然後 Claude 可以做出適當的回應。然而,您可能想要偵測錯誤並以不同方式處理它們,例如提早停止執行或實作自訂錯誤處理。
在 Python 和 TypeScript SDK 中,使用工具回應方法(Python 中的 generate_tool_call_response(),TypeScript 中的 generateToolResponse())來攔截工具結果,並在它們被發送給 Claude 之前檢查錯誤。其他 SDK 不提供該掛鉤。它們的分頁描述了最接近的替代方案:
client = anthropic.Anthropic()
runner = client.beta.messages.tool_runner(
model="claude-opus-5",
max_tokens=1024,
tools=[my_tool],
messages=[{"role": "user", "content": "Run my_tool with the query 'hello'."}],
)
for message in runner:
tool_response = runner.generate_tool_call_response()
if tool_response is not None:
# tool_response 是一個 dict:{"role": "user", "content": [...]}
# 檢查是否有任何工具結果發生錯誤
for block in tool_response["content"]:
if block.get("is_error"):
# 選項 1:拋出例外以停止迴圈
raise RuntimeError(f"Tool failed: {json.dumps(block['content'])}")
# 選項 2:記錄後繼續(讓 Claude 處理)
# logger.error(f"Tool error: {json.dumps(block['content'])}")
# 正常處理訊息
print(message.content)您可以在工具結果傳回給 Claude 之前修改它們。這對於新增中繼資料(例如 cache_control 以在工具結果上啟用提示快取)或轉換工具輸出很有用。
在 Python 和 TypeScript SDK 中,使用工具回應方法取得工具結果,然後在執行器繼續之前修改它。是要明確附加修改後的結果還是就地變更它,取決於 SDK。請參閱每個分頁中的程式碼註解。
client = anthropic.Anthropic()
runner = client.beta.messages.tool_runner(
model="claude-opus-5",
max_tokens=1024,
tools=[search_documents],
messages=[
{
"role": "user",
"content": "Search for information about the climate of San Francisco",
}
],
)
for message in runner:
tool_response = runner.generate_tool_call_response()
if tool_response is not None:
# tool_response 是一個 dict:{"role": "user", "content": [...]}
# 修改工具結果以加入快取控制
for block in tool_response["content"]:
if block["type"] == "tool_result":
# 加入 cache_control 以快取此工具結果
block["cache_control"] = {"type": "ephemeral"}
# 附加修改後的回應(這可防止自動附加原始回應)
runner.append_messages(message, tool_response)
print(message.content)啟用串流以逐步處理每個回合的回應。每次迭代都會產生一個串流物件,您可以迭代其事件。
設定 stream=True 並使用 get_final_message() 取得累積的訊息。
client = anthropic.Anthropic()
runner = client.beta.messages.tool_runner(
model="claude-opus-5",
max_tokens=1024,
tools=[calculate_sum],
messages=[{"role": "user", "content": "What is 15 + 27?"}],
stream=True,
)
# 使用串流時,runner 會回傳 BetaMessageStream
for message_stream in runner:
for event in message_stream:
print("event:", event)
print("message:", message_stream.get_final_message())
print(runner.until_done())使用文法約束取樣在 Claude 的工具輸入上強制執行 JSON Schema 合規性。
解析 tool_use 區塊、格式化 tool_result 回應,並使用 is_error 處理錯誤。
啟用、格式化和停用平行工具呼叫,並提供訊息歷史記錄指引和疑難排解。
指定工具 schema、撰寫有效的描述,並控制 Claude 何時呼叫您的工具。
Was this page helpful?