Claude Platform Docs
MessagesTool-Infrastruktur

Programmatische Tool-Aufrufe

Lass Claude deine Tools aus Code im Code-Ausführungs-Container aufrufen und reduziere so Modell-Roundtrips und Token-Verbrauch in Multi-Tool-Workflows.

„Programmatic tool calling“ (programmatische Tool-Aufrufe) ermöglicht es Claude, Code zu schreiben, der deine Tools programmatisch innerhalb eines Code-Ausführungs-Containers aufruft, anstatt für jeden Tool-Aufruf einen Roundtrip durch das Modell zu erfordern. Dies reduziert die „latency“ (Latenz) bei Multi-Tool-Workflows und senkt den Token-Verbrauch, indem Claude Daten filtern oder verarbeiten kann, bevor sie das „context window“ (Kontextfenster) des Modells erreichen. Bei agentischen Such-Benchmarks wie BrowseComp und DeepSearchQA, die mehrstufige Web-Recherche und komplexe Informationsbeschaffung testen, verbesserte das Hinzufügen programmatischer Tool-Aufrufe zu einfachen Such-Tools die Leistung um durchschnittlich 11 %, während 24 % weniger Input-Token verbraucht wurden (siehe Improved web search with dynamic filtering).

Stell dir vor, du prüfst die Budgeteinhaltung von 20 Mitarbeitenden: Der herkömmliche Ansatz erfordert 20 separate Modell-Roundtrips und zieht dabei Tausende von Spesenposten in den Kontext. Mit programmatischen Tool-Aufrufen führt ein einziges Skript alle 20 Abfragen aus, filtert die Ergebnisse und gibt nur die Mitarbeitenden zurück, die ihre Limits überschritten haben – wodurch das, worüber Claude nachdenken muss, von Hunderten Kilobyte auf eine Handvoll Zeilen schrumpft.

Programmatische Tool-Aufrufe erfordern das Code-Ausführungstool mit der Tool-Version code_execution_20260120 oder neuer.

Schnellstart

Hier ist ein Beispiel, in dem Claude programmatisch mehrfach eine Datenbank abfragt und die Ergebnisse aggregiert. Das Hinzufügen von allowed_callers: ["code_execution_20260120"] zu einer Tool-Definition macht dieses Tool aus der Code-Ausführung heraus aufrufbar (siehe Das Feld allowed_callers):

client = anthropic.Anthropic()

response = client.messages.create(
    model="claude-opus-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)

Die Antwort stoppt mit stop_reason: "tool_use", einer container-ID und einem tool_use-Block für query_database, dessen caller-Feld den Code-Ausführungslauf identifiziert, der ihn aufgerufen hat. Gib das Ergebnis wie in Schritt 3 des Beispiel-Workflows gezeigt zurück, damit der Code abschließen kann.

So funktionieren programmatische Tool-Aufrufe

Wenn du ein Tool so konfigurierst, dass es aus der Code-Ausführung aufrufbar ist, und Claude feststellt, dass dieses Tool benötigt wird:

  1. Claude schreibt Python-Code, der das Tool als Funktion aufruft, möglicherweise einschließlich mehrerer Tool-Aufrufe und Vor-/Nachverarbeitungslogik
  2. Claude führt diesen Code über die Code-Ausführung in einem Sandbox-Container aus
  3. Wenn eine Tool-Funktion aufgerufen wird, pausiert die Code-Ausführung und die API gibt einen tool_use-Block zurück
  4. Du stellst das Tool-Ergebnis bereit, und die Code-Ausführung wird fortgesetzt (Zwischenergebnisse werden nicht in Claudes Kontextfenster geladen)
  5. Sobald die gesamte Code-Ausführung abgeschlossen ist, erhält Claude die endgültige Ausgabe und arbeitet weiter an der Aufgabe

Dieser Ansatz ist besonders nützlich für:

  • Verarbeitung großer Datenmengen: Filtere oder aggregiere Tool-Ergebnisse, bevor sie Claudes Kontext erreichen
  • Mehrstufige Workflows: Spare Token und Latenz, indem du Tools seriell oder in einer Schleife aufrufst, ohne Claude zwischen den Tool-Aufrufen zu sampeln
  • Bedingte Logik: Triff Entscheidungen basierend auf Zwischenergebnissen von Tools

Kernkonzepte

Das Feld allowed_callers

Das 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_20260120"]
}

Mögliche Werte:

  • ["direct"] - Claude wird angeleitet, dieses Tool direkt aufzurufen (Standard, wenn weggelassen)
  • ["code_execution_20260120"] - Claude wird angeleitet, dieses Tool nur aus der Code-Ausführung heraus aufzurufen
  • ["direct", "code_execution_20260120"] - Claude kann dieses Tool direkt oder aus der Code-Ausführung heraus aufrufen

Sowohl "code_execution_20260120" als auch "code_execution_20260521" werden in allowed_callers akzeptiert und sind austauschbar: Eine Anfrage, die eine der beiden Code-Ausführungs-Tool-Versionen verwendet, erfüllt Tools, die einen der beiden Caller auflisten. Antwortblöcke kennzeichnen den Caller immer als code_execution_20260120, unabhängig davon, welche Version die Anfrage deklariert hat.

Das Feld caller in Antworten

Jeder Tool-Use-Block enthält ein caller-Feld, das angibt, wie er aufgerufen wurde:

Direkter Aufruf (herkömmliche Tool-Nutzung):

{
  "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_20260120",
    "tool_id": "srvtoolu_abc123"
  }
}

Die tool_id ist die id des server_tool_use-Blocks der Code-Ausführung, der den Aufruf getätigt hat, sodass du jedes programmatische tool_use dem Code-Ausführungslauf zuordnen kannst, der es erzeugt hat.

Container-Lebenszyklus

Programmatische Tool-Aufrufe verwenden dieselben Container wie die Code-Ausführung:

  • Container-Erstellung: Für jede Anfrage wird ein neuer Container erstellt, sofern du keinen bestehenden wiederverwendest
  • Container-ID: Wird in Antworten im Feld container zurückgegeben, zusammen mit einem expires_at-Zeitstempel
  • Wiederverwendung: Übergib die Container-ID bei der nächsten Anfrage erneut, um den Zustand beizubehalten. Während ein programmatischer Tool-Aufruf auf dein Ergebnis wartet, ist die Container-ID bei dieser Anfrage erforderlich, nicht optional: Die API lehnt die Anfrage ohne sie ab.
  • Ablauf: expires_at gibt an, wie lange der Container noch verfügbar ist. Inaktive Container werden derzeit nach etwa 5 Minuten freigegeben, und kein Container kann mehr als 30 Tage nach seiner Erstellung wiederverwendet werden.

Beispiel-Workflow

So funktioniert ein vollständiger Ablauf mit programmatischen Tool-Aufrufen:

Schritt 1: Erste Anfrage

Sende eine Anfrage mit Code-Ausführung und einem Tool, das programmatische Aufrufe zulässt. Um programmatische Aufrufe zu aktivieren, füge das Feld allowed_callers zu deiner Tool-Definition hinzu.

Die Form der Anfrage ist identisch mit dem Schnellstart-Beispiel: Nimm code_execution in deine Tools-Liste auf, füge allowed_callers: ["code_execution_20260120"] zu jedem Tool hinzu, das Claude aus Code aufrufen soll, und sende deine User-Nachricht. Die übrigen Schritte in diesem Workflow verwenden die User-Nachricht "Query customer purchase history from the last quarter and identify our top 5 customers by revenue".

Schritt 2: API-Antwort mit Tool-Aufruf

Claude schreibt Code, der dein Tool aufruft. Die API pausiert und gibt zurück:

Output
{
  "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"
}

Schritt 3: Tool-Ergebnis bereitstellen

Sende den vollständigen Gesprächsverlauf plus dein Tool-Ergebnis. Drei Details sind bei dieser Anfrage wichtig:

  • Die User-Nachricht, die dein Ergebnis enthält, darf nur tool_result-Blöcke enthalten. Siehe Einschränkungen bei der Nachrichtenformatierung.
  • Übergib die container-ID aus der pausierten Antwort. Die API lehnt eine Fortsetzung ab, die ausstehende programmatische Tool-Aufrufe, aber keine Container-ID hat.
  • Sende dasselbe tools-Array wie in der ursprünglichen Anfrage. Das Code-Ausführungstool muss weiterhin vorhanden sein, damit der pausierte Code fortgesetzt werden kann, und die Tools, die du bei dieser Anfrage sendest, sind die Definitionen, die Claude und der laufende Code für den Rest des Turns verwenden können.
response = client.messages.create(
    model="claude-opus-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}, ...]',
                }
            ],
        },
    ],
    # Dasselbe tools-Array wie in der ursprünglichen Anfrage
    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)

Schritt 4: Nächster Tool-Aufruf oder Abschluss

Der Code setzt dort fort, wo er pausiert hat, und verarbeitet dein Ergebnis. Jede Fortsetzungsantwort pausiert entweder erneut mit weiteren programmatischen tool_use-Blöcken oder schließt die Code-Ausführung ab und lässt Claude den Turn fortsetzen (Schritt 5). Prüfe stop_reason und das caller-Feld jedes tool_use-Blocks, um die beiden Fälle zu unterscheiden: Eine Antwort, die auf dich wartet, hat stop_reason: "tool_use" und einen tool_use-Block, dessen caller eine Code-Ausführungsversion nennt, und du wiederholst Schritt 3 mit einem tool_result für jeden ausstehenden programmatischen Aufruf in einer einzigen User-Nachricht.

Schritt 5: Endgültige Antwort

Sobald die Code-Ausführung abgeschlossen ist, liefert Claude die endgültige Antwort:

Output
{
  "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"
}

Fortgeschrittene Muster

Batch-Verarbeitung mit Schleifen

Claude kann Code schreiben, der mehrere Elemente effizient verarbeitet:

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)

# Ergebnisse programmatisch verarbeiten
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:

  • Reduziert Modell-Roundtrips von N (einer pro Region) auf 1
  • Verarbeitet große Ergebnismengen programmatisch, bevor sie an Claude zurückgegeben werden
  • Spart Token, indem nur aggregierte Schlussfolgerungen statt Rohdaten zurückgegeben werden

Vorzeitiger Abbruch

Claude kann die Verarbeitung stoppen, sobald die Erfolgskriterien erfüllt sind:

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 remaining

Bedingte Tool-Auswahl

path = "/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)

Datenfilterung

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)

Antwortformat

Programmatischer Tool-Aufruf

Wenn die Code-Ausführung ein Tool aufruft:

{
  "type": "tool_use",
  "id": "toolu_abc123",
  "name": "query_database",
  "input": { "sql": "<sql>" },
  "caller": {
    "type": "code_execution_20260120",
    "tool_id": "srvtoolu_xyz789"
  }
}

Verarbeitung von Tool-Ergebnissen

Dein 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}, ...]"
    }
  ]
}

Abschluss der Code-Ausführung

Wenn alle Tool-Aufrufe beantwortet 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": []
  }
}

Fehlerbehandlung

Häufige Fehler

FehlerWo er auftrittBeschreibungLösung
invalid_tool_inputerror_code im code_execution_tool_result-Fehlerblock in der AntwortUngültige Parameter wurden an das Code-Ausführungstool übergebenSiehe die Fehler des Code-Ausführungstools
invalid_request_error (bei tool_choice)HTTP-400-Fehlerantworttool_choice nennt ein Tool, dessen allowed_callers nicht "direct" enthältFüge entweder "direct" zu den allowed_callers dieses Tools hinzu oder entferne das Tool aus tool_choice und lass Claude es aus Code aufrufen

Container-Ablauf während eines Tool-Aufrufs

Wenn dein Tool-Ergebnis nicht innerhalb von etwa 4 Minuten eintrifft, löst der ausstehende Aufruf innerhalb von Claudes laufendem Code einen TimeoutError aus. Claude sieht den Fehler in stderr und wiederholt den Aufruf typischerweise:

{
  "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": []
  }
}

Um Timeouts zu vermeiden:

  • Überwache das Feld expires_at in Antworten
  • Implementiere Timeouts für deine Tool-Ausführung
  • Erwäge, lange Operationen in kleinere Teile aufzuteilen

Fehler bei der Tool-Ausführung

Wenn dein Tool einen Fehler zurückgibt:

{
  "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 angemessen behandeln.

Einschränkungen und Limitierungen

Feature-Inkompatibilitäten

  • Strukturierte Ausgaben: Tools mit strict: true werden bei programmatischen Aufrufen nicht unterstützt
  • Tool-Auswahl: Du kannst den programmatischen Aufruf eines bestimmten Tools nicht über tool_choice erzwingen
  • Parallele Tool-Nutzung: disable_parallel_tool_use: true wird bei programmatischen Aufrufen nicht unterstützt

Einschränkungen beim Input-Schema

Benutzerdefinierte Tools, deren input_schema ein rekursives $ref enthält (einen Referenzzyklus, etwa ein Schema, das auf sich selbst verweist), können nicht für programmatische Aufrufe aktiviert werden. Wenn du für ein solches Tool eine Code-Ausführungs-Tool-Version in allowed_callers aufnimmst, schlägt die Anfrage mit einem 400 invalid_request_error fehl, dessen Meldung Circular $ref detected enthält. Dasselbe Schema wird für direkte Tool-Aufrufe akzeptiert.

Um dies zu umgehen, tue eines der folgenden Dinge:

  • Belasse das Tool bei ausschließlich direkten Aufrufen, indem du allowed_callers weglässt (oder auf ["direct"] setzt). Andere Tools in derselben Anfrage können weiterhin programmatische Aufrufe verwenden.
  • Entferne den Zyklus aus dem Schema. Rolle zum Beispiel die Rekursion bis zu einer festen Tiefe aus und beschreibe jede tiefere Verschachtelung in der description der innersten Ebene, oder ersetze die rekursive Eigenschaft durch ein einfaches {"type": "object"}, dessen description die erwartete Form erklärt.

Tool-Einschränkungen

Die folgenden Tools können nicht programmatisch aufgerufen werden:

  • Tools, die von einem MCP-Connector bereitgestellt werden
  • Die Toolsets für Computer Use und Browser Use (computer_toolset_20260801 und browser_toolset_20260801), deren allowed_callers-Feld nur "direct" akzeptiert

Einschränkungen bei der Nachrichtenformatierung

Beim Beantworten programmatischer Tool-Aufrufe gelten strenge Formatierungsanforderungen:

Antworten nur mit Tool-Ergebnissen: Wenn ausstehende programmatische Tool-Aufrufe auf Ergebnisse warten, darf deine Antwortnachricht nur tool_result-Blöcke enthalten. Du kannst keinen Textinhalt einfügen, auch nicht nach den Tool-Ergebnissen.

Ungültig - Beim Beantworten programmatischer Tool-Aufrufe darf kein Text enthalten sein:

{
  "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?" }
  ]
}

Gültig - Nur Tool-Ergebnisse beim Beantworten programmatischer Tool-Aufrufe:

{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01",
      "content": "[{\"customer_id\": \"C1\", \"revenue\": 45000}]"
    }
  ]
}

Diese Einschränkung gilt nur beim Beantworten programmatischer (Code-Ausführungs-)Tool-Aufrufe. Bei regulären clientseitigen Tool-Aufrufen kannst du nach den Tool-Ergebnissen Textinhalt einfügen.

Nur Text als Tool-Ergebnis-Inhalt: Der content jedes tool_result, das einen programmatischen Aufruf beantwortet, muss ein String oder text-Blöcke sein. Bild-, Dokument- und andere Content-Block-Typen werden abgelehnt.

Ratenlimits

Programmatische Tool-Aufrufe unterliegen denselben „rate limits“ (Ratenlimits) wie reguläre Tool-Aufrufe. Jeder Tool-Aufruf aus der Code-Ausführung zählt als separater Aufruf.

Tool-Ergebnisse vor der Verwendung validieren

Bei der Implementierung benutzerdefinierter Tools, die programmatisch aufgerufen werden:

  • Tool-Ergebnisse werden als Strings zurückgegeben: Sie können beliebige Inhalte enthalten, einschließlich Code-Snippets oder ausführbarer Befehle, die von der Ausführungsumgebung verarbeitet werden könnten.
  • Validiere externe Tool-Ergebnisse: Wenn dein Tool Daten aus externen Quellen zurückgibt oder Benutzereingaben akzeptiert, sei dir der Risiken von Code-Injection bewusst, falls die Ausgabe als Code interpretiert oder ausgeführt wird.

Token-Effizienz

Programmatische Tool-Aufrufe reduzieren den Token-Verbrauch auf drei Arten:

  • Tool-Ergebnisse aus programmatischen Aufrufen werden nicht zu Claudes Kontext hinzugefügt - nur die endgültige Code-Ausgabe
  • Zwischenverarbeitung findet im Code statt - Filterung, Aggregation und andere Transformationen verbrauchen keine Modell-Token
  • Mehrere Tool-Aufrufe in einer Code-Ausführung - reduziert den Overhead im Vergleich zu separaten Modell-Turns

Zum Beispiel verbraucht das direkte Aufrufen von 10 Tools etwa das 10-Fache der Token im Vergleich zum programmatischen Aufrufen mit Rückgabe einer Zusammenfassung.

In Anthropics internen Evaluierungen mit einem produktiven Claude-Modell:

  • Bei einem Projektmanagement-Agenten-Benchmark mit 75 Tools reduzierte das Aktivieren programmatischer Tool-Aufrufe die abgerechneten Input-Token um etwa 38 %, ohne Änderung der Aufgabengenauigkeit.
  • Bei τ²-bench (Domänen Airline, Einzelhandel und Telekommunikation), wo jeder Turn einen oder zwei sequenzielle Tool-Aufrufe macht, ließen programmatische Tool-Aufrufe die Ergebnisse unverändert und kosteten etwa 8 % mehr. Sequenzielle Workflows mit Einzelaufrufen profitieren nicht.
  • Über den produktiven API-Traffic hinweg erzielen Anfragen, deren tools-Array 10 bis 49 Tool-Definitionen enthält, mit aktivierten programmatischen Tool-Aufrufen typische Token-Einsparungen von 20 % bis 40 %.

Die tatsächlichen Einsparungen variieren je nach Form des Workloads. Siehe Wann programmatische Aufrufe verwendet werden sollten.

Nutzung und Preise

Programmatische Tool-Aufrufe verwenden dieselben Preise wie die Code-Ausführung. Details findest du unter Preise für die Code-Ausführung.

Best Practices

Tool-Design

  • Gib detaillierte Ausgabebeschreibungen an: Da Claude Tool-Ergebnisse im Code deserialisiert, dokumentiere das Format (JSON-Struktur und Feldtypen)
  • Gib strukturierte Daten zurück: JSON oder andere maschinenlesbare Formate eignen sich am besten für die programmatische Verarbeitung
  • Halte Antworten knapp: Gib nur notwendige Daten zurück, um den Verarbeitungsaufwand zu minimieren

Wann programmatische Aufrufe verwendet werden sollten

Programmatische Tool-Aufrufe tauschen einen kleinen festen Overhead (Container-Start, Skriptgenerierung) gegen große Einsparungen bei Tool-Ergebnis-Token und Modell-Roundtrips. Ob sich dieser Tausch lohnt, hängt von der Form des Workloads ab.

Gut geeignet:

  • Fan-out- oder parallele Operationen über viele Elemente (zum Beispiel das Prüfen von 50 Endpunkten oder das Nachschlagen von 20 Datensätzen)
  • Große Tool-Ergebnisse, die gefiltert, aggregiert oder zusammengefasst werden können, bevor sie Claudes Kontext erreichen
  • Agentische Suche und Retrieval, bei denen iteratives Abfragen und Ergebnisfilterung den Workflow dominieren

Weniger geeignet:

  • Streng sequenzielle Workflows, bei denen jeder Aufruf davon abhängt, dass Claude über das vorherige Ergebnis nachdenkt, da das Skript in diesem Fall den Modell-Roundtrip nicht überspringen kann
  • Eine kleine Anzahl von Tool-Aufrufen mit kleinen Antworten, insbesondere im ersten Turn eines Gesprächs, wo Container- und Skript-Overhead die Einsparungen übersteigen können
  • Tools, die zwischen den Aufrufen sofortiges Benutzerfeedback erfordern

Wenn du unsicher bist, miss die abgerechneten Input-Token mit und ohne allowed_callers an einer repräsentativen Stichprobe deines Traffics, bevor du es breit aktivierst.

Performance-Optimierung

  • Verwende Container wieder, wenn du mehrere zusammenhängende Anfragen stellst, um den Zustand beizubehalten
  • Bündle ähnliche Operationen wenn möglich in einer einzigen Code-Ausführung

Fehlerbehebung

Häufige Probleme

invalid_request_error beim Setzen von tool_choice

  • tool_choice kann kein Tool nennen, dessen allowed_callers "direct" nicht enthält. Füge entweder "direct" zu den allowed_callers dieses Tools hinzu oder entferne das Tool aus tool_choice und lass Claude es aus Code aufrufen.

Container-Ablauf

  • Beantworte jeden programmatischen Tool-Aufruf deutlich vor dem expires_at-Zeitstempel der pausierten Antwort. Claudes Code wartet nach etwa 4 Minuten nicht mehr auf ein Ergebnis, und inaktive Container werden derzeit nach etwa 5 Minuten freigegeben.
  • Erwäge, eine schnellere Tool-Ausführung zu implementieren

Tool-Ergebnis wird nicht korrekt geparst

  • Stelle sicher, dass dein Tool String-Daten zurückgibt, die Claude deserialisieren kann
  • Gib in deiner Tool-Beschreibung eine klare Dokumentation des Ausgabeformats an

Debugging-Tipps

  1. Protokolliere alle Tool-Aufrufe und Ergebnisse, um den Ablauf nachzuverfolgen
  2. Prüfe das Feld caller, um den programmatischen Aufruf zu bestätigen
  3. Überwache Container-IDs, um eine korrekte Wiederverwendung sicherzustellen
  4. Teste Tools unabhängig, bevor du programmatische Aufrufe aktivierst

Warum programmatische Tool-Aufrufe funktionieren

Claude ist auf großen Mengen Code trainiert, sodass die Darstellung von Tools als aufrufbare Python-Funktionen diese Stärke nutzt:

  • Tool-Komposition: Verkettete Aufrufe, Schleifen und Bedingungen sind gewöhnlicher Python-Kontrollfluss statt einer Reihe von Modell-Roundtrips
  • Ergebnisverarbeitung: Claudes Code filtert und aggregiert große Tool-Ausgaben oder schreibt sie in Dateien, und nur die endgültige Ausgabe gelangt ins Kontextfenster
  • Latenz: Das Modell wird zwischen den Tool-Aufrufen innerhalb einer Code-Ausführung nicht erneut gesampelt

Alternative Implementierungen

Programmatische Tool-Aufrufe sind ein verallgemeinerbares Muster, das auch auf deiner eigenen Infrastruktur implementiert werden kann. So lassen sich die Ansätze vergleichen:

Clientseitige direkte Ausführung

Stelle Claude ein Code-Ausführungstool bereit und beschreibe, welche Funktionen in dieser Umgebung verfügbar sind. Wenn Claude das Tool mit Code aufruft, führt deine Anwendung ihn lokal dort aus, wo diese Funktionen definiert sind.

Vorteile:

  • Minimale Umstrukturierung deiner Anwendung
  • Volle Kontrolle über die Umgebung und die Anweisungen

Nachteile:

  • Führt nicht vertrauenswürdigen Code außerhalb einer Sandbox aus
  • Tool-Aufrufe können Vektoren für Code-Injection sein

Verwende dies, wenn: Deine Anwendung beliebigen Code sicher ausführen kann, du die kleinste Implementierung möchtest und Anthropics verwaltetes Angebot nicht zu deinen Anforderungen passt.

Selbstverwaltete Sandbox-Ausführung

Aus Claudes Sicht derselbe Ansatz, aber der Code läuft in einem Sandbox-Container mit Sicherheitseinschränkungen (zum Beispiel kein ausgehender Netzwerkverkehr). Wenn deine Tools externe Ressourcen benötigen, brauchst du ein Protokoll zum Ausführen von Tool-Aufrufen außerhalb der Sandbox.

Vorteile:

  • Sichere programmatische Tool-Aufrufe auf deiner eigenen Infrastruktur
  • Volle Kontrolle über die Ausführungsumgebung

Nachteile:

  • Komplex zu bauen und zu warten
  • Erfordert die Verwaltung sowohl der Infrastruktur als auch der Interprozesskommunikation

Verwende dies, wenn: Sicherheit entscheidend ist und Anthropics verwaltete Lösung nicht zu deinen Anforderungen passt.

Von Anthropic verwaltete Ausführung

Anthropics programmatische Tool-Aufrufe sind eine verwaltete Version der Sandbox-Ausführung mit einer auf Claude abgestimmten, vorkonfigurierten Python-Umgebung. Anthropic übernimmt die Container-Verwaltung, die Code-Ausführung und die sichere Kommunikation bei Tool-Aufrufen.

Vorteile:

  • Standardmäßig sicher und geschützt
  • Aktivierung über eine Tool-Definition, ohne Infrastruktur betreiben zu müssen
  • Umgebung und Anweisungen für Claude optimiert

Erwäge die Verwendung von Anthropics verwalteter Lösung, wenn du die Claude API, Claude Platform on AWS oder Microsoft Foundry verwendest. Auf Microsoft Foundry erfordern programmatische Tool-Aufrufe ein Hosted on Anthropic-Deployment.

Datenaufbewahrung

Programmatische Tool-Aufrufe basieren auf der Code-Ausführungsinfrastruktur und verwenden dieselben Sandbox-Container. Container-Daten, einschließlich Ausführungsartefakten und Ausgaben, werden bis zu 30 Tage aufbewahrt.

Zur ZDR-Berechtigung über alle Features hinweg siehe API und Datenaufbewahrung.

Nächste Schritte

Streame Tool-Eingaben ohne serverseitiges JSON-Buffering für latenzempfindliche Anwendungen.

Führe Python- und Bash-Code in einem Sandbox-Container aus, um Daten zu analysieren, Dateien zu generieren und Lösungen iterativ zu verbessern.

Verbinde Claude mit externen Tools und APIs. Erfahre, wo Tools ausgeführt werden, wann Claude sie aufruft und welches Tool zu deiner Aufgabe passt.

Lege Tool-Schemas fest, schreibe effektive Beschreibungen und steuere, wann Claude deine Tools aufruft.

Compatibility

Supported models
  • Fable 5 and 5.1
  • Mythos 5 and 5.1
  • Opus 4.5, 4.6, 4.7, 4.8, and 5
  • Sonnet 4.5, 4.6, and 5
Supported platforms
  • Claude API
  • Claude Platform on AWS
  • Microsoft Foundry1
  1. Auf Microsoft Foundry erfordern programmatische Tool-Aufrufe ein Hosted on Anthropic-Deployment.
  • Programmatische Tool-Aufrufe erfordern das Code-Ausführungstool mit der Tool-Version code_execution_20260120 oder neuer.
  • Claude Haiku 4.5 akzeptiert die Tool-Versionen code_execution_20260120 und neuer, unterstützt aber keine programmatischen Tool-Aufrufe.

Was this page helpful?