En la primera parte conté por qué terminé construyendo un flujo multiagente en vez de seguir empujando todo dentro de una sola conversación. La idea seguía teniendo sentido: separar responsabilidades, usar modelos distintos según la fase y mantener aprobación humana antes de implementar me daba más orden, mejor coste y menos ruido.
Pero ahí todavía estaba resolviendo el problema conceptual.
Esta segunda etapa fue distinta. Ya no se trataba de defender la idea, sino de ejecutarla de verdad. Y fue ahí donde aparecieron los problemas que no se ven en un diagrama ni en una buena narrativa: permisos, sistemas de IA que no se comportan igual, procesos que necesitan una terminal interactiva real, configuración que envejece mal y decisiones de orquestación que en papel suenan bien, pero en la práctica no alcanzan.
El cambio más importante: dejé de pensar en un pipeline y empecé a pensar en un runtime
Creo que la mejor forma de explicar esta evolución es esta: agentflow dejó de ser solo una forma de organizar prompts, archivos y pasos, y empezó a convertirse en un runtime explícito.
Eso cambió bastante mi forma de verlo.
Antes la configuración describía más qué había que generar. Ahora describe cómo corre cada rol: qué proveedor usa, qué modelo, qué nivel de esfuerzo, qué sandbox y qué prompt lo gobierna. Ya no es solo una herramienta para “montar un flujo”, sino una base para ejecutar roles de verdad con más control.
Ese cambio es importante porque me hizo ver algo que antes no estaba tan claro: separar bien los roles no basta. También necesitas el runtime que haga viable esa separación.
La ejecución real fue la que mostró dónde estaba el hueco
El hallazgo más claro de esta etapa fue bastante simple y bastante brutal: los agentes no podían escribir archivos de forma autónoma.
No porque faltara diseño. El campo sandbox ya existía y la intención estaba bien planteada. El problema era más incómodo: el adaptador de Claude no estaba traduciendo esa intención a los flags reales del CLI. Entonces el sistema corría, pero se bloqueaba pidiendo permisos para cada escritura.
Ese fue uno de esos momentos que te obligan a aterrizar. Porque ahí entiendes que “el sistema corre” y “el sistema funciona” no son la misma cosa.
El fix fue directo, pero la lección fue más importante que el fix. Para Claude Code hubo que traducir workspace-write a --dangerously-skip-permissions y read-only a --permission-mode plan. Codex ya resolvía mejor ese lado con --sandbox workspace-write. OpenCode, en cambio, sigue teniendo una limitación más estructural porque su CLI no expone un flag equivalente.
Ese problema no lo descubres afinando prompts. Lo descubres ejecutando.
También me quedó claro que orquestar no es lo mismo que delegar
Otra cosa que esta etapa dejó muy clara fue que el orquestador que yo tenía en mente todavía no estaba cerrando bien la última milla.
En teoría, agentflow run ya existía y ya tenía una lógica de secuenciación. Pero en la práctica, cuando Claude Code, Codex u OpenCode participaban en una sesión real, ese comando no bastaba. Los bootstrap skills eran demasiado superficiales. Básicamente delegaban y ya. No daban contexto suficiente para decidir cuándo parar, qué pasos correr, cómo manejar el review loop o cuándo pedir aprobación humana.
Ahí fue cuando se me hizo evidente algo que ahora ya me parece obvio: no hay un solo modo correcto de orquestación.
El modo CLI tiene sentido para automatización, CI y ejecución determinista. Pero una sesión interactiva necesita otra cosa. Necesita que el agente tenga criterio para clasificar la tarea, presentar un plan, esperar aprobación antes de implementar y decidir cómo avanzar según el contexto. Intentar que un mismo mecanismo sirviera tanto para automatización y CI como para una sesión interactiva con criterio y aprobación humana generaba más fricción de la que resolvía.
No toda tarea merece el pipeline completo
Otra mejora que me parece realmente importante en esta etapa fue aterrizar por fin el classifier.
En la parte 1 ya estaba la intuición de que no todas las tareas deberían costar lo mismo. Pero todavía era más una tesis que una capacidad real del sistema.
Ahora sí hay un rol que clasifica la complejidad como small, medium o large, y eso cambia el flujo. Un cambio pequeño no tiene por qué pasar por toda la ceremonia. Una tarea mayor sí justifica pipeline completo, review loop y posibles ajustes de modelo. Además, si el proyecto viene de una configuración vieja y no tiene todavía ese rol, el sistema no se rompe: cae en un fallback heurístico y sigue funcionando.
Esto me gusta porque mueve la optimización al lugar correcto. No después de gastar tiempo y tokens, sino antes.
Y dicho más simple: no tiene sentido tratar un bug pequeño como si fuera una migración compleja.
Los proveedores no son intercambiables
También me ayudó mucho esta etapa para bajarme de una simplificación que en abstracto es tentadora: pensar que todos los proveedores de IA son más o menos lo mismo.
No lo son.
Cuando hablo de un proveedor de IA, me refiero al sistema externo que ejecuta una tarea concreta dentro del flujo. Puede ser Claude, Codex u otro. Es, básicamente, el servicio al que le delego trabajo en una fase del proceso.
Y cuando llevé esto a ejecución real, quedó claro que esos proveedores no se comportan todos igual. Cambian los permisos, la forma en que se integran, cómo manejan los procesos e incluso cómo esperan ejecutarse.
En algunos casos, además, no basta con lanzar un comando y esperar una respuesta. Hay herramientas que necesitan correr dentro de una terminal interactiva real, como si estuvieran abiertas directamente en consola. A eso normalmente se le llama TTY, pero dicho en lenguaje simple significa esto: la herramienta necesita una consola “de verdad” para funcionar bien.
Eso fue lo que me llevó a usar estrategias distintas según el proveedor. Para algunos casos funcionaba bien una ejecución basada en pipes. Para Codex, en cambio, terminé necesitando PTY real con node-pty, porque su interfaz puede fallar o quedarse colgada si no corre en una terminal interactiva de verdad.
Parece un detalle menor, pero no lo es. Porque trabajar con agentes no es solo trabajar con texto: también es trabajar con procesos, permisos, terminales y errores reales. Y si eso no se diseña bien, el sistema se siente frágil aunque la idea sea buena.
Varias mejoras útiles no fueron vistosas, pero sí necesarias
También hubo mejoras menos llamativas, pero bastante más importantes de lo que parecen.
Una fue dejar de depender de un testRunner rígido en el config. Ese tipo de campo envejece mal. Cambias el proyecto, cambias el runner o cambias el stack, y terminas cargando una instrucción vieja. Me pareció mucho mejor permitir que el tester lo detecte desde el propio proyecto cuando no está definido.
No son cambios vistosos, pero sí son de esos que hacen que una herramienta deje de sentirse rígida.
Todavía no todo está cerrado, pero ya estamos en el tipo correcto de problemas
No quiero contar esta etapa como si todo hubiera quedado perfecto, porque no sería verdad.
Todavía hay pendientes. La suite de tests ya pasa, pero todavía no cubre de forma profunda todo el contrato runtime-first, sobre todo la ejecución real de adapters, agent run y el classifier. La documentación ya está bastante más alineada con el runtime actual, pero OpenCode sigue teniendo una limitación real con el sandbox que no depende solo de agentflow.
Pero, sinceramente, esos ya me parecen problemas sanos.
Porque ya no estoy discutiendo si la idea tiene sentido. Ya no estoy en la etapa de justificar la tesis. Ahora estoy en la etapa de cerrar gaps concretos: compatibilidad, documentación, robustez y consistencia de ejecución.
Y prefiero mucho más estar ahí.
Lo que realmente me dejó esta parte 2
Si la parte 1 era sobre por qué un sistema multiagente tenía más sentido que una sola conversación gigante, esta parte 2 es sobre otra cosa: qué pasa cuando esa idea sale del papel y se encuentra con la realidad.
Ahí fue donde aparecieron los huecos de verdad: permisos, orquestación efectiva, complejidad, proveedores que no se comportan igual, procesos, defaults frágiles y trazas.
La idea original no se cayó. De hecho, para mí salió fortalecida.
Pero ahora la veo de forma más completa: una arquitectura multiagente no está lista solo porque se vea bien en el diseño. Está lista cuando puede ejecutar de verdad sin romperse en cosas básicas.
Cierre
La primera versión me enseñó a separar responsabilidades.
Esta segunda etapa me obligó a construir el runtime que hace viable esa separación.
Y la ejecución real me terminó enseñando lo más importante: entre “esto corre” y “esto funciona como debería” hay una distancia grande. Esa distancia no se cierra con más teoría. Se cierra ejecutando, observando dónde falla y corrigiendo con cambios concretos.
Eso, para mí, es lo que realmente cuenta de esta segunda parte.
Top comments (0)