De forma predeterminada, Claude puede llamar a varias herramientas en una sola respuesta. Esta página explica cómo ejecutar esas llamadas, cómo formatear el historial de mensajes para que el paralelismo siga funcionando y cómo deshabilitar el uso de herramientas en paralelo cuando lo necesites. Para el flujo de una sola llamada, consulta Manejar llamadas a herramientas.
Cuando Claude llama a herramientas, la respuesta tiene un stop_reason de tool_use y puede contener varios bloques tool_use en un solo turno del asistente. Cómo ejecutas esas llamadas es tu decisión. La API no prescribe un orden de ejecución: puedes ejecutar las llamadas de forma concurrente (Promise.all, asyncio.gather), secuencialmente en el orden en que aparecen, o en cualquier combinación que se adapte a tus herramientas.
Elige la estrategia según lo que hagan tus herramientas. Las operaciones independientes y de solo lectura suelen ser seguras para ejecutarse en paralelo y así reducir la "latency" (latencia). Las herramientas con efectos secundarios, estado compartido o requisitos de orden podrían ejecutarse mejor de forma secuencial.
Sea cual sea la estrategia que uses, devuelve un tool_result por cada bloque tool_use, todos juntos en el siguiente mensaje de usuario. Asocia cada resultado con su llamada mediante tool_use_id, y coloca todos los bloques tool_result antes de cualquier contenido de texto en ese mensaje. Consulta Manejar llamadas a herramientas para ver las reglas completas de formato. Si decides no ejecutar una llamada en particular (por ejemplo, porque ejecutaste el lote secuencialmente y una llamada anterior falló), devuelve igualmente un tool_result para ella con is_error: true y una breve explicación.
{
"type": "tool_result",
"tool_use_id": "toolu_02",
"is_error": true,
"content": "Not executed: the preceding write_file call failed."
}Usa el Tool Runner para la mayoría de las aplicaciones: el Tool Runner del SDK maneja las respuestas con múltiples llamadas a herramientas y formatea los resultados por ti, para que no tengas que escribir este manejo tú mismo. Usa el patrón manual de esta página cuando necesites control directo sobre cómo se ejecutan las llamadas, como agrupamiento personalizado, ordenamiento o manejo de errores.
El siguiente script envía una solicitud que debería activar llamadas a herramientas en paralelo, verifica que la respuesta las contenga y formatea los resultados de las herramientas para que el paralelismo siga funcionando. Ejecútalo con ANTHROPIC_API_KEY configurada en tu entorno:
client = Anthropic()
# Define las herramientas
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"],
},
},
]
# Conversación de prueba con llamadas a herramientas en paralelo
messages = [
{
"role": "user",
"content": "What's the weather in SF and NYC, and what time is it there?",
}
]
# Realiza la solicitud inicial
print("Requesting parallel tool calls...")
response = client.messages.create(
model="claude-opus-4-8", max_tokens=1024, messages=messages, tools=tools
)
# Verifica si hay llamadas a herramientas en paralelo
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 la ejecución de herramientas y formatea los resultados correctamente
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}
)
# Continúa la conversación con los resultados de las herramientas
messages.extend(
[
{"role": "assistant", "content": response.content},
{"role": "user", "content": tool_results}, # All results in one message!
]
)
# Obtén la respuesta final
print("\nGetting final response...")
final_response = client.messages.create(
model="claude-opus-4-8", 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 el formato
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")Las líneas de resumen al final reiteran las dos reglas de formato que mantienen el paralelismo funcionando: todos los resultados de herramientas se devuelven en un solo mensaje de usuario, y no aparece ningún contenido de texto antes de los resultados de herramientas en ese mensaje.
Los modelos Claude 4 realizan llamadas a herramientas en paralelo de forma predeterminada cuando una solicitud se beneficia de múltiples herramientas. Para todos los modelos, puedes aumentar la probabilidad de llamadas a herramientas en paralelo con prompts específicos:
El uso de herramientas en paralelo está activado de forma predeterminada. Para desactivarlo, establece disable_parallel_tool_use: true dentro del objeto tool_choice. No es un parámetro de nivel superior de la solicitud. El efecto depende del tipo de tool_choice.
Cuando el tipo de tool_choice es auto (el predeterminado), establecer disable_parallel_tool_use: true significa que Claude llama como máximo a una herramienta por respuesta. Claude aún puede responder en texto plano sin llamar a ninguna herramienta. Las líneas resaltadas son el único cambio respecto a una solicitud estándar de uso de herramientas:
client = Anthropic()
response = client.messages.create(
model="claude-opus-4-8",
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)Cuando el tipo de tool_choice es any o tool, establecer disable_parallel_tool_use: true significa que Claude llama exactamente a una herramienta. El siguiente ejemplo usa any. El mismo campo funciona con tool:
client = Anthropic()
response = client.messages.create(
model="claude-opus-4-8",
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)Si Claude no está realizando llamadas a herramientas en paralelo cuando se espera, revisa estos problemas comunes:
1. Formato incorrecto de resultados de herramientas
El problema más común es formatear incorrectamente los resultados de herramientas en el historial de conversación. Esto "enseña" a Claude a evitar las llamadas en paralelo.
Específicamente para el uso de herramientas en paralelo:
// 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 Manejar llamadas a herramientas para otras reglas de formato.
2. Prompts débiles
Los prompts predeterminados pueden no ser suficientes. Usa la indicación del sistema más fuerte de Maximizar el uso de herramientas en paralelo.
3. Medir el uso de herramientas en paralelo
Para verificar que las llamadas a herramientas en paralelo están funcionando:
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}")
# Debería ser > 1.0 si las llamadas paralelas funcionan4. Las llamadas en un lote parecen depender unas de otras
El orden de ejecución es tu elección. Si tus herramientas tienen dependencias de orden, ejecutar el lote secuencialmente y detenerse en el primer fallo es una estrategia válida: devuelve is_error: true para cualquier llamada que no ejecutaste. Si ejecutas en paralelo y una llamada falla porque su prerrequisito no se había completado, devuelve is_error: true con el mensaje de error natural. Claude volverá a emitir la llamada en el siguiente turno. Para reducir que aparezcan juntas llamadas dependientes, agrega esto a tu indicación del sistema: "Only batch tool calls that are independent of each other."
Usa la abstracción Tool Runner del SDK para manejar automáticamente el bucle agéntico, el encapsulamiento de errores y la seguridad de tipos.
Analiza bloques tool_use, formatea respuestas tool_result y maneja errores con is_error.
Especifica esquemas de herramientas, escribe descripciones efectivas y controla cuándo Claude llama a tus herramientas.
Was this page helpful?