====== Patrones agénticos ====== Un patrón agéntico es una forma conocida de **conectar varias llamadas al modelo** para resolver algo que una sola llamada no resuelve bien. En el tema anterior vimos que el grafo es el mapa y el bucle es el camino; los patrones de aquí son los mapas que ya se sabe que funcionan. **Empieza por lo más simple que pueda funcionar.** Una llamada bien planteada con buen contexto resuelve la mayoría de las tareas. Cada patrón añade latencia, coste y sitios donde fallar, así que solo se sube de patrón cuando el anterior se queda corto de verdad, no porque quede mejor en el diagrama. ^ Patrón ^ Cuándo se usa ^ | [[#1_pipeline_prompt_chain|Pipeline]] | La tarea se parte en pasos fijos, conocidos de antemano | | [[#2_enrutador|Enrutador]] | Entradas de tipos distintos que se atienden mejor por separado | | [[#3_planificador-ejecutor|Planificador-Ejecutor]] | Conviene revisar el plan antes de que se toque nada | | [[#4_orquestador|Orquestador]] | Las subtareas no se conocen hasta ver el problema | | [[#5_ejecutor-revisor|Ejecutor-Revisor]] | Hay criterios claros y la crítica mejora el resultado | | [[#6_adversarios|Adversarios]] | Interesa encontrar el fallo, no pulir el acabado | | [[#7_best-of-n|Best-of-N]] | Los intentos salen muy distintos y verificar es barato | | [[#8_human-in-the-loop_hitl|Human-in-the-loop]] | Hay acciones irreversibles o responsabilidad de por medio | | [[#9_memoria_persistente|Memoria persistente]] | El trabajo dura más que una sesión | ---- ===== 1. Pipeline (prompt chain) ===== La tarea se parte en **pasos fijos** y la salida de cada uno es la entrada del siguiente. Entre paso y paso se pone una puerta que comprueba que lo producido sirve antes de seguir. start :paso 1; if (pasa la puerta) then (si) :paso 2; if (pasa la puerta) then (si) :paso 3; else (no) :corregir el paso 2; endif else (no) :corregir el paso 1; endif stop Es el patrón del //spec-driven development//: requisitos → diseño → tareas → código, con una aprobación en cada salto (tema 10). Cada paso ve un problema más pequeño y mejor acotado que el original, y por eso lo hace mejor. * **A favor**: cada paso es simple, verificable y depurable por separado. * **En contra**: latencia, y un error del paso 1 se arrastra hasta el final. De ahí que la puerta entre pasos sea obligatoria, no decorativa. * **Condición**: los pasos tienen que ser siempre los mismos. Si cambian según el problema, lo que hace falta es un orquestador. ---- ===== 2. Enrutador ===== Una primera llamada **clasifica** la entrada y la manda a la ruta adecuada: otro prompt, otro modelo u otra herramienta. start :clasificar la peticion; if (tipo) then (bug) :flujo de depuracion; elseif (tipo) then (funcionalidad nueva) :flujo completo de spec; else (otro) :ruta por defecto; endif stop Los dos usos que de verdad aparecen: * **Por especialidad**: un //bug// va al flujo de depuración; una funcionalidad nueva, al flujo de especificación completo. * **Por coste**: lo fácil al modelo barato, lo difícil al caro. El ahorro es grande y la calidad no baja, porque lo que se enruta mal es lo que estaba en la frontera. **Siempre tiene que haber ruta por defecto.** El fallo típico del enrutador no es equivocarse de ruta, es no tener ninguna para lo que no encaja en ninguna categoría. ---- ===== 3. Planificador-Ejecutor ===== Se separa **decidir qué hacer** de **hacerlo**. El planificador produce un plan escrito; el ejecutor lo cumple paso a paso. La ventaja es que el plan es un artefacto **revisable antes de que se toque una sola línea**, que es justo cuando corregir sale barato. Es también el patrón que explota el modo //Plan// de las herramientas del tema 3: el modelo caro planifica, uno más barato ejecuta lo ya decidido. * **Cuándo**: cambios que tocan varios ficheros, o donde el enfoque importa más que el teclear. * **Riesgo**: un plan malo contamina todo lo que viene detrás, y el ejecutor no suele darse cuenta porque su trabajo es obedecer. Por eso el plan se lee. * **Detalle práctico**: si el plan queda escrito en un fichero del repositorio, el ejecutor puede ir marcando lo hecho y una sesión nueva retoma por donde iba. ---- ===== 4. Orquestador ===== Un agente central mira el problema, **decide sobre la marcha en qué subtareas se parte**, se las reparte a trabajadores especializados y funde los resultados. start :orquestador: partir el trabajo; fork :trabajador A; fork again :trabajador B; fork again :trabajador C; end fork :orquestador: fundir resultados; stop La diferencia con el pipeline es **quién decide los pasos**: en el pipeline están escritos de antemano; aquí los decide el orquestador en tiempo de ejecución, al ver el caso concreto. En desarrollo con IA la ventaja que más se nota no es el paralelismo, es el **contexto**: cada trabajador arranca con su propia ventana limpia y solo con lo suyo, así que el orquestador puede abarcar un problema que no cabría en una sola conversación. * **A favor**: control centralizado, trazable y reproducible; subtareas en paralelo. * **En contra**: el orquestador es un punto único de fallo —si parte mal el trabajo al principio, todo lo de debajo sobra— y el coste se multiplica por el número de trabajadores. * **Lo difícil está en la fusión**: juntar resultados parciales que se contradicen es más trabajo del que parece al dibujarlo. ---- ===== 5. Ejecutor-Revisor ===== Un agente produce, **otro distinto** lo critica contra unos criterios, y se repite hasta que pase o hasta agotar las vueltas. start repeat :ejecutor: producir o corregir; :revisor: evaluar contra los criterios; backward:devolver con los comentarios; repeat while (aprobado) is (no) not (si) :entregar; stop Es la capa 5 del harnés (tema 4) convertida en patrón. Funciona cuando se cumplen las dos condiciones: - **Hay criterios claros** contra los que evaluar. Sin eso el revisor opina, y opinar no converge. - **La crítica mejora el resultado**, igual que a una persona le sirve que le revisen el código. El revisor tiene que ser **otro agente con el encargo explícito de buscar problemas**, y con límite de vueltas. Un modelo revisando su propia salida tiende a aprobarla; y sin tope de iteraciones, dos agentes se pueden pasar la tarde puliendo un detalle. ---- ===== 6. Adversarios ===== La vuelta de tuerca del anterior: el segundo agente no pule, **ataca**. Su encargo no es «¿está bien?» sino «encuentra el caso en el que esto se rompe». ^ ^ Revisor ^ Adversario ^ | Pregunta | ¿Cumple los criterios? | ¿Por dónde falla? | | Produce | Una lista de mejoras | Un contraejemplo concreto | | Termina cuando | Aprueba | No encuentra por dónde entrar | Dónde se usa de verdad: * **Contra la especificación**: buscar el requisito ambiguo, el caso que no se contempló, la contradicción entre dos apartados. Sale mucho más barato aquí que en producción. * **Contra la implementación**: generar los tests que la rompen, no los que la confirman. Emparejado con el //mutation testing// del tema 7, que mide exactamente eso. * **Contra la seguridad**: el papel de //red team//. El valor está en que el criterio de éxito de los dos agentes es **opuesto**, y eso impide el acuerdo cómodo al que llegan dos modelos con el mismo objetivo. ---- ===== 7. Best-of-N ===== Se lanza **el mismo encargo N veces en paralelo** —con temperatura alta o con modelos distintos— y se elige el mejor resultado. Sirve porque los intentos salen genuinamente distintos entre sí. Lo difícil no es generar: es **elegir**. Y de eso depende que el patrón valga o no valga nada: ^ Cómo se elige ^ Fiabilidad ^ | Verificador objetivo: compila, pasa los tests, mide mejor en el //benchmark// | Alta. Es el caso que interesa | | Un modelo juez compara las N salidas | Regular: hereda los sesgos del juez | | Una persona mira las N | Alta, pero no escala | * **Cuándo**: verificar es mucho más barato que generar, y un intento suelto falla a menudo. El caso claro en código es tener N implementaciones y quedarse con la que pasa la batería de tests. * **En contra**: cuesta N veces. Se reserva para el trozo difícil, no para todo el trabajo. ---- ===== 8. Human-in-the-loop (HITL) ===== No es «que alguien lo mire»: es **decidir en qué puntos concretos se para y se espera a una persona**. Los tres sitios donde tiene sentido poner la puerta: * **Aprobar el plan**, antes de que se escriba nada. El punto más rentable de todos: corregir aquí cuesta un párrafo. * **Aprobar la acción irreversible**, justo antes de ejecutarla. * **Aprobar la entrega**, antes de que salga de cara al cliente. Lo que pasa por una persona **siempre**: borrar datos, desplegar, mandar correos, gastar dinero, tocar producción. Todo lo que el historial no deshace. **La persona va en la puerta, no en cada paso.** Un flujo que pide confirmación de todo acaba aprobándose a ciegas, y eso es peor que no tener puerta: da la sensación de control sin el control. Las capas de abajo —límites, comprobaciones, revisión automática— están para reducir lo que llega al humano a lo que de verdad necesita criterio. ---- ===== 9. Memoria persistente ===== Un agente empieza de cero cada sesión. La memoria persistente es lo que le permite retomar el trabajo y acumular lo aprendido. Tres tipos, con papeles distintos: ^ Memoria ^ Qué guarda ^ Dónde vive ^ | **De trabajo** | El contexto de la tarea actual | La ventana de contexto. Se pierde al cerrar | | **Episódica** | Qué se hizo, qué se intentó y qué falló | El plan con lo hecho marcado, el historial de decisiones | | **Semántica** | Hechos estables del proyecto: convenciones, arquitectura, reglas | ''CLAUDE.md'', ''AGENTS.md'', ''.kiro/steering/'', los ADR | En desarrollo, la memoria que funciona son **ficheros dentro del repositorio**, no una base vectorial. Son legibles por una persona, van versionados, se revisan en el //pull request// y se corrigen a mano cuando dicen una tontería. Una base vectorial aporta cuando el volumen no cabe en ficheros; antes de eso es complejidad que solo estorba. Lo que hay que decidir explícitamente es la **política de actualización**: qué se escribe, cuándo y quién lo borra. Una memoria a la que solo se añade se pudre: acumula decisiones viejas que ya no valen, y el agente las sigue a rajatabla porque no sabe que caducaron. ---- ===== 10. Cómo elegir ===== ^ Patrón ^ Fuerte en ^ Su límite ^ Coste ^ | Pipeline | Pasos simples y verificables uno a uno | Los pasos son rígidos | Bajo | | Enrutador | Ahorro y especialización | Se equivoca al clasificar | Bajo | | Planificador-Ejecutor | Corregir cuando aún es barato | Un plan malo contamina todo | Medio | | Orquestador | Problemas grandes, contexto repartido | Punto único de fallo; la fusión | Alto | | Ejecutor-Revisor | Calidad con criterios claros | Sin criterios, no converge | Medio-alto | | Adversarios | Encontrar lo que falla | No mejora el acabado | Medio | | Best-of-N | Calidad cuando verificar es barato | Se paga N veces | Alto | | HITL | Responsabilidad y lo irreversible | El humano es el cuello de botella | Bajo, pero lento | | Memoria persistente | Trabajo que dura semanas | Se pudre sin mantenimiento | Bajo | Los patrones **se combinan**, y casi siempre se usan combinados. Las dos combinaciones que aparecen una y otra vez en desarrollo con IA: * **Planificador → HITL → Pipeline → Ejecutor-Revisor**: se planifica, una persona aprueba el plan, se ejecuta por fases y cada fase pasa por revisión. Es, punto por punto, lo que hacen los frameworks SDD del tema 11. * **Orquestador → trabajadores → Adversario**: se reparte el trabajo grande y al final un agente intenta romper el resultado unificado. ===== Fuentes ===== * [[https://dzone.com/articles/ai-agent-architectures-patterns-applications-guide|AI Agent Architectures: Patterns, Applications, and Implementation Guide]]