「Programmatic tool calling」(程式化工具呼叫)允許 Claude 在 code execution(程式碼執行)容器內編寫程式碼來以程式化方式呼叫您的工具,而不需要每次工具調用都經過模型往返。這降低了多工具工作流程的延遲,並透過讓 Claude 在資料進入模型的上下文視窗之前先進行過濾或處理,從而減少 token 消耗。在測試多步驟網路研究和複雜資訊檢索的代理式搜尋基準測試(如 BrowseComp 和 DeepSearchQA)中,在基本搜尋工具之上加入程式化工具呼叫,平均提升了 11% 的效能,同時減少了 24% 的輸入 token(請參閱 Improved web search with dynamic filtering)。
以檢查 20 名員工的預算合規性為例:傳統方法需要 20 次獨立的模型往返,過程中會將數千筆費用明細項目拉入上下文。使用程式化工具呼叫時,單一腳本即可執行全部 20 次查詢、過濾結果,並僅回傳超出限額的員工,將 Claude 需要推理的內容從數百 KB 縮減到僅僅幾行。
若要深入了解程式化工具呼叫所解決的推論和上下文成本問題,請參閱 Advanced tool use。
此功能需要啟用程式碼執行工具。
此功能不符合零資料保留(Zero Data Retention,ZDR)的資格。資料將依據該功能的標準保留政策進行保留。
程式化工具呼叫需要 code_execution_20260120 或更新版本,以下模型支援此功能:
| 模型 |
|---|
| Claude Fable 5 (claude-fable-5) |
| Claude Mythos 5 (claude-mythos-5) |
| Claude Opus 4.8 (claude-opus-4-8) |
| Claude Opus 4.7 (claude-opus-4-7) |
| Claude Opus 4.6 (claude-opus-4-6) |
| Claude Sonnet 5 (claude-sonnet-5) |
| Claude Sonnet 4.6 (claude-sonnet-4-6) |
| Claude Opus 4.5 (claude-opus-4-5-20251101) |
| Claude Sonnet 4.5 (claude-sonnet-4-5-20250929) |
如需完整的程式碼執行工具版本對照表,請參閱程式碼執行工具模型相容性表格。程式化工具呼叫可在 Claude API、AWS 上的 Claude Platform 以及 Microsoft Foundry 上使用。在 Microsoft Foundry 上,程式化工具呼叫需要 Hosted on Anthropic 部署。目前在 Amazon Bedrock 或 Google Cloud 上尚不可用。
以下範例展示 Claude 如何以程式化方式多次查詢資料庫並彙總結果:
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-4-8",
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 決定使用該工具時:
tool_use 區塊此方法特別適用於:
允許程式碼執行呼叫者的工具會以非同步 Python 函式的形式暴露給 Claude 的程式碼,因此 Claude 可以使用 asyncio.gather 平行執行它們。每個函式接受單一引數字典並回傳字串:即您送回的 tool_result 文字。Claude 的程式碼使用頂層 await 等待這些函式,並解析需要作為結構化資料的結果,例如 rows = json.loads(await query_database({"sql": "<sql>"}))。
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。
為每個工具選擇 ["direct"] 或 ["code_execution_20260120"] 其中之一,而非同時啟用兩者,因為這能為 Claude 提供更清晰的指引,說明如何最佳地使用該工具。
allowed_callers 控制工具如何呈現給 Claude,並會針對 tool_choice 進行驗證,但它並非 API 層級對直接調用的硬性阻擋。Claude 會被強烈引導遵守此設定,但您的用戶端仍應準備好處理其定義的任何工具的直接 tool_use。請勿將 allowed_callers 視為安全邊界。
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 與產生它的程式碼執行作業進行配對。
程式化工具呼叫使用與程式碼執行相同的容器:
container 欄位中回傳,並附帶 expires_at 時間戳記expires_at 告訴您容器剩餘的時間。閒置容器目前會在約 5 分鐘後被回收,且任何容器在建立後超過 30 天都無法再重複使用。當 Claude 的程式碼正在等待程式化工具結果時,待處理的呼叫會在約 4 分鐘後逾時,並在程式碼內部引發 TimeoutError。請在暫停回應的 expires_at 時間戳記之前充分提早回傳每個工具結果。請參閱工具呼叫期間容器過期。
以下是完整程式化工具呼叫流程的運作方式:
發送包含程式碼執行和允許程式化呼叫之工具的請求。若要啟用程式化呼叫,請在您的工具定義中新增 allowed_callers 欄位。
在工具描述中提供工具輸出格式的詳細說明。如果您指定工具回傳 JSON,Claude 會嘗試在程式碼中反序列化並處理結果。您提供的輸出結構描述越詳細,Claude 就越能以程式化方式處理回應。
請求結構與快速入門範例相同:在您的工具清單中包含 code_execution,為您希望 Claude 從程式碼中調用的任何工具新增 allowed_callers: ["code_execution_20260120"],然後發送您的使用者訊息。此工作流程的其餘步驟使用的使用者訊息為 "Query customer purchase history from the last quarter and identify our top 5 customers by revenue"。
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"
}發送完整的對話歷史記錄加上您的工具結果。此請求有三個重要細節:
tool_result 區塊。請參閱訊息格式限制。container ID。若有待處理的程式化工具呼叫但沒有容器 ID,API 會拒絕該延續請求。tools 陣列。程式碼執行工具必須仍然存在,暫停的程式碼才能恢復執行,且您在此請求中發送的工具即為 Claude 和執行中程式碼在該回合其餘部分可使用的定義。response = client.messages.create(
model="claude-opus-4-8",
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": "object",
"properties": {
"sql": {"type": "string", "description": "SQL query to execute"}
},
"required": ["sql"],
},
"allowed_callers": ["code_execution_20260120"],
},
],
)
print(response)程式碼從暫停處繼續執行並處理您的結果。每個延續回應要麼再次暫停並帶有更多程式化 tool_use 區塊,要麼完成程式碼執行並讓 Claude 繼續該回合(步驟 5)。檢查 stop_reason 和每個 tool_use 區塊的 caller 以區分兩者:為您暫停的回應具有 stop_reason: "tool_use" 以及一個 caller 指名程式碼執行版本的 tool_use 區塊,此時您需重複步驟 3,在一則使用者訊息中為每個待處理的程式化呼叫提供 tool_result。
程式碼執行完成後,Claude 提供最終回應:
{
"content": [
{
"type": "code_execution_tool_result",
"tool_use_id": "srvtoolu_abc123",
"content": {
"type": "code_execution_result",
"stdout": "Top 5 customers: [{'customer_id': 'C1', 'revenue': 45000}, {'customer_id': 'C2', 'revenue': 38000}, {'customer_id': 'C5', 'revenue': 32000}, {'customer_id': 'C8', 'revenue': 28500}, {'customer_id': 'C3', 'revenue': 24000}]",
"stderr": "",
"return_code": 0,
"content": []
}
},
{
"type": "text",
"text": "I've analyzed the purchase history from last quarter. Your top 5 customers generated $167,500 in total revenue, with Customer C1 leading at $45,000."
}
],
"stop_reason": "end_turn"
}Claude 可以編寫高效處理多個項目的程式碼:
regions = ["West", "East", "Central", "North", "South"]
results = {}
for region in regions:
rows = json.loads(await query_database({"sql": f"<sql for {region}>"}))
results[region] = sum(row["revenue"] for row in rows)
# 以程式化方式處理結果
top_region = max(results.items(), key=lambda x: x[1])
print(f"Top region: {top_region[0]} with ${top_region[1]:,} in revenue")此模式:
Claude 可以在滿足成功條件後立即停止處理:
endpoints = ["us-east", "eu-west", "apac"]
for endpoint in endpoints:
status = await check_health({"endpoint": endpoint})
if status == "healthy":
print(f"Found healthy endpoint: {endpoint}")
break # Stop early, don't check remainingpath = "/tmp/example.txt"
file_info = json.loads(await get_file_info({"path": path}))
if file_info["size"] < 10000:
content = await read_full_file({"path": path})
else:
content = await read_file_summary({"path": path})
print(content)server_id = "srv-01"
log_text = await fetch_logs({"server_id": server_id})
errors = [line for line in log_text.splitlines() if "ERROR" in line]
print(f"Found {len(errors)} errors")
for error in errors[-10:]: # Only return last 10 errors
print(error)當程式碼執行呼叫工具時:
{
"type": "tool_use",
"id": "toolu_abc123",
"name": "query_database",
"input": { "sql": "<sql>" },
"caller": {
"type": "code_execution_20260120",
"tool_id": "srvtoolu_xyz789"
}
}您的工具結果會傳回給執行中的程式碼:
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_abc123",
"content": "[{\"customer_id\": \"C1\", \"revenue\": 45000, \"orders\": 23}, {\"customer_id\": \"C2\", \"revenue\": 38000, \"orders\": 18}, ...]"
}
]
}當所有工具呼叫都已滿足且程式碼完成時:
{
"type": "code_execution_tool_result",
"tool_use_id": "srvtoolu_xyz789",
"content": {
"type": "code_execution_result",
"stdout": "Analysis complete. Top 5 customers identified from 847 total records.",
"stderr": "",
"return_code": 0,
"content": []
}
}| 錯誤 | 出現位置 | 描述 | 解決方案 |
|---|---|---|---|
invalid_tool_input | 回應中 code_execution_tool_result 錯誤區塊的 error_code | 傳遞給程式碼執行工具的參數無效 | 請參閱程式碼執行工具錯誤 |
invalid_request_error(針對 tool_choice) | HTTP 400 錯誤回應 | tool_choice 指定的工具其 allowed_callers 不包含 "direct" | 將 "direct" 新增至該工具的 allowed_callers,或從 tool_choice 中移除該工具並讓 Claude 從程式碼中調用它 |
如果您的工具結果未在約 4 分鐘內送達,待處理的呼叫會在 Claude 執行中的程式碼內部引發 TimeoutError。Claude 會在 stderr 中看到該錯誤,通常會重試該呼叫:
{
"type": "code_execution_tool_result",
"tool_use_id": "srvtoolu_abc123",
"content": {
"type": "code_execution_result",
"stdout": "",
"stderr": "TimeoutError: Calling tool ['query_database'] timed out (no response after 270s).",
"return_code": 0,
"content": []
}
}為防止逾時:
expires_at 欄位如果您的工具回傳錯誤:
{
"type": "tool_result",
"tool_use_id": "toolu_abc123",
"content": "Error: Query timeout - table lock exceeded 30 seconds"
}Claude 的程式碼會接收此錯誤並可適當處理。
strict: true 的工具不支援程式化呼叫tool_choice 強制對特定工具進行程式化呼叫disable_parallel_tool_use: true 不支援程式化呼叫input_schema 包含遞迴 $ref(參照循環,例如結構描述參照自身)的自訂工具無法啟用程式化呼叫。在此類工具的 allowed_callers 中包含程式碼執行工具版本會導致請求失敗,並回傳訊息包含 Circular $ref detected 的 400 invalid_request_error。相同的結構描述在直接工具呼叫中是可接受的。
若要解決此問題,請執行下列其中一項:
allowed_callers(或將其設為 ["direct"])使該工具僅限直接呼叫。同一請求中的其他工具仍可使用程式化呼叫。description 中描述任何更深的巢狀結構,或將遞迴屬性替換為純 {"type": "object"},並在其 description 中說明預期的結構。以下工具無法以程式化方式呼叫:
回應程式化工具呼叫時,有嚴格的格式要求:
僅限工具結果的回應: 如果有待處理的程式化工具呼叫正在等待結果,您的回應訊息必須僅包含 tool_result 區塊。您不能包含任何文字內容,即使在工具結果之後也不行。
無效 - 回應程式化工具呼叫時不能包含文字:
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_01",
"content": "[{\"customer_id\": \"C1\", \"revenue\": 45000}]"
},
{ "type": "text", "text": "What should I do next?" }
]
}有效 - 回應程式化工具呼叫時僅包含工具結果:
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_01",
"content": "[{\"customer_id\": \"C1\", \"revenue\": 45000}]"
}
]
}此限制僅適用於回應程式化(程式碼執行)工具呼叫時。對於一般的用戶端工具呼叫,您可以在工具結果之後包含文字內容。
僅限文字的工具結果內容: 回應程式化呼叫的每個 tool_result 的 content 必須是字串或 text 區塊。圖片、文件和其他內容區塊類型會被拒絕。
程式化工具呼叫受到與一般工具呼叫相同的速率限制。來自程式碼執行的每個工具呼叫都計為一次獨立的調用。
實作將被程式化呼叫的使用者定義工具時:
程式化工具呼叫透過三種方式減少 token 消耗:
例如,直接呼叫 10 個工具所使用的 token 約為以程式化方式呼叫並回傳摘要的 10 倍。
在 Anthropic 對正式環境 Claude 模型的內部評估中:
tools 陣列包含 10 到 49 個工具定義的請求,在啟用程式化工具呼叫後通常可節省 20% 到 40% 的 token。實際節省量因工作負載型態而異。請參閱何時使用程式化呼叫。
程式化工具呼叫使用與程式碼執行相同的定價。詳情請參閱程式碼執行定價。
程式化工具呼叫的 token 計算:程式化調用的工具結果不計入您的輸入/輸出 token 使用量。只有最終的程式碼執行結果和 Claude 的回應會計入。
程式化工具呼叫以少量固定開銷(容器啟動、腳本生成)換取工具結果 token 和模型往返的大幅節省。這種取捨是否划算取決於工作負載型態。
非常適合:
不太適合:
如果您不確定,請在廣泛啟用之前,針對您流量的代表性樣本測量啟用和未啟用 allowed_callers 時的計費輸入 token。
設定 tool_choice 時出現 invalid_request_error
tool_choice 不能指定 allowed_callers 省略 "direct" 的工具。請將 "direct" 新增至該工具的 allowed_callers,或從 tool_choice 中移除該工具並讓 Claude 從程式碼中調用它。容器過期
expires_at 時間戳記之前充分提早回應每個程式化工具呼叫。Claude 的程式碼在約 4 分鐘後會停止等待結果,且閒置容器目前會在約 5 分鐘後被回收。工具結果未正確解析
caller 欄位以確認程式化調用Claude 在大量程式碼上進行訓練,因此將工具呈現為可呼叫的 Python 函式能讓它發揮這項優勢:
程式化工具呼叫是一種可通用化的模式,也可以在您自己的基礎架構上實作。以下是各種方法的比較:
為 Claude 提供程式碼執行工具,並描述該環境中可用的函式。當 Claude 使用程式碼調用該工具時,您的應用程式會在定義這些函式的本機環境中執行它。
優點:
缺點:
適用時機: 您的應用程式可以安全地執行任意程式碼、您希望實作最精簡,且 Anthropic 的託管方案不符合您的需求。
從 Claude 的角度來看方法相同,但程式碼在具有安全限制(例如,無網路出口)的沙箱容器中執行。如果您的工具需要外部資源,您需要一個在沙箱外執行工具呼叫的協定。
優點:
缺點:
適用時機: 安全性至關重要,且 Anthropic 的託管解決方案不符合您的需求。
Anthropic 的程式化工具呼叫是沙箱執行的託管版本,具有針對 Claude 調校的特定 Python 環境。Anthropic 負責處理容器管理、程式碼執行和安全的工具調用通訊。
優點:
如果您使用 Claude API、AWS 上的 Claude Platform 或 Microsoft Foundry,請考慮使用 Anthropic 的託管解決方案。在 Microsoft Foundry 上,程式化工具呼叫需要 Hosted on Anthropic 部署。
程式化工具呼叫建立在程式碼執行基礎架構之上,並使用相同的沙箱容器。容器資料(包括執行產物和輸出)最多保留 30 天。
如需所有功能的 ZDR 資格資訊,請參閱 API 與資料保留。
針對延遲敏感的應用程式,在無需伺服器端 JSON 緩衝的情況下串流工具輸入。
在沙箱容器中執行 Python 和 bash 程式碼,以分析資料、生成檔案並反覆改進解決方案。
將 Claude 連接到外部工具和 API。了解工具在何處執行、Claude 何時呼叫它們,以及哪種工具適合您的任務。
指定工具結構描述、撰寫有效的描述,並控制 Claude 何時呼叫您的工具。
Was this page helpful?