El 90% de los AI Agents de GitHub Ejecutan Tool Calls Como si Fuera 1999
Uno tras otro. Esperando a que el anterior termine aunque no tengan ninguna dependencia entre sí.
Eso desperdicia entre un 47% y un 62% de la latencia — y no se arregla con un mejor modelo. Se arregla con un scheduler.
Los modelos ya emiten múltiples tool calls en una sola pasada de generación. GPT‑5.6, Claude y todos los frontier models de 2026 despachan lotes completos de llamadas a herramientas cada iteración del loop. El problema es que los frameworks de orquestación más populares las ejecutan en el orden en que llegan, una a una, como quien recorre un array con un for y espera a cada elemento.
*El error de diseño raíz no es el modelo. Es tratar el agent loop como una lista de tareas cuando es un grafo de dependencias. *
La sabiduría convencional asume que la calidad de un agente depende del modelo o del prompt. El dato del 47-62% demuestra que el cuello de botella está en la capa de orquestación: cómo se programan y se despachan las llamadas a herramientas, no en qué modelo las genera.
El Problema: Creéis que un Agent Loop es una Lista de Tareas
Tomad un agente de research típico. El modelo emite en una sola pasada tres tool calls:
- web_search("precios SaaS 2026 en España")
- query_database("SELECT id, mrr FROM clientes WHERE churned = true")
- read_file("docs/comparativa_2025.md")
Ninguna depende de la otra. Son tres ramas independientes.
¿Qué hace un orquestador secuencial ingenuo? Espera a que web_search termine. Espera a que query_database termine. Espera a que read_file termine.
En secuencial tardas la suma de los tres. En paralelo tardas el máximo de los tres.
Para un agente con 5 ramas independientes que cada una tarda 2 segundos: 10 segundos en secuencial, 2 en paralelo. El ahorro crece con el número de ramas independientes — y casi ningún flujo real es 100% secuencial.
❌ El anti-patrón (lo que generan el 90% de los frameworks por defecto):
Ese for serializa incluso llamadas completamente independientes. Es la fuente del 47-62% de latencia extra.
✅ El despacho paralelo con primitivas nativas:
asyncio.gather en Python, Promise.all en TypeScript. La misma idea. El modelo ya emitió el lote; el scheduler decide quién espera y quién no.
La Evidencia: Lo que Pasa Cuando No Orquestas
No me creáis a mí. Medidlo vosotros.
Antes de tocar nada, instrumentad vuestro loop actual con un wrapper de timing que registre el wall-clock por tool_call y por iteración completa:
Responded a esta pregunta: ¿cuántas de vuestras tool calls por iteración son realmente dependientes? En casi cualquier flujo real — research, extracción, e-commerce, atención al cliente — el ratio de ramas independientes está por encima del 50%.
Una nota de honestidad: las cifras del 90% y del 47-62% provienen de un análisis observacional del ecosistema de GitHub, no de un benchmark externo publicado. Tratadlas como hipótesis medibles. El harness de medición de arriba es vuestra herramienta de validación — replicad la medición en vuestro propio stack y comprobad el delta vosotros mismos.
El Framework: El Orquestador de 3 Fases
La corrección no vive en el modelo ni en el prompt. Vive en una capa de scheduling entre la salida del LLM y la ejecución. Lo llamo El Orquestador de 3 Fases, y en el fondo es un DAG disfrazado.
Fase 1: Secuenciación Obligada
Inventariad vuestras tools y clasificad sus dependencias. Para cada par de herramientas, responded a una pregunta: ¿la salida de una es entrada de la otra?
Si web_search alimenta parse_results, son secuencia obligada. Se ejecutan en orden, sin discusión. Modelar esto explícitamente ya aporta valor aunque no haya ni una sola llamada paralela: fuerza a hacer visible qué depende de qué en vez de asumirlo.
Fase 2: Fan-Out de Ramas Independientes
Los nodos sin aristas entre sí se lanzan en paralelo con asyncio.gather o Promise.all. Con timeouts por rama, para que una herramienta lenta no bloquee todo el bucle.
El paralelismo no es ilimitado. Es fan-out controlado: límites de concurrencia configurables y capas de espera si alguna rama toca el mismo rate limit.
Fase 3: Agregación y Orden Canónico
Aquí es donde el 90% de las implementaciones naive de paralelismo se rompen. Paralelizar cambia la semántica de error.
En secuencial, un fallo aborta el flujo limpiamente. En paralelo tienes fallos parciales, retries por rama y el problema crítico: inyectar resultados desordenados en el contexto del LLM.
La solución es un orden canónico determinista basado en el orden de aparición de las tool calls en el lote original. Ese es el orden que el modelo espera cuando le devolvéis el contexto — romperlo degrada la coherencia aunque todos los resultados sean correctos.
El manejo de fallos en ramas paralelas
Con return_exceptions=True en Python o Promise.allSettled en TypeScript, una rama que reviente no aborta las demás:
- Retry por rama, no por lote completo.
- Resultados parciales tolerados: si tres de cinco ramas responden, se devuelven las tres con una nota de fallo.
- Orden canónico de inyección para no romper la coherencia que el LLM espera.
La Analogía que lo Explica Todo
En scraping aprendí una lección que aplica a agents: el código es commodity; la capa operativa es el producto.
Cualquiera escribe una función con un decorador y llama a MCP.add_tool() — las definiciones de tools son commodity. Pero el bucle que decide qué se ejecuta en paralelo, qué se secuencia y cómo se agregan los resultados es la capa operativa que distingue un demo de un sistema en producción.
Los modelos no planifican ejecución eficiente. Emiten llamadas. Sin una capa de scheduling que clasifique dependencias, el modelo no tiene forma de forzar paralelismo — y el dato del 47-62% sugiere que tampoco los frameworks actuales lo hacen por defecto. El scheduling es responsabilidad del orquestador, no del modelo.
Esto conecta con lo que OpenAI ya empuja en 2026 con su Programmatic Tool Calling: escribir JavaScript para orquestar tools, ejecutar llamadas independientes en paralelo y procesar los outputs fuera del context window. El modelo se queda con lo que requiere inteligencia — aplicar juicio — y la capa operativa hace el scheduling.
Cómo Implementarlo Hoy en tu Stack
Paso 1 — Inventaría tus tools. Lista cada una y escribe sus dependencias explícitas. No las dejes implícitas en el prompt.
Paso 2 — Divide tu flujo en las 3 fases. Fase 1 con dependencias reales, Fase 2 con el fan-out, Fase 3 con la agregación determinista.
Paso 3 — Implementa el despacho paralelo con asyncio.gather o Promise.all. Timeouts por rama.
Paso 4 — Mide antes y después. Wall-clock por tool_call y por iteración completa. El delta frente a tu medición base es tu ahorro real — no el 47-62% teórico, sino el tuyo.
Paso 5 — Añade semántica de fallos. allSettled, retry por rama, resultados parciales y orden canónico de inyección.
Si trabajáis con SDKs como Claude Agent SDK, LangGraph o CrewAI, el patrón se integra igual: interceptad el lote de tool calls que emite el modelo y sustituid el dispatch por defecto por vuestro orquestador de 3 fases. No necesitáis cambiar de framework — necesitáis una capa de scheduling encima del que ya usáis.
La Conclusión Directa
El 90% de los agents de GitHub pierden entre 47% y 62% de su latencia en un error de diseño que no necesita un modelo mejor: necesita un scheduler.
Tratad el agent loop como lo que es: un grafo de dependencias, no un array. Orquestad en fases. Medid el delta en vuestro stack.
El modelo emite. El orquestador decide. Y esa capa de decisión es el producto real que os separa de un demo — la capa operativa que el resto del ecosistema sigue tratando como commodity.
Artículos relacionados
- Tool Orchestration en AI Agents: El Patrón de 3 Fases que Secuencia y Paraleliza Tool Calls sin Romper el Loop
- Tool Orchestration en AI Agents: El 90% Ejecuta Tool Calls Como si Fuera 1999
- El 95% de los AI Agents No Son Agents: Cómo Construir el 5% Que Realmente Funciona en 2026
- Tool Orchestration en AI Agents 2026: El 90% Ejecuta Tool Calls Como si Fuera 1999
- Tool Orchestration en AI Agents 2026: El 90% Ejecuta en Serie y se Deja un 47% de Latencia
---
¿Quieres recibir contenido como este cada semana? Suscríbete a mi newsletter

