Saltar al contenido principal

19 · Orquestación en producción

Sistemas multi-agente

Roles, pipelines y verificación independiente, y cuándo un solo agente es la mejor respuesta.

12 minCaso de estudio: docket (se abre en una ventana nueva) · Tack (se abre en una ventana nueva)

Imaginemos un único con todas las herramientas y la tarea "implementa X, revisa que esté bien y verifica que los tests pasen". Aparecen cuatro problemas: el mismo agente que escribió el código decide si está bien (conflicto de intereses); cuando llega a revisar, su contexto está lleno de intentos fallidos (contexto contaminado); tiene permiso de escritura incluso mientras "revisa" (privilegio máximo todo el tiempo); y si el resultado es malo no sabemos si falló la planificación, la implementación o la verificación (fallas opacas).

Un reparte ese trabajo entre roles. Bien hecho, resuelve esos cuatro problemas. Mal hecho, multiplica el costo y agrega puntos de falla sin mejorar nada. Veamos cómo distinguir un caso del otro.

Dividir por rol

Pipeline              Orquestador-worker        Paralela
A ──► B ──► C             Orquestador           ┌─► B ─┐
                        ┌─────┼─────┐         A ┼─► C ─┼─► E
Con rework              ▼     ▼     ▼           └─► D ─┘
A ──► B ──► R ──► T     B     C     D
      ▲     │
      └─────┘

La elección no es estética. Un pipeline es fácil de razonar, trazar y reanudar tras un fallo. Un orquestador dinámico es flexible, pero más difícil de acotar en costo y de testear. El paralelismo reduce latencia solo si las subtareas son de verdad independientes (no escriben los mismos archivos).

Los roles clásicos para trabajo de código:

Rol Hace No debería poder
Lead planifica y delega editar código
Implementer escribe el cambio aprobar su propio trabajo
Reviewer lee el diff, pide cambios escribir ni ejecutar
Tester corre la suite, da PASS/FAIL editar archivos

El pod de docket

Lo central es cómo se hace cumplir cada rol. La plantilla del Reviewer dice "read-only", pero eso no es lo que lo hace read-only.

Prohibición declarativa Prohibición estructural
prompt: "no uses write" el registry no contiene write
el modelo ve la herramienta el modelo no la ve
un texto persuasivo puede convencerlo no hay nada que convencer
falla en silencio un intento deja "unknown tool" en la traza

Handoffs tipados

Concatenar toda la salida de un agente en el prompt del siguiente crece sin límite y mezcla ruido con señal. docket pasa un HandoffArtifact (src/docket/core/handoff.py), un modelo Pydantic que rechaza campos extra, con summary, files_changed, diff_ref y verdict. files_changed no lo declara el modelo: sale de git. Si un dato se puede obtener del mundo real, no se le pregunta al modelo. Cada rol tiene además un de para el handoff (token_budget en archetypes.py) y los campos se descartan en un orden fijo (DROP_ORDER) cuando no caben; el detalle está en Contexto, routing y costo.

Gates que el modelo no puede convencer

Un Implementer dice "listo, los tests pasan". ¿Cómo lo sabemos? Con un gate: una condición evaluada fuera del modelo.

Tres reglas generales salen de aquí:

  • Una salida ambigua es un fallo, no un éxito.
  • Los ciclos de corrección necesitan techo, o un Reviewer exigente y un Implementer incapaz iteran (y gastan) sin fin.
  • Prefiere evidencia mecánica a juicio del modelo. Si un comando puede decidir, que decida el comando; un Tester con modelo es para lo que un comando no puede verificar.

La verificación independiente significa que quien verifica no es quien produjo, no comparte su contexto y no tiene sus herramientas. Un Reviewer que puede escribir tiende a "arreglar" en vez de pedir cambios, y entonces nadie revisa lo que escribió. Además lee el diff, que puede contener texto hostil: lo que ese texto logre depende enteramente de las herramientas del Reviewer.

Cuándo un solo agente es mejor

Cada agente adicional agrega llamadas al modelo, latencia, un handoff donde se pierde información y un punto de falla. "Suena más avanzado" no es una razón.

Beneficio Costo
revisión independiente más llamadas, más latencia
mínimo privilegio por rol roles mal diseñados bloquean trabajo legítimo
contexto enfocado pérdida de información en cada handoff
fallas localizables más estados y más código de orquestación
gates estructurales modelos pequeños fallan el formato a menudo

La recomendación del README de docket coincide con la literatura seria: empieza con el pod mínimo y agrega Reviewer o Tester cuando un gate de calidad concreto justifique los turnos extra.

Tack: el equipo como frontera

Es otra forma legítima de dividir: el tablero decide qué trabajo existe y en qué orden; el harness decide cómo se hace. La frontera del "equipo" es el ítem.

Para CTOs

  • Exige una razón concreta para cada rol adicional: un gate que hoy falla o un privilegio que hoy sobra.
  • Verifica que los límites de rol estén en el código (registry, ), no en el prompt.
  • Pide un verifyCmd o equivalente mecánico antes de aceptar cualquier gate basado en la opinión de un modelo.
  • Decide dónde vive la frontera: orquestación dentro de tu runtime o delegación a un harness externo que trazas desde fuera.

Para llevar

  • Multi-agente resuelve conflicto de intereses, contexto contaminado y privilegio excesivo, a cambio de costo y coordinación.
  • Los roles se hacen cumplir quitando herramientas del registry, no con instrucciones en el prompt.
  • Los handoffs deben ser estructuras tipadas, con datos obtenidos del mundo real cuando sea posible.
  • Los gates mecánicos y los veredictos estrictamente parseados convierten una mala respuesta en una falla visible.
  • Empieza con el sistema mínimo y agrega roles solo cuando una necesidad medida lo pida.

Comprueba lo aprendido

¿Por qué quitar `write` del registry del Reviewer es más fuerte que prohibirlo en su prompt?

Porque el modelo nunca ve la herramienta, así que ningún texto puede convencerlo de usarla, y un intento queda registrado como herramienta desconocida. Una instrucción en el prompt depende de la obediencia del modelo.

¿Qué hace docket si el Reviewer escribe `APPROVE` en una línea y `REQUEST-CHANGES` en otra?

parse_verdict lo trata como no parseable, porque hay dos valores distintos, y un veredicto no parseable bloquea el avance igual que un rechazo.

¿Cuándo es preferible un solo agente?

Cuando no hay un gate ni un límite de privilegio concreto que justifique otro rol, o cuando las subtareas comparten mucho contexto y dependen entre sí. En esos casos, más agentes agregan costo y handoffs con pérdida sin mejorar el resultado.