Llamadas paralelas a herramientas: reduce la latencia
Claude puede solicitar varias herramientas en una sola respuesta, y tu código puede ejecutarlas juntas. El video revisa un sitio de trabajo para Meridian, una consultora de ingeniería ficticia. Ejecutar las llamadas a herramientas una por una toma 19.9 segundos, mientras que las llamadas paralelas a herramientas toman 10.8.
La demostración de este video se grabó en septiembre de 2026. Se ejecutó en Claude Sonnet 5 (claude-sonnet-5). Los resultados pueden diferir en modelos más nuevos.
Ejecutar las llamadas a herramientas una a la vez hace que tu usuario espere por cada una en su turno.
Cuando las herramientas que Claude solicita no dependen unas de otras, puede pedirlas todas en una sola respuesta. Claude hace esto por defecto, así que tu bucle tiene que manejar cada llamada a herramienta y enviar un resultado de vuelta por cada una.
Tres llamadas a herramientas en una sola respuesta
El uso de herramientas en paralelo significa que una respuesta contiene varios bloques tool_use.
Meridian tiene un script en Python que verifica si un sitio de trabajo está listo para el trabajo de campo. La verificación del sitio necesita tres búsquedas que no dependen unas de otras: el estado del proyecto, el clima en el sitio y el estado del permiso.
Aquí está la respuesta de Claude a la verificación del sitio de Meridian, con un bloque tool_use para cada herramienta que solicita.
{
"role": "assistant",
"stop_reason": "tool_use",
"content": [
{"type": "tool_use", "id": "toolu_01", "name": "get_project_status",
"input": {"job_number": "MEG-2026-0142"}},
{"type": "tool_use", "id": "toolu_02", "name": "get_site_weather",
"input": {"site": "Riverside"}},
{"type": "tool_use", "id": "toolu_03", "name": "get_permit_state",
"input": {"permit_id": "P-88213"}}
]
}El stop_reason de la respuesta es tool_use, y cada llamada a herramienta tiene su propio id.
Ejecuta cada llamada a herramienta
Un bucle escrito para una sola llamada a herramienta solo lee el primer bloque tool_use. Envía un solo resultado, dos llamadas a herramientas nunca obtienen el suyo, y la API rechaza la solicitud. Así que recopila cada bloque tool_use en la respuesta.
calls = [b for b in resp.content if b.type == "tool_use"]A continuación, ejecuta esas llamadas a herramientas al mismo tiempo. Cada búsqueda pasa la mayor parte de su tiempo esperando a otro sistema. Dale a cada una su propio hilo, y las tres esperas se superponen en lugar de sumarse.
with ThreadPoolExecutor() as pool:
results = list(pool.map(run_tool, calls))run_tool ejecuta una llamada a herramienta y devuelve su resultado, y las siguientes dos secciones lo construyen.
Ejecutar llamadas a herramientas al mismo tiempo suele ser seguro cuando solo leen datos y no dependen unas de otras, como las búsquedas de Meridian. Cuando las herramientas cambian datos, o deben ir en un orden establecido, podría ser mejor ejecutarlas una tras otra.
Envía cada resultado de vuelta en un solo mensaje
Una vez que las tres llamadas a herramientas se han ejecutado, Claude está esperando sus resultados. Cada resultado vuelve en un bloque tool_result, y su tool_use_id contiene el id de la llamada a herramienta que responde.
result = {"type": "tool_result", "tool_use_id": call.id}Cada bloque tool_use obtiene un tool_result, y todos van en el siguiente mensaje de usuario.
messages.append({"role": "assistant", "content": resp.content})
messages.append({"role": "user", "content": results})
Un mensaje de usuario con los tres resultados mantiene a Claude llamando herramientas en paralelo.
Si tu bucle envía cada resultado en su propio mensaje, la conversación se lee como si Claude hubiera pedido una herramienta a la vez. Esa es una razón común por la que Claude hace menos llamadas paralelas a herramientas.
Devuelve un resultado de error para una llamada a herramienta fallida
Ejecutar tres llamadas a herramientas a la vez significa que una puede fallar mientras las otras dos tienen éxito. Si tu código lanza una excepción y nada la captura, tu bucle se detiene, y los dos resultados buenos se pierden con él.
Así que envía el fallo de vuelta como un resultado. Es un tool_result ordinario con el mensaje de error como su content, más is_error: true. El mensaje debe decir qué salió mal y qué debería intentar Claude a continuación.
try:
result["content"] = HANDLERS[call.name](**call.input)
except Exception as exc:
result["content"] = f"{call.name} failed: {exc}"
result["is_error"] = TrueHANDLERS es un diccionario que mapea nombres de herramientas a las funciones de Python que realizan el trabajo de cada herramienta. Cada función devuelve una cadena, porque el content de un tool_result es una cadena o una lista de bloques de contenido.
Arma el bucle completo
Los fragmentos anteriores encajan en el bucle de Meridian que se muestra a continuación. El script ya ha configurado client, tools, prompt y HANDLERS.
Puntos clave
- Ejecuta cada llamada a herramienta en una respuesta, y ejecútalas al mismo tiempo cuando no dependan unas de otras.
- Envía de vuelta un
tool_resultpor cada llamada a herramienta, y ponlos todos en un solo mensaje de usuario. - No envíes cada resultado en su propio mensaje, porque eso reduce el uso paralelo de herramientas.
- Envía un fallo de vuelta como resultado con
is_error: true, para que una llamada a herramienta fallida no detenga el bucle.