程式化工具呼叫
讓 Claude 在程式碼執行容器中透過程式碼呼叫您的工具,減少多工具工作流程中的模型往返次數與 token 使用量。
「Programmatic tool calling」(程式化工具呼叫)讓 Claude 能夠撰寫程式碼,在程式碼執行容器中以程式化方式呼叫您的工具,而不需要每次工具呼叫都經過模型往返。這能降低多工具工作流程的「latency」(延遲),並讓 Claude 在資料進入模型的「context window」(上下文視窗)之前先行篩選或處理,從而減少 token 消耗。在 BrowseComp 和 DeepSearchQA 等測試多步驟網路研究與複雜資訊檢索的代理式搜尋基準測試中,在基本搜尋工具之上加入程式化工具呼叫,平均提升了 11% 的效能,同時減少了 24% 的輸入 token(請參閱透過動態篩選改善網路搜尋)。
以檢查 20 位員工的預算合規情況為例:傳統做法需要 20 次獨立的模型往返,過程中會將數千筆費用明細拉進上下文。使用程式化工具呼叫時,單一腳本即可執行全部 20 次查詢、篩選結果,並只回傳超出額度的員工,將 Claude 需要推理的內容從數百 KB 縮減到寥寥數行。
程式化工具呼叫需要使用工具版本為 code_execution_20260120 或更新版本的程式碼執行工具。若要在傳送請求前確認模型是否支援程式化工具呼叫,請從 Models API 讀取其 capabilities.code_execution.supported 值。使用 Models API 說明了此欄位。
快速開始
以下範例中,Claude 以程式化方式多次查詢資料庫並彙總結果。在工具定義中加入 allowed_callers: ["code_execution_20260120"],即可讓該工具能夠從程式碼執行中被呼叫(請參閱 allowed_callers 欄位):
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-5-5",
max_tokens=4096,
messages=[
{
"role": "user",
"content": "Query sales data for the West, East, and Central regions, then tell me which region had the highest revenue",
}
],
tools=[
{"type": "code_execution_20260120", "name": "code_execution"},
{
"name": "query_database",
"description": "Execute a SQL query against the sales database. Returns a list of rows as JSON objects.",
"input_schema": {
"type": "object",
"properties": {
"sql": {"type": "string", "description": "SQL query to execute"}
},
"required": ["sql"],
},
"allowed_callers": ["code_execution_20260120"],
},
],
)
print(response)回應會以 stop_reason: "tool_use" 停止,並帶有一個 container ID,以及一個 query_database 的 tool_use 區塊,其 caller 欄位標示了呼叫它的程式碼執行作業。請依照範例工作流程的步驟 3 所示回傳結果,讓程式碼得以完成執行。
程式化工具呼叫的運作方式
當您將某個工具設定為可從程式碼執行中呼叫,且 Claude 判斷需要該工具時:
- Claude 撰寫 Python 程式碼,將該工具當作函式呼叫,其中可能包含多次工具呼叫以及前置/後置處理邏輯
- Claude 透過程式碼執行在沙箱容器中執行這段程式碼
- 當工具函式被呼叫時,程式碼執行會暫停,API 回傳一個
tool_use區塊 - 您提供工具結果,程式碼執行繼續進行(中間結果不會載入 Claude 的上下文視窗)
- 所有程式碼執行完成後,Claude 收到最終輸出並繼續處理任務
這種做法特別適用於:
- 大量資料處理:在工具結果進入 Claude 的上下文之前先行篩選或彙總
- 多步驟工作流程:以序列或迴圈方式呼叫工具,而不需在工具呼叫之間對 Claude 進行取樣,從而節省 token 與延遲
- 條件邏輯:根據中間工具結果做出決策
核心概念
allowed_callers 欄位
allowed_callers 欄位指定哪些情境可以呼叫某個工具:
{
"name": "query_database",
"description": "Execute a SQL query against the database",
"input_schema": {
// ...
},
"allowed_callers": ["code_execution_20260120"]
}可能的值:
["direct"]- 引導 Claude 直接呼叫此工具(省略時的預設值)["code_execution_20260120"]- 引導 Claude 僅從程式碼執行中呼叫此工具["direct", "code_execution_20260120"]- Claude 可以直接呼叫此工具,也可以從程式碼執行中呼叫
"code_execution_20260120" 與 "code_execution_20260521" 在 allowed_callers 中皆可接受且可互換:使用任一程式碼執行工具版本的請求,都能滿足列出任一呼叫者的工具。無論請求宣告的是哪個版本,回應區塊一律將呼叫者標記為 code_execution_20260120。
回應中的 caller 欄位
每個工具使用區塊都包含一個 caller 欄位,標示其被呼叫的方式:
直接呼叫(傳統工具使用):
{
"type": "tool_use",
"id": "toolu_abc123",
"name": "query_database",
"input": { "sql": "<sql>" },
"caller": { "type": "direct" }
}程式化呼叫:
{
"type": "tool_use",
"id": "toolu_xyz789",
"name": "query_database",
"input": { "sql": "<sql>" },
"caller": {
"type": "code_execution_20260120",
"tool_id": "srvtoolu_abc123"
}
}tool_id 是發出該呼叫的程式碼執行 server_tool_use 區塊的 id,因此您可以將每個程式化 tool_use 對應到產生它的程式碼執行作業。
容器生命週期
程式化工具呼叫使用與程式碼執行相同的容器:
- 容器建立:除非您重複使用現有容器,否則每個請求都會建立一個新容器
- 容器 ID:在回應的
container欄位中回傳,並附帶expires_at時間戳記 - 重複使用:在下一個請求中傳回容器 ID 以保留狀態。當程式化工具呼叫正在等待您的結果時,該請求必須提供容器 ID,而非選填:若未提供,API 會拒絕該請求。
- 到期:
expires_at告訴您容器還剩多少時間。閒置容器目前約在 5 分鐘後被回收,且任何容器在建立超過 30 天後都無法再重複使用。
範例工作流程
以下是完整程式化工具呼叫流程的運作方式:
步驟 1:初始請求
傳送一個包含程式碼執行以及允許程式化呼叫之工具的請求。若要啟用程式化呼叫,請在工具定義中加入 allowed_callers 欄位。
請求的形式與快速開始範例相同:在工具清單中加入 code_execution,為任何您希望 Claude 從程式碼中呼叫的工具加上 allowed_callers: ["code_execution_20260120"],然後傳送您的使用者訊息。本工作流程的其餘步驟使用的使用者訊息為 "Query customer purchase history from the last quarter and identify our top 5 customers by revenue"。
步驟 2:帶有工具呼叫的 API 回應
Claude 撰寫呼叫您工具的程式碼。API 暫停並回傳:
{
"role": "assistant",
"content": [
{
"type": "text",
"text": "I'll query the purchase history and analyze the results."
},
{
"type": "server_tool_use",
"id": "srvtoolu_abc123",
"name": "code_execution",
"input": {
"code": "import json\n\nrows = json.loads(await query_database({'sql': '<sql>'}))\ntop_customers = sorted(rows, key=lambda x: x['revenue'], reverse=True)[:5]\nprint(f'Top 5 customers: {top_customers}')"
}
},
{
"type": "tool_use",
"id": "toolu_def456",
"name": "query_database",
"input": { "sql": "<sql>" },
"caller": {
"type": "code_execution_20260120",
"tool_id": "srvtoolu_abc123"
}
}
],
"container": {
"id": "container_xyz789",
"expires_at": "2026-01-20T14:30:00Z"
},
"stop_reason": "tool_use"
}步驟 3:提供工具結果
傳送完整的對話歷史以及您的工具結果。此請求有三個細節需要注意:
- 承載您結果的使用者訊息只能包含
tool_result區塊。請參閱訊息格式限制。 - 傳入暫停回應中的
containerID。若接續請求有待處理的程式化工具呼叫卻沒有容器 ID,API 會拒絕該請求。 - 傳送與原始請求相同的
tools陣列。程式碼執行工具必須仍然存在,暫停的程式碼才能恢復執行,而您在此請求中傳送的工具,就是 Claude 與執行中的程式碼在本輪其餘部分可使用的定義。
response = client.messages.create(
model="claude-opus-5-5",
max_tokens=4096,
container="container_xyz789", # Reuse the container
messages=[
{
"role": "user",
"content": "Query customer purchase history from the last quarter and identify our top 5 customers by revenue",
},
{
"role": "assistant",
"content": [
{
"type": "text",
"text": "I'll query the purchase history and analyze the results.",
},
{
"type": "server_tool_use",
"id": "srvtoolu_abc123",
"name": "code_execution",
"input": {"code": "..."},
},
{
"type": "tool_use",
"id": "toolu_def456",
"name": "query_database",
"input": {"sql": "<sql>"},
"caller": {
"type": "code_execution_20260120",
"tool_id": "srvtoolu_abc123",
},
},
],
},
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_def456",
"content": '[{"customer_id": "C1", "revenue": 45000}, {"customer_id": "C2", "revenue": 38000}, ...]',
}
],
},
],
# 與原始請求相同的 tools 陣列
tools=[
{"type": "code_execution_20260120", "name": "code_execution"},
{
"name": "query_database",
"description": "Execute a SQL query against the sales database. Returns a list of rows as JSON objects.",
"input_schema": {
"type"