---
title: Chiamata programmatica degli strumenti
url: https://platform.claude.com/docs/it/agents-and-tools/tool-use/programmatic-tool-calling
description: Consenti a Claude di chiamare i tuoi strumenti dal codice nel container di esecuzione del codice, riducendo i round trip del modello e l'uso di token nei flussi di lavoro con più strumenti.
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: Su [Microsoft Foundry](https://platform.claude.com/docs/it/build-with-claude/claude-in-microsoft-foundry), la chiamata programmatica degli strumenti richiede un [deployment Hosted on Anthropic](https://platform.claude.com/docs/it/build-with-claude/claude-in-microsoft-foundry#additional-features-not-supported-when-hosted-on-azure).
  details:
    - La chiamata programmatica degli strumenti richiede lo strumento di esecuzione del codice con la [versione dello strumento](https://platform.claude.com/docs/it/agents-and-tools/tool-use/code-execution-tool#tool-versions) `code_execution_20260120` o successiva.
    - Claude Haiku 4.5 accetta le versioni dello strumento `code_execution_20260120` e successive, ma non supporta la chiamata programmatica degli strumenti.
---

Il "programmatic tool calling" (chiamata programmatica degli strumenti) consente a Claude di scrivere codice che chiama i tuoi strumenti in modo programmatico all'interno di un container di [esecuzione del codice](https://platform.claude.com/docs/it/agents-and-tools/tool-use/code-execution-tool), invece di richiedere round trip attraverso il modello per ogni invocazione di strumento. Questo riduce la "latency" (latenza) per i flussi di lavoro multi-strumento e diminuisce il consumo di token consentendo a Claude di filtrare o elaborare i dati prima che raggiungano la "context window" (finestra di contesto) del modello. Su benchmark di ricerca agentica come [BrowseComp](https://arxiv.org/abs/2504.12516) e [DeepSearchQA](https://github.com/google-deepmind/deepsearchqa), che testano la ricerca web multistep e il recupero di informazioni complesse, l'aggiunta della chiamata programmatica degli strumenti sopra gli strumenti di ricerca di base ha migliorato le prestazioni in media dell'11% utilizzando il 24% in meno di token di input (vedi [Improved web search with dynamic filtering](https://claude.com/blog/improved-web-search-with-dynamic-filtering)).

Considera la verifica della conformità al budget per 20 dipendenti: l'approccio tradizionale richiede 20 round trip separati del modello, portando nel contesto migliaia di voci di spesa lungo il percorso. Con la chiamata programmatica degli strumenti, un singolo script esegue tutte le 20 ricerche, filtra i risultati e restituisce solo i dipendenti che hanno superato i loro limiti, riducendo ciò su cui Claude deve ragionare da centinaia di kilobyte a una manciata di righe.

<Tip>
  Per uno sguardo più approfondito ai costi di inferenza e di contesto che la chiamata programmatica degli strumenti affronta, consulta [Advanced tool use](https://www.anthropic.com/engineering/advanced-tool-use).
</Tip>

La chiamata programmatica degli strumenti richiede lo [strumento di esecuzione del codice](https://platform.claude.com/docs/it/agents-and-tools/tool-use/code-execution-tool) con la versione dello strumento `code_execution_20260120` o successiva. Per verificare se un modello supporta la chiamata programmatica degli strumenti prima di inviare una richiesta, leggi il suo valore `capabilities.code_execution.supported` dalla Models API. [Utilizzo della Models API](https://platform.claude.com/docs/it/models/overview#using-the-models-api) descrive il campo.

## Avvio rapido

Ecco un esempio in cui Claude interroga programmaticamente un database più volte e aggrega i risultati. Aggiungere `allowed_callers: ["code_execution_20260120"]` a una definizione di strumento è ciò che rende quello strumento chiamabile dall'interno dell'esecuzione del codice (vedi [Il campo `allowed_callers`](https://platform.claude.com/docs/it/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>

La risposta si interrompe con `stop_reason: "tool_use"`, un ID `container` e un blocco `tool_use` per `query_database` il cui campo `caller` identifica l'esecuzione del codice che lo ha chiamato. Restituisci il risultato come mostrato nel [Passaggio 3 del flusso di lavoro di esempio](https://platform.claude.com/docs/it/agents-and-tools/tool-use/programmatic-tool-calling#step-3-provide-tool-result) in modo che il codice possa terminare.

## Come funziona la chiamata programmatica degli strumenti

Quando configuri uno strumento per essere chiamabile dall'esecuzione del codice e Claude determina che quello strumento è necessario:

1. Claude scrive codice Python che invoca lo strumento come funzione, includendo potenzialmente più chiamate di strumenti e logica di pre/post-elaborazione
2. Claude esegue questo codice in un container sandbox tramite l'esecuzione del codice
3. Quando viene chiamata una funzione strumento, l'esecuzione del codice si mette in pausa e l'API restituisce un blocco `tool_use`
4. Tu fornisci il risultato dello strumento e l'esecuzione del codice continua (i risultati intermedi non vengono caricati nella finestra di contesto di Claude)
5. Una volta completata tutta l'esecuzione del codice, Claude riceve l'output finale e continua a lavorare sul compito

Questo approccio è particolarmente utile per:

* **Elaborazione di grandi quantità di dati:** Filtra o aggrega i risultati degli strumenti prima che raggiungano il contesto di Claude
* **Flussi di lavoro multistep:** Risparmia token e latenza chiamando gli strumenti in serie o in un ciclo senza campionare Claude tra le chiamate degli strumenti
* **Logica condizionale:** Prendi decisioni basate sui risultati intermedi degli strumenti

<Note>
  Gli strumenti che consentono un chiamante di esecuzione del codice vengono esposti al codice di Claude come funzioni Python asincrone, quindi Claude può eseguirli in parallelo con `asyncio.gather`. Ogni funzione accetta un singolo dict di argomenti e restituisce una stringa: il testo del `tool_result` che invii in risposta. Il codice di Claude attende queste funzioni con `await` di primo livello e analizza i risultati di cui ha bisogno come dati strutturati, ad esempio `rows = json.loads(await query_database({"sql": "<sql>"}))`.
</Note>

## Concetti fondamentali

### Il campo `allowed_callers`

Il campo `allowed_callers` specifica quali contesti possono invocare uno strumento:

```json
{
  "name": "query_database",
  "description": "Execute a SQL query against the database",
  "input_schema": {
    // ...
  },
  "allowed_callers": ["code_execution_20260120"]
}
```

**Valori possibili:**

* `["direct"]` - Claude è guidato a chiamare questo strumento direttamente (predefinito se omesso)
* `["code_execution_20260120"]` - Claude è guidato a chiamare questo strumento solo dall'interno dell'esecuzione del codice
* `["direct", "code_execution_20260120"]` - Claude può chiamare questo strumento direttamente o dall'interno dell'esecuzione del codice

Sia `"code_execution_20260120"` che `"code_execution_20260521"` sono accettati in `allowed_callers` e sono intercambiabili: una richiesta che utilizza una qualsiasi delle due versioni dello strumento di esecuzione del codice soddisfa gli strumenti che elencano uno qualsiasi dei due chiamanti. I blocchi di risposta etichettano sempre il chiamante come `code_execution_20260120` indipendentemente dalla versione dichiarata nella richiesta.

<Tip>
  Scegli `["direct"]` oppure `["code_execution_20260120"]` per ogni strumento invece di abilitare entrambi, poiché questo fornisce a Claude indicazioni più chiare su come utilizzare al meglio lo strumento.
</Tip>

<Note>
  `allowed_callers` controlla come lo strumento viene presentato a Claude ed è validato rispetto a `tool_choice`, ma non è un blocco rigido a livello di API sull'invocazione diretta. Claude è fortemente guidato a rispettarlo, ma il tuo client dovrebbe comunque essere preparato a gestire un `tool_use` diretto per qualsiasi strumento che definisce. Non fare affidamento su `allowed_callers` come confine di sicurezza.
</Note>

### Il campo `caller` nelle risposte

Ogni blocco di uso degli strumenti include un campo `caller` che indica come è stato invocato:

**Invocazione diretta (uso degli strumenti tradizionale):**

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

**Invocazione programmatica:**

```json
{
  "type": "tool_use",
  "id": "toolu_xyz789",
  "name": "query_database",
  "input": { "sql": "<sql>" },
  "caller": {
    "type": "code_execution_20260120",
    "tool_id": "srvtoolu_abc123"
  }
}
```

Il `tool_id` è l'`id` del blocco `server_tool_use` di esecuzione del codice che ha effettuato la chiamata, quindi puoi associare ogni `tool_use` programmatico all'esecuzione del codice che lo ha prodotto.

### Ciclo di vita del container

La chiamata programmatica degli strumenti utilizza gli stessi container dell'esecuzione del codice:

* **Creazione del container:** Viene creato un nuovo container per ogni richiesta a meno che tu non ne riutilizzi uno esistente
* **ID del container:** Restituito nelle risposte nel campo `container`, insieme a un timestamp `expires_at`
* **Riutilizzo:** Passa l'ID del container nella richiesta successiva per mantenere lo stato. Mentre una chiamata programmatica di strumento è in attesa del tuo risultato, l'ID del container è obbligatorio in quella richiesta, non opzionale: l'API rifiuta la richiesta senza di esso.
* **Scadenza:** `expires_at` ti indica quanto tempo rimane al container. I container inattivi vengono attualmente recuperati dopo circa 5 minuti, e nessun container può essere riutilizzato più di 30 giorni dopo la sua creazione.

<Warning>
  Mentre il codice di Claude è in attesa di un risultato programmatico di strumento, la chiamata in sospeso va in timeout dopo circa 4 minuti e solleva un `TimeoutError` all'interno del codice. Restituisci ogni risultato di strumento ben prima del timestamp `expires_at` della risposta in pausa. Vedi [Scadenza del container durante la chiamata dello strumento](https://platform.claude.com/docs/it/agents-and-tools/tool-use/programmatic-tool-calling#container-expiration-during-tool-call).
</Warning>

## Flusso di lavoro di esempio

Ecco come funziona un flusso completo di chiamata programmatica degli strumenti:

### Passaggio 1: Richiesta iniziale

Invia una richiesta con l'esecuzione del codice e uno strumento che consente la chiamata programmatica. Per abilitare la chiamata programmatica, aggiungi il campo `allowed_callers` alla definizione del tuo strumento.

<Note>
  Fornisci descrizioni dettagliate del formato di output del tuo strumento nella descrizione dello strumento. Se specifichi che lo strumento restituisce JSON, Claude tenta di deserializzare ed elaborare il risultato nel codice. Più dettagli fornisci sullo schema di output, meglio Claude può gestire la risposta in modo programmatico.
</Note>

La forma della richiesta è identica all'esempio di [Avvio rapido](https://platform.claude.com/docs/it/agents-and-tools/tool-use/programmatic-tool-calling#quick-start): includi `code_execution` nella tua lista di strumenti, aggiungi `allowed_callers: ["code_execution_20260120"]` a qualsiasi strumento che vuoi che Claude invochi dal codice, e invia il tuo messaggio utente. I passaggi rimanenti di questo flusso di lavoro utilizzano il messaggio utente `"Query customer purchase history from the last quarter and identify our top 5 customers by revenue"`.

### Passaggio 2: Risposta API con chiamata di strumento

Claude scrive codice che chiama il tuo strumento. L'API si mette in pausa e restituisce:

```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"
}
```

### Passaggio 3: Fornisci il risultato dello strumento

Invia l'intera cronologia della conversazione più il risultato del tuo strumento. Tre dettagli sono importanti in questa richiesta:

* Il messaggio utente che trasporta il tuo risultato può contenere solo blocchi `tool_result`. Vedi [Restrizioni di formattazione dei messaggi](https://platform.claude.com/docs/it/agents-and-tools/tool-use/programmatic-tool-calling#message-formatting-restrictions).
* Passa l'ID `container` dalla risposta in pausa. L'API rifiuta una continuazione che ha chiamate programmatiche di strumenti in sospeso ma nessun ID del container.
* Invia lo stesso array `tools` della richiesta originale. Lo strumento di esecuzione del codice deve essere ancora presente affinché il codice in pausa possa riprendere, e gli strumenti che invii in questa richiesta sono le definizioni che Claude e il codice in esecuzione possono utilizzare per il resto del turno.

<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}, ...]
  # Stesso array tools della richiesta originale
  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}, ...]',
                  }
              ],
          },
      ],
      # Stesso array di strumenti della richiesta originale
      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}, ...]'
          }
        ]
      }
    ],
    // Stesso array tools della richiesta originale
    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}, ...]"
                  }
              }
          }
      ],
      // Stesso array di strumenti della richiesta originale
      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}, ...]`,
  						}},
  					},
  				}},
  			},
  		},
  	},
  	// Stesso array di strumenti della richiesta originale
  	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())
          ))
          // Stesso array tools della richiesta originale
          .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',
      // Stesso array tools della richiesta originale
      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}, ...]'
          }
        ]
      }
    ],
    # Stesso array tools della richiesta originale
    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>

### Passaggio 4: Chiamata di strumento successiva o completamento

Il codice riprende da dove si era messo in pausa ed elabora il tuo risultato. Ogni risposta di continuazione o si mette nuovamente in pausa con altri blocchi `tool_use` programmatici, oppure completa l'esecuzione del codice e consente a Claude di continuare il turno (Passaggio 5). Controlla `stop_reason` e il `caller` di ogni blocco `tool_use` per distinguere i due casi: una risposta che si mette in pausa per te ha `stop_reason: "tool_use"` e un blocco `tool_use` il cui `caller` indica una versione di esecuzione del codice, e tu ripeti il Passaggio 3 con un `tool_result` per ogni chiamata programmatica in sospeso in un unico messaggio utente.

### Passaggio 5: Risposta finale

Una volta completata l'esecuzione del codice, Claude fornisce la risposta finale:

```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"
}
```

## Pattern avanzati

### Elaborazione batch con cicli

Claude può scrivere codice che elabora più elementi in modo efficiente:

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

# Elabora i risultati in modo programmatico
top_region = max(results.items(), key=lambda x: x[1])
print(f"Top region: {top_region[0]} with ${top_region[1]:,} in revenue")
```

Questo pattern:

* Riduce i round trip del modello da N (uno per regione) a 1
* Elabora grandi set di risultati in modo programmatico prima di restituirli a Claude
* Risparmia token restituendo solo conclusioni aggregate invece di dati grezzi

### Terminazione anticipata

Claude può interrompere l'elaborazione non appena i criteri di successo sono soddisfatti:

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

### Selezione condizionale degli strumenti

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

### Filtraggio dei dati

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

## Formato della risposta

### Chiamata programmatica di strumento

Quando l'esecuzione del codice chiama uno strumento:

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

### Gestione del risultato dello strumento

Il risultato del tuo strumento viene passato al codice in esecuzione:

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

### Completamento dell'esecuzione del codice

Quando tutte le chiamate di strumenti sono soddisfatte e il codice è completato:

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

## Gestione degli errori

### Errori comuni

| Errore                                     | Dove appare                                                                   | Descrizione                                                                        | Soluzione                                                                                                                                              |
| ------------------------------------------ | ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `invalid_tool_input`                       | `error_code` nel blocco di errore `code_execution_tool_result` nella risposta | Sono stati passati parametri non validi allo strumento di esecuzione del codice    | Vedi gli [errori dello strumento di esecuzione del codice](https://platform.claude.com/docs/it/agents-and-tools/tool-use/code-execution-tool#errors)   |
| `invalid_request_error` (su `tool_choice`) | Risposta di errore HTTP 400                                                   | `tool_choice` indica uno strumento il cui `allowed_callers` non include `"direct"` | Aggiungi `"direct"` agli `allowed_callers` di quello strumento, oppure rimuovi lo strumento da `tool_choice` e lascia che Claude lo invochi dal codice |

### Scadenza del container durante la chiamata dello strumento

Se il risultato del tuo strumento non arriva entro circa 4 minuti, la chiamata in sospeso solleva un `TimeoutError` all'interno del codice in esecuzione di Claude. Claude vede l'errore in `stderr` e tipicamente ritenta la chiamata:

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

Per prevenire i timeout:

* Monitora il campo `expires_at` nelle risposte
* Implementa timeout per l'esecuzione dei tuoi strumenti
* Considera di suddividere le operazioni lunghe in blocchi più piccoli

### Errori di esecuzione degli strumenti

Se il tuo strumento restituisce un errore:

```json
{
  "type": "tool_result",
  "tool_use_id": "toolu_abc123",
  "content": "Error: Query timeout - table lock exceeded 30 seconds"
}
```

Il codice di Claude riceve questo errore e può gestirlo in modo appropriato.

## Vincoli e limitazioni

### Incompatibilità delle funzionalità

* **Output strutturati:** Gli strumenti con `strict: true` non sono supportati con la chiamata programmatica
* **Scelta dello strumento:** Non puoi forzare la chiamata programmatica di uno strumento specifico tramite `tool_choice`
* **Uso parallelo degli strumenti:** `disable_parallel_tool_use: true` non è supportato con la chiamata programmatica

### Limitazioni dello schema di input

Gli strumenti personalizzati il cui `input_schema` contiene un `$ref` ricorsivo (un ciclo di riferimenti, come uno schema che fa riferimento a se stesso) non possono essere abilitati per la chiamata programmatica. Includere una versione dello strumento di esecuzione del codice in `allowed_callers` per un tale strumento fa fallire la richiesta con un `400 invalid_request_error` il cui messaggio contiene `Circular $ref detected`. Lo stesso schema è accettato per la chiamata diretta degli strumenti.

Per aggirare questo problema, esegui una delle seguenti operazioni:

* Mantieni lo strumento solo diretto omettendo `allowed_callers` (o impostandolo su `["direct"]`). Gli altri strumenti nella stessa richiesta possono comunque utilizzare la chiamata programmatica.
* Rimuovi il ciclo dallo schema. Ad esempio, srotola la ricorsione a una profondità fissa e descrivi qualsiasi annidamento più profondo nella `description` del livello più interno, oppure sostituisci la proprietà ricorsiva con un semplice `{"type": "object"}` la cui `description` spiega la forma attesa.

### Restrizioni degli strumenti

I seguenti strumenti non possono essere chiamati in modo programmatico:

* Strumenti forniti da un [connettore MCP](https://platform.claude.com/docs/it/agents-and-tools/mcp-connector)
* I toolset [computer use](https://platform.claude.com/docs/it/agents-and-tools/tool-use/computer-use-tool) e [browser use](https://platform.claude.com/docs/it/agents-and-tools/tool-use/browser-use-tool) (`computer_toolset_20260801` e `browser_toolset_20260801`), il cui campo `allowed_callers` accetta solo `"direct"`

### Restrizioni di formattazione dei messaggi

Quando rispondi alle chiamate programmatiche di strumenti, ci sono requisiti di formattazione rigorosi:

**Risposte con soli risultati di strumenti:** Se ci sono chiamate programmatiche di strumenti in sospeso in attesa di risultati, il tuo messaggio di risposta deve contenere **solo** blocchi `tool_result`. Non puoi includere alcun contenuto testuale, nemmeno dopo i risultati degli strumenti.

Non valido - Non è possibile includere testo quando si risponde a chiamate programmatiche di strumenti:

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

Valido - Solo risultati di strumenti quando si risponde a chiamate programmatiche di strumenti:

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

Questa restrizione si applica solo quando si risponde a chiamate di strumenti programmatiche (esecuzione del codice). Per le normali chiamate di strumenti lato client, puoi includere contenuto testuale dopo i risultati degli strumenti.

**Contenuto dei risultati degli strumenti solo testuale:** Il `content` di ogni `tool_result` che risponde a una chiamata programmatica deve essere una stringa o blocchi `text`. Immagini, documenti e altri tipi di blocchi di contenuto vengono rifiutati.

### Limiti di velocità

Le chiamate programmatiche di strumenti sono soggette agli stessi "rate limit" (limiti di velocità) delle normali chiamate di strumenti. Ogni chiamata di strumento dall'esecuzione del codice conta come un'invocazione separata.

### Valida i risultati degli strumenti prima dell'uso

Quando implementi strumenti definiti dall'utente che verranno chiamati in modo programmatico:

* **I risultati degli strumenti vengono restituiti come stringhe:** Possono contenere qualsiasi contenuto, inclusi frammenti di codice o comandi eseguibili che potrebbero essere elaborati dall'ambiente di esecuzione.
* **Valida i risultati degli strumenti esterni:** Se il tuo strumento restituisce dati da fonti esterne o accetta input dell'utente, sii consapevole dei rischi di code injection se l'output verrà interpretato o eseguito come codice.

## Efficienza dei token

La chiamata programmatica degli strumenti riduce il consumo di token in tre modi:

* **I risultati degli strumenti dalle chiamate programmatiche non vengono aggiunti al contesto di Claude** - solo l'output finale del codice lo è
* **L'elaborazione intermedia avviene nel codice** - filtraggio, aggregazione e altre trasformazioni non consumano token del modello
* **Più chiamate di strumenti in un'unica esecuzione del codice** - riduce l'overhead rispetto a turni del modello separati

Ad esempio, chiamare 10 strumenti direttamente utilizza circa 10 volte i token rispetto a chiamarli in modo programmatico e restituire un riepilogo.

Nelle valutazioni interne di Anthropic su un modello Claude di produzione:

* Su un benchmark di agente di project management con 75 strumenti, l'abilitazione della chiamata programmatica degli strumenti ha ridotto i token di input fatturati di circa il 38% senza alcuna variazione nell'accuratezza dei compiti.
* Su [τ²-bench](https://arxiv.org/abs/2506.07982) (domini aereo, retail e telecomunicazioni), dove ogni turno effettua una o due chiamate di strumenti sequenziali, la chiamata programmatica degli strumenti ha lasciato i punteggi invariati ed è costata circa l'8% in più. I flussi di lavoro sequenziali a chiamata singola non ne traggono beneficio.
* Nel traffico API di produzione, le richieste il cui array `tools` contiene da 10 a 49 definizioni di strumenti registrano risparmi tipici di token dal 20% al 40% con la chiamata programmatica degli strumenti abilitata.

I risparmi effettivi variano in base alla forma del carico di lavoro. Vedi [Quando usare la chiamata programmatica](https://platform.claude.com/docs/it/agents-and-tools/tool-use/programmatic-tool-calling#when-to-use-programmatic-calling).

## Utilizzo e prezzi

La chiamata programmatica degli strumenti utilizza gli stessi prezzi dell'esecuzione del codice. Consulta i [prezzi dell'esecuzione del codice](https://platform.claude.com/docs/it/agents-and-tools/tool-use/code-execution-tool#usage-and-pricing) per i dettagli.

<Note>
  Conteggio dei token per le chiamate programmatiche di strumenti: I risultati degli strumenti dalle invocazioni programmatiche non contano ai fini del tuo utilizzo di token di input/output. Contano solo il risultato finale dell'esecuzione del codice e la risposta di Claude.
</Note>

## Best practice

### Progettazione degli strumenti

* **Fornisci descrizioni dettagliate dell'output:** Poiché Claude deserializza i risultati degli strumenti nel codice, documenta il formato (struttura JSON e tipi dei campi)
* **Restituisci dati strutturati:** JSON o altri formati leggibili dalle macchine funzionano meglio per l'elaborazione programmatica
* **Mantieni le risposte concise:** Restituisci solo i dati necessari per minimizzare l'overhead di elaborazione

### Quando usare la chiamata programmatica

La chiamata programmatica degli strumenti scambia un piccolo overhead fisso (avvio del container, generazione dello script) con grandi risparmi sui token dei risultati degli strumenti e sui round trip del modello. Se questo scambio conviene dipende dalla forma del carico di lavoro.

**Adatta:**

* Operazioni fan-out o parallele su molti elementi (ad esempio, controllare 50 endpoint o cercare 20 record)
* Risultati di strumenti di grandi dimensioni che possono essere filtrati, aggregati o riepilogati prima di raggiungere il contesto di Claude
* Ricerca e recupero agentici, dove l'interrogazione iterativa e il filtraggio dei risultati dominano il flusso di lavoro

**Poco adatta:**

* Flussi di lavoro strettamente sequenziali in cui ogni chiamata dipende dal ragionamento di Claude sul risultato precedente, perché in quel caso lo script non può saltare il round trip del modello
* Un piccolo numero di chiamate di strumenti con risposte piccole, specialmente al primo turno di una conversazione, dove l'overhead del container e dello script può superare i risparmi
* Strumenti che richiedono un feedback immediato dell'utente tra le chiamate

Se non sei sicuro, misura i token di input fatturati con e senza `allowed_callers` su un campione rappresentativo del tuo traffico prima di abilitarla in modo esteso.

### Ottimizzazione delle prestazioni

* **Riutilizza i container** quando effettui più richieste correlate per mantenere lo stato
* **Raggruppa operazioni simili** in un'unica esecuzione del codice quando possibile

## Risoluzione dei problemi

### Problemi comuni

**`invalid_request_error` quando si imposta `tool_choice`**

* `tool_choice` non può indicare uno strumento il cui `allowed_callers` omette `"direct"`. Aggiungi `"direct"` agli `allowed_callers` di quello strumento, oppure rimuovi lo strumento da `tool_choice` e lascia che Claude lo invochi dal codice.

**Scadenza del container**

* Rispondi a ogni chiamata programmatica di strumento ben prima del timestamp `expires_at` della risposta in pausa. Il codice di Claude smette di attendere un risultato dopo circa 4 minuti, e i container inattivi vengono attualmente recuperati dopo circa 5 minuti.
* Considera di implementare un'esecuzione degli strumenti più veloce

**Risultato dello strumento non analizzato correttamente**

* Assicurati che il tuo strumento restituisca dati stringa che Claude possa deserializzare
* Fornisci una documentazione chiara del formato di output nella descrizione del tuo strumento

### Suggerimenti per il debugging

1. **Registra tutte le chiamate di strumenti e i risultati** per tracciare il flusso
2. **Controlla il campo `caller`** per confermare l'invocazione programmatica
3. **Monitora gli ID dei container** per garantire un corretto riutilizzo
4. **Testa gli strumenti in modo indipendente** prima di abilitare la chiamata programmatica

## Perché la chiamata programmatica degli strumenti funziona

Claude è addestrato su grandi quantità di codice, quindi presentare gli strumenti come funzioni Python chiamabili gli consente di sfruttare questo punto di forza:

* **Composizione degli strumenti:** Chiamate concatenate, cicli e condizionali sono normale flusso di controllo Python invece di una serie di round trip del modello
* **Elaborazione dei risultati:** Il codice di Claude filtra e aggrega output di strumenti di grandi dimensioni, o li scrive su file, e solo l'output finale entra nella finestra di contesto
* **Latenza:** Il modello non viene ricampionato tra le chiamate di strumenti all'interno di un'unica esecuzione del codice

## Implementazioni alternative

La chiamata programmatica degli strumenti è un pattern generalizzabile che può essere implementato anche sulla tua infrastruttura. Ecco come si confrontano gli approcci:

### Esecuzione diretta lato client

Fornisci a Claude uno strumento di esecuzione del codice e descrivi quali funzioni sono disponibili in quell'ambiente. Quando Claude invoca lo strumento con del codice, la tua applicazione lo esegue localmente dove quelle funzioni sono definite.

**Vantaggi:**

* Minima riprogettazione della tua applicazione
* Pieno controllo sull'ambiente e sulle istruzioni

**Svantaggi:**

* Esegue codice non attendibile al di fuori di una sandbox
* Le invocazioni degli strumenti possono essere vettori di code injection

**Usa quando:** La tua applicazione può eseguire in sicurezza codice arbitrario, vuoi l'implementazione più piccola possibile e l'offerta gestita di Anthropic non si adatta alle tue esigenze.

### Esecuzione sandbox autogestita

Stesso approccio dal punto di vista di Claude, ma il codice viene eseguito in un container sandbox con restrizioni di sicurezza (ad esempio, nessun traffico di rete in uscita). Se i tuoi strumenti richiedono risorse esterne, avrai bisogno di un protocollo per eseguire le chiamate degli strumenti al di fuori della sandbox.

**Vantaggi:**

* Chiamata programmatica degli strumenti sicura sulla tua infrastruttura
* Pieno controllo sull'ambiente di esecuzione

**Svantaggi:**

* Complessa da costruire e mantenere
* Richiede la gestione sia dell'infrastruttura che della comunicazione tra processi

**Usa quando:** La sicurezza è critica e la soluzione gestita di Anthropic non si adatta ai tuoi requisiti.

### Esecuzione gestita da Anthropic

La chiamata programmatica degli strumenti di Anthropic è una versione gestita dell'esecuzione sandbox con un ambiente Python opinionated ottimizzato per Claude. Anthropic gestisce la gestione dei container, l'esecuzione del codice e la comunicazione sicura per l'invocazione degli strumenti.

**Vantaggi:**

* Sicura e protetta per impostazione predefinita
* Abilitata con una definizione di strumento, senza infrastruttura da gestire
* Ambiente e istruzioni ottimizzati per Claude

Considera l'utilizzo della soluzione gestita di Anthropic se stai utilizzando la Claude API, [Claude Platform on AWS](https://platform.claude.com/docs/it/build-with-claude/claude-platform-on-aws) o [Microsoft Foundry](https://platform.claude.com/docs/it/build-with-claude/claude-in-microsoft-foundry). Su Microsoft Foundry, la chiamata programmatica degli strumenti richiede un [deployment Hosted on Anthropic](https://platform.claude.com/docs/it/build-with-claude/claude-in-microsoft-foundry#additional-features-not-supported-when-hosted-on-azure).

## Conservazione dei dati

La chiamata programmatica degli strumenti è costruita sull'infrastruttura di esecuzione del codice e utilizza gli stessi container sandbox. I dati dei container, inclusi gli artefatti di esecuzione e gli output, vengono conservati per un massimo di 30 giorni.

Per l'idoneità ZDR di tutte le funzionalità, consulta [API e conservazione dei dati](https://platform.claude.com/docs/it/manage-claude/api-and-data-retention).

## Passaggi successivi

<CardGroup cols={2}>
  <Card title="Streaming granulare degli strumenti" icon="bolt" href="https://platform.claude.com/docs/it/agents-and-tools/tool-use/fine-grained-tool-streaming">
    Trasmetti in streaming gli input degli strumenti senza buffering JSON lato server per applicazioni sensibili alla latenza.
  </Card>

  <Card title="Strumento di esecuzione del codice" icon="code" href="https://platform.claude.com/docs/it/agents-and-tools/tool-use/code-execution-tool">
    Esegui codice Python e bash in un container sandbox per analizzare dati, generare file e iterare sulle soluzioni.
  </Card>

  <Card title="Uso degli strumenti con Claude" icon="wrench" href="https://platform.claude.com/docs/it/agents-and-tools/tool-use/overview">
    Collega Claude a strumenti e API esterni. Scopri dove vengono eseguiti gli strumenti, quando Claude li chiama e quale strumento si adatta al tuo compito.
  </Card>

  <Card title="Definisci gli strumenti" icon="hammer" href="https://platform.claude.com/docs/it/agents-and-tools/tool-use/define-tools">
    Specifica gli schemi degli strumenti, scrivi descrizioni efficaci e controlla quando Claude chiama i tuoi strumenti.
  </Card>
</CardGroup>
