---
title: Programmatische Tool-Aufrufe
url: https://platform.claude.com/docs/de/agents-and-tools/tool-use/programmatic-tool-calling
description: Lass Claude deine Tools aus Code im Code-Execution-Container aufrufen, um Modell-Roundtrips und Token-Verbrauch in Multi-Tool-Workflows zu reduzieren.
featureMetadata:
  status: ga
  zdr: not-eligible
  supportedModels:
    - claude-fable-5-1
    - claude-mythos-5-1
    - claude-fable-5
    - claude-mythos-5
    - claude-opus-5-5
    - claude-opus-5
    - claude-opus-4-8
    - claude-opus-4-7
    - claude-opus-4-6
    - claude-opus-4-5-20251101
    - claude-sonnet-5-5
    - claude-sonnet-5
    - claude-sonnet-4-6
    - claude-sonnet-4-5-20250929
    - claude-haiku-5-5
  supportedPlatforms:
    Claude API: ga
    Claude Platform on AWS: ga
    Microsoft Foundry:
      availability: ga
      note: Auf [Microsoft Foundry](https://platform.claude.com/docs/de/build-with-claude/claude-in-microsoft-foundry) erfordert der programmatische Tool-Aufruf ein [Hosted on Anthropic-Deployment](https://platform.claude.com/docs/de/build-with-claude/claude-in-microsoft-foundry#additional-features-not-supported-when-hosted-on-azure).
  details:
    - Der programmatische Tool-Aufruf erfordert das Code-Ausführungstool mit der [Tool-Version](https://platform.claude.com/docs/de/agents-and-tools/tool-use/code-execution-tool#tool-versions) `code_execution_20260120` oder neuer.
    - Claude Haiku 4.5 akzeptiert die Tool-Versionen `code_execution_20260120` und neuer, unterstützt aber keinen programmatischen Tool-Aufruf.
---

„Programmatic tool calling“ (programmatische Tool-Aufrufe) ermöglicht es Claude, Code zu schreiben, der deine Tools programmatisch innerhalb eines [Code-Ausführungs](https://platform.claude.com/docs/de/agents-and-tools/tool-use/code-execution-tool)-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](https://arxiv.org/abs/2504.12516) und [DeepSearchQA](https://github.com/google-deepmind/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](https://claude.com/blog/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.

<Tip>
  Einen tieferen Einblick in die Inferenz- und Kontextkosten, die programmatische Tool-Aufrufe adressieren, findest du unter [Advanced tool use](https://www.anthropic.com/engineering/advanced-tool-use).
</Tip>

Der programmatische Tool-Aufruf erfordert das [Code-Ausführungstool](https://platform.claude.com/docs/de/agents-and-tools/tool-use/code-execution-tool) mit der Tool-Version `code_execution_20260120` oder neuer. Um vor dem Senden einer Anfrage zu prüfen, ob ein Modell den programmatischen Tool-Aufruf unterstützt, lies seinen Wert `capabilities.code_execution.supported` aus der Models API aus. [Die Models API verwenden](https://platform.claude.com/docs/de/models/overview#using-the-models-api) beschreibt das Feld.

## 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`](https://platform.claude.com/docs/de/agents-and-tools/tool-use/programmatic-tool-calling#the-allowed-callers-field)):

<CodeGroup>
  ```bash cURL
  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-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"]
              }
          ]
      }'
  ```

  ```bash CLI
  ant messages create <<'YAML'
  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
  YAML
  ```

  ```python Python
  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)
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const response = await 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" as const,
          properties: {
            sql: {
              type: "string",
              description: "SQL query to execute"
            }
          },
          required: ["sql"]
        },
        allowed_callers: ["code_execution_20260120"]
      }
    ]
  });

  console.log(response);
  ```

  ```csharp C#
  AnthropicClient client = new();

  var parameters = new MessageCreateParams
  {
      Model = Model.ClaudeOpus5_5,
      MaxTokens = 4096,
      Messages = [
          new() {
              Role = Role.User,
              Content = "Query sales data for the West, East, and Central regions, then tell me which region had the highest revenue"
          }
      ],
      Tools = [
          new CodeExecutionTool20260120(),
          new ToolUnion(new Tool()
          {
              Name = "query_database",
              Description = "Execute a SQL query against the sales database. Returns a list of rows as JSON objects.",
              InputSchema = new InputSchema()
              {
                  Properties = new Dictionary<string, JsonElement>
                  {
                      ["sql"] = JsonSerializer.SerializeToElement(new { type = "string", description = "SQL query to execute" }),
                  },
                  Required = ["sql"],
              },
              AllowedCallers = ["code_execution_20260120"]
          }),
      ]
  };

  var message = await client.Messages.Create(parameters);
  Console.WriteLine(message);
  ```

  ```go Go
  client := anthropic.NewClient()

  response, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
  	Model:     anthropic.ModelClaudeOpus5_5,
  	MaxTokens: 4096,
  	Messages: []anthropic.MessageParam{
  		anthropic.NewUserMessage(anthropic.NewTextBlock("Query sales data for the West, East, and Central regions, then tell me which region had the highest revenue")),
  	},
  	Tools: []anthropic.ToolUnionParam{
  		{OfCodeExecutionTool20260120: &anthropic.CodeExecutionTool20260120Param{}},
  		{OfTool: &anthropic.ToolParam{
  			Name:        "query_database",
  			Description: anthropic.String("Execute a SQL query against the sales database. Returns a list of rows as JSON objects."),
  			InputSchema: anthropic.ToolInputSchemaParam{
  				Properties: map[string]any{
  					"sql": map[string]any{
  						"type":        "string",
  						"description": "SQL query to execute",
  					},
  				},
  				Required: []string{"sql"},
  			},
  			AllowedCallers: []string{"code_execution_20260120"},
  		}},
  	},
  })
  if err != nil {
  	log.Fatal(err)
  }
  fmt.Println(response.RawJSON())
  ```

  ```java Java
  import com.anthropic.models.messages.CodeExecutionTool20260120;
  // ...

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      MessageCreateParams params = MessageCreateParams.builder()
          .model(Model.CLAUDE_OPUS_5_5)
          .maxTokens(4096L)
          .addUserMessage("Query sales data for the West, East, and Central regions, then tell me which region had the highest revenue")
          .addTool(CodeExecutionTool20260120.builder().build())
          .addTool(Tool.builder()
              .name("query_database")
              .description("Execute a SQL query against the sales database. Returns a list of rows as JSON objects.")
              .inputSchema(InputSchema.builder()
                  .properties(JsonValue.from(Map.of(
                      "sql", Map.of(
                          "type", "string",
                          "description", "SQL query to execute"
                      )
                  )))
                  .putAdditionalProperty("required", JsonValue.from(List.of("sql")))
                  .build())
              .allowedCallers(List.of(Tool.AllowedCaller.of("code_execution_20260120")))
              .build())
          .build();

      Message response = client.messages().create(params);
      IO.println(response);
  }
  ```

  ```php PHP
  $client = new Client();

  $message = $client->messages->create(
      maxTokens: 4096,
      messages: [
          ['role' => 'user', 'content' => 'Query sales data for the West, East, and Central regions, then tell me which region had the highest revenue'],
      ],
      model: 'claude-opus-5-5',
      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'],
          ],
      ],
  );

  echo $message;
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  message = 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"]
      }
    ]
  )

  puts message
  ```
</CodeGroup>

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](https://platform.claude.com/docs/de/agents-and-tools/tool-use/programmatic-tool-calling#step-3-provide-tool-result) 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

<Note>
  Tools, die einen Code-Ausführungs-Caller zulassen, werden Claudes Code als asynchrone Python-Funktionen bereitgestellt, sodass Claude sie mit `asyncio.gather` parallel ausführen kann. Jede Funktion nimmt ein einzelnes Dict mit Argumenten entgegen und gibt einen String zurück: den Text des `tool_result`, das du zurücksendest. Claudes Code wartet mit Top-Level-`await` auf diese Funktionen und parst die benötigten Ergebnisse als strukturierte Daten, zum Beispiel `rows = json.loads(await query_database({"sql": "<sql>"}))`.
</Note>

## Kernkonzepte

### Das Feld `allowed_callers`

Das Feld `allowed_callers` gibt an, welche Kontexte ein Tool aufrufen können:

```json
{
  "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.

<Tip>
  Wähle für jedes Tool entweder `["direct"]` oder `["code_execution_20260120"]`, anstatt beides zu aktivieren, da dies Claude eine klarere Anleitung gibt, wie das Tool am besten zu verwenden ist.
</Tip>

<Note>
  `allowed_callers` steuert, wie das Tool Claude präsentiert wird, und wird gegen `tool_choice` validiert, ist aber keine harte Sperre auf API-Ebene gegen direkte Aufrufe. Claude wird stark angeleitet, es zu respektieren, aber dein Client sollte dennoch darauf vorbereitet sein, ein direktes `tool_use` für jedes von ihm definierte Tool zu verarbeiten. Verlasse dich nicht auf `allowed_callers` als Sicherheitsgrenze.
</Note>

### 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):**

```json
{
  "type": "tool_use",
  "id": "toolu_abc123",
  "name": "query_database",
  "input": { "sql": "<sql>" },
  "caller": { "type": "direct" }
}
```

**Programmatischer Aufruf:**

```json
{
  "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.

<Warning>
  Während Claudes Code auf ein programmatisches Tool-Ergebnis wartet, läuft der ausstehende Aufruf nach etwa 4 Minuten in ein Timeout und löst innerhalb des Codes einen `TimeoutError` aus. Gib jedes Tool-Ergebnis deutlich vor dem `expires_at`-Zeitstempel der pausierten Antwort zurück. Siehe [Container-Ablauf während eines Tool-Aufrufs](https://platform.claude.com/docs/de/agents-and-tools/tool-use/programmatic-tool-calling#container-expiration-during-tool-call).
</Warning>

## 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.

<Note>
  Gib in der Tool-Beschreibung detaillierte Beschreibungen des Ausgabeformats deines Tools an. Wenn du angibst, dass das Tool JSON zurückgibt, versucht Claude, das Ergebnis im Code zu deserialisieren und zu verarbeiten. Je mehr Details du zum Ausgabeschema angibst, desto besser kann Claude die Antwort programmatisch verarbeiten.
</Note>

Die Form der Anfrage ist identisch mit dem [Schnellstart](https://platform.claude.com/docs/de/agents-and-tools/tool-use/programmatic-tool-calling#quick-start)-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:

```json 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](https://platform.claude.com/docs/de/agents-and-tools/tool-use/programmatic-tool-calling#message-formatting-restrictions).
* Ü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.

<CodeGroup>
  ```bash cURL
  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-5-5",
          "max_tokens": 4096,
          "container": "container_xyz789",
          "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": [
              {
                  "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"]
              }
          ]
      }'
  ```

  ```bash CLI
  ant messages create <<'YAML'
  model: claude-opus-5-5
  max_tokens: 4096
  container: container_xyz789
  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
  YAML
  ```

  ```python Python
  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}, ...]',
                  }
              ],
          },
      ],
      # 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)
  ```

  ```typescript TypeScript
  const response = await 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}, ...]'
          }
        ]
      }
    ],
    // 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" as const,
          properties: {
            sql: {
              type: "string",
              description: "SQL query to execute"
            }
          },
          required: ["sql"]
        },
        allowed_callers: ["code_execution_20260120"]
      }
    ]
  });

  console.log(response);
  ```

  ```csharp C#
  AnthropicClient client = new();

  var parameters = new MessageCreateParams
  {
      Model = Model.ClaudeOpus5_5,
      MaxTokens = 4096,
      Container = "container_xyz789",
      Messages =
      [
          new()
          {
              Role = Role.User,
              Content = "Query customer purchase history from the last quarter and identify our top 5 customers by revenue"
          },
          new()
          {
              Role = Role.Assistant,
              Content = new ContentBlock[]
              {
                  new TextBlock { Text = "I'll query the purchase history and analyze the results." },
                  new ServerToolUseBlock
                  {
                      Id = "srvtoolu_abc123",
                      Name = "code_execution",
                      Input = new { code = "..." }
                  },
                  new ToolUseBlock
                  {
                      Id = "toolu_def456",
                      Name = "query_database",
                      Input = new { sql = "<sql>" },
                      Caller = new ToolCaller
                      {
                          Type = "code_execution_20260120",
                          ToolId = "srvtoolu_abc123"
                      }
                  }
              }
          },
          new()
          {
              Role = Role.User,
              Content = new ContentBlockParam[]
              {
                  new ToolResultBlockParam
                  {
                      ToolUseID = "toolu_def456",
                      Content = "[{\"customer_id\": \"C1\", \"revenue\": 45000}, {\"customer_id\": \"C2\", \"revenue\": 38000}, ...]"
                  }
              }
          }
      ],
      // Dasselbe tools-Array wie in der ursprünglichen Anfrage
      Tools = [
          new CodeExecutionTool20260120(),
          new ToolUnion(new Tool()
          {
              Name = "query_database",
              Description = "Execute a SQL query against the sales database. Returns a list of rows as JSON objects.",
              InputSchema = new InputSchema()
              {
                  Properties = new Dictionary<string, JsonElement>
                  {
                      ["sql"] = JsonSerializer.SerializeToElement(new { type = "string", description = "SQL query to execute" }),
                  },
                  Required = ["sql"],
              },
              AllowedCallers = ["code_execution_20260120"]
          }),
      ]
  };

  var message = await client.Messages.Create(parameters);
  Console.WriteLine(message);
  ```

  ```go Go
  client := anthropic.NewClient()

  response, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
  	Model:     anthropic.ModelClaudeOpus5_5,
  	MaxTokens: 4096,
  	Container: anthropic.MessageCreateParamsContainerUnion{
  		OfString: anthropic.String("container_xyz789"),
  	},
  	Messages: []anthropic.MessageParam{
  		anthropic.NewUserMessage(anthropic.NewTextBlock("Query customer purchase history from the last quarter and identify our top 5 customers by revenue")),
  		{
  			Role: anthropic.MessageParamRoleAssistant,
  			Content: []anthropic.ContentBlockParamUnion{
  				anthropic.NewTextBlock("I'll query the purchase history and analyze the results."),
  				{OfServerToolUse: &anthropic.ServerToolUseBlockParam{
  					ID:    "srvtoolu_abc123",
  					Name:  anthropic.ServerToolUseBlockParamNameCodeExecution,
  					Input: map[string]any{"code": "..."},
  				}},
  				{OfToolUse: &anthropic.ToolUseBlockParam{
  					ID:    "toolu_def456",
  					Name:  "query_database",
  					Input: map[string]any{"sql": "<sql>"},
  					Caller: anthropic.ServerToolUseBlockParamCallerUnion{
  						OfCodeExecution20260120: &anthropic.ServerToolCaller20260120Param{
  							ToolID: "srvtoolu_abc123",
  						},
  					},
  				}},
  			},
  		},
  		{
  			Role: anthropic.MessageParamRoleUser,
  			Content: []anthropic.ContentBlockParamUnion{
  				{OfToolResult: &anthropic.ToolResultBlockParam{
  					ToolUseID: "toolu_def456",
  					Content: []anthropic.ToolResultBlockParamContentUnion{
  						{OfText: &anthropic.TextBlockParam{
  							Text: `[{"customer_id": "C1", "revenue": 45000}, {"customer_id": "C2", "revenue": 38000}, ...]`,
  						}},
  					},
  				}},
  			},
  		},
  	},
  	// Dasselbe tools-Array wie in der ursprünglichen Anfrage
  	Tools: []anthropic.ToolUnionParam{
  		{OfCodeExecutionTool20260120: &anthropic.CodeExecutionTool20260120Param{}},
  		{OfTool: &anthropic.ToolParam{
  			Name:        "query_database",
  			Description: anthropic.String("Execute a SQL query against the sales database. Returns a list of rows as JSON objects."),
  			InputSchema: anthropic.ToolInputSchemaParam{
  				Properties: map[string]any{
  					"sql": map[string]any{
  						"type":        "string",
  						"description": "SQL query to execute",
  					},
  				},
  				Required: []string{"sql"},
  			},
  			AllowedCallers: []string{"code_execution_20260120"},
  		}},
  	},
  })
  if err != nil {
  	log.Fatal(err)
  }
  fmt.Println(response.RawJSON())
  ```

  ```java Java
  import com.anthropic.models.messages.CodeExecutionTool20260120;
  // ...

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      MessageCreateParams params = MessageCreateParams.builder()
          .model(Model.CLAUDE_OPUS_5_5)
          .maxTokens(4096L)
          .container("container_xyz789")
          .addUserMessage("Query customer purchase history from the last quarter and identify our top 5 customers by revenue")
          .addAssistantMessageOfBlockParams(List.of(
              ContentBlockParam.ofText(
                  TextBlockParam.builder()
                      .text("I'll query the purchase history and analyze the results.")
                      .build()),
              ContentBlockParam.ofServerToolUse(
                  ServerToolUseBlockParam.builder()
                      .id("srvtoolu_abc123")
                      .name("code_execution")
                      .input(JsonValue.from(Map.of("code", "...")))
                      .build()),
              ContentBlockParam.ofToolUse(
                  ToolUseBlockParam.builder()
                      .id("toolu_def456")
                      .name("query_database")
                      .input(JsonValue.from(Map.of("sql", "<sql>")))
                      .codeExecution20260120Caller("srvtoolu_abc123")
                      .build())
          ))
          .addUserMessageOfBlockParams(List.of(
              ContentBlockParam.ofToolResult(
                  ToolResultBlockParam.builder()
                      .toolUseId("toolu_def456")
                      .content("[{\"customer_id\": \"C1\", \"revenue\": 45000}, {\"customer_id\": \"C2\", \"revenue\": 38000}, ...]")
                      .build())
          ))
          // Dasselbe tools-Array wie in der ursprünglichen Anfrage
          .addTool(CodeExecutionTool20260120.builder().build())
          .addTool(Tool.builder()
              .name("query_database")
              .description("Execute a SQL query against the sales database. Returns a list of rows as JSON objects.")
              .inputSchema(InputSchema.builder()
                  .properties(JsonValue.from(Map.of(
                      "sql", Map.of(
                          "type", "string",
                          "description", "SQL query to execute"
                      )
                  )))
                  .putAdditionalProperty("required", JsonValue.from(List.of("sql")))
                  .build())
              .allowedCallers(List.of(Tool.AllowedCaller.of("code_execution_20260120")))
              .build())
          .build();

      Message response = client.messages().create(params);
      IO.println(response);
  }
  ```

  ```php PHP
  $client = new Client();

  $message = $client->messages->create(
      maxTokens: 4096,
      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}, ...]',
                  ],
              ],
          ],
      ],
      model: 'claude-opus-5-5',
      container: 'container_xyz789',
      // 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'],
          ],
      ],
  );

  echo $message;
  ```

  ```ruby Ruby
  require "anthropic"

  client = Anthropic::Client.new

  message = client.messages.create(
    model: "claude-opus-5-5",
    max_tokens: 4096,
    container: "container_xyz789",
    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"]
      }
    ]
  )

  puts message
  ```
</CodeGroup>

### 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:

```json 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:

```python
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:

```python
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

```python
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

```python
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:

```json
{
  "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:

```json
{
  "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:

```json
{
  "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

| Fehler                                      | Wo er auftritt                                                          | Beschreibung                                                                    | Lösung                                                                                                                                             |
| ------------------------------------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `invalid_tool_input`                        | `error_code` im `code_execution_tool_result`-Fehlerblock in der Antwort | Ungültige Parameter wurden an das Code-Ausführungstool übergeben                | Siehe die [Fehler des Code-Ausführungstools](https://platform.claude.com/docs/de/agents-and-tools/tool-use/code-execution-tool#errors)             |
| `invalid_request_error` (bei `tool_choice`) | HTTP-400-Fehlerantwort                                                  | `tool_choice` nennt ein Tool, dessen `allowed_callers` nicht `"direct"` 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 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:

```json
{
  "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:

```json
{
  "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](https://platform.claude.com/docs/de/agents-and-tools/mcp-connector) bereitgestellt werden
* Die Toolsets für [Computer Use](https://platform.claude.com/docs/de/agents-and-tools/tool-use/computer-use-tool) und [Browser Use](https://platform.claude.com/docs/de/agents-and-tools/tool-use/browser-use-tool) (`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:

```json
{
  "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:

```json
{
  "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](https://arxiv.org/abs/2506.07982) (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](https://platform.claude.com/docs/de/agents-and-tools/tool-use/programmatic-tool-calling#when-to-use-programmatic-calling).

## 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](https://platform.claude.com/docs/de/agents-and-tools/tool-use/code-execution-tool#usage-and-pricing).

<Note>
  Token-Zählung für programmatische Tool-Aufrufe: Tool-Ergebnisse aus programmatischen Aufrufen zählen nicht zu deinem Input-/Output-Token-Verbrauch. Nur das endgültige Ergebnis der Code-Ausführung und Claudes Antwort zählen.
</Note>

## 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](https://platform.claude.com/docs/de/build-with-claude/claude-platform-on-aws) oder [Microsoft Foundry](https://platform.claude.com/docs/de/build-with-claude/claude-in-microsoft-foundry) verwendest. Auf Microsoft Foundry erfordern programmatische Tool-Aufrufe ein [Hosted on Anthropic-Deployment](https://platform.claude.com/docs/de/build-with-claude/claude-in-microsoft-foundry#additional-features-not-supported-when-hosted-on-azure).

## 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](https://platform.claude.com/docs/de/manage-claude/api-and-data-retention).

## Nächste Schritte

<CardGroup cols={2}>
  <Card title="Feingranulares Tool-Streaming" icon="bolt" href="https://platform.claude.com/docs/de/agents-and-tools/tool-use/fine-grained-tool-streaming">
    Streame Tool-Eingaben ohne serverseitiges JSON-Buffering für latenzempfindliche Anwendungen.
  </Card>

  <Card title="Code-Ausführungstool" icon="code" href="https://platform.claude.com/docs/de/agents-and-tools/tool-use/code-execution-tool">
    Führe Python- und Bash-Code in einem Sandbox-Container aus, um Daten zu analysieren, Dateien zu generieren und Lösungen iterativ zu verbessern.
  </Card>

  <Card title="Tool-Nutzung mit Claude" icon="wrench" href="https://platform.claude.com/docs/de/agents-and-tools/tool-use/overview">
    Verbinde Claude mit externen Tools und APIs. Erfahre, wo Tools ausgeführt werden, wann Claude sie aufruft und welches Tool zu deiner Aufgabe passt.
  </Card>

  <Card title="Tools definieren" icon="hammer" href="https://platform.claude.com/docs/de/agents-and-tools/tool-use/define-tools">
    Lege Tool-Schemas fest, schreibe effektive Beschreibungen und steuere, wann Claude deine Tools aufruft.
  </Card>
</CardGroup>
