Per impostazione predefinita, Claude può chiamare più strumenti in una singola risposta. Questa pagina spiega come eseguire quelle chiamate, come formattare la cronologia dei messaggi in modo che il parallelismo continui a funzionare e come disabilitare l'uso degli strumenti in parallelo quando necessario. Per il flusso a chiamata singola, consulta Gestire le chiamate agli strumenti.
Quando Claude chiama gli strumenti, la risposta ha uno stop_reason di tool_use e può contenere diversi blocchi tool_use in un singolo turno dell'assistente. Come eseguire quelle chiamate è una tua decisione. L'API non prescrive un ordine di esecuzione: puoi eseguire le chiamate in modo concorrente (Promise.all, asyncio.gather), in sequenza nell'ordine in cui appaiono, o in qualsiasi combinazione adatta ai tuoi strumenti.
Scegli la strategia in base a ciò che fanno i tuoi strumenti. Le operazioni indipendenti e di sola lettura sono generalmente sicure da eseguire in parallelo per una minore "latency" (latenza). Gli strumenti con effetti collaterali, stato condiviso o requisiti di ordinamento potrebbero essere eseguiti meglio in sequenza.
Qualunque strategia tu usi, restituisci un tool_result per ogni blocco tool_use, tutti insieme nel successivo messaggio utente. Abbina ogni risultato alla sua chiamata con tool_use_id e metti ogni blocco tool_result prima di qualsiasi contenuto testuale in quel messaggio. Consulta Gestire le chiamate agli strumenti per le regole di formattazione complete. Se scegli di non eseguire una particolare chiamata (ad esempio, perché hai eseguito il batch in sequenza e una chiamata precedente è fallita), restituisci comunque un tool_result per essa con is_error: true e una breve spiegazione.
{
"type": "tool_result",
"tool_use_id": "toolu_02",
"is_error": true,
"content": "Not executed: the preceding write_file call failed."
}Lo script seguente invia una richiesta che dovrebbe attivare chiamate agli strumenti in parallelo, verifica che la risposta le contenga e formatta i risultati degli strumenti in modo che il parallelismo continui a funzionare. Eseguilo con ANTHROPIC_API_KEY impostata nel tuo ambiente:
client = Anthropic()
# Definisci gli strumenti
tools = [
{
"name": "get_weather",
"description": "Get the current weather in a given location",
"input_schema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g. San Francisco, CA",
}
},
"required": ["location"],
},
},
{
"name": "get_time",
"description": "Get the current time in a given timezone",
"input_schema": {
"type": "object",
"properties": {
"timezone": {
"type": "string",
"description": "The timezone, e.g. America/New_York",
}
},
"required": ["timezone"],
},
},
]
# Conversazione di test con chiamate parallele agli strumenti
messages = [
{
"role": "user",
"content": "What's the weather in SF and NYC, and what time is it there?",
}
]
# Effettua la richiesta iniziale
print("Requesting parallel tool calls...")
response = client.messages.create(
model="claude-opus-5", max_tokens=1024, messages=messages, tools=tools
)
# Verifica la presenza di chiamate parallele agli strumenti
tool_uses = [block for block in response.content if block.type == "tool_use"]
print(f"\n✓ Claude made {len(tool_uses)} tool calls")
if len(tool_uses) > 1:
print("✓ Parallel tool calls detected!")
for tool in tool_uses:
print(f" - {tool.name}: {tool.input}")
else:
print("✗ No parallel tool calls detected")
# Simula l'esecuzione degli strumenti e formatta correttamente i risultati
tool_results = []
for tool_use in tool_uses:
if tool_use.name == "get_weather":
if "San Francisco" in str(tool_use.input):
result = "San Francisco: 68°F, partly cloudy"
else:
result = "New York: 45°F, clear skies"
else: # get_time
if "Los_Angeles" in str(tool_use.input):
result = "2:30 PM PST"
else:
result = "5:30 PM EST"
tool_results.append(
{"type": "tool_result", "tool_use_id": tool_use.id, "content": result}
)
# Continua la conversazione con i risultati degli strumenti
messages.extend(
[
{"role": "assistant", "content": response.content},
{"role": "user", "content": tool_results}, # All results in one message!
]
)
# Ottieni la risposta finale
print("\nGetting final response...")
final_response = client.messages.create(
model="claude-opus-5", max_tokens=1024, messages=messages, tools=tools
)
final_text = next(
block.text for block in final_response.content if block.type == "text"
)
print(f"\nClaude's response:\n{final_text}")
# Verifica la formattazione
print("\n--- Verification ---")
print(f"✓ Tool results sent in single user message: {len(tool_results)} results")
print("✓ No text before tool results in content array")
print("✓ Conversation formatted correctly for future parallel tool use")Le righe di riepilogo alla fine ribadiscono le due regole di formattazione che mantengono funzionante il parallelismo: ogni risultato degli strumenti viene restituito in un singolo messaggio utente e nessun contenuto testuale appare prima dei risultati degli strumenti in quel messaggio.
Claude 4 e i modelli successivi effettuano chiamate agli strumenti in parallelo per impostazione predefinita quando una richiesta beneficia di più strumenti. Per tutti i modelli, puoi aumentare la probabilità di chiamate agli strumenti in parallelo con prompting mirato:
L'uso degli strumenti in parallelo è attivo per impostazione predefinita. Per disattivarlo, imposta disable_parallel_tool_use: true all'interno dell'oggetto tool_choice. Non è un parametro di richiesta di primo livello. L'effetto dipende dal tipo di tool_choice.
Quando il tipo di tool_choice è auto (il valore predefinito), impostare disable_parallel_tool_use: true significa che Claude chiama al massimo uno strumento per risposta. Claude può comunque rispondere in testo semplice senza chiamare alcuno strumento. Le righe evidenziate sono l'unica modifica rispetto a una richiesta standard di uso degli strumenti:
client = Anthropic()
response = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
tools=[
{
"name": "get_weather",
"description": "Get the current weather in a given location",
"input_schema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g. San Francisco, CA",
}
},
"required": ["location"],
},
}
],
tool_choice={"type": "auto", "disable_parallel_tool_use": True},
messages=[
{
"role": "user",
"content": "What is the weather in San Francisco and New York?",
}
],
)
print(response.content)Quando il tipo di tool_choice è any o tool, impostare disable_parallel_tool_use: true significa che Claude chiama esattamente uno strumento. L'esempio seguente usa any. Lo stesso campo funziona con tool:
client = Anthropic()
response = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
tools=[
{
"name": "get_weather",
"description": "Get the current weather in a given location",
"input_schema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g. San Francisco, CA",
}
},
"required": ["location"],
},
}
],
tool_choice={"type": "any", "disable_parallel_tool_use": True},
messages=[
{
"role": "user",
"content": "What is the weather in San Francisco and New York?",
}
],
)
print(response.content)Se Claude non sta effettuando chiamate agli strumenti in parallelo quando previsto, verifica questi problemi comuni:
1. Formattazione errata dei risultati degli strumenti
Il problema più comune è formattare in modo errato i risultati degli strumenti nella cronologia della conversazione. Questo "insegna" a Claude a evitare le chiamate in parallelo.
Nello specifico per l'uso degli strumenti in parallelo:
// Wrong: separate user messages reduce parallel tool use
[
{"role": "assistant", "content": [tool_use_1, tool_use_2]},
{"role": "user", "content": [tool_result_1]},
{"role": "user", "content": [tool_result_2]} // Separate message
]
// Correct: one user message with all results maintains parallel tool use
[
{"role": "assistant", "content": [tool_use_1, tool_use_2]},
{"role": "user", "content": [tool_result_1, tool_result_2]} // Single message
]Consulta Gestire le chiamate agli strumenti per le altre regole di formattazione.
2. Prompting debole
Il prompting predefinito potrebbe non essere sufficiente. Usa il prompt di sistema più forte da Massimizzare l'uso degli strumenti in parallelo.
3. Misurare l'uso degli strumenti in parallelo
Per verificare che le chiamate agli strumenti in parallelo funzionino:
messages = [] # Message objects returned by client.messages.create across your run
tool_call_messages = [
msg for msg in messages if any(block.type == "tool_use" for block in msg.content)
]
total_tool_calls = sum(
len([block for block in msg.content if block.type == "tool_use"])
for msg in tool_call_messages
)
avg_tools_per_message = (
total_tool_calls / len(tool_call_messages) if tool_call_messages else 0.0
)
print(f"Average tools per message: {avg_tools_per_message}")
# Dovrebbe essere > 1.0 se le chiamate parallele funzionano4. Le chiamate in un batch sembrano dipendere l'una dall'altra
L'ordine di esecuzione è una tua scelta. Se i tuoi strumenti hanno dipendenze di ordinamento, eseguire il batch in sequenza e fermarsi al primo fallimento è una strategia valida: restituisci is_error: true per qualsiasi chiamata che non hai eseguito. Se esegui in parallelo e una chiamata fallisce perché il suo prerequisito non era stato completato, restituisci is_error: true con il messaggio di errore naturale. Claude riemetterà la chiamata al turno successivo. Per ridurre le chiamate dipendenti che appaiono insieme, aggiungi questo al tuo prompt di sistema: "Only batch tool calls that are independent of each other."
Usa l'astrazione Tool Runner dell'SDK per gestire automaticamente il loop agentico, il wrapping degli errori e la sicurezza dei tipi.
Analizza i blocchi tool_use, formatta le risposte tool_result e gestisci gli errori con is_error.
Specifica gli schemi degli strumenti, scrivi descrizioni efficaci e controlla quando Claude chiama i tuoi strumenti.
Was this page helpful?