# ¿Qué es la orquestación de agentes de IA? Lo difícil es el estado compartido y los handoffs

> Canonical: https://vxi.me/es/posts/ai-agent-orchestration-after-assistants/
> Locale: es-es
> Published: 2026-03-30
> Updated: 2026-10-07
> Markdown: https://vxi.me/es/posts/ai-agent-orchestration-after-assistants.md

Si solo utilizas un agente, la mayoría de los problemas de coordinación son bastante sencillos. Le das una tarea, herramientas, dejas que ejecute pruebas y revisas el resultado. Los problemas serios suelen empezar cuando Codex, Claude Code, Cursor y varios workers automáticos empiezan a tocar el mismo repositorio.

En ese momento los primeros fallos no suelen tener que ver con qué modelo es más inteligente. Son fallos normales de colaboración. Claude supone que Codex todavía no ha empezado y edita el mismo archivo. Se ha configurado una tarea programada, así que otro agente lo interpreta como prueba de que la tarea ya se ejecutó. Se envió una petición por chat, pero el receptor nunca aceptó realmente la responsabilidad. Un agente trabajó desde un commit antiguo y el siguiente continuó como si ese estado siguiera siendo actual.

Añadir otro orquestador no resuelve mágicamente estos problemas. El routing responde a una pregunta: ¿quién debe recibir la siguiente tarea? El trabajo multiagente fiable necesita una segunda capa: **quién es responsable ahora, qué estado es canónico, si el handoff fue realmente aceptado, si el entorno asignado dispone de la capacidad necesaria y quién verificó que el trabajo terminó.**

Un ejemplo útil es el [central message board de microcredit-agent-testbed](https://github.com/scottonchain/microcredit-agent-testbed/issues/15). El proyecto coordina Hermes, Claude Code y un carril Codex/ChatGPT mediante un issue público y un world model canónico. El dominio no es lo interesante. Lo interesante es el protocolo: una petición no equivale a ownership aceptado, una programación no es prueba de ejecución y una configuración correcta no demuestra que una ejecución posterior haya terminado bien.

Eso me hizo replantear cómo describo Agent Orchestration. Antes me centraba sobre todo en repartir trabajo entre roles especializados. Ahora creo que eso deja fuera la capa en la que la orquestación se convierte en ingeniería de verdad: **el routing es solo el punto de entrada; el estado compartido y los handoffs explícitos son lo que hace fiable el sistema.**

## La orquestación empieza por ownership, no por añadir más agentes

La guía actual de OpenAI sobre [Orchestration and handoffs](https://developers.openai.com/api/docs/guides/agents/orchestration) hace una distinción importante. En un patrón, un especialista recibe un handoff y asume la responsabilidad de la siguiente parte de la interacción. En otro, un manager mantiene la responsabilidad sobre el resultado final y llama a especialistas como herramientas.

La diferencia importa porque responde a una pregunta que muchos sistemas multiagente dejan borrosa: **¿quién es responsable del resultado actual?**

Si el manager sigue siendo responsable, el especialista se comporta más como una función. Realiza un trabajo acotado y devuelve un resultado. Si ocurre un handoff, el control cambia de verdad. Muchos sistemas de agentes se vuelven desordenados porque existe delegación a nivel de código, mientras que el ownership sigue implícito en el estado. Todo el mundo puede ver que “alguien está trabajando en ello”, pero nadie puede responder con seguridad quién es responsable en este momento.

Un workflow de programación sencillo podría verse así:

~~~text
issue
  -> triage agent
  -> implementation agent
  -> review agent
~~~

Parece limpio hasta que haces preguntas operativas. Una vez que el implementation agent acepta la tarea, ¿puede el triage agent seguir editando el mismo alcance? ¿El review agent es solo lectura o puede parchear código directamente? ¿DONE significa que la tarea terminó o únicamente que el implementation agent dejó de trabajar? Si el review falla, ¿volvemos a WORKING o creamos una nueva petición?

Si esas reglas viven únicamente dentro de prompts, el sistema acaba dependiendo de que los agentes entiendan aproximadamente el proceso esperado. Prefiero un contrato de coordinación muy pequeño. Un handoff debería hacer explícitos, como mínimo: request id, sender, receiver, owner, deliverable, source revision, dependencies, acceptance test, required capability, fallback y estado actual.

No se trata de convertir el trabajo con agentes en otro Jira. Se trata de eliminar estados ambiguos que, de otro modo, habría que reconstruir leyendo el historial de conversación.

El modelo de estados que acabé usando es deliberadamente pequeño:

~~~text
REQUESTED
  -> ACKNOWLEDGED
  -> WORKING
  -> DONE
  -> VERIFIED
~~~

Lo importante no son las cinco etiquetas. Lo importante es que el sistema no puede saltarse su significado.

Enviar un mensaje solo demuestra REQUESTED. ACKNOWLEDGED debería exigir que el receptor lo acepte. Crear un job programado no demuestra que el trabajo haya llegado a DONE. Que un agente diga “terminado” puede mover la tarea a DONE, pero VERIFIED debería exigir output de tests, un diff, logs o alguna otra evidencia concreta.

Puede sonar conservador, pero cuando hay varios agentes activos en realidad aligera el sistema. Un nuevo worker ya no tiene que releer una conversación larga para adivinar qué ocurrió. Puede consultar el estado canónico y los receipts más recientes.

## Convertí estas reglas en un pequeño validador

Un protocolo sirve de poco si solo existe como prosa, así que construí un experimento first-party en Content Lab. No ejecuté código del repositorio de terceros mencionado arriba. Utilicé fixtures sintéticos para probar las propias reglas de coordinación.

La primera parte fue un validador del contrato de coordinación. Creé deliberadamente estados incorrectos comunes: dos agentes reclamando ownership activo sobre el mismo scope; una tarea marcada DONE sin acknowledgement del receptor; un handoff ligado a una source revision obsoleta; una tarea que requiere capacidad de merge asignada a un entorno que solo dispone de read/write; finalización sin evidencia de verificación; una acción externa duplicada mientras otra petición sigue activa; y una tarea superseded que continúa marcada como activa.

Los ocho casos de fixture se comportaron como se esperaba.

Esto no demuestra que la tasa de colisiones en producción haya bajado, y no lo presentaría así. Lo que sí demuestra es algo más modesto y más útil: **muchos fallos que parecen problemas de inteligencia del agente son en realidad errores deterministas de coordinación que pueden comprobarse fuera del modelo.**

El mismatch de capacidades es un buen ejemplo. Es fácil decir “este agente tiene acceso a GitHub”, pero leer, editar, hacer push, merge, deploy, acceder a secrets y enviar mensajes externos no son la misma capacidad. Que una sesión interactiva pueda hacer push no significa que un worker programado en otro entorno pueda hacer lo mismo.

Por eso cada vez evito más un flag ambiguo de has-access. La tarea debería declarar qué capacidades necesita y el entorno de ejecución debería declarar qué capacidades tiene de verdad.

La documentación actual de [subagents de Claude Code](https://code.claude.com/docs/en/sub-agents) apunta en la misma dirección. Los subagents tienen contexto aislado y pueden disponer de herramientas y permisos restringidos; los worktrees permiten aislar cambios del repositorio. La guía también deja claro que los subagents son especialmente útiles para exploración independiente, aislamiento de herramientas o trabajos que pueden devolver un resultado acotado. Cuando varias fases necesitan compartir mucho contexto y mantener un intercambio constante, puede ser mejor conservar el trabajo en una sesión principal. Multi-agent no es automáticamente mejor. Es más útil allí donde las fronteras ya son reales.

El segundo experimento probó el replay de receipts.

Modelé un log append-only de eventos que avanza desde REQUESTED hasta VERIFIED y después probé transiciones inválidas. REQUESTED -> WORKING fue rechazado porque “se envió una petición” no significa “el receptor la aceptó”. REQUESTED -> DONE fue rechazado porque programar o disparar trabajo no es prueba de ejecución. También se rechazó un ACKNOWLEDGED escrito por alguien distinto del receptor y un VERIFIED sin evidencia.

Los siete checks de replay pasaron. Y, más importante, después de borrar el estado derivado, el estado final VERIFIED pudo reconstruirse únicamente a partir del event log.

Esto importa en workflows de agentes de larga duración. Si el estado solo existe dentro de un chat, la compresión de contexto, una nueva sesión o una máquina diferente pueden convertir el siguiente paso en una adivinanza. Si los receipts de request, acknowledgement, completion y verification son duraderos, el siguiente agente no tiene que confiar en un resumen. Puede leer hechos.

## GitHub funciona bien como control plane, pero no como base de datos de runtime

Para equipos pequeños y desarrolladores independientes, GitHub resulta sorprendentemente útil para esta capa de coordinación.

No porque GitHub sea una plataforma de orquestación, sino porque ya tiene varias propiedades que necesita un control plane. El estado está versionado. Los cambios tienen autor y timestamp. Los commits aportan revisiones. Issues y PRs pueden contener evidencia. Los archivos del repositorio son legibles directamente por herramientas como Codex y Claude Code. No necesitas necesariamente un backend dedicado de orquestación desde el primer día; fijar el estado canónico en un repositorio ya resuelve una gran clase de problemas entre sesiones.

Mi propio Content Lab funciona así. El topic activo, el Dossier activo, el comando anterior, el siguiente comando y el estado del lifecycle se persisten. El historial del Dossier avanza de DISCOVERED a SCORED, RESEARCHING y READY_FOR_TEST en lugar de confiar en que una ventana de chat recuerde dónde se detuvo el workflow. Este experimento confirmó además que un active pointer, un next command explícito y un historial append-only funcionan bien juntos dentro del mismo flujo respaldado por GitHub.

Aun así, no pondría todos los detalles de runtime en Git. Locks de alta frecuencia, leases de milisegundos, colas de mensajes, tokens temporales y credenciales sensibles no son el tipo de datos para el que Git está pensado. GitHub es mejor para hechos duraderos que deben sobrevivir a las sesiones y seguir siendo auditables.

Yo lo separo en dos capas:

~~~text
runtime state
  -> execution locks, streams, short-lived messages, transient state

canonical coordination state
  -> owner, revision, handoff, receipt, evidence, final decision
~~~

La primera capa puede vivir en una base de datos, cola o sesión SDK. La segunda debería seguir teniendo sentido días después, cuando otro agente necesite comprender qué ocurrió realmente.

La documentación actual de OpenAI sobre [Running agents](https://developers.openai.com/api/docs/guides/agents/running-agents) trata igualmente el estado como una decisión explícita de continuidad: puedes gestionar el historial tú mismo, usar sesiones, emplear continuidad administrada en servidor o reanudar ejecuciones interrumpidas. La guía de [observability del Agents SDK](https://developers.openai.com/api/docs/guides/agents/integrations-observability) registra model calls, tool calls, handoffs y guardrails. Refuerza el mismo punto: **tanto el execution state como el estado auditable necesitan diseño deliberado; los prompts por sí solos no bastan.**

## Lo primero que añadiría es una cadena de evidencia

Sigo de acuerdo con un principio de la versión anterior de este artículo: si un agente puede completar una tarea de forma fiable, no la dividas entre cinco agentes solo para que la arquitectura parezca más sofisticada. La propia guía de OpenAI también recomienda empezar con un solo agente cuando sea posible e introducir especialistas cuando el aislamiento de capacidades, las políticas, la claridad del prompt o la legibilidad del trace realmente lo justifiquen.

Pero una vez que ya hay varios agentes implicados, hoy añadiría estado compartido antes de lo que lo hacía antes.

No un supervisor más complicado. No una jerarquía planner-reviewer por puro gusto arquitectónico. Solo algunos hechos que no pueden permanecer ambiguos: quién controla este scope ahora, si el receptor confirmó realmente la tarea, en qué revisión se basa, qué capacidades tiene el entorno de ejecución, qué evidencia respalda DONE y si el historial de eventos puede reconstruir después la secuencia real.

Esta capa no es llamativa. No hará que una demo parezca más inteligente. Con el tiempo, sin embargo, importa más que añadir otro agente.

El fallo más peligroso de un sistema multiagente no siempre es que un modelo tome una mala decisión. Puede ocurrir que cada decisión local sea razonable por separado mientras el estado global ya es falso. Un agente cree que nadie ha empezado. Otro cree que ya terminó. Una automation supone que un schedule ya se ejecutó. Un reviewer verifica una revisión antigua. Cada paso puede sonar plausible y, aun así, todo el workflow puede estar equivocado.

Por eso, cuando alguien me pregunta ahora qué es realmente Agent Orchestration, ya no me detengo en “varios agentes trabajando juntos”.

Lo describiría así: **organizar tareas, estado, permisos y evidencia en un workflow que no dependa de adivinar.**

El routing decide quién recibe el siguiente paso. Ownership indica quién es responsable ahora. Un handoff transporta contexto y límites. Un receipt demuestra que el receptor realmente aceptó. Los límites de capacidades evitan asignar trabajo a un entorno que no puede ejecutarlo. Los traces y la evidencia hacen que el estado final pueda explicarse después.

Si estás introduciendo Coding Agents más profundamente en proyectos reales, el artículo relacionado [Cómo separé AGENTS.md, Skills y CI cuando CLAUDE.md creció demasiado](/es/posts/claude-md-agents-md-skills-ci/) cubre la capa anterior: dónde deberían vivir las reglas. Este artículo es la siguiente capa: cuando empieza a trabajar más de un agente, **¿cómo comparten una única versión fiable de la realidad?**
