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.
SKILL.md; en el resto va solo el cuerpo, que es lo que cambia.
| Patrón | Cuándo se usa |
|---|---|
| Pipeline | La tarea se parte en pasos fijos, conocidos de antemano |
| Enrutador | Entradas de tipos distintos que se atienden mejor por separado |
| Planificador-Ejecutor | Conviene revisar el plan antes de que se toque nada |
| Orquestador | Las subtareas no se conocen hasta ver el problema |
| Ejecutor-Revisor | Hay criterios claros y la crítica mejora el resultado |
| Adversarios | Interesa encontrar el fallo, no pulir el acabado |
| Razonador-Refutador | La causa de un fallo no está clara y conviene acertar antes de arreglar |
| Best-of-N | Los intentos salen muy distintos y verificar es barato |
| Human-in-the-loop | Hay acciones irreversibles o responsabilidad de por medio |
| Memoria persistente | El trabajo dura más que una sesión |
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.
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.
Ejemplo. Una funcionalidad nueva, de la petición al código. Como skill del proyecto, con su cabecera:
--- name: pipeline-funcionalidad description: Implementa una funcionalidad nueva por fases. Usar cuando se pida añadir algo que no existe todavía. --- Implementa la funcionalidad en cuatro pasos. No empieces uno hasta cerrar el anterior. 1. REQUISITOS: escribe en docs/specs/<nombre>/requirements.md qué tiene que pasar y cómo se comprueba. Para y espera el visto bueno. 2. DISEÑO: a partir de ese fichero, escribe design.md: ficheros que se tocan, contratos, modelo de datos. Para y espera el visto bueno. 3. TAREAS: parte el diseño en tareas de menos de una hora en tasks.md, cada una con su criterio de hecho. 4. CÓDIGO: implementa las tareas en orden. Después de cada una lanza los tests; si fallan, arregla antes de pasar a la siguiente. Si en el paso 3 o en el 4 descubres que el diseño estaba mal, vuelve al paso 2 y corrígelo antes de seguir.
Una primera llamada clasifica la entrada y la manda a la ruta adecuada: otro prompt, otro modelo u otra herramienta.
Los dos usos que de verdad aparecen:
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.
Ejemplo. Clasificar lo que llega antes de ponerse a trabajar:
Antes de tocar nada, clasifica la petición en una de estas rutas y di en
una línea cuál has elegido:
- BUG: algo que ya debería funcionar y no funciona.
-> Reproduce el fallo con un test que falle, arregla, comprueba que el
test pasa. No refactorices nada más por el camino.
- FUNCIONALIDAD: algo que no existe todavía.
-> Flujo completo: requisitos, diseño, tareas, código.
- CAMBIO MECÁNICO: renombrar, mover, subir una dependencia.
-> Hazlo y enseña el diff. Sin especificación.
- NO ENCAJA: si dudas entre dos rutas, o no es ninguna, pregunta.
No elijas por tu cuenta.
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.
Ejemplo. Un cambio que toca varios ficheros:
FASE 1, PLAN. No escribas código todavía. Lee el código afectado y escribe un plan con: - los ficheros que vas a tocar y qué cambia en cada uno - el orden de los cambios - lo que has descartado, y por qué - lo que no tienes claro, en forma de preguntas Para y espera a que apruebe el plan. FASE 2, EJECUCIÓN. Cumple el plan aprobado, y nada más que el plan. Si a mitad descubres que no se sostiene, para y dilo en lugar de improvisar otra solución por tu cuenta.
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.
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.
Ejemplo. Diseño, implementación y calidad, cada uno en su agente. Un subagente empieza de cero y no sabe nada de esta conversación, así que el encargo lleva dentro quién es y qué tiene que devolver:
Eres el orquestador: no escribes código, repartes el trabajo y unes el
resultado. Cada subagente que lances arranca en blanco, así que dile en
el propio encargo quién es, qué le das, qué tiene que devolver y qué no
puede tocar.
1. Lanza un subagente con este encargo:
"Eres el diseñador. Tienes el repositorio en solo lectura: no
escribes ni modificas nada. Dado este enunciado <enunciado>,
devuelve el enfoque, la lista de ficheros que hay que tocar y los
contratos entre las partes. No implementes."
2. Parte el diseño en trozos independientes y lanza un subagente por
cada trozo:
"Eres quien implementa <parte>. Este es el trozo de diseño que te
toca: <trozo>, y estos los contratos que tienes que respetar:
<contratos>. Implementa solo eso. No toques ficheros fuera de esta
lista: <ficheros>. Devuelve el diff y los tests que añadas."
3. Junta los resultados. Si dos se contradicen, resuélvelo tú y di cómo.
4. Sobre el resultado ya unido, lanza un subagente que no haya escrito
nada de esto:
"Eres el revisor de calidad de un código que no has escrito. Aquí
tienes el diff completo <diff> y los requisitos <requisitos>. Busca
requisitos sin cumplir, casos límite sin tratar y errores que se
tragan. Devuelve cada hallazgo como BLOQUEANTE o MENOR."
5. Si vuelve algún BLOQUEANTE, repite el punto 2 solo con la parte
afectada, añadiendo el hallazgo al encargo.
A cada subagente pásale el texto que necesita, nunca la conversación
entera: repartir el contexto es justamente para lo que sirve esto.
Un agente produce, otro distinto lo critica contra unos criterios, y se repite hasta que pase o hasta agotar las vueltas.
Es la capa 5 del harnés (tema 4) convertida en patrón. Funciona cuando se cumplen las dos condiciones:
Ejemplo. Uno programa y otro revisa. El revisor se lanza en ese momento y recibe en el encargo su papel y el material, porque no ha visto nada de lo anterior:
Implementa la tarea. Al terminar, di qué has hecho y qué has dejado
fuera a propósito.
Después, sin revisarlo tú, lanza un subagente con este encargo:
"Eres el revisor de este cambio, que no has escrito. Aquí tienes el
diff <diff> y el requisito que dice lo que tenía que hacer
<requisito>. Revisa en este orden:
1. ¿Hace lo que pide el requisito? Cítalo.
2. ¿Casos límite sin tratar: nulos, lista vacía, concurrencia?
3. ¿Errores que se tragan sin registrar?
4. ¿Los tests comprueban el comportamiento o la implementación?
Marca cada hallazgo como BLOQUEANTE o MENOR. No comentes estilo: de
eso se encarga el formateador. Si no encuentras nada, dilo; no
inventes hallazgos para justificar la revisión."
Arregla los BLOQUEANTES y lanza un revisor **nuevo** con el diff ya
corregido. Tres vueltas como máximo; a la tercera, para y resume lo que
queda abierto.
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:
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.
Ejemplo. Dos agentes defienden decisiones de arquitectura distintas. Cada uno recibe su papel al lanzarlo, y el papel es precisamente lo que los hace adversarios:
Hay que decidir si el envío de correos va dentro de la petición o a una cola. No lo decidas tú: monta el debate. Lanza un subagente: "Defiende que el envío vaya dentro de la petición. Explica cómo se implementa, qué cuesta y qué se rompe el día que haya diez veces más tráfico. Este es el código de hoy: <contexto>. No te cures en salud reconociendo las ventajas de la otra opción: tu trabajo es la mejor versión de esta." Lanza otro con el mismo encargo, cambiando la opción por la cola. Con las dos propuestas encima de la mesa, lanza un subagente por cada una: "Aquí tienes una propuesta de arquitectura <propuesta>. Tu único trabajo es encontrar el escenario concreto en el que falla: carga, fallo parcial, reintentos, despliegue, operación. No vale opinar ni pedir mejoras: hace falta el caso, con números si los hay." Y con todo eso, un último subagente que no haya participado: "Aquí tienes dos propuestas de arquitectura y los ataques que ha recibido cada una <material>. Decide una y escribe en docs/adr/ la decisión, el motivo y la opción descartada con su razón. Si las dos aguantan igual, dilo: entonces se elige la más fácil de deshacer."
Antes de arreglar nada, un agente escribe su razonamiento paso a paso —qué ha visto, qué deduce de ello y qué piensa hacer— y otro distinto busca el paso que no se sostiene. Solo cuando el razonamiento aguanta se toca el código.
Se parece a los dos anteriores, pero mira otra cosa y en otro momento:
| Revisor | Adversario | Refutador | |
|---|---|---|---|
| Pregunta | ¿Cumple los criterios? | ¿Por dónde falla? | ¿Se deduce esto de lo que hemos visto? |
| Mira | El resultado terminado | Una propuesta o una implementación | La explicación del problema |
| Cuándo | Después de hacerlo | Antes o después | Antes de tocar nada |
El fallo que evita es muy común: una solución impecable para un problema que no era el problema. El modelo ve un síntoma, se convence de una causa y la arregla con todo detalle. El Refutador hace las preguntas incómodas: ¿eso lo has comprobado o lo supones?, ¿de verdad se sigue de lo anterior?, ¿hay otra explicación para lo mismo?
Por qué gana el Refutador aunque tenga menos pruebas. Para que una explicación sea cierta tiene que cumplirse todo lo que exige; para que sea falsa basta con que falle una sola cosa. Por eso mil pistas a favor no pesan nada frente a un hecho que la hace imposible.
Por ejemplo, fallan 30 tests con NullPointerException dentro de PedidoService.calcularTotal(), y el Razonador concluye que el pedido llega sin cliente. El Refutador lee el código: el constructor de Pedido lanza una excepción si no recibe cliente, así que un pedido sin cliente nunca llega hasta ahí. La explicación es falsa, da igual cuántos tests fallen.
Qué pasa cuando gana. El trabajo no termina ahí: vuelve al Razonador, y lo que ha tumbado la explicación pasa a ser un hecho comprobado. Con esa pista nueva, el Razonador propone otra explicación —«el cliente nunca es nulo, así que el nulo sale de otro campo que usa calcularTotal(): el descuento, que solo se rellena cuando hay cupón»— y el Refutador intenta tumbarla también. Esta vez no puede: los 30 tests que fallan crean pedidos sin cupón y los que pasan, con cupón. Se repite hasta que una explicación aguanta, y solo entonces se arregla. Cada vuelta descarta una causa y deja un hecho más, así que el círculo se va cerrando.
Ejemplo. Encontrar la causa de un fallo antes de arreglarlo. El auditor se lanza en ese momento y no sabe nada del problema, así que el encargo lleva el contexto y el razonamiento:
Hay un fallo y no está claro de dónde viene. No toques código todavía.
FASE 1, RAZONAMIENTO. Escribe tres listas:
- HECHOS: lo que has visto de verdad: errores, trazas, qué tests
fallan y cuáles no. Solo lo comprobado.
- DEDUCCIONES: qué concluyes, un paso por línea, diciendo de qué hecho
sale cada uno.
- PLAN: qué cambiarías y qué esperas que pase después.
FASE 2, REFUTACIÓN. Sin revisarlo tú, lanza un subagente con este encargo:
"Eres un auditor de lógica. Aquí tienes el contexto del problema
<contexto> y un razonamiento sobre su causa <razonamiento>.
Comprueba solo esto:
1. ¿Se da algo por cierto sin haberlo comprobado?
2. ¿Hay algún paso que no se deduce del anterior?
3. ¿Hay otra causa que explique los mismos hechos y se ha pasado
por alto?
Puedes comprobar lo que haga falta sin modificar nada. No propongas
soluciones ni escribas código. Devuelve cada paso que no se sostiene
con la prueba que lo tumba, o 'RAZONAMIENTO SÓLIDO'."
FASE 3. Si vuelve algún fallo, añade sus pruebas a HECHOS, formula otra
explicación que las respete y lanza un auditor nuevo. Tres vueltas como
máximo; a la tercera, para y resume lo descartado y lo que queda abierto.
Con 'RAZONAMIENTO SÓLIDO', implementa el plan.
Más informnació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 |
Ejemplo. Tres diseños, y solo uno se implementa:
Diseña TRES soluciones distintas para esta tarea. Distintas de verdad: si las tres son la misma con otros nombres, vuelve a empezar. De cada una: el enfoque en cinco líneas, los ficheros que toca, qué se gana, qué se paga, y qué pasa el día que haya que añadir un proveedor más. Compáralas en una tabla contra estos criterios, por orden: 1. cumple el requisito 2. esfuerzo de implementación 3. lo que cuesta cambiarla dentro de un año 4. cuánto código nuevo mete en el proyecto Recomienda una, y di en qué caso cambiaría la recomendación. No implementes ninguna hasta que te diga cuál.
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:
Lo que pasa por una persona siempre: borrar datos, desplegar, mandar correos, gastar dinero, tocar producción. Todo lo que el historial no deshace.
Ejemplo. La persona aprueba la especificación antes de que empiece el diseño:
Escribe la especificación en requirements.md y PARA.
No empieces el diseño, no escribas código, no propongas el paso
siguiente. Termina el documento con dos listas:
- las decisiones que has tomado por tu cuenta porque el enunciado no
las decía (esta es la parte importante: es donde se cuela lo que yo
no quería)
- las preguntas que necesitas que conteste una persona
Sigo yo. Cuando te diga "aprobado", pasas al diseño. Cualquier otra
respuesta es una corrección de los requisitos.
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 |
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.
Ejemplo. Los ficheros que el agente lee al empezar y mantiene al terminar:
La memoria de este proyecto son ficheros. Antes de nada, lee:
.kiro/steering/ reglas que valen para todo el proyecto
docs/specs/<actual>/ requisitos, diseño y tareas de lo que hacemos
docs/adr/ decisiones ya tomadas, y por qué
Reglas:
- Si algo de lo que te digo contradice lo que hay escrito, gana lo
escrito y me avisas.
- Toda decisión que afecte a tareas futuras va a docs/adr/ el mismo día.
- Al terminar una tarea, márcala en tasks.md. La sesión siguiente
empieza leyendo ese fichero, no preguntándome por dónde ibas.
- Si un documento ha dejado de ser verdad, corrígelo en el mismo cambio
que lo desmiente. Nunca escribas encima dejando debajo la versión
vieja.
| 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 |
| Razonador-Refutador | Acertar con la causa antes de arreglar | Sobra si la causa era obvia | 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: