L'invocazione programmatica di strumenti consente a Claude di scrivere codice che chiama i tuoi strumenti in modo programmatico all'interno di un contenitore di esecuzione del codice, piuttosto che richiedere round trip attraverso il modello per ogni invocazione di strumento. Questo riduce la 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 finestra di contesto del modello.
L'invocazione programmatica di strumenti è attualmente in beta pubblica.
Per utilizzare questa funzione, aggiungi l'intestazione beta "advanced-tool-use-2025-11-20" alle tue richieste API.
Questa funzione richiede che lo strumento di esecuzione del codice sia abilitato.
L'invocazione programmatica di strumenti è disponibile sui seguenti modelli:
| Modello | Versione dello strumento |
|---|---|
Claude Opus 4.5 (claude-opus-4-5-20251101) | code_execution_20250825 |
Claude Sonnet 4.5 (claude-sonnet-4-5-20250929) | code_execution_20250825 |
L'invocazione programmatica di strumenti è disponibile tramite l'API Claude e Microsoft Foundry.
Ecco un semplice esempio in cui Claude interroga programmaticamente un database più volte e aggrega i risultati:
curl https://api.anthropic.com/v1/messages \
--header "x-api-key: $ANTHROPIC_API_KEY" \
--header "anthropic-version: 2023-06-01" \
--header "anthropic-beta: advanced-tool-use-2025-11-20" \
--header "content-type: application/json" \
--data '{
"model": "claude-sonnet-4-5",
"max_tokens": 4096,
"messages": [
{
"role": "user",
"content": "Query sales data for the West, East, and Central regions, then tell me which region had the highest revenue"
}
],
"tools": [
{
"type": "code_execution_20250825",
"name": "code_execution"
},
{
"name": "query_database",
"description": "Execute a SQL query against the sales database. Returns a list of rows as JSON objects.",
"input_schema": {
"type": "object",
"properties": {
"sql": {
"type": "string",
"description": "SQL query to execute"
}
},
"required": ["sql"]
},
"allowed_callers": ["code_execution_20250825"]
}
]
}'Quando configuri uno strumento per essere richiamabile dall'esecuzione del codice e Claude decide di utilizzare quello strumento:
tool_useQuesto approccio è particolarmente utile per:
Gli strumenti personalizzati vengono convertiti in funzioni Python asincrone per supportare le chiamate parallele degli strumenti. Quando Claude scrive codice che chiama i tuoi strumenti, utilizza await (ad es., result = await query_database("<sql>")) e include automaticamente la funzione wrapper asincrona appropriata.
Il wrapper asincrono è omesso dagli esempi di codice in questa documentazione per chiarezza.
allowed_callersIl campo allowed_callers specifica quali contesti possono invocare uno strumento:
{
"name": "query_database",
"description": "Execute a SQL query against the database",
"input_schema": {...},
"allowed_callers": ["code_execution_20250825"]
}Valori possibili:
["direct"] - Solo Claude può chiamare questo strumento direttamente (predefinito se omesso)["code_execution_20250825"] - Richiamabile solo dall'interno dell'esecuzione del codice["direct", "code_execution_20250825"] - Richiamabile sia direttamente che dall'esecuzione del codiceConsigliamo di scegliere ["direct"] o ["code_execution_20250825"] per ogni strumento piuttosto che abilitare entrambi, in quanto ciò fornisce una guida più chiara a Claude su come utilizzare al meglio lo strumento.
caller nelle risposteOgni blocco di utilizzo dello strumento include un campo caller che indica come è stato invocato:
Invocazione diretta (utilizzo tradizionale dello strumento):
{
"type": "tool_use",
"id": "toolu_abc123",
"name": "query_database",
"input": {"sql": "<sql>"},
"caller": {"type": "direct"}
}Invocazione programmatica:
{
"type": "tool_use",
"id": "toolu_xyz789",
"name": "query_database",
"input": {"sql": "<sql>"},
"caller": {
"type": "code_execution_20250825",
"tool_id": "srvtoolu_abc123"
}
}Il tool_id fa riferimento allo strumento di esecuzione del codice che ha effettuato la chiamata programmatica.
L'invocazione programmatica di strumenti utilizza gli stessi contenitori dell'esecuzione del codice:
containerQuando uno strumento viene chiamato programmaticamente e il contenitore è in attesa del risultato dello strumento, devi rispondere prima che il contenitore scada. Monitora il campo expires_at. Se il contenitore scade, Claude potrebbe trattare la chiamata dello strumento come scaduta e ritentarla.
Ecco come funziona un flusso di invocazione programmatica di strumenti completo:
Invia una richiesta con esecuzione del codice e uno strumento che consente la chiamata programmatica. Per abilitare la chiamata programmatica, aggiungi il campo allowed_callers alla definizione dello strumento.
Fornisci descrizioni dettagliate del formato di output dello strumento nella descrizione dello strumento. Se specifichi che lo strumento restituisce JSON, Claude tenterà di deserializzare ed elaborare il risultato nel codice. Più dettagli fornisci sullo schema di output, meglio Claude può gestire la risposta in modo programmatico.
response = client.beta.messages.create(
model="claude-sonnet-4-5",
betas=["advanced-tool-use-2025-11-20"],
max_tokens=4096,
messages=[{
"role": "user",
"content": "Query customer purchase history from the last quarter and identify our top 5 customers by revenue"
}],
tools=[
{
"type": "code_execution_20250825",
"name": "code_execution"
},
{
"name": "query_database",
"description": "Execute a SQL query against the sales database. Returns a list of rows as JSON objects.",
"input_schema": {...},
"allowed_callers": ["code_execution_20250825"]
}
]
)Claude scrive codice che chiama il tuo strumento. L'API si interrompe e restituisce:
{
"role": "assistant",
"content": [
{
"type": "text",
"text": "I'll query the purchase history and analyze the results."
},
{
"type": "server_tool_use",
"id": "srvtoolu_abc123",
"name": "code_execution",
"input": {
"code": "results = await query_database('<sql>')\ntop_customers = sorted(results, key=lambda x: x['revenue'], reverse=True)[:5]\nprint(f'Top 5 customers: {top_customers}')"
}
},
{
"type": "tool_use",
"id": "toolu_def456",
"name": "query_database",
"input": {"sql": "<sql>"},
"caller": {
"type": "code_execution_20250825",
"tool_id": "srvtoolu_abc123"
}
}
],
"container": {
"id": "container_xyz789",
"expires_at": "2025-01-15T14:30:00Z"
},
"stop_reason": "tool_use"
}Includi la cronologia completa della conversazione più il risultato dello strumento:
response = client.beta.messages.create(
model="claude-sonnet-4-5",
betas=["advanced-tool-use-2025-11-20"],
max_tokens=4096,
container="container_xyz789", # Riutilizza il contenitore
messages=[
{"role": "user", "content": "Query customer purchase history from the last quarter and identify our top 5 customers by revenue"},
{
"role": "assistant",
"content": [
{"type": "text", "text": "I'll query the purchase history and analyze the results."},
{
"type": "server_tool_use",
"id": "srvtoolu_abc123",
"name": "code_execution",
"input": {"code": "..."}
},
{
"type": "tool_use",
"id": "toolu_def456",
"name": "query_database",
"input": {"sql": "<sql>"},
"caller": {
"type": "code_execution_20250825",
"tool_id": "srvtoolu_abc123"
}
}
]
},
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_def456",
"content": "[{\"customer_id\": \"C1\", \"revenue\": 45000}, {\"customer_id\": \"C2\", \"revenue\": 38000}, ...]"
}
]
}
],
tools=[...]
)L'esecuzione del codice continua ed elabora i risultati. Se sono necessarie ulteriori chiamate di strumenti, ripeti il Passaggio 3 fino a quando tutte le chiamate di strumenti non sono soddisfatte.
Una volta completata l'esecuzione del codice, Claude fornisce la risposta finale:
{
"content": [
{
"type": "code_execution_tool_result",
"tool_use_id": "srvtoolu_abc123",
"content": {
"type": "code_execution_result",
"stdout": "Top 5 customers by revenue:\n1. Customer C1: $45,000\n2. Customer C2: $38,000\n3. Customer C5: $32,000\n4. Customer C8: $28,500\n5. Customer C3: $24,000",
"stderr": "",
"return_code": 0,
"content": []
}
},
{
"type": "text",
"text": "I've analyzed the purchase history from last quarter. Your top 5 customers generated $167,500 in total revenue, with Customer C1 leading at $45,000."
}
],
"stop_reason": "end_turn"
}Claude può scrivere codice che elabora più elementi in modo efficiente:
# async wrapper omitted for clarity
regions = ["West", "East", "Central", "North", "South"]
results = {}
for region in regions:
data = await query_database(f"<sql for {region}>")
results[region] = sum(row["revenue"] for row in data)
# Process results programmatically
top_region = max(results.items(), key=lambda x: x[1])
print(f"Top region: {top_region[0]} with ${top_region[1]:,} in revenue")Questo modello:
Claude può interrompere l'elaborazione non appena vengono soddisfatti i criteri di successo:
# async wrapper omitted for clarity
endpoints = ["us-east", "eu-west", "apac"]
for endpoint in endpoints:
status = await check_health(endpoint)
if status == "healthy":
print(f"Found healthy endpoint: {endpoint}")
break # Stop early, don't check remaining# async wrapper omitted for clarity
file_info = await get_file_info(path)
if file_info["size"] < 10000:
content = await read_full_file(path)
else:
content = await read_file_summary(path)
print(content)# async wrapper omitted for clarity
logs = await fetch_logs(server_id)
errors = [log for log in logs if "ERROR" in log]
print(f"Found {len(errors)} errors")
for error in errors[-10:]: # Only return last 10 errors
print(error)Quando l'esecuzione del codice chiama uno strumento:
{
"type": "tool_use",
"id": "toolu_abc123",
"name": "query_database",
"input": {"sql": "<sql>"},
"caller": {
"type": "code_execution_20250825",
"tool_id": "srvtoolu_xyz789"
}
}Il risultato dello strumento viene passato al codice in esecuzione:
{
"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}, ...]"
}
]
}Quando tutte le chiamate di strumenti sono soddisfatte e il codice si completa:
{
"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": []
}
}| Errore | Descrizione | Soluzione |
|---|---|---|
invalid_tool_input | L'input dello strumento non corrisponde allo schema | Convalida il input_schema dello strumento |
tool_not_allowed | Lo strumento non consente il tipo di chiamante richiesto | Verifica che allowed_callers includa i contesti giusti |
missing_beta_header | Intestazione beta PTC non fornita | Aggiungi entrambe le intestazioni beta alla tua richiesta |
Se il tuo strumento impiega troppo tempo per rispondere, l'esecuzione del codice riceverà un TimeoutError. Claude lo vede in stderr e di solito ritenterà:
{
"type": "code_execution_tool_result",
"tool_use_id": "srvtoolu_abc123",
"content": {
"type": "code_execution_result",
"stdout": "",
"stderr": "TimeoutError: Calling tool ['query_database'] timed out.",
"return_code": 0,
"content": []
}
}Per prevenire i timeout:
expires_at nelle risposteSe il tuo strumento restituisce un errore:
# Fornisci informazioni sull'errore nel risultato dello strumento
{
"type": "tool_result",
"tool_use_id": "toolu_abc123",
"content": "Error: Query timeout - table lock exceeded 30 seconds"
}Il codice di Claude riceverà questo errore e può gestirlo in modo appropriato.
strict: true non sono supportati con la chiamata programmaticatool_choicedisable_parallel_tool_use: true non è supportato con la chiamata programmaticaI seguenti strumenti attualmente non possono essere chiamati programmaticamente, ma il supporto potrebbe essere aggiunto nelle versioni future:
Quando rispondi alle chiamate programmatiche degli strumenti, ci sono rigorosi requisiti di formattazione:
Risposte solo con risultati dello strumento: Se ci sono chiamate di strumenti programmatiche in sospeso in attesa di risultati, il tuo messaggio di risposta deve contenere solo blocchi tool_result. Non puoi includere alcun contenuto di testo, nemmeno dopo i risultati dello strumento.
// ❌ INVALID - Cannot include text when responding to programmatic tool calls
{
"role": "user",
"content": [
{"type": "tool_result", "tool_use_id": "toolu_01", "content": "[{\"customer_id\": \"C1\", \"revenue\": 45000}]"},
{"type": "text", "text": "What should I do next?"} // This will cause an error
]
}
// ✅ VALID - Only tool results when responding to programmatic tool calls
{
"role": "user",
"content": [
{"type": "tool_result", "tool_use_id": "toolu_01", "content": "[{\"customer_id\": \"C1\", \"revenue\": 45000}]"}
]
}Questa restrizione si applica solo quando rispondi alle chiamate di strumenti programmatiche (esecuzione del codice). Per le normali chiamate di strumenti lato client, puoi includere contenuto di testo dopo i risultati dello strumento.
Le chiamate programmatiche degli strumenti sono soggette agli stessi limiti di velocità delle normali chiamate di strumenti. Ogni chiamata di strumento dall'esecuzione del codice conta come una separata invocazione.
Quando implementi strumenti personalizzati che verranno chiamati programmaticamente:
L'invocazione programmatica di strumenti può ridurre significativamente il consumo di token:
Ad esempio, chiamare 10 strumenti direttamente utilizza ~10 volte i token di chiamarli programmaticamente e restituire un riepilogo.
L'invocazione programmatica di strumenti utilizza gli stessi prezzi dell'esecuzione del codice. Vedi i prezzi dell'esecuzione del codice per i dettagli.
Conteggio dei token per le chiamate programmatiche degli strumenti: I risultati dello strumento dalle invocazioni programmatiche non contano verso l'utilizzo dei token di input/output. Solo il risultato finale dell'esecuzione del codice e la risposta di Claude contano.
Buoni casi d'uso:
Casi d'uso meno ideali:
Errore "Tool not allowed"
"allowed_callers": ["code_execution_20250825"]Scadenza del contenitore
expires_at nelle risposteProblemi con l'intestazione beta
"advanced-tool-use-2025-11-20"Il risultato dello strumento non viene analizzato correttamente
caller per confermare l'invocazione programmaticaL'addestramento di Claude include un'ampia esposizione al codice, rendendolo efficace nel ragionare attraverso e concatenare le chiamate di funzioni. Quando gli strumenti vengono presentati come funzioni richiamabili all'interno di un ambiente di esecuzione del codice, Claude può sfruttare questa forza per:
Questo approccio abilita flussi di lavoro che sarebbero impraticabili con l'utilizzo tradizionale dello strumento, come l'elaborazione di file superiori a 1M token, consentendo a Claude di lavorare con i dati in modo programmatico piuttosto che caricare tutto nel contesto della conversazione.
L'invocazione programmatica di strumenti è un modello generalizzabile che può essere implementato al di fuori dell'esecuzione del codice gestito di Anthropic. Ecco una panoramica degli approcci:
Fornisci a Claude uno strumento di esecuzione del codice e descrivi quali funzioni sono disponibili in quell'ambiente. Quando Claude invoca lo strumento con il codice, la tua applicazione lo esegue localmente dove quelle funzioni sono definite.
Vantaggi:
Svantaggi:
Usa quando: La tua applicazione può eseguire in modo sicuro codice arbitrario, desideri una soluzione semplice e l'offerta gestita di Anthropic non si adatta alle tue esigenze.
Lo stesso approccio dal punto di vista di Claude, ma il codice viene eseguito in un contenitore sandbox con restrizioni di sicurezza (ad es., nessun egresso di rete). Se i tuoi strumenti richiedono risorse esterne, avrai bisogno di un protocollo per eseguire le chiamate di strumenti al di fuori della sandbox.
Vantaggi:
Svantaggi:
Usa quando: La sicurezza è critica e la soluzione gestita di Anthropic non si adatta ai tuoi requisiti.
L'invocazione programmatica di strumenti di Anthropic è una versione gestita dell'esecuzione sandbox con un ambiente Python orientato che è sintonizzato per Claude. Anthropic gestisce la gestione dei contenitori, l'esecuzione del codice e la comunicazione sicura dell'invocazione dello strumento.
Vantaggi:
Consigliamo di utilizzare la soluzione gestita di Anthropic se stai utilizzando l'API Claude.