Programmatischer Tool-Aufruf ermöglicht es Claude, Code zu schreiben, der Ihre Tools programmatisch innerhalb eines Code-Ausführungs-Containers aufruft, anstatt mehrere Roundtrips durch das Modell für jeden Tool-Aufruf zu erfordern. Dies reduziert die Latenz für Multi-Tool-Workflows und verringert den Token-Verbrauch, indem Claude Daten filtern oder verarbeiten kann, bevor sie das Kontextfenster des Modells erreichen.
Programmatischer Tool-Aufruf befindet sich derzeit in der öffentlichen Beta.
Um diese Funktion zu nutzen, fügen Sie den "advanced-tool-use-2025-11-20" Beta-Header zu Ihren API-Anfragen hinzu.
Diese Funktion erfordert, dass das Code-Ausführungs-Tool aktiviert ist.
Programmatischer Tool-Aufruf ist auf den folgenden Modellen verfügbar:
| Modell | Tool-Version |
|---|---|
Claude Opus 4.5 (claude-opus-4-5-20251101) | code_execution_20250825 |
Claude Sonnet 4.5 (claude-sonnet-4-5-20250929) | code_execution_20250825 |
Programmatischer Tool-Aufruf ist über die Claude API und Microsoft Foundry verfügbar.
Hier ist ein einfaches Beispiel, bei dem Claude programmatisch mehrmals eine Datenbank abfragt und Ergebnisse aggregiert:
Wenn Sie ein Tool so konfigurieren, dass es von der Code-Ausführung aufgerufen werden kann, und Claude beschließt, dieses Tool zu verwenden:
tool_use-Block zurückDieser Ansatz ist besonders nützlich für:
Benutzerdefinierte Tools werden in asynchrone Python-Funktionen konvertiert, um parallele Tool-Aufrufe zu unterstützen. Wenn Claude Code schreibt, der Ihre Tools aufruft, verwendet es await (z. B. result = await query_database("<sql>")) und fügt automatisch die entsprechende asynchrone Wrapper-Funktion ein.
Die asynchrone Wrapper wird in den Code-Beispielen in dieser Dokumentation aus Gründen der Klarheit weggelassen.
allowed_callersDas Feld allowed_callers gibt an, welche Kontexte ein Tool aufrufen können:
{
"name": "query_database",
"description": "Execute a SQL query against the database",
"input_schema": {...},
"allowed_callers": ["code_execution_20250825"]
}Mögliche Werte:
["direct"] - Nur Claude kann dieses Tool direkt aufrufen (Standard, wenn weggelassen)["code_execution_20250825"] - Nur von innerhalb der Code-Ausführung aufrufbar["direct", "code_execution_20250825"] - Von direkt und von Code-Ausführung aufrufbarWir empfehlen, für jedes Tool entweder ["direct"] oder ["code_execution_20250825"] zu wählen, anstatt beide zu aktivieren, da dies Claude eine klarere Anleitung gibt, wie das Tool am besten verwendet wird.
caller in AntwortenJeder Tool-Use-Block enthält ein Feld caller, das angibt, wie es aufgerufen wurde:
Direkter Aufruf (traditionelle Tool-Verwendung):
{
"type": "tool_use",
"id": "toolu_abc123",
"name": "query_database",
"input": {"sql": "<sql>"},
"caller": {"type": "direct"}
}Programmatischer Aufruf:
{
"type": "tool_use",
"id": "toolu_xyz789",
"name": "query_database",
"input": {"sql": "<sql>"},
"caller": {
"type": "code_execution_20250825",
"tool_id": "srvtoolu_abc123"
}
}Die tool_id verweist auf das Code-Ausführungs-Tool, das den programmatischen Aufruf getätigt hat.
Programmatischer Tool-Aufruf verwendet die gleichen Container wie Code-Ausführung:
container zurückgegebenWenn ein Tool programmatisch aufgerufen wird und der Container auf Ihr Tool-Ergebnis wartet, müssen Sie antworten, bevor der Container abläuft. Überwachen Sie das Feld expires_at. Wenn der Container abläuft, kann Claude den Tool-Aufruf als Timeout behandeln und ihn erneut versuchen.
Hier ist ein Beispiel für einen vollständigen programmatischen Tool-Aufruf-Ablauf:
Senden Sie eine Anfrage mit Code-Ausführung und einem Tool, das programmatische Aufrufe ermöglicht. Um programmatische Aufrufe zu aktivieren, fügen Sie das Feld allowed_callers zu Ihrer Tool-Definition hinzu.
Geben Sie detaillierte Beschreibungen des Ausgabeformats Ihres Tools in der Tool-Beschreibung an. Wenn Sie angeben, dass das Tool JSON zurückgibt, wird Claude versuchen, das Ergebnis in Code zu deserialisieren und zu verarbeiten. Je mehr Details Sie über das Ausgabeschema bereitstellen, desto besser kann Claude die Antwort programmatisch verarbeiten.
Claude schreibt Code, der Ihr Tool aufruft. Die API pausiert und gibt folgendes zurück:
{
"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"
}Fügen Sie die vollständige Gesprächshistorie plus Ihr Tool-Ergebnis ein:
Die Code-Ausführung wird fortgesetzt und verarbeitet die Ergebnisse. Wenn zusätzliche Tool-Aufrufe erforderlich sind, wiederholen Sie Schritt 3, bis alle Tool-Aufrufe erfüllt sind.
Sobald die Code-Ausführung abgeschlossen ist, stellt Claude die endgültige Antwort bereit:
{
"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 kann Code schreiben, der mehrere Elemente effizient verarbeitet:
# 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")Dieses Muster:
Claude kann die Verarbeitung beenden, sobald Erfolgskriterien erfüllt sind:
# 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)Wenn Code-Ausführung ein Tool aufruft:
{
"type": "tool_use",
"id": "toolu_abc123",
"name": "query_database",
"input": {"sql": "<sql>"},
"caller": {
"type": "code_execution_20250825",
"tool_id": "srvtoolu_xyz789"
}
}Ihr Tool-Ergebnis wird an den laufenden Code zurückgegeben:
{
"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}, ...]"
}
]
}Wenn alle Tool-Aufrufe erfüllt sind und der Code abgeschlossen ist:
{
"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": []
}
}| Fehler | Beschreibung | Lösung |
|---|---|---|
invalid_tool_input | Tool-Eingabe stimmt nicht mit Schema überein | Validieren Sie das input_schema Ihres Tools |
tool_not_allowed | Tool erlaubt den angeforderten Caller-Typ nicht | Überprüfen Sie, dass allowed_callers die richtigen Kontexte enthält |
missing_beta_header | PTC-Beta-Header nicht bereitgestellt | Fügen Sie beide Beta-Header zu Ihrer Anfrage hinzu |
Wenn Ihr Tool zu lange zum Antworten braucht, erhält die Code-Ausführung einen TimeoutError. Claude sieht dies in stderr und wird normalerweise erneut versuchen:
{
"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": []
}
}Um Timeouts zu vermeiden:
expires_at in AntwortenWenn Ihr Tool einen Fehler zurückgibt:
# Provide error information in the tool result
{
"type": "tool_result",
"tool_use_id": "toolu_abc123",
"content": "Error: Query timeout - table lock exceeded 30 seconds"
}Claudes Code erhält diesen Fehler und kann ihn entsprechend verarbeiten.
strict: true werden nicht mit programmatischem Aufruf unterstützttool_choice erzwingendisable_parallel_tool_use: true wird nicht mit programmatischem Aufruf unterstütztDie folgenden Tools können derzeit nicht programmatisch aufgerufen werden, aber die Unterstützung kann in zukünftigen Versionen hinzugefügt werden:
Bei der Antwort auf programmatische Tool-Aufrufe gibt es strenge Formatierungsanforderungen:
Nur Tool-Ergebnis-Antworten: Wenn es ausstehende programmatische Tool-Aufrufe gibt, die auf Ergebnisse warten, muss Ihre Antwortnachricht nur tool_result-Blöcke enthalten. Sie können keinen Text-Inhalt einschließen, auch nicht nach den Tool-Ergebnissen.
// ❌ UNGÜLTIG - Kann keinen Text einschließen, wenn auf programmatische Tool-Aufrufe geantwortet wird
{
"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
]
}
// ✅ GÜLTIG - Nur Tool-Ergebnisse bei Antwort auf programmatische Tool-Aufrufe
{
"role": "user",
"content": [
{"type": "tool_result", "tool_use_id": "toolu_01", "content": "[{\"customer_id\": \"C1\", \"revenue\": 45000}]"}
]
}Diese Einschränkung gilt nur bei der Antwort auf programmatische (Code-Ausführungs-)Tool-Aufrufe. Für reguläre Client-seitige Tool-Aufrufe können Sie Text-Inhalt nach Tool-Ergebnissen einschließen.
Programmatische Tool-Aufrufe unterliegen den gleichen Rate Limits wie reguläre Tool-Aufrufe. Jeder Tool-Aufruf von Code-Ausführung zählt als separate Invokation.
Bei der Implementierung benutzerdefinierter Tools, die programmatisch aufgerufen werden:
Programmatischer Tool-Aufruf kann den Token-Verbrauch erheblich reduzieren:
Beispielsweise verwendet das direkte Aufrufen von 10 Tools etwa 10x die Token des programmatischen Aufrufs und der Rückgabe einer Zusammenfassung.
Programmatischer Tool-Aufruf verwendet die gleiche Preisgestaltung wie Code-Ausführung. Siehe die Code-Ausführungs-Preisgestaltung für Details.
Token-Zählung für programmatische Tool-Aufrufe: Tool-Ergebnisse von programmatischen Invokationen zählen nicht zu Ihrer Input-/Output-Token-Nutzung. Nur das endgültige Code-Ausführungsergebnis und Claudes Antwort zählen.
Gute Anwendungsfälle:
Weniger ideale Anwendungsfälle:
"Tool not allowed"-Fehler
"allowed_callers": ["code_execution_20250825"] enthältContainer-Ablauf
expires_at in AntwortenBeta-Header-Probleme
"advanced-tool-use-2025-11-20"Tool-Ergebnis wird nicht korrekt analysiert
caller, um programmatische Invokation zu bestätigenClaudes Training umfasst umfangreiche Exposition gegenüber Code, was es effektiv macht, durch Tool-Aufrufe zu argumentieren und sie zu verketten. Wenn Tools als aufrufbare Funktionen innerhalb einer Code-Ausführungsumgebung präsentiert werden, kann Claude diese Stärke nutzen, um:
Dieser Ansatz ermöglicht Workflows, die mit traditioneller Tool-Verwendung unpraktisch wären – wie die Verarbeitung von Dateien über 1M Token – indem Claude mit Daten programmatisch arbeiten kann, anstatt alles in den Gesprächskontext zu laden.
Programmatischer Tool-Aufruf ist ein verallgemeinerbares Muster, das außerhalb von Anthropics verwalteter Code-Ausführung implementiert werden kann. Hier ist ein Überblick über die Ansätze:
Stellen Sie Claude ein Code-Ausführungs-Tool zur Verfügung und beschreiben Sie, welche Funktionen in dieser Umgebung verfügbar sind. Wenn Claude das Tool mit Code aufruft, führt Ihre Anwendung es lokal aus, wo diese Funktionen definiert sind.
Vorteile:
Nachteile:
Verwenden Sie, wenn: Ihre Anwendung sicher beliebigen Code ausführen kann, Sie eine einfache Lösung möchten und Anthropics verwaltetes Angebot nicht passt.
Gleicher Ansatz aus Claudes Perspektive, aber Code läuft in einem Sandbox-Container mit Sicherheitsbeschränkungen (z. B. kein Netzwerk-Egress). Wenn Ihre Tools externe Ressourcen benötigen, benötigen Sie ein Protokoll zum Ausführen von Tool-Aufrufen außerhalb der Sandbox.
Vorteile:
Nachteile:
Verwenden Sie, wenn: Sicherheit ist kritisch und Anthropics verwaltete Lösung passt nicht zu Ihren Anforderungen.
Anthropics programmatischer Tool-Aufruf ist eine verwaltete Version der Sandbox-Ausführung mit einer für Claude optimierten Python-Umgebung. Anthropic verwaltet Container-Management, Code-Ausführung und sichere Tool-Invokations-Kommunikation.
Vorteile:
Wir empfehlen die Verwendung von Anthropics verwalteter Lösung, wenn Sie die Claude API verwenden.
curl https://api.anthropic.com/v1/messages \
--header "x-api-key: $ANTHROPIC_API_KEY" \
--header "anthropic-version: 2023-06-01" \
--header "anthropic-beta: advanced-tool-use-2025-11-20" \
--header "content-type: application/json" \
--data '{
"model": "claude-sonnet-4-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_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"]
}
]
}'response = client.beta.messages.create(
model="claude-sonnet-4-5",
betas=["advanced-tool-use-2025-11-20"],
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"]
}
]
)response = client.beta.messages.create(
model="claude-sonnet-4-5",
betas=["advanced-tool-use-2025-11-20"],
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=[...]
)Verstehen Sie die Grundlagen der Tool-Verwendung mit Claude.