====== Ingeniería: prompts, contexto, harneses, bucles y grafos ====== Trabajar con un modelo empezó siendo //escribir bien una pregunta//. Hoy es //construir un sistema alrededor del modelo//. Entre una cosa y otra hay **cinco capas**, y cada una apareció cuando la anterior se quedó corta. ^ Capa ^ Qué se diseña ^ La pregunta que responde ^ | **Prompt** | La petición concreta que se envía | ¿Lo estoy pidiendo bien? | | **Contexto** | Lo que el modelo ve al responder | ¿Tiene la información para resolverlo? | | **Harnés** | El andamiaje alrededor de //una// ejecución | ¿Puede actuar sin romper nada? | | **Bucle** | El ciclo que repite un agente solo | ¿Cuándo comprueba su trabajo y para? | | **Grafo** | La coordinación entre //varios// agentes | ¿Quién hace qué, en qué orden y compartiendo qué? | **Las capas se acumulan, no se sustituyen.** Un grafo está hecho de nodos, un nodo bueno es un bucle bien diseñado, y un bucle bueno necesita el harnés debajo haciendo su trabajo. Saltarse una capa de abajo no la elimina: hace que el fallo aparezca más arriba, más tarde y mucho más difícil de depurar. Ese es también el orden en que conviene subir: **no se pasa a la capa siguiente hasta que la anterior se queda corta de verdad**. ---- ===== 1. Ingeniería de prompts ===== Es la capa de **un solo turno**: qué palabras se mandan. Sigue siendo la base, porque las cuatro capas de encima acaban escribiendo prompts; lo que cambia es quién los escribe. Un prompt sirve cuando lleva cuatro cosas: * **Objetivo** concreto, no un tema. * **Restricciones**: versión del lenguaje, librerías permitidas, ficheros que no se tocan. * **Formato de salida** esperado. * **Criterio de terminado**: cómo se sabe que está bien. Malo: arregla este código Bueno: arregla el NullPointerException de PedidoService.calcularTotal, explica qué estaba mal, no cambies la firma pública del método y deja pasando los tests de PedidoServiceTest ==== Las dos técnicas que se usan a diario ==== ^ Técnica ^ En qué consiste ^ Cuándo ^ | **Zero-shot** | Se pide directamente, sin ejemplos | Lo normal: tareas que el modelo ha visto mil veces | | **Few-shot** | Se dan dos o tres ejemplos de entrada y salida antes de la petición real | Cuando la salida tiene un formato propio. Enseñar cómo es "hecho" funciona mucho mejor que describirlo | El //chain-of-thought// —pedir que razone paso a paso— era la tercera de la lista, pero los modelos actuales razonan solos: hoy no hace falta pedirlo. ==== Dónde se queda corto ==== Cada conversación empieza de cero. Las reglas del proyecto hay que repetirlas cada vez, la información que cambia hay que pegarla a mano, y seis personas del equipo escriben seis versiones distintas del mismo prompt con seis calidades distintas de resultado. ---- ===== 2. Ingeniería de contexto ===== Ya no es //cómo// se pregunta, sino **qué información ve el modelo** al responder. El cuello de botella casi nunca es la redacción: es que al modelo le falta el documento, la fila de la base de datos o la salida de la herramienta que necesitaba. Las piezas con las que se construye el contexto: ^ Pieza ^ Qué aporta ^ | **System prompt** | Instrucciones permanentes, por encima de la conversación: rol, reglas duras, tono | | **Fichero de instrucciones del proyecto** | ''CLAUDE.md'', ''AGENTS.md''. Convenciones del equipo, viaja con el repositorio | | **Historial** | Lo ya dicho en la sesión, para que las decisiones anteriores sigan valiendo | | **Documentos recuperados (RAG)** | Se busca en una base de conocimiento y se inyecta lo relevante | | **Salida de herramientas** | El modelo pide lo que necesita mientras trabaja: leer ficheros, consultar una API, lanzar los tests | Las dos últimas son el salto importante: con RAG se **prepara** el contexto por adelantado; con herramientas el modelo lo **va pidiendo**, que es lo que hace falta cuando no se puede saber de antemano qué información va a necesitar. MCP es el estándar que normaliza esa conexión a herramientas y datos (tema 2). Más contexto **no** es mejor contexto. La definición de Karpathy es "llenar la ventana con exactamente la información necesaria para el paso siguiente, ni más ni menos". Lo que sobra distrae al modelo, cuesta dinero y desplaza a lo que sí importaba. ==== Dónde se queda corto ==== Un modelo perfectamente informado sigue siendo un modelo: no tiene criterio sobre si lo que va a hacer es peligroso, no duda antes de romper algo y no sabe cuándo parar. Una ventana de contexto más grande no convierte un agente inestable en un sistema fiable. ---- ===== 3. Ingeniería de harneses ===== //Harnés// es el arnés del escalador: no hace el trabajo, pero si algo sale mal limita el daño. Aquí es el conjunto de reglas, comprobaciones y mecanismos de seguridad **alrededor** del modelo, para una ejecución. El cambio de mentalidad es este: Cuando el agente se equivoca, el trabajo no es corregir esa salida: es **cambiar el sistema para que ese error concreto no pueda volver a ocurrir**. Reprompting arregla hoy; el harnés arregla siempre. ==== Las cinco capas del harnés ==== ^ ^ Capa ^ Qué es ^ Dónde se ve en el curso ^ | 1 | **Límites** | Lo que el agente //no puede// hacer, impuesto por el entorno: contenedor o VM, acceso de solo lectura, reglas de red, directorios permitidos | Tema 8: Sandbox | | 2 | **Instrucciones** | Las normas permanentes del proyecto en ''CLAUDE.md'' / ''AGENTS.md'': estilo, librerías aprobadas, qué hacer ante una duda, errores ya cometidos | Temas 2 y 10 | | 3 | **Comprobaciones** | Lint, tipos, tests, análisis de seguridad. Puertas que el agente **no puede saltarse**, no sugerencias | Temas 6 y 7 | | 4 | **Recuperación** | Qué pasa cuando una comprobación falla: reintento con tope, //rollback//, reducir el alcance, escalar a una persona | | | 5 | **Revisión** | Un revisor **distinto** del que hizo el trabajo | Tema 5: Ejecutor-Revisor | La capa 1 va primera justamente porque **no depende de que el modelo se porte bien**. Una instrucción se puede ignorar; un contenedor sin permiso de escritura, no. Los //hooks// (tema 9) son la forma práctica de convertir las capas 1 y 3 en algo que el agente tiene que cumplir. ==== Dos tipos de comprobación ==== ^ Tipo ^ Quién juzga ^ Ejemplos ^ Coste ^ Fiabilidad ^ | **Computacional** | Código normal, regla fija | Tests, linters, comprobador de tipos, validación de esquema | Barato y rápido | Altísima, pero solo pilla lo que se te ocurrió comprobar | | **Inferencial** | Otro modelo | LLM-as-judge, revisor de código con IA | Lento y caro | Pilla problemas difusos, pero puede equivocarse | Un harnés decente usa los dos: lo determinista primero, porque es gratis, y el modelo juez solo para lo que no se puede expresar como regla. El revisor tiene que ser **otro agente**, con el encargo explícito de buscar problemas. Un modelo que revisa su propia salida tiende a aprobarla aunque acabe de detectarle fallos. ==== Por dónde empezar, según lo que hay en juego ==== * **Proyecto personal**: solo la capa 2. Un buen fichero de instrucciones, actualizado cada vez que el agente mete la pata. * **Flujo de un equipo**: añadir la capa 3. Los mismos tests y linters que se le exigen al código humano, como puerta. * **El agente toca datos o servicios**: añadir las capas 1 y 4. * **Sistema de cara al cliente o sensible**: añadir la capa 5, con revisión humana final. ==== Dónde se queda corto ==== El harnés hace que //una// ejecución sea fiable, pero sigue dando por supuesto que hay una persona lanzándola, leyendo el resultado y decidiendo qué se hace después. ---- ===== 4. Ingeniería de bucles ===== Aquí el humano **deja de apretar el botón**. En vez de escribir un prompt, leer la respuesta y escribir el siguiente, se construye un sistema pequeño que hace ese ciclo: mira qué queda pendiente, decide qué intentar, se lo pasa al agente, comprueba si el resultado cumple el objetivo, guarda lo aprendido y vuelve a empezar o para. start :leer el estado del proyecto; repeat :elegir la siguiente tarea; :ejecutar el agente; :pasar el verificador; if (verificador en verde) then (si) :guardar el avance; else (no) :registrar el fallo; endif repeat while (queda objetivo y queda presupuesto) is (si) not (no) stop La versión mínima de esto es la **técnica Ralph**: un ''while'' de shell que arranca una instancia nueva del agente en cada vuelta con el mismo prompt contra una especificación escrita, que coge una tarea, la implementa y termina. Sin memoria entre vueltas salvo lo que quede escrito en disco. Parece demasiado simple para funcionar, y funciona. ==== Las tres cosas que hay que acertar ==== - **El objetivo tiene que ser demostrable, no solo enunciado.** «Mejora el proceso de compra» no le da al bucle nada contra lo que comprobarse, así que parará cuando le parezca. Hay que escribir el estado final esperado, la prueba de que se ha alcanzado y las reglas que no se pueden romper por el camino. - **El verificador es el cuello de botella real, no el modelo.** Un bucle vale exactamente lo que valga su capacidad de distinguir trabajo bueno de trabajo malo. Con una comprobación débil, marcará como hecho lo que está roto y seguirá adelante. La mayor parte del esfuerzo de ingeniería se va ahí, no al prompt. - **Límites duros**: número de vueltas, tope de gasto, tiempo máximo. ==== Estilos de bucle ==== ^ Estilo ^ Cómo funciona ^ Bueno para ^ Riesgo ^ | **Cerrado, con aprobación humana** | Propone la acción siguiente y espera el visto bueno | Cambios de riesgo, primeros días de un bucle nuevo | Lento; si se aprueba todo sin mirar, no aporta nada | | **Abierto, con presupuesto** | Corre desatendido hasta el tope de vueltas, de coste o hasta cumplir el objetivo | Tandas nocturnas, refactorizaciones acotadas | Puede quemar el presupuesto en lo que no era | | **Ralph** | Un agente, una especificación, instancia nueva cada vuelta | Tareas de código pequeñas y bien definidas | Repite trabajo que no recuerda haber hecho; exige una especificación muy clara | | **Orquestado** | Un bucle de control lanza subagentes especializados y funde los resultados | Objetivos que se parten en piezas independientes | El coste de coordinación, y un verificador flojo en la fusión tira abajo todo lo de debajo | //Loopmaxxing//: dejar bucles corriendo horas porque sí. Objetivo vago más verificador flojo da como resultado una montaña de código que nadie pidió y una factura. Un bucle no es magia, es un sistema de control, y vale lo que valga aquello que le mandas comprobar. ---- ===== 5. Ingeniería de grafos ===== El bucle diseña el ciclo de //un// agente. El grafo diseña **cómo se conectan varios**. Tres piezas: * **Nodos** — quien hace el trabajo: un agente especializado (investigador, redactor, revisor) o un paso determinista, como una llamada a una herramienta. * **Aristas** — el encaminamiento: entrega directa, rama condicional, //fan-out// a varios nodos a la vez, //fan-in// que vuelve a juntar los resultados. * **Estado compartido** — el objeto que viaja por las aristas. Es lo que convierte un montón de agentes en un sistema en vez de en un grupo de asistentes que se olvidan de todo al pasarse el trabajo. start :investigador; repeat fork :escribir el codigo; fork again :escribir los tests; end fork :revisor; backward:devolver con los comentarios; repeat while (pide otra pasada) is (si) not (no) :publicar; stop **El grafo es el mapa; el bucle es el camino.** El grafo dice qué es alcanzable y quién habla con quién. No dice cuántas veces reintenta un nodo, cuándo se rinde ni qué es suficientemente bueno: eso sigue siendo del bucle, dentro de cada nodo. Un agente trabajando solo es el grafo más pequeño posible: un nodo con una arista a sí mismo. No confundirlo con un //knowledge graph// ni con GraphRAG: aquellos modelan **datos** y sus relaciones para recuperarlos; esto modela la **ejecución**, qué nodo corre después y con qué estado. ==== Cuándo merece la pena ==== La respuesta honesta por defecto es **que no**. Lo normal es que un agente bien acotado con un buen verificador baste, y adelantarse al grafo es cómo una tarea de dos horas se convierte en un proyecto de dos semanas de //framework//. ^ Señal ^ Basta un bucle ^ Toca grafo ^ | Forma de la tarea | Un trabajo, una meta clara | Se parte en especialidades que se pasan el trabajo | | Paralelismo | Los pasos van en serie | Hacen falta varias cosas a la vez y luego juntarlas | | Herramientas por paso | Las mismas todo el rato | Modelo o herramientas distintos en cada fase | | Verificación | El agente comprueba lo suyo | Un nodo aparte revisa el trabajo de otro | | Aislamiento de fallos | Un paso malo reintenta y ya | Un nodo que falla no debe envenenar el resto | Si la mayoría de las respuestas sinceras caen en la columna de la izquierda, es un bucle al que alguien ha convencido de que necesitaba arquitectura. ==== Frameworks ==== ^ Framework ^ Modelo de orquestación ^ | **LangGraph** | ''StateGraph'' explícito: se declaran los nodos y las aristas. Código primero | | **AutoGen (GraphFlow)** | Orquestación por grafo sobre el modelo de agentes de Microsoft | | **Google ADK** | Agentes de flujo secuencial, paralelo y en bucle como primitivas | | **Protocolo A2A** | Delegación entre agentes de **sistemas y equipos distintos**, no el grafo interno de una aplicación | Un grafo implícito sigue siendo un grafo: simplemente no se ve hasta que algo se rompe. Mejor un framework que obligue a hacerlo explícito que uno propio que lo esconda. ==== Lista de comprobación antes de montar uno ==== - Intenta que siga siendo un bucle. Si un agente bien acotado con un verificador decente hace el trabajo, para ahí. - Un nodo solo se crea si es una especialidad de verdad, otro modelo, otras herramientas o un revisor de solo lectura. Un paso que podrías meter dentro de otro no es un nodo. - Dibuja las aristas antes de escribir código. Si no cabe en una servilleta, ya es demasiado complejo. - Diseña el estado compartido a propósito y decide **quién puede escribir en él**. La deriva del estado es la forma más rápida de pudrir un grafo. - Dale dientes al revisor: un agente distinto del que produjo el trabajo, no el mismo poniéndose la nota. - Aísla los fallos: un nodo malo reintenta sin corromper el estado ni contaminar el resto de la ejecución. ---- ===== 6. Resumen ===== * **Prompt**: una petición bien hecha. Objetivo, restricciones, formato, criterio de terminado. * **Contexto**: exactamente la información necesaria, ni más ni menos. Instrucciones del proyecto, recuperación y herramientas. * **Harnés**: límites, instrucciones, comprobaciones, recuperación y revisión alrededor de una ejecución. Cuando falla algo, se cambia el sistema, no la salida. * **Bucle**: el sistema decide el paso siguiente. Objetivo demostrable, verificador fuerte y presupuesto con tope. * **Grafo**: varios nodos especializados con estado compartido. Solo cuando el trabajo lo pide. Los patrones concretos para montar todo esto —pipeline, enrutador, planificador-ejecutor, orquestador, ejecutor-revisor, //best-of-N//, //human-in-the-loop//— son el tema 5. ===== Fuentes ===== * [[https://hackernoon.com/from-prompts-to-harnesses-how-ai-engineering-has-grown-up|From Prompts to Harnesses: How AI Engineering Has Grown Up]] * [[https://dzone.com/articles/loop-engineering-llms|Loop Engineering: The Layer After Prompt, Context, and Harness Engineering]] * [[https://dzone.com/articles/understanding-graph-engineering|Graph Engineering: The Layer After Loop Engineering]] * [[https://dzone.com/articles/trust-no-agent-securing-autonomous-ai-tools|Trust No Agent: Securing Autonomous AI Tools]] * [[https://dzone.com/articles/mcp-vs-skills-vs-agents|MCP vs Skills vs Agents With Scripts]]