Herramientas de usuario

Herramientas del sitio


cursos:sdd:12-patrones-agenticos

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Ambos lados, revisión anteriorRevisión previa
Próxima revisión
Revisión previa
cursos:sdd:12-patrones-agenticos [2026/11/05 22:22] – borrado - editor externo (Fecha desconocida) 127.0.0.1cursos:sdd:12-patrones-agenticos [2026/11/05 22:23] (actual) – Renumera el tema y sus referencias tras añadir el tema 7 (AGENTS.md) claude
Línea 1: Línea 1:
 +====== 12. 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.
 +
 +<note tip>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 9) 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.</note>
 +
 +<note important>**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.</note>
 +
 +^ Patrón ^ Cuándo se usa ^
 +| [[#pipeline_prompt_chain|Pipeline]] | La tarea se parte en pasos fijos, conocidos de antemano |
 +| [[#enrutador|Enrutador]] | Entradas de tipos distintos que se atienden mejor por separado |
 +| [[#planificador-ejecutor|Planificador-Ejecutor]] | Conviene revisar el plan antes de que se toque nada |
 +| [[#orquestador|Orquestador]] | Las subtareas no se conocen hasta ver el problema |
 +| [[#ejecutor-revisor|Ejecutor-Revisor]] | Hay criterios claros y la crítica mejora el resultado |
 +| [[#adversarios|Adversarios]] | Interesa encontrar el fallo, no pulir el acabado |
 +| [[#razonador-refutador|Razonador-Refutador]] | La causa de un fallo no está clara y conviene acertar antes de arreglar |
 +| [[#best-of-n|Best-of-N]] | Los intentos salen muy distintos y verificar es barato |
 +| [[#human-in-the-loop_hitl|Human-in-the-loop]] | Hay acciones irreversibles o responsabilidad de por medio |
 +| [[#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.
 +
 +<uml>
 +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
 +</uml>
 +
 +Es el patrón del //spec-driven development//: requisitos → diseño → tareas → código, con una aprobación en cada salto (tema 18). 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:
 +
 +<code>
 +---
 +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.
 +</code>
 +
 +----
 +
 +===== 2. Enrutador =====
 +
 +Una primera llamada **clasifica** la entrada y la manda a la ruta adecuada: otro prompt, otro modelo u otra herramienta.
 +
 +<uml>
 +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
 +</uml>
 +
 +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:
 +
 +<code>
 +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.
 +</code>
 +
 +----
 +
 +===== 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 de los temas 3 y 4: 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:
 +
 +<code>
 +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.
 +</code>
 +
 +----
 +
 +===== 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.
 +
 +<uml>
 +start
 +:orquestador: partir el trabajo;
 +fork
 +  :trabajador A;
 +fork again
 +  :trabajador B;
 +fork again
 +  :trabajador C;
 +end fork
 +:orquestador: fundir resultados;
 +stop
 +</uml>
 +
 +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. 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:
 +
 +<code>
 +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.
 +</code>
 +
 +----
 +
 +===== 5. Ejecutor-Revisor =====
 +
 +Un agente produce, **otro distinto** lo critica contra unos criterios, y se repite hasta que pase o hasta agotar las vueltas.
 +
 +<uml>
 +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
 +</uml>
 +
 +Es la capa 5 del harnés (tema 11) 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.
 +
 +<note warning>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.</note>
 +
 +**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:
 +
 +<code>
 +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.
 +</code>
 +
 +----
 +
 +===== 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 13, 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. Cada uno recibe su papel al lanzarlo, y el papel es precisamente lo que los hace adversarios:
 +
 +<code>
 +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."
 +</code>
 +
 +----
 +
 +===== 7. Razonador-Refutador =====
 +
 +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.
 +
 +<uml>
 +start
 +repeat
 +  :razonador: explicacion con hechos, deducciones y plan;
 +  :refutador: buscar el paso que no se sostiene;
 +backward:la prueba en contra pasa a ser un hecho;
 +repeat while (razonamiento solido) is (no) not (si)
 +:implementar el plan;
 +stop
 +</uml>
 +
 +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.
 +
 +  * **Cuándo**: tests que unas veces pasan y otras no, código lento sin causa clara, errores cuyo origen no se ve a simple vista.
 +  * **En contra**: más tiempo y más coste. Si la causa era obvia desde el principio, sobra.
 +  * **Regla del Refutador**: puede comprobar hechos —leer el código, lanzar un test—, pero no propone soluciones ni escribe código. Solo señala qué paso no se sostiene y con qué prueba.
 +
 +**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:
 +
 +<code>
 +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.
 +</code>
 +
 +Más informnación:
 +  * [[https://dzone.com/articles/multi-agent-infrastructure-observability|What Actually Makes AI Infrastructure Agents More Reliable (It's Not More Agents)]]
 +
 +===== 8. 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:
 +
 +<code>
 +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.
 +</code>
 +
 +----
 +
 +===== 9. 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.
 +
 +<note tip>**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.</note>
 +
 +**Ejemplo.** La persona aprueba la especificación antes de que empiece el diseño:
 +
 +<code>
 +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.
 +</code>
 +
 +----
 +
 +===== 10. 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 |
 +
 +<note tip>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.</note>
 +
 +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:
 +
 +<code>
 +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.
 +</code>
 +
 +----
 +
 +===== 11. 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 |
 +| 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:
 +
 +  * **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 hace [[cursos:sdd:19-kiro|Kiro]] (tema 19).
 +  * **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]]