程式化工具呼叫允許 Claude 在程式碼執行容器中撰寫程式碼來以程式化方式呼叫您的工具,而不需要每次工具呼叫都透過模型進行來回通訊。這減少了多工具工作流程的延遲,並透過允許 Claude 在資料到達模型的上下文視窗之前進行過濾或處理,來降低 token 消耗。
此功能需要啟用程式碼執行工具。
This feature is not covered by Zero Data Retention (ZDR) arrangements. Data is retained according to the feature's standard retention policy.
程式化工具呼叫可在以下模型上使用:
| 模型 | 工具版本 |
|---|---|
Claude Opus 4.6 (claude-opus-4-6) | code_execution_20250825 |
Claude Sonnet 4.6 (claude-sonnet-4-6) | code_execution_20250825 |
Claude Sonnet 4.5 (claude-sonnet-4-5-20250929) | code_execution_20250825 |
Claude Opus 4.5 (claude-opus-4-5-20251101) | code_execution_20250825 |
程式化工具呼叫可透過 Claude API 和 Microsoft Foundry 使用。
以下是一個簡單的範例,Claude 以程式化方式多次查詢資料庫並彙總結果:
curl https://api.anthropic.com/v1/messages \
--header "x-api-key: $ANTHROPIC_API_KEY" \
--header "anthropic-version: 2023-06-01" \
--header "content-type: application/json" \
--data '{
"model": "claude-opus-4-6",
"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_20250825",
"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_20250825"]
}
]
}'當您將工具設定為可從程式碼執行中呼叫,且 Claude 決定使用該工具時:
tool_use 區塊此方法特別適用於:
自訂工具會被轉換為非同步 Python 函式以支援平行工具呼叫。當 Claude 撰寫呼叫您工具的程式碼時,它會使用 await(例如 result = await query_database("<sql>"))並自動包含適當的非同步包裝函式。
為了清晰起見,本文件的程式碼範例中省略了非同步包裝。
allowed_callers 欄位allowed_callers 欄位指定哪些上下文可以呼叫工具:
{
"name": "query_database",
"description": "Execute a SQL query against the database",
"input_schema": {...},
"allowed_callers": ["code_execution_20250825"]
}可能的值:
["direct"] - 只有 Claude 可以直接呼叫此工具(省略時的預設值)["code_execution_20250825"] - 只能從程式碼執行中呼叫["direct", "code_execution_20250825"] - 可直接呼叫也可從程式碼執行中呼叫我們建議為每個工具選擇 ["direct"] 或 ["code_execution_20250825"] 其中之一,而不是同時啟用兩者,因為這能為 Claude 提供更清晰的指引,讓它知道如何最佳地使用該工具。
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_20250825",
"tool_id": "srvtoolu_abc123"
}
}tool_id 參照進行程式化呼叫的程式碼執行工具。
程式化工具呼叫使用與程式碼執行相同的容器:
container 欄位在回應中回傳當工具被程式化呼叫且容器正在等待您的工具結果時,您必須在容器過期之前回應。請監控 expires_at 欄位。如果容器過期,Claude 可能會將工具呼叫視為逾時並重試。
以下是完整的程式化工具呼叫流程:
發送包含程式碼執行和允許程式化呼叫的工具的請求。要啟用程式化呼叫,請在您的工具定義中新增 allowed_callers 欄位。
在工具描述中提供工具輸出格式的詳細說明。如果您指定工具回傳 JSON,Claude 將嘗試在程式碼中反序列化和處理結果。您提供的輸出結構描述越詳細,Claude 就能越好地以程式化方式處理回應。
response = client.messages.create(
model="claude-opus-4-6",
max_tokens=4096,
messages=[
{
"role": "user",
"content": "Query customer purchase history from the last quarter and identify our top 5 customers by revenue",
}
],
tools=[
{"type": "code_execution_20250825", "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": {...},
"allowed_callers": ["code_execution_20250825"],
},
],
)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": "results = await query_database('<sql>')\ntop_customers = sorted(results, 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_20250825",
"tool_id": "srvtoolu_abc123"
}
}
],
"container": {
"id": "container_xyz789",
"expires_at": "2025-01-15T14:30:00Z"
},
"stop_reason": "tool_use"
}包含完整的對話歷史記錄加上您的工具結果:
response = client.messages.create(
model="claude-opus-4-6",
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_20250825",
"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=[...],
)程式碼執行繼續並處理結果。如果需要額外的工具呼叫,重複步驟 3 直到所有工具呼叫都被滿足。
程式碼執行完成後,Claude 提供最終回應:
{
"content": [
{
"type": "code_execution_tool_result",
"tool_use_id": "srvtoolu_abc123",
"content": {
"type": "code_execution_result",
"stdout": "Top 5 customers by revenue:\n1. Customer C1: $45,000\n2. Customer C2: $38,000\n3. Customer C5: $32,000\n4. Customer C8: $28,500\n5. Customer C3: $24,000",
"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 可以撰寫高效處理多個項目的程式碼:
# async wrapper omitted for clarity
regions = ["West", "East", "Central", "North", "South"]
results = {}
for region in regions:
data = await query_database(f"<sql for {region}>")
results[region] = sum(row["revenue"] for row in data)
# Process results programmatically
top_region = max(results.items(), key=lambda x: x[1])
print(f"Top region: {top_region[0]} with ${top_region[1]:,} in revenue")此模式:
Claude 可以在滿足成功條件後立即停止處理:
# async wrapper omitted for clarity
endpoints = ["us-east", "eu-west", "apac"]
for endpoint in endpoints:
status = await check_health(endpoint)
if status == "healthy":
print(f"Found healthy endpoint: {endpoint}")
break # Stop early, don't check remaining# async wrapper omitted for clarity
file_info = await get_file_info(path)
if file_info["size"] < 10000:
content = await read_full_file(path)
else:
content = await read_file_summary(path)
print(content)# async wrapper omitted for clarity
logs = await fetch_logs(server_id)
errors = [log for log in logs if "ERROR" in log]
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_20250825",
"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 | 工具輸入不符合結構描述 | 驗證您工具的 input_schema |
tool_not_allowed | 工具不允許請求的呼叫者類型 | 檢查 allowed_callers 是否包含正確的上下文 |
missing_beta_header | 未提供必要的 beta 標頭 | 在您的請求中新增必要的 beta 標頭 |
如果您的工具回應時間太長,程式碼執行將收到 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.",
"return_code": 0,
"content": []
}
}防止逾時的方法:
expires_at 欄位如果您的工具回傳錯誤:
# Provide error information in the tool result
{
"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 不支援程式化呼叫以下工具目前無法以程式化方式呼叫,但未來版本可能會新增支援:
回應程式化工具呼叫時,有嚴格的格式要求:
僅包含工具結果的回應:如果有待處理的程式化工具呼叫等待結果,您的回應訊息必須僅包含 tool_result 區塊。您不能包含任何文字內容,即使在工具結果之後也不行。
// ❌ INVALID - Cannot include text when responding to programmatic tool calls
{
"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?"} // This will cause an error
]
}
// ✅ VALID - Only tool results when responding to programmatic tool calls
{
"role": "user",
"content": [
{"type": "tool_result", "tool_use_id": "toolu_01", "content": "[{\"customer_id\": \"C1\", \"revenue\": 45000}]"}
]
}此限制僅適用於回應程式化(程式碼執行)工具呼叫時。對於一般的客戶端工具呼叫,您可以在工具結果之後包含文字內容。
程式化工具呼叫受到與一般工具呼叫相同的速率限制。來自程式碼執行的每個工具呼叫都算作一次單獨的呼叫。
實作將被程式化呼叫的自訂工具時:
程式化工具呼叫可以顯著減少 token 消耗:
例如,直接呼叫 10 個工具使用的 token 大約是以程式化方式呼叫它們並回傳摘要的 10 倍。
程式化工具呼叫使用與程式碼執行相同的定價。詳情請參閱程式碼執行定價。
程式化工具呼叫的 token 計算:來自程式化呼叫的工具結果不計入您的輸入/輸出 token 使用量。只有最終的程式碼執行結果和 Claude 的回應才會計算。
適合的使用案例:
較不理想的使用案例:
「Tool not allowed」錯誤
"allowed_callers": ["code_execution_20250825"]容器過期
expires_at 欄位工具結果未正確解析
caller 欄位以確認程式化呼叫Claude 的訓練包含大量的程式碼接觸,使其能有效地推理和串連函式呼叫。當工具在程式碼執行環境中作為可呼叫函式呈現時,Claude 可以利用這一優勢來:
此方法使傳統工具使用不切實際的工作流程成為可能——例如處理超過 1M token 的檔案——透過允許 Claude 以程式化方式處理資料,而不是將所有內容載入對話上下文。
程式化工具呼叫是一種可通用的模式,可以在 Anthropic 的託管程式碼執行之外實作。以下是各種方法的概述:
為 Claude 提供程式碼執行工具,並描述該環境中可用的函式。當 Claude 使用程式碼呼叫工具時,您的應用程式在定義了這些函式的本地環境中執行它。
優點:
缺點:
適用時機: 您的應用程式可以安全地執行任意程式碼,您想要簡單的解決方案,且 Anthropic 的託管方案不符合您的需求。
從 Claude 的角度來看方法相同,但程式碼在具有安全限制的沙箱容器中執行(例如,無網路出口)。如果您的工具需要外部資源,您需要一個在沙箱外執行工具呼叫的協議。
優點:
缺點:
適用時機: 安全性至關重要且 Anthropic 的託管解決方案不符合您的需求。
Anthropic 的程式化工具呼叫是沙箱執行的託管版本,具有為 Claude 調校的固定 Python 環境。Anthropic 處理容器管理、程式碼執行和安全的工具呼叫通訊。
優點:
如果您使用 Claude API,我們建議使用 Anthropic 的託管解決方案。
Was this page helpful?