De loops que nadie puede auditar a grafos que se leen antes de ejecutarse
Cada vez que un agente decide "reintentar, escalar o seguir", esa decisión ocurre dentro del modelo: invisible, inauditable, irrepetible. Este curso enseña la alternativa — escribirla antes de que pase.
Qué es graph engineering y por qué existe como capa por encima de los loops.
Los tres compromisos: plan inmutable, capas separadas, escalamiento estricto.
Cómo construir tu primer grafo, con un ejemplo resuelto de migración de código.
Cuándo NO usarlo — y el estado honesto de la evidencia (spoiler: aún no está probado a escala).
Cada año la palanca de la ingeniería de IA se mueve un nivel más afuera del modelo. Graph engineering es el último peldaño — y se apoya en todos los anteriores (el término lo nombró Addy Osmani para "loop engineering" en junio 2026; "graph engineering" explotó en X el 18-jul-2026 con un tweet de Peter Steinberger):
No es una escalera que abandonás: un grafo está lleno de nodos; un buen nodo es un loop bien diseñado; un buen loop necesita un buen harness. Saltate una capa de abajo y el grafo de arriba falla de una forma más elaborada — si tus nodos son agentes débiles, conectarlos en un organigrama te da un organigrama débil. Por eso este curso empieza por el loop.
Antes de empezar: el paper que origina este framework incluye una declaración de imparcialidad de su propio autor: es un diseño no implementado, y si entrega sus beneficios prometidos en producción a escala sigue siendo una pregunta empírica abierta. Este curso enseña el framework con esa advertencia incluida, porque entender una propuesta rigurosa aún no probada es más útil que fingir que es un hecho cerrado.
Cómo usar este curso
Navega con la barra lateral o con los botones al pie de cada lección. Los interactivos y los videos animados están pensados para recorrerse en orden. Tu progreso se guarda automáticamente en este navegador.
Un loop esconde una decisión dentro de una caja negra
Un loop de agente es un ciclo: intentar → observar → decidir qué sigue, repetido hasta terminar. Funciona muy bien para muchísimas tareas. Y es estructuralmente una caja negra justo en el momento que más importa.
El paper detrás de este framework (arXiv:2604.11378, Hu Wei) nombra con precisión las tres debilidades estructurales del Agent Loop: (1) dependencias implícitas entre pasos — "modifica el código y luego corre los tests" vive solo en la ventana de contexto, sin ningún guard estructural que impida desordenar el orden; (2) recuperación sin semántica acotada — al fallar, el LLM decide solo si reintentar, saltar o re-planificar, sin contrato de qué acciones existen ni límite de intentos; (3) historial de ejecución mutable — si el LLM revisa su plan a mitad, el original se sobreescribe y ya no se puede reconstruir un audit trail fiel.
La reframing clave: el loop es un scheduler
El paper caracteriza al Agent Loop como un scheduler de unidad única lista: en cada instante hay como máximo una unidad activa (cardinalidad del ready-set |𝒰| = 1), y cuál se activa es la salida de una inferencia opaca del LLM, no una política inspeccionable. Esa caracterización es la que permite comparar loops y grafos en un mismo continuo (lo vemos en la lección 02).
el momento crítico¿Qué pasa cuando algo falla?
Cuando el agente de un loop decide reintentar un paso fallido, esa decisión nació del modelo razonando sobre su propio contexto. No puedes inspeccionar la decisión antes de que ocurra; solo observar el resultado después.
Si el agente reintenta el mismo enfoque fallido cinco veces seguidas, quemando costo cada vez, nada en la estructura del loop lo impidió — porque la decisión de reintentar vivió por completo dentro del juicio del modelo, no en una regla externa verificable.
por qué importaBarato y de bajo riesgo: bien. Caro y de alto riesgo: problema real.
Un reintento desperdiciado de vez en cuando no cuesta nada relevante en tareas baratas y de bajo riesgo. Se convierte en un pasivo real en trabajo de largo horizonte, caro o de alto riesgo — exactamente la categoría de tareas que los sistemas agénticos están recibiendo cada vez más.
El argumento central del paper: a medida que los agentes asumen trabajo más importante, la opacidad de "qué se ejecuta a continuación" deja de ser una caja negra aceptable y se convierte en el punto de falla que vale la pena ingenierear directamente.
Antes de los grafos existe loop engineering (término de Addy Osmani, junio 2026): el arte de diseñar bien el ciclo de un agente. Es la capa inmediatamente inferior — y el nodo de cualquier grafo es, por dentro, un loop. Su fórmula central:
Prompt decide cómo empieza → Context decide qué ve → Loop decide qué tan lejos llega
Boris Cherny lo resumió: "Ya no le escribo prompts a Claude. Tengo loops que están corriendo." Pero loop engineering también nombra sus propios riesgos — las tres deudas que el grafo viene a atacar:
Si el verificador es débil (o el agente se auto-verifica), el loop "aprueba" trabajo malo. El grafo responde con un reviewer separado — compromiso 2.
Cada vuelta el contexto crece y el agente entiende peor dónde está. El grafo responde con plan inmutable y contexto separado — C1 + C_exec/C_diag.
Cuando el operador deja de entender qué hace el loop y solo confía. El grafo responde haciendo la estructura inspeccionable antes de ejecutar.
El mantra de loop engineering es "Build the loop, but stay the engineer": automatiza el ciclo, pero sigue siendo tú quien entiende y controla. El grafo es la herramienta para no rendir ese control — exactamente el problema con que abre esta lección.
Un grafo hace esa decisión explícita
Un grafo reemplaza la decisión implícita del modelo por una estructura definida antes de que empiece la ejecución: qué estados existen, qué transiciones son válidas y qué condición dispara cada una. El agente sigue haciendo trabajo real dentro de cada estado; lo que ya no hace es decidir invisiblemente la forma del proceso mientras avanza.
los cinco movimientosPlan · Ejecutar · Recuperar · Escalar · Repetir
Cualquier turno de un grafo así se describe con cinco movimientos. Haz clic en cada nodo para explorarlo, o pulsa el recorrido automático:
Mira lo que cambió respecto al loop: cada uno de los cinco movimientos es ahora un estado nombrado e inspeccionable, con transiciones definidas entre ellos — en lugar de una decisión ocurriendo en silencio dentro de una sola llamada al modelo.
El paper no plantea "loop malo, grafo bueno". Plantea que loops y grafos viven en un único continuo semántico parametrizado por dos ejes: la cardinalidad del ready-set |𝒰| (cuántas unidades pueden despacharse a la vez) y la explicitud de la política (qué tan determinística e inspeccionable es la decisión de scheduling). El Agent Loop está en el extremo |𝒰|=1 + política opaca; un grafo estático sube ambos. "Loop vs grafo" es en realidad elegir un punto en ese gradiente.
la otra gananciaEl grafo habilita paralelismo
Auditar no es lo único que gana un grafo. Como puede despachar varios nodos a la vez (|𝒰| > 1), habilita ejecución paralela. El ejemplo motivacional del paper — arreglar un bug buscando en dos módulos, leyendo ambos, probando dos parches alternativos — se ve así:
El paper distingue dos formas de paralelismo:
Constructivo
Todas las ramas deben completarse (leer dos archivos a la vez). SGH lo soporta — join all_of / any_of.
Competitivo
Solo una rama hace falta y el resto se cancela (probar dos fixes, parar al primero que ande). SGH lo excluye a propósito (join first_of) por controlabilidad.
El propio paper subraya que este ejemplo asume condiciones ideales: que el planner identifica bien todo el paralelismo, que las dependencias se conocen al planificar, y que el LLM ejecuta cada nodo correctamente. Cuando el planner falla (dependencias faltantes, sobre-descomposición), las ganancias se degradan. Es una ganancia potencial, no garantizada.
Plan inmutable: el plan no se mueve a mitad de camino
El plan de ejecución no puede cambiar durante la ejecución. Una vez generado y bloqueado, existe como una única versión fija durante toda la corrida. El agente no puede revisar silenciosamente su propio plan a mitad de camino, como hace constantemente un agente en loop — sin registro externo de la revisión.
Esto suena restrictivo, y lo es a propósito. La restricción es el punto entero: un agente que puede revisar libremente su propio plan durante la ejecución es exactamente el agente cuyo comportamiento se vuelve imposible de auditar después — porque el plan que revisas al final no es el plan que se siguió, sino aquello en lo que el plan derivó.
El sistema va por el paso 6 de 12 y descubre que el orden original no era óptimo. ¿Qué hace cada patrón? Pulsa ambos y compara:
- actualizar dependencias base
- migrar src/core/*
- migrar src/auth/*
- migrar módulo legacy billing
- actualizar tests de integración
- regenerar documentación
Elige una opción arriba
En el loop, el agente reescribe el plan en silencio: los pasos 4–6 cambian sin registro. En el grafo, el plan queda intacto y la desviación se convierte en un evento visible: un escalamiento con ticket, contexto y decisión humana.
El matiz exacto del paper: el plan es inmutable dentro de una versión del plan ("immutable for the duration of a plan version"). No prohíbe re-planificar; prohíbe editar en silencio la versión vigente. Si hace falta cambiar, se genera una versión nueva (v2) en una ejecución nueva — la v1 queda intacta y auditable. Por eso el interactivo de arriba muestra un ticket que autoriza "plan v2", no una edición.
Bloquear el plan cambia flexibilidad real por inspeccionabilidad real — y ese intercambio no es gratis. Una situación genuinamente nueva que el plan no anticipó se maneja peor con un plan inmutable que con un loop que adapta libremente. La apuesta deliberada: para la categoría de tareas que este framework apunta, predecible y auditable le gana a máximamente adaptativo.
Capas separadas: planificar, ejecutar y recuperar no son el mismo rol
En un loop, las tres cosas ocurren dentro del mismo proceso de razonamiento continuo. En un grafo viven en tres capas independientes, cada una con un trabajo — y solo uno.
- genera el plan inmutable (compromiso 1)
- define criterios de éxito por paso
- no ejecuta pasos
- no maneja fallas
- ejecuta el paso definido
- reporta PASS / FAIL con evidencia concreta
- no decide qué pasa al fallar
- solo dice qué pasó, nunca qué hacer
- recibe reportes de falla
- aplica el protocolo numerado definido
- no ejecuta trabajo nuevo directamente
- solo decide cómo responder a lo que ya pasó
las tres funciones enredadas en una sola llamada al modelo — imposibles de auditar por separado, porque en el rastro nunca fueron distintas.
= una sopa de razonamiento
auditoría: imposible
Es el mismo principio que separar Builder de Judge en un loop de verificación: el rol que produce trabajo no debe ser el mismo rol que lo evalúa o decide sobre él, porque colapsar los dos erosiona la independencia que hace valioso el chequeo. Aquí la separación es triple en vez de doble — el razonamiento de fondo es idéntico.
El paper lleva la separación un paso más: separación de contexto. La capa de ejecución corre con un contexto de ejecución (C_exec) limpio, y los fallos se diagnostican en un contexto de diagnóstico (C_diag) separado. Así la recuperación no contamina el contexto con el que se ejecuta, y cada capa razona con la información mínima necesaria — otra forma de hacer cada función auditable por separado.
Escalamiento estricto: hay un número, y hay un final
La recuperación sigue un protocolo fijo en vez de reintentar indefinidamente esperando que algo funcione. Define de antemano: cuántos intentos se permiten, qué cuenta como éxito o falla de cada intento, y qué pasa al llegar al límite — entregar el control a un humano, no intentar una variación creativa más.
El análisis del paper sobre 70 sistemas reales encontró que una gran parte de las implementaciones de loops de agentes no tenía ningún límite formal sobre intentos de recuperación. El comportamiento real cuando algo fallaba lo decidía lo que el modelo resolviera en el momento — no una regla que un humano hubiera revisado y aprobado de antemano.
El paso 4 falla y ningún reintento va a funcionar (escenario realista: el error requiere juicio humano). Pulsa ejecutar y mira el costo de cada patrón:
LOOP sin condición de parada decide el modelo
GRAFO con protocolo decide la regla
Humano notificado con historial completo: paso que falló, ambos intentos, error específico de cada uno. La ejecución automática se detiene.
Loop: 12 reintentos del mismo enfoque, ~37.700 tokens, cero registro de por qué — y podría haber seguido para siempre. Grafo: 2 reintentos definidos por protocolo, 3.700 tokens, y un humano con el contexto completo en la mano. El protocolo no arregló el problema — hizo visible el problema a la persona correcta, a costo acotado.
El paper llama a esto Bounded Recovery (recuperación acotada) y subraya el enforcement mecánico: el límite no es una instrucción que el modelo "debería" respetar, sino una regla que el sistema hace cumplir estructuralmente — el intento 3 literalmente no existe en el protocolo. Es la diferencia entre pedirle autodisciplina a un loop y construir una máquina que no puede pasarse.
El cuarto principio: clasificación de efectos secundarios
Además de los tres compromisos, el paper propone un cuarto principio: clasificar los efectos secundarios de cada nodo — si es idempotente/reintentable, o si tiene efectos externos irreversibles (un pago, un envío, un borrado). Importa porque con LLMs un reintento no es idempotente: re-ejecutar un nodo puede dar salidas distintas, y si el nodo ya tuvo un efecto externo, reintentar a ciegas puede duplicar el daño. Clasificar los efectos es lo que permite decidir qué es seguro reintentar y qué debe escalar sí o sí.
Construye tu primer grafo en cinco pasos
Traducir los tres compromisos a algo implementable. La regla de oro: primero en papel, después en código.
PASO 1 · Define los estados explícitamente, en papel
Antes de escribir código o prompts. Para una tarea típica, el mínimo es: Planning → Executing paso N → Recovering → Escalated → Complete. Para cada estado escribe exactamente dos cosas: qué ocurre mientras el sistema está ahí, y qué condición provoca salir de él.
PASO 2 · El plan es un artefacto versionado, no un documento vivo
La versión simple y práctica: una lista numerada de pasos discretos, cada uno con criterio de éxito explícito, en modo solo-lectura por el resto de la ejecución.
Cualquier necesidad genuina de desviarse dispara un escalamiento explícito a un humano — nunca una revisión interna silenciosa.
PASO 3 · La capa de ejecución solo reporta resultados
PASS o FAIL, con detalle específico — nunca una decisión sobre qué sigue. Es el rol Builder: produce trabajo y reporta honestamente, sin ser también el rol que decide si se reintenta. Un reporte que dice "esto probablemente necesita otro enfoque" ya violó la separación.
PASO 4 · La recuperación es un protocolo numerado y concreto
Lo bastante concreto para que un humano leyéndolo de antemano pueda predecir exactamente qué hará el sistema en cada etapa. "Reintentar una cantidad razonable de veces" no es un protocolo: es un loop con vocabulario de grafo.
PASO 5 · El escalamiento es un evento real y visible
No un log perdido. Al llegar al estado Escalated: se notifica a un humano con el historial completo — qué se intentó y por qué falló cada intento. La misma disciplina que se recomienda para condiciones de parada en loops de verificación.
Todo junto: migración de código paso a paso
Tarea real y común: migrar un módulo legacy a una nueva versión del framework. Recorre la ejecución con los botones — incluye una falla que ningún intento de recuperación puede arreglar.
Cada decisión — si reintentar, cómo, cuándo rendirse — es visible en la estructura del grafo antes de que empiece la ejecución. Un revisor de código o un auditor de compliance puede mirar solo la definición del grafo y saber exactamente qué es capaz de hacer el sistema en cada escenario de falla — sin haberlo visto ejecutarse jamás.
Grafo vs loop: cuándo usar cada uno
Ninguno es un default permanente. La posición honesta — y la del propio autor del paper — es que esto es un tradeoff que entender profundamente, no un reemplazo estrictamente superior.
| LOOP | GRAFO | |
|---|---|---|
| qué se ejecuta después | lo decide el modelo, en su razonamiento | definido antes de ejecutar |
| auditoría | a posteriori, releyendo transcripts | a priori: la estructura se lee sola |
| ante una falla | reintento improvisado | protocolo numerado |
| costo ante error | potencialmente ilimitado | acotado por el protocolo |
| adaptabilidad | máxima | limitada (por diseño) |
| uso ideal | exploración, causas raíz desconocidas, trabajo creativo | migraciones, pagos, datos regulados, agentes desatendidos |
Una regla más operativa, cruzando dos preguntas — ¿qué tan compleja es la tarea? (columnas) y ¿qué tanto paralelismo necesita? (filas):
Loop simple
Simple + bajo paralelismo. No sobre-optimices. "Escribe una función que ordene una lista."
Loop paralelo
Simple + alto paralelismo. Varios loops simples lado a lado. "Revisa 10 PRs independientes."
Loop por etapas
Compleja + bajo paralelismo. Loop secuencial con checkpoints. "Construye una feature con revisión por hito."
Grafo
Compleja + alto paralelismo. Aquí brilla: reviewers en paralelo + ruteo condicional. "Revisa un PR crítico que toca auth, schema y API."
Si tu tarea tiene 3 o más pasos de verificación independientes Y ruteo de decisión complejo, usa un grafo. Si no, un loop está bien — y graficar de más es comprarte un problema de sistemas distribuidos que no tenías.
No son excluyentes: un diseño pragmático muy común usa un grafo en el nivel externo (estructura general + condiciones de parada) y permite un loop dentro de un estado EJECUTAR para la sub-tarea genuinamente exploratoria. Auditabilidad donde más importa; adaptabilidad donde realmente vale.
El paper no opina al vacío: encuestó 70 proyectos de agentes LLM open-source y los clasificó por patrón de ejecución. El resultado explica por qué este framework existe:
El ~60% usa Agent Loop. Y el hallazgo cualitativo clave: el comportamiento de failure-loop (reintentos sin fin) fue común en los sistemas de orquestación graph/flow del dataset, pero raro en los sistemas basados en máquinas de estados. Tener un grafo no basta: sin estados terminales estables y recuperación acotada, un grafo reproduce el mismo fallo que un loop.
el trade-off, formalizadoTres ejes que tiran en direcciones opuestas
El paper analiza cualquier diseño en tres ejes. Subir uno suele costar otro — por eso no hay "mejor" universal, solo puntos de diseño:
Controlabilidad — ¿puedo predecir y restringir qué hace? El grafo la maximiza.
Expresividad — ¿qué tan rico es el comportamiento expresable? El loop la maximiza.
Implementabilidad — ¿qué tan fácil es construirlo y verificarlo bien?
Para maximizar controlabilidad y verificabilidad, SGH recorta expresividad a propósito y excluye: el join first_of (paralelismo competitivo), la expansión recursiva de sub-grafos (un nodo que genera más grafo en runtime) y el rollback de cadena de padres (deshacer hacia atrás). Cada exclusión es una decisión de diseño explícita, no una limitación accidental — y define exactamente dónde no conviene usar SGH.
Prueba el grafo antes de confiar en él
Cada compromiso tiene su propia forma de fallar en silencio si se implementa con descuido. Tres stress tests, uno por compromiso:
A mitad de una ejecución, construye un escenario donde el "siguiente paso obviamente correcto" se desvíe del plan bloqueado.
debe pasar: el sistema escala a un humano — no adapta el plan en silencio. Si se adapta, el plan nunca fue inmutable de verdad.Revisa los reportes de falla de la capa de ejecución buscando rastros de decisión: frases como "esto probablemente necesita otro enfoque" en lo que debería ser un PASS/FAIL neutro.
debe pasar: reportes puramente factuales. Si ejecución ya opina sobre recuperación, la separación no es real — solo fue re-etiquetada.Inyecta una falla que ninguno de los dos intentos definidos pueda arreglar.
debe pasar: escala limpiamente en el límite exacto — sin un tercer intento indefinido. Es el equivalente a probar la condición de parada de un loop contra una tarea imposible.La métrica que un loop no te puede dar
En uso real, mide la tasa a la que las ejecuciones llegan al estado Escalado, desglosada por qué intento de recuperación falló cada vez. Un grafo escalando constantemente en el mismo paso específico te dice que el protocolo de ese paso está mal calibrado — no que la tarea sea uniformemente difícil. El mismo valor diagnóstico que rastrear disparos de condición de parada en loops, pero con más granularidad, porque el punto de falla es un estado nombrado, no un momento inferido en un transcript opaco.
Bloquear el plan en papel mientras ejecución se desvía en la práctica: lo peor de ambos mundos — ni adaptabilidad real ni auditoría real, porque el rastro ya no calza con el plan que revisarías.
Dejar que ejecución también decida recuperación "porque es más rápido de construir". Si las capas no son genuinamente independientes, construiste un loop con vocabulario de grafo.
"Reintentar un número razonable de enfoques alternativos" no es un protocolo: es una instrucción blanda con el mismo modo de falla que un loop ilimitado. Un protocolo real nombra el número específico y la condición de cada intento.
Construir un grafo para una tarea exploratoria porque suena más riguroso — y terminar con un sistema más difícil de construir que un loop y peor en el trabajo que un loop habría hecho.
Construye tu primer loop y tu primer grafo funcionales
Hasta aquí, teoría. Ahora vas a correr los dos patrones sobre la misma tarea — aquí mismo en el navegador, sin instalar nada — ver la diferencia en tokens y auditoría con tus propios ojos, y modificar el código hasta que los tres compromisos sean obvios. El código Python real está incrustado más abajo, para leerlo o copiarlo.
No hay ningún LLM detrás: la tarea es determinística a propósito. El objetivo del curso es la estructura (dónde vive la decisión de "qué sigue"), no el comportamiento de un modelo. Por eso puedes predecir cada línea de la salida antes de ejecutarla.
Una migración de código de 6 pasos. El migrar legacy billing falla con cualquier enfoque automático y solo se arregla con juicio humano — igual que el ejemplo de la lección 07. Ambos patrones se enfrentan a exactamente la misma tarea. (Ojo al índice: el código cuenta desde 0, así que en la salida verás "paso 3"; es el 4º paso del plan, el "paso 4" de las lecciones 05 y 07.)
La función decidir_proxima_accion() es la caja negra: simula al modelo "razonando" internamente. No hay ninguna regla externa que la gobierne ni registro de lo que decidió. Observa cómo, sin condición de parada, el costo se dispara sin que nada lo impida.
Pulsa ▶ loop_minimo en el ejecutor de arriba y mira la caja negra en acción: 8 reintentos del mismo enfoque, ~19.600 tokens, sin resolver y sin registro. La salida es idéntica a la del Python (mismo código, puerto a JS).
Mismo problema, estructura distinta. Busca en el código dónde está cada compromiso:
C1 · plan inmutable → @dataclass(frozen=True) y el plan es una tuple (no se edita en silencio).
C2 · capas separadas → Planner, Executor y Recoverer son clases distintas; el Executor solo devuelve Reporte(ok, evidencia), jamás una decisión.
C3 · escalamiento estricto → MAX_INTENTOS = 2 está escrito antes de ejecutar; al agotarse, ESCALAR notifica al humano.
Pulsa ▶ grafo_minimo arriba: el paso 3 falla, el protocolo intenta scope_acotado y patron_LIB07, y al agotarse escala al humano — todo en ~9.900 tokens y con rastro completo. Después sube MAX_INTENTOS a 99 y compara los tokens.
Misma tarea, dos finales. El loop quemó 19.600 tokens sin resolver y sin dejar rastro. El grafo completó la migración entera en 9.900 tokens con un historial que cualquier revisor puede leer sin ver el modelo. La diferencia no es el modelo: es dónde vive la decisión.
Rompe cada compromiso a propósito y mira qué se rompe. Si al romperlo no pasa nada visible, tu implementación no era real — era un loop con vocabulario de grafo.
Pon MAX_INTENTOS en 99 en el ejecutor de arriba y pulsa grafo_minimo (o edita grafo_minimo.py). ¿En qué se parece ahora al loop? Mira los tokens explotar a ~116.600.
Haz que Executor.ejecutar() devuelva también una opinión ("esto necesita otro enfoque"). ¿Por qué eso destruye la separación de capas?
Cambia tuple(...) por list(...) en Planner y modifica un paso a mitad de correr(). ¿Qué le pasa al rastro de auditoría?
Edita tarea.py para que el enfoque patron_LIB07 SÍ arregle el paso 3 (sin fix_humano). El grafo ahora debe resolver sin escalar.
Corre el grafo con distintas tareas y cuenta cuántas ejecuciones llegan a ESCALAR y en qué intento. Esa tasa es la métrica que un loop no te puede dar.
Cada ejercicio reproduce uno de los cuatro errores clásicos (lección 09) y uno de los tres stress tests. Ya no solo entiendes graph engineering: lo corriste, lo rompiste y lo mediste. Marca la lección como completada.
El ecosistema: frameworks, patrones, costo y el chequeo de hype
Hasta aquí aprendiste el framework (SGH) con rigor académico. Pero allá afuera "graph engineering" significa también otra cosa, hay frameworks que lo hacían antes del nombre, y el hype trajo humo. Esta lección te da el mapa completo — para que no te pierdas ni te creas cualquier cifra.
El término se usa para dos cosas distintas. Confundirlas es la fuente de la mitad del ruido:
1 · Control de flujo (este curso)
Grafo = DAG estático que reemplaza la decisión implícita del modelo sobre "qué sigue". Foco: auditabilidad y recuperación acotada. Fuente: paper SGH (Hu Wei) + curso de @cyrilXBT. Trata sobre una ejecución bien controlada.
2 · Organización multi-agente (el discurso de X)
Grafo = red de agentes especializados (nodos) conectados por dependencias (aristas) con estado compartido. Foco: paralelismo y división del trabajo. Explotó el 18-jul-2026 con Peter Steinberger (@steipete, creador de OpenClaw): "Are we still talking loops or did we shift to graphs yet?"
Hay un tercer significado que NO es esto: knowledge graphs / GraphRAG / aristas tipadas (supersedes, depends_on…). Eso modela datos para retrieval, no ejecución. Misma palabra, problema distinto.
La frase que une ambos: "los loops hicieron programable el comportamiento de un agente; los grafos hacen programable la organización de muchos agentes". Y un loop es el caso degenerado: un grafo de un solo nodo con una arista hacia sí mismo. La disciplina SGH de este curso (hacer explícita la estructura) aplica a ambos significados.
La mecánica no es nueva. Estos frameworks hacían orquestación en grafo antes de que existiera el término:
| framework | qué es |
|---|---|
| LangGraph (LangChain) | Un StateGraph de nodos y aristas sobre estado compartido — "runtime de orquestación para agentes stateful de larga duración". |
| AutoGen GraphFlow (Microsoft) | Orquestación multi-agente en grafo: describís cómo se conecta y delega un equipo de agentes. |
| Google ADK | Agentes de workflow secuenciales, paralelos y loop + routing; fan-out/fan-in como bloques de primera clase. |
| A2A (Agent2Agent) | Protocolo abierto de delegación entre agentes — "las aristas entre grafos que pertenecen a equipos distintos". |
| XState | Máquinas de estados — "grafos dirigidos de estados y transiciones son ciencias de la computación de hace décadas". |
Harrison Chase, creador de LangGraph (la implementación de referencia), cuando le preguntaron: "So I didn't really know what graph engineering is, and I still don't really… but it's basically just langgraph?". Cuando el autor del framework de referencia duda que el nombre nombre algo nuevo, hay que registrarlo, no ignorarlo.
Shubham Saboo (Senior AI PM en Google) dio la distinción estructural más clara: los sistemas multi-agente en producción tienen dos grafos simultáneos:
Org graph · estructural
Estable. Agentes de larga vida con roles fijos (Researcher, Writer, Validator), propiedad de zona, memoria preservada. Es el organigrama. Responde quién.
Work graph · dinámico
Efímero. Tareas que existen mientras dura el trabajo: se dividen, fusionan, reordenan o desaparecen según llega la evidencia. Es el tablero de sprint que se reescribe solo. Responde qué, ahora.
Un orquestador caro (modelo grande) lee el contexto y rutea; workers baratos ejecutan. Logra ~92% de la calidad del modelo caro solo, al ~63% del precio (SWE-bench Pro). Un orquestador, muchos workers, un nodo de agregación.
Especialistas de larga vida por dominio (Security / Data / API / Frontend). Cada uno corre un loop en su zona; los pedidos cruzan zonas por el work graph. Un Security Agent que revisó 300 PRs ya sabe el modelo de amenazas de memoria.
Un grafo es más rápido pero no siempre más barato:
Loop secuencial
Wall-clock alto · tokens medio. Mejor en tareas simples o de baja pass-rate. Modo de falla: reintentos infinitos y context bloat.
Grafo paralelo
Wall-clock bajo (~3× más rápido) · tokens más alto (varios agentes a la vez). Modo de falla: explosión de costo si la pass-rate es baja (fallan los 3 reviewers → re-corre todo).
El grafo gana en costo cuando la pass-rate por ciclo supera ~50%. Con 30% de pass-rate, ambos necesitan ~3.3 ciclos, pero cada ciclo del grafo cuesta 3× más tokens. La métrica que importa es costo por tarea completada con éxito, no solo wall-clock. (Estas cifras —3×, ~50%— son heurísticas del discurso de practicantes, no datos peer-reviewed: úsalas como referencia y mide en tu propio contexto.)
GraphRAG-Bench (arXiv 2506.05690): los sistemas basados en grafo ganan en razonamiento complejo multi-hop — HippoRAG2 53.4% vs 42.9% de RAG con rerank (dataset Novel) — y en síntesis sobre corpus completos; pierden en búsqueda de hechos simples. Y cuidado con la resolución de entidades: con 85% de precisión por salto, un recorrido de 5 saltos es confiable solo 44% de las veces (0.85⁵).
El término atrajo tanto humo que los mejores del rubro salieron a bajarlo. Concedamos todo lo que es cierto:
Grafos dirigidos de estados y transiciones no son nuevos. Anunciarlos como novedad es no conocer la historia.
"I call BS… solo dale al agente el objetivo, por qué importa y cómo se mide el éxito." El naming confunde el mecanismo (loops/grafos) con la sustancia (objetivos y verificación).
"Sub-agentes con un propósito definido ES un grafo. Pero bueno, confundamos a todos y llamémoslo algo completamente nuevo."
En pleno hype circuló un supuesto estudio de Stanford con un grant de $3.1M que NO existe (lo desmintió Eugeniu Ghelbur). Si ves cifras impresionantes sin fuente verificable, duda.
La mecánica no es nueva y gran parte del contenido de julio-2026 es ruido. Pero la escalación es real: equipos que dominaron un agente en loop están chocando con que un loop ya no alcanza, y dividen el trabajo en nodos especializados coordinados. La etiqueta es opcional; la escalación, no. Exactamente igual que el paper SGH: una propuesta rigurosa, aún no probada a escala.
Checklist antes de convertir un loop en grafo
1. Intentá que siga siendo un loop — si un agente con buen verificador alcanza, pará ahí.
2. Nombres de nodo solo si son especialidades reales (otro modelo, otro toolset, un reviewer read-only) — "pasos que podría inlinear" no son nodos.
3. Dibujá las aristas antes de codear — si no entra en una servilleta, es demasiado complejo.
4. Diseñá el estado compartido explícitamente — el state drift es la forma #1 en que los grafos se pudren.
5. Dale dientes al nodo reviewer — un verificador separado y read-only es el nodo de más valor.
6. Aislá las fallas — un nodo debe poder fallar sin corromper el estado ni envenenar a los demás.
7. Usá un framework, no reinventes el runtime (LangGraph / GraphFlow / ADK).
8. Poné un tope de gasto — un grafo es muchos loops; un verificador débil ahora quema tokens en paralelo.
El grafo ideal para nuestro voice agent — y el prompt para construirlo
Basta de ejemplos genéricos. Apliquemos todo al voice-agent-server, el proyecto real que tenemos en este repo: audio del reloj → Whisper → router Qwen → agente → respuesta. Verás que ya es un loop — y cómo se vería como grafo.
Mira el corazón de server/main.py. Es el patrón de la lección 01, literal:
continueSi la transcripción sale vacía, hace continue y ya. Sin estado explícito, sin contar intentos, sin pedir repetir, sin escalar. Si el audio falla 50 veces, hace 50 continue en silencio.
router.parse_intent() es una inferencia opaca de Qwen que decide qué agente (con un fallback keyword-based si la API falla — que tampoco verifica nada). Si se equivoca (confunde "dile" con "prende"), no hay verificación ni confianza explícita — simplemente ejecuta el agente equivocado.
Si executor.execute() falla, devuelve un string "✗ Error..." y se envía tal cual. Sin reintento, sin fallback, sin escalamiento. El usuario recibe el error crudo.
"Prende la luz y dile a María que llego" tiene DOS intents (home + hermes). El router elige uno solo — la mitad del comando se pierde. Un loop no puede fan-out.
El mismo sistema, pero con la estructura explícita: cada etapa es un nodo, cada falla tiene su camino, y el recovery y el escalamiento están escritos antes de ejecutar:
La transcripción vacía ya no es un continue mudo: es una transición a PEDIR REPETIR. El routing dudoso va a ACLARAR (no adivina). El agente que falla pasa por RECUPERAR (2 intentos: reintento → fallback keywords) y, si no, ESCALAR con log estructurado. Nada de eso es una decisión del modelo en el momento: está escrito en el grafo.
Aquí es donde el grafo hace algo que el loop no puede. "Prende la luz de la sala y dile a María que llego en 10" son dos intents independientes. El loop actual elige uno y descarta el otro. El grafo hace fan-out:
En el loop, ese comando tarda luz + mensaje en serie (y pierde uno). En el grafo, ambos agentes corren a la vez y la respuesta espera a los dos (all_of). Esto es el |𝒰| > 1 de la lección 02, aplicado a algo que literalmente decimos en voz alta todos los días.
Ahora la parte meta: ¿cómo le pides a un agente (opencode, Claude) que te construya esto y no un loop disfrazado? El prompt es la especificación del grafo — aplica los tres compromisos a la instrucción misma:
Por qué este prompt funciona (y uno genérico no)
Un prompt tipo "haz que el voice agent maneje errores" produce un loop con más if. Este prompt funciona porque no delega ninguna decisión estructural: los estados están enumerados (no los inventa), las transiciones son una tabla (no criterio del modelo), el límite de recovery es un número (MAX_INTENTOS=2, no "razonable"), y cada nodo tiene un criterio de éxito verificable (returncode==0, no "que se vea bien"). Es el grafo entero, escrito antes de ejecutar — exactamente la definición de la lección 02. El agente solo rellena la implementación; la forma ya está decidida y es auditable.
Un loop le dice al agente "resuelve esto". Un grafo le dice "resuelve esto, por aquí, hasta aquí, y si pasa esto, me avisas". El prompt ideal no pide un buen agente; especifica una buena estructura y deja al agente hacer su trabajo dentro de ella.
Migrar de loop a grafo sin reescribir todo
Tu equipo ya tiene loops corriendo — el voice agent, sin ir más lejos. La pregunta real no es "¿construyo un grafo desde cero?" sino "¿cómo convierto lo que ya existe, por etapas, sin romper nada?". Esta lección es ese camino, aplicado al main.py real.
Una etapa a la vez, y verifica cada una antes de pasar a la siguiente. Migrar las cuatro de golpe es un big-bang que falla en algún punto y no sabrás dónde. Cada etapa deja el sistema funcionando y estrictamente mejor que antes — si una etapa lo empeora, revierte esa etapa sola.
El loop ya tiene estados, pero implícitos (transcribir, routear, ejecutar están mezclados en el flujo). Nómbralos: un Enum con TRANSCRIBIR, ROUTEAR, EJECUTAR, RESPONDER. Aún no cambies la lógica — solo haz visible la estructura que ya existe. Verifica: el sistema se comporta idéntico; ahora puedes loguear en qué estado está.
Hoy main.py transcribe, rutea y ejecuta en la misma función. Extrae Router, Executor y un Recoverer como unidades que devuelven resultados, no que deciden. El orquestador llama; las capas reportan. Verifica: cada capa es testeable por separado con inputs fijos.
Reemplaza el continue mudo por un protocolo: MAX_INTENTOS=2 (reintento → fallback keywords) y luego ESCALAR con log estructurado. Verifica: fuerza una falla y confirma que reintenta 2 veces y escala — nunca una tercera.
Solo al final, y solo donde hay independencia real: detecta multi-intent en el Router y haz fan-out a varios Executor con join all_of. Verifica: "prende la luz y dile a María" ejecuta home y hermes y responde por ambos.
Cada etapa depende de la anterior y cada una entrega valor por sí sola: tras la etapa 1 ya puedes observar; tras la 2 ya puedes testear; tras la 3 ya no hay reintentos infinitos; la 4 es la guinda del paralelismo. Si te quedas a mitad (digamos, en la etapa 3), ya tienes un sistema estrictamente mejor que el loop original — no necesitas llegar a la 4 para que valga la pena.
Un comando simple de voz ("¿qué hora es?") es un loop perfecto; graficarlo es overhead. La migración aplica a los flujos donde el loop ya te está doliendo: reintentos sin fin, decisiones inauditables, comandos multi-parte que se pierden. Migra esos. Deja en loop lo que funciona como loop.
Cuando el planner falla: el plan puede estar mal
Un plan inmutable es tan bueno como el planner que lo hizo. El paper lo dice directo: el valor de SGH está acotado por la calidad del planner — puede generar un DAG estructuralmente válido pero estratégicamente errado, y como el plan está bloqueado, ese error se ejecuta fielmente hasta el final. (La limitación que el paper pone primera es la falta de validación empírica — lección 18; la calidad del planner es el principal riesgo al usarlo en la práctica.)
El plan pone "correr tests" antes de "instalar dependencias". Faltó la arista. El nodo corre con inputs que aún no existen.
El plan serializa dos pasos que eran independientes. No es incorrecto, pero mata el paralelismo y agrega latencia sin razón.
El plan elige la semántica de join incorrecta: usa all_of donde iba any_of (o al revés). Ej: obliga a que todas las ramas alternativas completen cuando bastaba una — o descarta ramas que sí hacían falta.
El plan divide una tarea simple en 15 micro-nodos. Puro overhead: más estados, más estado compartido, más puntos de falla.
El plan deja un nodo gigante ("hacer todo el backend") que esconde complejidad y no se puede verificar ni recuperar por partes.
Validación estructural (antes de correr)
Como el plan es un artefacto explícito, se puede validar antes de ejecutar: ¿es un DAG válido (sin ciclos)? ¿hay nodos inalcanzables? ¿todo nodo tiene sus inputs cubiertos por algún nodo anterior? ¿los criterios de éxito están definidos? Un loop no te deja hacer esto — el "plan" está enterrado en el razonamiento.
Detección en runtime
Cada nodo valida su contrato al terminar (¿se cumplió el criterio de éxito?). Si un nodo produce algo que el siguiente no puede consumir, se detecta la divergencia en el punto exacto donde ocurre — no 20 pasos después cuando todo explota.
Seas riguroso o no, queda un riesgo residual: el planner es un LLM y puede producir un plan que pasa toda validación estructural y aun así está semánticamente mal. La red de seguridad final es la misma de siempre — el checkpoint humano: escalamiento cuando el recovery se agota, y un humano que mira el plan antes de ejecuciones de alto riesgo. El grafo no elimina el error del planner; lo hace visible y atrapable, que es más de lo que un loop ofrece.
El estado compartido: lo que viaja por las aristas
Un grafo son nodos, aristas y un objeto de estado que fluye entre ellos: la tarea, el borrador hasta ahora, las notas, el veredicto. Ese estado es la sangre del sistema — y el state drift (que se pudra sin que nadie note quién lo cambió) es la forma #1 en que los grafos se degradan.
El estado convierte "un grupo de agentes" en un sistema. Sin él, cada nodo empieza de cero y el grafo es un grupo de chat que olvida todo. Con él mal diseñado, es un grupo de chat donde todos editan el mismo documento a la vez.
| Estado sano | God object (anti-patrón) | |
|---|---|---|
| schema | Explícito y tipado: se sabe qué campos existen y qué significan | Un dict enorme donde cada nodo mete lo que quiere |
| escritura | Cada campo tiene un único escritor conocido (o escrituras controladas) | Cualquier nodo muta cualquier campo en cualquier momento |
| historial | Snapshots/checkpoints: puedes ver el estado en cada paso | Solo existe el estado final; el intermedio se perdió |
| tamaño | Mínimo: viaja solo lo que los nodos necesitan | Se acumula todo "por si acaso" → bloat y contexto inflado |
| debug | "El nodo X escribió Y en el paso 3" — trazable | "Apareció un valor raro y nadie sabe quién lo puso" |
Esto es la separación de contexto de la lección 04 aplicada al estado: el C_exec (lo que el nodo necesita para trabajar) y el C_diag (lo que se necesita para diagnosticar una falla) no deberían ser el mismo blob. Separarlos evita que la recuperación contamine la ejecución y que el estado de trabajo se infle con metadata de debug.
Para grafos de larga duración: checkpointing
Si el grafo corre minutos u horas (una migración, un pipeline editorial), persiste el estado en cada transición. Así, si un nodo falla o el proceso se cae, retomas desde el último checkpoint en vez de recomenzar desde cero — y de paso obtienes el historial completo de estados para auditar. Sin checkpoints, un grafo largo es tan frágil como un loop largo.
Observabilidad: leer y debuggear un grafo en producción
"Auditable" es la promesa; la observabilidad es la práctica. De nada sirve un grafo explícito si no registras su ejecución de forma estructurada. Esta lección es cómo pasar del log.info() disperso del loop a un rastro de auditoría que reconstruye cualquier ejecución.
Loop actual (main.py)
log.info("Transcripción: %s", texto)
log.info("Intent: %s", intent)
log.info("Ejecución: %s", result)
→ 3 prints sueltos. Si hermes falla, el error se devuelve como string: no hay registro estructurado de qué falló, ni recovery, ni métrica por nodo.
Grafo (rastro estructurado)
Cada transición es un evento con timestamp, estado, resultado, duración y costo. El rastro es la ejecución — se puede replayear, auditar y alertar sobre él.
Con este rastro, cualquiera responde en segundos: ¿qué falló? hermes. ¿Se recuperó? sí, al primer reintento. ¿Cuánto costó? 180 tokens. ¿Hubo que escalar? no. Eso es auditabilidad real — no releer el razonamiento de un modelo.
Cada cambio de nodo con timestamp. Es el esqueleto del rastro — la secuencia exacta de por dónde pasó la ejecución.
Qué recibió y qué produjo cada nodo, y si cumplió su criterio de éxito. Así una divergencia se localiza en el nodo exacto.
Tokens y segundos por nodo. Revela dónde se va el presupuesto y qué nodo es el cuello de botella.
Cada reintento (con qué enfoque) y cada escalamiento (con el historial). La señal más importante de salud del sistema.
Tasa de escalamiento por nodo (¿qué nodo escala más?), tasa de falla por nodo, costo por ejecución exitosa y tasa de divergencia del plan. Si un nodo escala de golpe mucho más que antes, algo cambió — y el rastro te dice el qué. Un loop no te da estas métricas por nodo porque no tiene nodos.
Medición: ¿tu grafo es realmente mejor?
El principio de honestidad del curso, aplicado al final: no asumas que el grafo gana — mídelo. El paper propone un diseño experimental de 7 grupos justamente porque la ganancia no es automática. Esta lección es cómo comprobarlo en tu sistema, con números.
Un grafo tiene overhead de estructura: planificar, validar, mantener estado, loguear. Ese costo es roughly fijo. Solo se paga cuando la tarea es bastante compleja o larga para que el ahorro (paralelismo, recovery acotado, menos reintentos) lo supere. En tareas simples, el grafo pierde — pagas la estructura sin cosechar el beneficio.
¿Completa la tarea correctamente? Tasa de éxito. De nada sirve más rápido si falla más.
Tokens y wall-clock por ejecución. La métrica que todos miran — pero nunca sola.
Varianza entre ejecuciones, tasa de falla. Un sistema "rápido en promedio" pero errático no sirve en producción.
¿Puedes reconstruir cada ejecución? (Lección 16.) Un sistema que no puedes debuggear es una bomba de tiempo.
La difícil: ¿qué decisión de diseño causó la ganancia? El diseño de 7 grupos del paper aísla cada una (G_plan, G_graph, G_patch…) para no atribuir al grafo entero lo que hizo una sola pieza.
Un comando de una acción. El overhead del grafo supera cualquier ahorro. Loop.
Si cada ciclo falla mucho, el grafo re-ejecuta sus ramas paralelas y el costo explota (lección 11, break-even ~50%).
No puedes conocer la estructura de antemano. Bloquear un plan inmutable aquí es perder la adaptabilidad que necesitabas.
El A/B mínimo que sí puedes hacer
Corre el mismo set de tareas reales por el loop y por el grafo. Mide, para cada uno: tasa de éxito, tokens totales, wall-clock, y costo por ejecución exitosa (tokens ÷ éxitos — la métrica que importa). Cuenta además los escalamientos del grafo y en qué nodo. Si el costo-por-éxito del grafo no es claramente menor en tus tareas complejas, el grafo no está ganando — por más elegante que se vea el diagrama.
Graph engineering no es "grafos buenos, loops malos". Es saber en qué punto del continuo (lección 02) está cada tarea, construir la estructura explícita cuando vale la pena, observarla, y medir sin autoengaño si funcionó. Esa disciplina — tratar cada framework como una hipótesis a probar — es lo que te llevas de este curso, más que cualquier diagrama.
El estado honesto de la evidencia — y tu examen
Cerramos con la advertencia con la que abrimos, porque aquí importa más que en la mayoría de los writeups técnicos.
Los tres compromisos son una propuesta real y cuidadosamente razonada, analizada contra 70 sistemas reales para identificar dónde fallan los loops en silencio. No están validados todavía como entregando sus beneficios a escala en producción — por declaración explícita del propio autor (paper de arXiv, abril 2026, diseño no implementado). Esto no vuelve al framework inútil: lo vuelve una propuesta prometedora que merece experimentación deliberada y medición honesta de tus propios resultados.
La meta-habilidad debajo de todo el curso
Si construyes un sistema grafado con este curso, lo más valioso que puedes hacer es medir si realmente reduce los modos de falla que ataca — reintentos ilimitados, deriva de plan no detectada, decisiones de recuperación no auditadas — contra tu propio uso real. Tratar un framework bien razonado como una hipótesis a probar, no como un hecho a adoptar acríticamente, es la verdadera disciplina. Graph engineering, loop engineering, cualquier práctica con nombre en este campo: vale la pena aprenderla bien y probarla honestamente — no adoptarla solo porque tiene un nombre y un paper detrás.
La fuente primaria, citable
Hu Wei (2026). From Agent Loops to Structured Graphs: A Scheduler-Theoretic Framework for LLM Agent Execution.
arXiv:2604.11378 [cs.AI] · enviado 13 abr 2026 · 51 páginas, 4 figuras · cs.AI + eess.SY (Systems and Control) · DOI 10.48550/arXiv.2604.11378
El framework se llama SGH (Structured Graph Harness): un DAG estático explícito. El curso de X que origina este material es de @cyrilXBT; el paper académico subyacente es de Hu Wei. Cita el paper para el rigor; sigue a @cyrilXBT para las actualizaciones prácticas.
El paper es explícito sobre su propio alcance: es un position paper y una propuesta de diseño. Aporta un marco teórico, un análisis de diseño y un protocolo experimental — no una implementación de producción ni resultados empíricos. Fue verificado por consistencia interna y completitud de la máquina de estados, nada más. Y el propio autor lista seis limitaciones:
Las ganancias son predicciones teóricas. El diseño de 7 grupos existe precisamente para que otros lo validen en el futuro.
Asume que la estructura de la tarea se puede conocer al planificar. Las tareas que no se dejan estructurar de antemano encajan mal.
Los nodos son no-deterministas; un error de razonamiento puede propagarse por el grafo si no se detecta.
La recuperación acotada necesita una librería de patrones/protocolos conocidos que al principio no existe.
No hay cotas formales de complejidad computacional del scheduling con nodos LLM.
Scheduling concurrente, persistencia de estado y ejecución tolerante a fallos quedan como trabajo de ingeniería pendiente.
El paper propone un diseño experimental de 7 grupos que aísla la contribución de cada decisión de diseño — las ganancias G_plan, G_scaffold, G_graph, G_patch y G_replan — midiendo cinco familias de métricas: eficacia, eficiencia, estabilidad, observabilidad y atribución. Es el protocolo correcto; ejecutarlo está fuera del alcance del paper. Si tu equipo adopta SGH, este es el esquema que deberías replicar para medir si realmente funciona en su contexto.
- SGH Structured Graph Harness — el framework (DAG estático)
- |𝒰| cardinalidad del ready-set — unidades despachables a la vez
- política explícita vs opaca — qué tan inspeccionable es el scheduling
- continuum loops y grafos en un mismo gradiente, no binarios
- single-ready-unit scheduler con |𝒰|=1 siempre (el loop)
- all_of / any_of joins soportados (paralelismo constructivo)
- first_of join excluido (paralelismo competitivo)
- C_exec / C_diag contextos de ejecución vs diagnóstico separados
- bounded recovery recuperación con límite hecho cumplir mecánicamente
- side-effect class. 4º principio: clasificar efectos de cada nodo
→ Paper: arxiv.org/abs/2604.11378 (HTML: /html/2604.11378v1)
→ Curso original en X: @cyrilXBT — How to master graph engineering
→ Fundamentos citados por el paper: ReAct (Yao 2023) · Chain-of-Thought (Wei 2022) · Plan-and-Solve (Wang 2023) · LangGraph · Airflow/Luigi/Prefect · DAG scheduling clásico (Topcuoglu 2002)
RESUMEN EJECUTIVO
- S0 PLAN — descompone y bloquea, una sola vez
- S1 EJECUTAR — trabaja y reporta PASS/FAIL con evidencia
- S2 RECUPERAR — aplica el protocolo, no improvisa
- S3 ESCALAR — entrega el control a un humano, visible
- S4 REPETIR — siguiente paso del plan, o FIN
- C1 Plan inmutable — una versión fija por ejecución
- C2 Capas separadas — planificar ≠ ejecutar ≠ recuperar
- C3 Escalamiento estricto — número fijo de intentos, final humano
- inmutable solo de nombre · colapsar las capas · protocolo vago · saltarse el calce
usa un GRAFO cuando importa al revés