Herramientas de usuario

Herramientas del sitio


cursos:sdd:05-patrones-agenticos

¡Esta es una revisión vieja del documento!


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.

Cada patrón de esta página se le pide al agente con texto, y ese texto se deja escrito como una skill del proyecto (tema 2) para no reescribirlo cada vez. Los ejemplos de cada sección son eso: lo que hay que poner. El primero lleva la cabecera completa del SKILL.md; en el resto va solo el cuerpo, que es lo que cambia.
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
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
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

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.

paso 1pasa la puertasinopaso 2pasa la puertasinopaso 3corregir el paso 2corregir el paso 1

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.

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.

2. Enrutador

Una primera llamada clasifica la entrada y la manda a la ruta adecuada: otro prompt, otro modelo u otra herramienta.

clasificar la peticionbugtipoflujo de depuracionfuncionalidad nuevatipootroflujo completo de specruta por defecto

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.

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.

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.

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.

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.

orquestador: partir el trabajotrabajador Atrabajador Btrabajador Corquestador: fundir 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.

  • 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.

Ejemplo. Diseño, implementación y calidad, cada uno en su agente:

Eres el orquestador: no escribes código, repartes el trabajo y unes el
resultado.

1. Lanza un subagente DISEÑO con el enunciado. Que devuelva el enfoque,
   los ficheros afectados y los contratos. Solo lectura del repositorio.
2. Con ese diseño, lanza un subagente IMPLEMENTACIÓN por cada parte
   independiente, cada uno con su trozo del diseño y nada más.
3. Junta los resultados. Si dos se contradicen, resuélvelo tú y di cómo.
4. Lanza un subagente CALIDAD sobre el resultado ya unido: tests, casos
   límite, errores sin tratar. No puede ser ninguno de los que escribió
   ese código.
5. Si calidad devuelve bloqueantes, vuelve al punto 2, pero solo con la
   parte afectada.

A cada subagente pásale lo que necesita y nada más: no le des la
conversación entera.

5. Ejecutor-Revisor

Un agente produce, otro distinto lo critica contra unos criterios, y se repite hasta que pase o hasta agotar las vueltas.

ejecutor: producir o corregirrevisor: evaluar contra los criteriossiaprobadonodevolver con los comentariosentregar

Es la capa 5 del harnés (tema 4) convertida en patrón. Funciona cuando se cumplen las dos condiciones:

  1. Hay criterios claros contra los que evaluar. Sin eso el revisor opina, y opinar no converge.
  2. 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.

Ejemplo. Uno programa y otro revisa:

Trabajáis dos por turnos sobre la misma tarea.

EJECUTOR: implementa la tarea. Al terminar, di qué has hecho y qué has
dejado fuera a propósito.

REVISOR (otro agente, que no ha escrito ese código): revisa el diff
contra estos criterios y en este orden:
  1. ¿Hace lo que pedía 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. El estilo no se comenta:
de eso ya se encarga el formateador.

El ejecutor arregla los BLOQUEANTES y vuelve a pasar por revisión.
Tres vueltas como máximo; a la tercera, para y resume lo que queda
abierto.

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.

Ejemplo. Dos agentes defienden decisiones de arquitectura distintas:

Hay que decidir si el envío de correos va dentro de la petición o a una
cola.

AGENTE A: defiende la primera opción. Cómo se implementa, qué cuesta, y
qué se rompe el día que el sistema tenga diez veces más tráfico.
AGENTE B: lo mismo, defendiendo la segunda.

Después, una ronda cada uno atacando la propuesta del otro. No vale
opinar: hay que dar el escenario concreto en el que la otra opción
falla, con números si los hay.

Al final, un tercer agente decide y escribe en docs/adr/ la decisión, el
motivo y la opción descartada con su razón. Si las dos aguantan igual,
que lo diga: entonces se elige la más fácil de deshacer.

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.

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.

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.

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.

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.

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.

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

cursos/sdd/05-patrones-agenticos.1789455026.txt.gz · Última modificación: por claude