La chiamata programmatica degli strumenti consente a Claude di scrivere codice che chiama i tuoi strumenti in modo programmatico all'interno di un container di code execution (esecuzione del codice), anziché richiedere round trip attraverso il modello per ogni invocazione dello 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. Sui benchmark di ricerca agentica come BrowseComp e DeepSearchQA, che testano la ricerca web multi-step 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% di token di input in meno (vedi 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, inserendo migliaia di voci di spesa nel contesto 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.
Per un'analisi più approfondita dei costi di inferenza e di contesto che la chiamata programmatica degli strumenti affronta, consulta Advanced tool use.
Questa funzionalità richiede che lo strumento di esecuzione del codice sia abilitato.
Questa funzionalità non è idonea per Zero Data Retention (ZDR). I dati vengono conservati secondo la politica di conservazione standard della funzionalità.
La chiamata programmatica degli strumenti richiede code_execution_20260120 o versioni successive, supportato sui seguenti modelli:
| Modello |
|---|
| Claude Fable 5 (claude-fable-5) |
| Claude Mythos 5 (claude-mythos-5) |
| Claude Opus 4.8 (claude-opus-4-8) |
| Claude Opus 4.7 (claude-opus-4-7) |
| Claude Opus 4.6 (claude-opus-4-6) |
| Claude Sonnet 5 (claude-sonnet-5) |
| Claude Sonnet 4.6 (claude-sonnet-4-6) |
| Claude Opus 4.5 (claude-opus-4-5-20251101) |
| Claude Sonnet 4.5 (claude-sonnet-4-5-20250929) |
Per la matrice completa delle versioni dello strumento di esecuzione del codice, consulta la tabella di compatibilità dei modelli dello strumento di esecuzione del codice. La chiamata programmatica degli strumenti è disponibile sull'API di Claude, su Claude Platform on AWS e su Microsoft Foundry. Su Microsoft Foundry, la chiamata programmatica degli strumenti richiede un deployment Hosted on Anthropic. Attualmente non è disponibile su Amazon Bedrock o Google Cloud.
Ecco un esempio in cui Claude interroga programmaticamente un database più volte e aggrega i risultati:
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-4-8",
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)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 in modo che il codice possa terminare.
Quando configuri uno strumento per essere chiamabile dall'esecuzione del codice e Claude decide di utilizzare quello strumento:
tool_useQuesto approccio è particolarmente utile per:
Gli strumenti che consentono un caller di esecuzione del codice sono 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. 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>"})).
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_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 codiceSia "code_execution_20260120" che "code_execution_20260521" sono accettati in allowed_callers e sono intercambiabili: una richiesta che utilizza una delle due versioni dello strumento di esecuzione del codice soddisfa gli strumenti che elencano uno dei due caller. I blocchi di risposta contrassegnano sempre il caller come code_execution_20260120 indipendentemente dalla versione dichiarata nella richiesta.
Scegli ["direct"] oppure ["code_execution_20260120"] per ogni strumento anziché abilitare entrambi, poiché questo fornisce indicazioni più chiare a Claude su come utilizzare al meglio lo strumento.
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.
caller nelle risposteOgni blocco tool use include un campo caller che indica come è stato invocato:
Invocazione diretta (uso degli strumenti tradizionale):
{
"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_20260120",
"tool_id": "srvtoolu_abc123"
}
}Il tool_id è l'id del blocco server_tool_use di esecuzione del codice che ha effettuato la chiamata, così puoi abbinare ogni tool_use programmatico all'esecuzione del codice che lo ha prodotto.
La chiamata programmatica degli strumenti utilizza gli stessi container dell'esecuzione del codice:
container, insieme a un timestamp expires_atexpires_at ti indica quanto tempo rimane al container. I container inattivi vengono attualmente recuperati dopo circa 5 minuti, e nessun container può essere riutilizzato oltre 30 giorni dopo la sua creazione.Mentre il codice di Claude è in attesa di un risultato programmatico dello strumento, la chiamata in sospeso va in timeout dopo circa 4 minuti e genera un TimeoutError all'interno del codice. Restituisci ogni risultato dello strumento ben prima del timestamp expires_at sulla risposta in pausa. Vedi Scadenza del container durante la chiamata allo strumento.
Ecco come funziona un flusso completo di chiamata programmatica degli strumenti:
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.
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.
La forma della richiesta è identica all'esempio di Avvio rapido: 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 in questo flusso di lavoro utilizzano il messaggio utente "Query customer purchase history from the last quarter and identify our top 5 customers by revenue".
Claude scrive codice che chiama il tuo strumento. L'API si mette in pausa 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": "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"
}Invia l'intera cronologia della conversazione più il risultato del tuo strumento. Tre dettagli sono importanti in questa richiesta:
tool_result. Vedi Restrizioni di formattazione dei messaggi.container dalla risposta in pausa. L'API rifiuta una continuazione che ha chiamate programmatiche agli strumenti in sospeso ma nessun ID del container.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.response = client.messages.create(
model="claude-opus-4-8",
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)Il codice riprende da dove si era fermato ed elabora il tuo risultato. Ogni risposta di continuazione 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 ripeti il Passaggio 3 con un tool_result per ogni chiamata programmatica in sospeso in un unico messaggio utente.
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: [{'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"
}Claude può scrivere codice che elabora più elementi in modo efficiente:
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:
Claude può interrompere l'elaborazione non appena i criteri di successo sono soddisfatti:
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 remainingpath = "/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)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)Quando l'esecuzione del codice chiama uno strumento:
{
"type": "tool_use",
"id": "toolu_abc123",
"name": "query_database",
"input": { "sql": "<sql>" },
"caller": {
"type": "code_execution_20260120",
"tool_id": "srvtoolu_xyz789"
}
}Il risultato del tuo 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 agli strumenti sono soddisfatte e il codice è completato:
{
"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 | Dove appare | Descrizione | Soluzione |
|---|---|---|---|
invalid_tool_input | error_code sul 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 |
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" all'allowed_callers di quello strumento, oppure rimuovi lo strumento da tool_choice e lascia che Claude lo invochi dal codice |
Se il risultato del tuo strumento non arriva entro circa 4 minuti, la chiamata in sospeso genera un TimeoutError all'interno del codice in esecuzione di Claude. Claude vede l'errore in stderr e in genere riprova la chiamata:
{
"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:
expires_at nelle risposteSe il tuo strumento restituisce un errore:
{
"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.
strict: true non sono supportati con la chiamata programmaticatool_choicedisable_parallel_tool_use: true non è supportato con la chiamata programmaticaGli strumenti personalizzati il cui input_schema contiene un $ref ricorsivo (un ciclo di riferimento, 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 tale strumento causa il fallimento della richiesta con un 400 invalid_request_error il cui messaggio contiene Circular $ref detected. Lo stesso schema è accettato per la chiamata diretta agli strumenti.
Per aggirare questo problema, esegui una delle seguenti operazioni:
allowed_callers (o impostandolo su ["direct"]). Altri strumenti nella stessa richiesta possono comunque utilizzare la chiamata programmatica.description del livello più interno, oppure sostituisci la proprietà ricorsiva con un semplice {"type": "object"} la cui description spiega la forma prevista.I seguenti strumenti non possono essere chiamati in modo programmatico:
Quando rispondi alle chiamate programmatiche agli strumenti, ci sono requisiti di formattazione rigorosi:
Risposte solo con tool result: Se ci sono chiamate programmatiche agli strumenti 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 degli strumenti.
Non valido - Non è possibile includere testo quando si risponde a chiamate programmatiche agli strumenti:
{
"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 degli strumenti quando si risponde a chiamate programmatiche agli strumenti:
{
"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 programmatiche agli strumenti (esecuzione del codice). Per le normali chiamate agli strumenti lato client, puoi includere contenuto di testo dopo i risultati degli strumenti.
Contenuto del tool result solo testo: Il content di ogni tool_result che risponde a una chiamata programmatica deve essere una stringa o blocchi text. I tipi di blocco di contenuto immagine, documento e altri vengono rifiutati.
Le chiamate programmatiche agli strumenti sono soggette agli stessi limiti di velocità delle normali chiamate agli strumenti. Ogni chiamata a uno strumento dall'esecuzione del codice conta come un'invocazione separata.
Quando implementi strumenti definiti dall'utente che verranno chiamati in modo programmatico:
La chiamata programmatica degli strumenti riduce il consumo di token in tre modi:
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:
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.
La chiamata programmatica degli strumenti utilizza gli stessi prezzi dell'esecuzione del codice. Consulta i prezzi dell'esecuzione del codice per i dettagli.
Conteggio dei token per le chiamate programmatiche agli strumenti: i risultati degli strumenti dalle invocazioni programmatiche non contano ai fini dell'utilizzo dei token di input/output. Contano solo il risultato finale dell'esecuzione del codice e la risposta di Claude.
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.
Adatto:
Poco adatto:
Se non sei sicuro, misura i token di input fatturati con e senza allowed_callers su un campione rappresentativo del tuo traffico prima di abilitarlo ampiamente.
invalid_request_error quando si imposta tool_choice
tool_choice non può indicare uno strumento il cui allowed_callers omette "direct". Aggiungi "direct" all'allowed_callers di quello strumento, oppure rimuovi lo strumento da tool_choice e lascia che Claude lo invochi dal codice.Scadenza del container
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.Risultato dello strumento non analizzato correttamente
caller per confermare l'invocazione programmaticaClaude è addestrato su grandi quantità di codice, quindi presentare gli strumenti come funzioni Python chiamabili gli consente di sfruttare questo punto di forza:
La chiamata programmatica degli strumenti è un pattern generalizzabile che può anche essere implementato sulla tua infrastruttura. Ecco come si confrontano gli 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 del codice, la tua applicazione lo esegue localmente dove quelle funzioni sono definite.
Vantaggi:
Svantaggi:
Usa quando: La tua applicazione può eseguire in sicurezza codice arbitrario, desideri l'implementazione più piccola e l'offerta gestita di Anthropic non soddisfa le tue esigenze.
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 agli strumenti al di fuori della sandbox.
Vantaggi:
Svantaggi:
Usa quando: La sicurezza è critica e la soluzione gestita di Anthropic non soddisfa i tuoi requisiti.
La chiamata programmatica degli strumenti di Anthropic è una versione gestita dell'esecuzione sandbox con un ambiente Python opinionato ottimizzato per Claude. Anthropic gestisce la gestione dei container, l'esecuzione del codice e la comunicazione sicura delle invocazioni degli strumenti.
Vantaggi:
Considera di utilizzare la soluzione gestita di Anthropic se stai utilizzando l'API di Claude, Claude Platform on AWS o Microsoft Foundry. Su Microsoft Foundry, la chiamata programmatica degli strumenti richiede un deployment Hosted on Anthropic.
La chiamata programmatica degli strumenti è costruita sull'infrastruttura di esecuzione del codice e utilizza gli stessi container sandbox. I dati del container, inclusi gli artefatti di esecuzione e gli output, vengono conservati per un massimo di 30 giorni.
Per l'idoneità ZDR su tutte le funzionalità, consulta API e conservazione dei dati.
Trasmetti in streaming gli input degli strumenti senza buffering JSON lato server per applicazioni sensibili alla latenza.
Esegui codice Python e bash in un container sandbox per analizzare dati, generare file e iterare sulle soluzioni.
Connetti Claude a strumenti e API esterni. Scopri dove vengono eseguiti gli strumenti, quando Claude li chiama e quale strumento si adatta al tuo compito.
Specifica gli schemi degli strumenti, scrivi descrizioni efficaci e controlla quando Claude chiama i tuoi strumenti.
Was this page helpful?