Módulo 5: Dependencias entre workflows
7. Delegación entre múltiples agentes sin duplicar trabajo
Descripción
Al terminar esta lección vas a poder tomar un sistema donde un AI Agent delega trabajo en otro —el patrón de "un agente como tool de otro" que viste en la guía de chatbots— y garantizar que ningún efecto se dispare dos veces por culpa de la delegación, aunque dos agentes decidan hacer lo mismo, aunque un agente reintente, o aunque entren en un bucle de redelegación. Vas a ver por qué los agentes son especialmente peligrosos para la correctitud (son no deterministas: dos corridas pueden decidir cosas distintas), y vas a aprender la estrategia que lo resuelve sin matar la autonomía que hace útil a un agente: no intentar que los agentes no dupliquen, sino hacer que sus efectos sean idempotentes para que no importe si duplican. Las herramientas son las de siempre —la clave de idempotencia del Módulo 2, el ledger como memoria compartida del Módulo 4, el outbox de la lección 6— más dos frenos propios de los agentes: el límite de iteraciones y una tool para consultar qué ya se hizo.
Esto importa porque los sistemas multi-agente son la frontera donde más fácil se cuela un efecto duplicado, y donde más difícil es de depurar. Un agente no ejecuta un plan fijo: razona, elige, y a veces elige distinto la segunda vez. Si su tool es "emitir un reembolso" y por cualquier razón el agente la llama dos veces —porque reintentó, porque otro agente ya lo había hecho, porque el bucle de razonamiento dio una vuelta de más— tienes un reembolso duplicado disparado por una decisión que ni siquiera fue determinista. La buena noticia es que todo lo que construiste en este módulo aplica sin cambios: un efecto de agente es un efecto, y un efecto se protege igual venga de un nodo IF o de un modelo razonando.
Conexión con el módulo: esta lección es la aplicación de todo lo anterior a un caso concreto y de moda. El outbox de la lección 6 es la forma correcta de que un agente dispare un efecto peligroso: el agente no llama a la pasarela, anota una comanda. El ledger de la lección 1 y del Módulo 4 —el pizarrón compartido— es lo que deja que dos agentes no repitan el trabajo del otro. Y se apoya en la guía hermana de chatbots, Módulo 5: de ahí vienen el nodo AI Agent Tool, el mecanismo $fromAI(), el parámetro Max Iterations y los bucles de delegación. Aquí no volvemos a enseñar a construir el sistema multi-agente —eso es aquella guía—; aquí lo hacemos correcto: que sus efectos no se dupliquen.
Por qué un agente es más peligroso que un IF
Empecemos por entender qué hace especial —y riesgoso— a un agente respecto a todo lo que vimos hasta ahora.
Un nodo IF, un Switch, un flujo de nodos: son deterministas. Dado el mismo dato de entrada, hacen exactamente lo mismo, siempre. Si un flujo determinista decide emitir un reembolso, la única forma de que lo emita dos veces es que corra dos veces —el problema del duplicado que ya sabes manejar—.
Un AI Agent es distinto: es no determinista. Le das el mismo caso dos veces y puede razonar dos caminos distintos, elegir tools distintas, llegar a conclusiones distintas. Esa es justamente su virtud —se adapta a lo que no anticipaste— y es su peligro para la correctitud. Piénsalo con dos empleados nuevos a los que les dices "resuelve el problema de este cliente". Un empleado revisa, ve que corresponde un reembolso, y lo emite. El otro empleado, con el mismo caso, revisa, y también decide emitir el reembolso —quizás por un camino de razonamiento distinto, pero llega al mismo efecto—. Si los dos actúan, hay dos reembolsos. No porque ninguno haya fallado: los dos hicieron su trabajo bien. El problema es que nadie coordinó que el efecto ya estaba hecho.
Esa escena —dos que hacen bien lo mismo sin enterarse el uno del otro— es el desastre 3 de la lección 1, el efecto duplicado, en su versión más difícil de prevenir, porque los actores razonan y no puedes predecir exactamente qué van a decidir. Y se agrava con la delegación: cuando un agente delega en otro, aparecen caminos nuevos para que el mismo efecto se dispare dos veces.
Recordatorio de la delegación nativa
Para hablar de los riesgos hay que tener fresco el mecanismo. Viene de la guía de chatbots, Módulo 5, y lo resumimos sin volver a enseñarlo.
En n8n 2.0, un agente completo se puede conectar como tool de otro agente, usando el nodo AI Agent Tool (su tipo interno es @n8n/n8n-nodes-langchain.agentTool). Se conecta al puerto ai_tool del agente que llama, igual que se conectaría un nodo de Gmail. Desde el punto de vista del que llama —el orquestador—, es una tool más: tiene una Description que dice cuándo usarla, y recibe su encargo por un $fromAI("task", ...). La diferencia es que del otro lado del cable no hay una acción fija, sino otro agente que razona, elige entre sus propias tools, y devuelve un resultado.
En Cumbre, imagina un triage_agent (el orquestador, que atiende al cliente) que delega en un billing_agent (el especialista en cobros y reembolsos). Cuando el cliente dice "me cobraron de más por el pedido ORD-2041", el triage_agent decide delegar en billing_agent, pasándole un encargo autocontenido. billing_agent razona, consulta, y en cierto punto decide emitir un reembolso. Ese "emitir un reembolso" es un efecto, y es donde entra esta lección.
Tres piezas de aquella guía que aquí son frenos de correctitud:
Max Iterations: cuántas vueltas de razonar-actuar-observar puede dar un agente antes de rendirse. Viene con un valor por defecto —10 en el nodoAI Agent—. Es el freno contra los bucles infinitos.- Los bucles de delegación: un sistema multi-agente tiene bucles anidados —el interno de cada agente, el del orquestador, y el peligroso bucle de redelegación, donde dos especialistas se devuelven el mismo caso ("esto es de facturación" / "esto es de pedidos") y el orquestador redelega sin fin—.
- La regla de que los trabajadores no se delegan entre sí directamente: para que el grafo de agentes no tenga ciclos, un especialista no llama a otro especialista; todo pasa por el orquestador. Es la misma disciplina anti-ciclos de la lección 3, aplicada a agentes.
Con eso fresco, veamos los caminos nuevos por los que un efecto de agente se duplica.
Los tres caminos del duplicado en un sistema multi-agente
Camino 1 — El agente reintenta su propia tool
Un agente llama a su tool "emitir reembolso", la llamada tarda, el agente —o el motor— reintenta, y quedan dos llamadas al efecto para el mismo pedido. Es el duplicado clásico del Módulo 1, dentro del razonamiento de un agente. Como el agente no lleva por sí mismo un registro durable de "ya emití este reembolso", no tiene cómo saber que la primera llamada quizás sí funcionó.
Camino 2 — Dos agentes deciden el mismo efecto
El orquestador delega el caso en billing_agent, que emite el reembolso. Pero el encargo era ambiguo y el orquestador, al no recibir una confirmación clara, delega otra vez —quizás en el mismo agente, quizás en otro— que vuelve a emitir el reembolso. Dos delegaciones, dos reembolsos. Es la escena de los dos empleados: cada delegación hizo su trabajo, nadie coordinó que ya estaba hecho.
Camino 3 — El bucle de redelegación
El caso cae en una frontera difusa entre dos especialistas. order_agent dice "esto es de facturación", el orquestador delega en billing_agent, que dice "esto es de pedidos", el orquestador delega de vuelta en order_agent... y si en alguna de esas vueltas alguno emite un efecto "por si acaso", el efecto se repite en cada vuelta del bucle. Este bucle, además de duplicar, quema dinero y tiempo —cada vuelta es una llamada al modelo— y, como viste en la guía de chatbots, no produce ningún error: el sistema se ve "pensando" mientras gira en falso.
Los tres caminos tienen la misma raíz: el efecto se dispara desde un actor que no sabe, de forma durable y compartida, si ese efecto ya se hizo. Y por lo tanto tienen la misma cura.
La estrategia: no confíes en el agente, blinda el efecto
Aquí está la idea central de la lección, y es un cambio de mentalidad. La tentación es intentar que los agentes no dupliquen: escribir prompts perfectos, poner reglas para que el orquestador nunca redelega dos veces, afinar las fronteras entre especialistas. Todo eso ayuda —y hay que hacerlo— pero no es donde vive la garantía, por una razón de fondo: el agente es no determinista, así que nunca vas a poder garantizar por prompt que jamás dispare un efecto dos veces. Un prompt reduce la probabilidad; no la lleva a cero.
La garantía vive en otro lado: haz que el efecto sea idempotente, para que no importe cuántas veces lo dispare el agente. Si "emitir el reembolso de ORD-2041" es idempotente —ocurre una sola vez sin importar cuántas veces se pida— entonces los tres caminos del duplicado dejan de hacer daño. El agente puede reintentar (camino 1), el orquestador puede redelegar (camino 2), el bucle puede girar (camino 3): cada intento de emitir el reembolso, después del primero, no hace nada. La corrección no depende de que el agente se porte bien; depende de que el efecto esté blindado.
Piénsalo así: en vez de pedirles a los dos empleados que se coordinen perfectamente —lo cual es frágil— pones una regla en la caja donde se emiten los reembolsos: "un reembolso por número de pedido, y ya". No importa cuántos empleados vengan a pedir el reembolso del pedido ORD-2041; la caja lo emite una vez. Coordinar a los actores es difícil y frágil; blindar el recurso compartido es robusto.
Y esto ya lo tienes construido. Los dos mecanismos son de este módulo:
La tool del agente no es el efecto crudo — es el efecto idempotente. Cuando conectas una tool de "emitir reembolso" a billing_agent, esa tool no debe ser un HTTP Request directo a la pasarela. Debe ser el camino idempotente que construiste: o el sub-workflow issue-refund que verifica el ledger antes de emitir, o —mejor para un efecto peligroso— una comanda en el outbox. Así, cuando el agente "emite el reembolso", en realidad está anotando una comanda idempotente por order_id, y el relay la ejecuta una sola vez. El agente cree que emitió el reembolso; lo que hizo fue registrar una intención que el sistema ejecuta exactamente una vez.
El ledger es la memoria compartida entre agentes. El pizarrón de la cocina de la lección 1, ahora entre agentes. Antes de emitir un reembolso, un agente puede —y conviene que pueda— consultar el ledger: "¿ya se emitió el reembolso de ORD-2041?". Si sí, no lo intenta. Esto se le da al agente como una tool de lectura ("consultar estado del pedido"), y es lo que corta el camino 2 y el 3 en su origen: el segundo agente que va a emitir el reembolso mira el pizarrón, ve que ya está hecho, y no lo hace. Es más barato que dejar que lo dispare y que el efecto lo rechace, y le da al agente la información para razonar bien.
Fíjate que son dos capas: el agente consulta el ledger antes de actuar (evita el trabajo inútil y las llamadas al modelo de más), y el efecto es idempotente de todas formas (garantiza la corrección aunque el agente, siendo no determinista, ignore lo que vio en el ledger). La primera capa es eficiencia; la segunda es la garantía. Nunca dependas solo de la primera: el agente puede consultar el ledger y aun así decidir emitir el reembolso, porque es no determinista. La red de abajo —el efecto idempotente— es la que no falla.
Ejemplo trabajado: el reembolso que billing_agent no puede duplicar
Construyamos el caso completo y probémoslo contra los tres caminos.
El montaje. triage_agent (orquestador) tiene conectado a billing_agent como AI Agent Tool. billing_agent, a su vez, tiene dos tools:
- Una tool de lectura:
get_order_status, un sub-workflow que consulta el ledger y devuelve el estado del pedido, incluido si ya tiene un reembolso emitido o decidido. - Una tool de efecto:
request_refund, que no llama a la pasarela directamente. Es un sub-workflow que anota una comanda en eloutboxpara el reembolso, de forma atómica e idempotente pororder_id, como en la lección 6. Devuelve "reembolso registrado" o "reembolso ya estaba registrado".
El System Message de billing_agent incluye la política:
# System Message de billing_agent (fragmento de correctitud)
Antes de solicitar un reembolso, SIEMPRE consulta primero get_order_status.
Si el pedido ya tiene un reembolso emitido o decidido, NO vuelvas a
solicitarlo: informa que ya estaba hecho.
Para solicitar un reembolso usa request_refund con el order_id. Esta
herramienta es idempotente: si la llamas dos veces para el mismo pedido,
el reembolso ocurre una sola vez. Aun así, evita llamarla si ya sabes
que está hecho.
Nota lo que hace ese prompt: le dice al agente que consulte antes (capa 1, eficiencia) y le informa que la tool es idempotente (para que no tenga miedo de un duplicado si algo sale mal). Las dos capas, declaradas.
El efecto idempotente, por dentro. La tool request_refund es el sub-workflow de la lección 6:
# Sub-workflow: request_refund (Execute Sub-workflow Trigger)
# entrada (contrato): order_id, amount, currency
1. Postgres (atómico): registrar la decisión de reembolso en el ledger
E insertar la comanda en el outbox, con
idempotency_key = 'refund:' + order_id,
ON CONFLICT DO NOTHING.
2. Devolver: "registrado" si fue nuevo, "ya estaba" si el ON CONFLICT lo saltó.
El reembolso de verdad lo emite el relay, después, con la Idempotency-Key. billing_agent nunca toca la pasarela; solo registra la intención. Recuerda las reglas de n8n 2.0: el efecto externo (la pasarela) lo hace un HTTP Request en el relay, no un nodo Code; la escritura del outbox la hace un nodo Postgres. El agente decide; los nodos dedicados ejecutan.
Qué esperar, camino por camino.
Camino 1 — el agente reintenta request_refund. billing_agent llama a request_refund para ORD-2041; la llamada tarda; el agente reintenta. Las dos llamadas insertan con la misma idempotency_key = 'refund:ORD-2041'. La primera inserta la comanda; la segunda choca con el ON CONFLICT y no inserta nada. Hay una comanda en el outbox, el relay emite un reembolso. El reintento del agente no hizo daño.
Camino 2 — el orquestador redelega. triage_agent delega en billing_agent, que registra el reembolso. Por una ambigüedad, triage_agent delega otra vez. El segundo billing_agent, siguiendo su prompt, consulta get_order_status primero, ve que el reembolso ya está decidido, y no llama a request_refund —informa que ya estaba hecho—. La capa 1 (consultar antes) cortó el trabajo inútil. Y si por ser no determinista hubiera llamado a request_refund igual, el ON CONFLICT lo habría saltado: la capa 2 lo cubre. Un reembolso.
Camino 3 — el bucle de redelegación. El caso rebota entre billing_agent y order_agent. Aquí actúan dos frenos: el Max Iterations del orquestador corta el bucle antes de que gire sin fin (freno de la guía de chatbots), y aunque en alguna vuelta un agente llamara a request_refund, la idempotencia por order_id garantiza un solo reembolso. El bucle quema algo de dinero en llamadas al modelo antes de cortarse —por eso hay que trazar fronteras claras entre especialistas— pero no produce reembolsos duplicados. El daño del bucle queda acotado a costo, no a efectos.
En los tres caminos, exactamente un reembolso. Y fíjate en el patrón: los prompts y los límites reducen los intentos duplicados (eficiencia, costo), pero la garantía de que el efecto ocurre una vez viene de la idempotencia por order_id, no del comportamiento del agente. Esa es la lección.
Poner los frenos: iteraciones, claves y memoria compartida
Resumamos los frenos concretos, que son la combinación de esta guía y la de chatbots:
Límite de iteraciones (Max Iterations). Cada agente y el orquestador llevan un tope de vueltas. Sin él, el bucle de redelegación gira hasta agotar el presupuesto. Con él, el sistema se rinde de forma controlada y —bien configurado con una instrucción de honestidad en el prompt— dice "no pude resolver esto, lo escalo" en vez de girar. Calíbralo con tus trazas, como enseña la guía de chatbots: cuenta las iteraciones reales de un caso típico y dale margen.
Clave de idempotencia por tarea/efecto. Cada efecto que un agente puede disparar tiene su clave estable, derivada del negocio: refund:ORD-2041, inventory:ORD-2041:CF-ARA-500. La clave es lo que deduplica sin importar cuántos agentes o vueltas la disparen. La clave va por el efecto (el order_id, el sku), no por la corrida del agente —si la derivaras del identificador de la ejecución del agente, dos corridas tendrían claves distintas y no deduplicarían nada—.
El ledger como memoria compartida. Dale a los agentes una tool de lectura del ledger, para que consulten qué ya se hizo antes de actuar. Es la memoria común que evita que dos agentes repitan el trabajo. Y mantenla como fuente de verdad: el estado de un pedido vive en el ledger, no en la memoria conversacional de un agente —que es efímera y no compartida—.
Contra el bucle de redelegación, fronteras claras y un contador. La causa del bucle 3 es casi siempre una frontera difusa entre dos especialistas. La primera defensa es un buen diseño de tools (descripciones de ámbito con "no lo uses para..." explícito, como enseña la guía de chatbots). La segunda, un contador de redelegaciones en el prompt del orquestador o en el ledger: "si este caso ya rebotó dos veces entre especialistas, escálalo a un humano en vez de seguir delegando".
Una nota sobre los modelos y las fechas
Los modelos concretos que uses para cada agente —cuál va en el orquestador, cuál en el especialista— cambian seguido, y las recomendaciones envejecen rápido. Al momento de escribir esta guía, mediados de 2026, la práctica común es un modelo rápido y barato en el orquestador (que solo decide a quién delegar) y uno más capaz en los especialistas que toman decisiones costosas —como emitir dinero—. Pero los nombres y las capacidades específicas los debes verificar en la documentación y en el panel de tu instancia cuando montes esto: lo que no cambia es la arquitectura de correctitud —efectos idempotentes, ledger compartido, límites de iteración—, que es independiente del modelo que pongas detrás. Un sistema con el mejor modelo del mercado pero sin efectos idempotentes duplica reembolsos; uno con un modelo modesto pero con los efectos blindados, no. La correctitud no la da el modelo.
Errores comunes
Intentar prevenir el duplicado solo con el prompt (conceptual). Qué pasa: alguien escribe un System Message cuidadoso —"nunca emitas un reembolso dos veces", "coordina con los otros especialistas"— y confía en eso como garantía. Funciona en las pruebas, y un día, bajo un caso raro, el agente emite el reembolso dos veces igual, porque es no determinista y el prompt solo baja la probabilidad. Por qué pasa: un prompt bien escrito reduce tanto los duplicados que da la ilusión de haberlos eliminado. Cómo detectarlo: pregúntate "si el agente, por la razón que sea, dispara este efecto dos veces, ¿qué lo detiene?". Si la única respuesta es "el prompt le dijo que no", no hay garantía. Cómo corregirlo: el prompt es la capa de eficiencia; la garantía es el efecto idempotente por su clave de negocio. Escribe buenos prompts y blinda los efectos; nunca solo lo primero.
Conectar el efecto crudo como tool del agente (práctico). Qué pasa: se conecta un HTTP Request directo a la pasarela de pago como tool "emitir reembolso" del billing_agent. Como la tool es el efecto crudo, cada vez que el agente la llama —por reintento, por redelegación, por bucle— se emite un reembolso de verdad. El agente no determinista sobre un efecto no idempotente es la receta del duplicado. Por qué pasa: es lo más directo —el agente necesita "emitir un reembolso", conectas el nodo que emite reembolsos—. Cómo detectarlo: si la tool de efecto de un agente es una llamada externa sin idempotencia (sin Idempotency-Key, sin verificación de ledger, sin outbox), está cruda. Cómo corregirlo: la tool de efecto de un agente siempre es el camino idempotente —un sub-workflow que verifica el ledger o que anota una comanda en el outbox—, nunca el efecto crudo; el agente registra intenciones, el sistema las ejecuta una vez.
Derivar la clave de idempotencia de la ejecución del agente en vez del negocio (práctico). Qué pasa: alguien construye la clave del reembolso a partir del identificador de la corrida del agente o de la conversación, pensando "así cada intento tiene su clave". El resultado es lo contrario de lo que quería: como cada redelegación o reintento es una corrida distinta, cada una tiene una clave distinta, y todas pasan —se emiten varios reembolsos, cada uno "idempotente" respecto de sí mismo pero no respecto del pedido—. Por qué pasa: "una clave por intento" suena a idempotencia, pero la idempotencia se define respecto del efecto de negocio, no del intento. Cómo detectarlo: si dos intentos del mismo efecto (mismo pedido) producen claves distintas, la clave está mal derivada. Cómo corregirlo: la clave sale del negocio —refund:ORD-2041—, estable para todos los intentos del mismo efecto, sin importar qué agente, qué corrida o qué vuelta del bucle lo dispare.
Dejar que un especialista delegue en otro especialista (conceptual). Qué pasa: para "que se coordinen mejor", alguien conecta billing_agent como tool de order_agent y viceversa. Se crea un ciclo en el grafo de agentes, y aparece la delegación circular directa: billing_agent llama a order_agent, que llama a billing_agent, sin que el orquestador se entere, girando y potencialmente duplicando efectos en cada vuelta. Por qué pasa: parece eficiente que dos especialistas se hablen directo en vez de subir todo al orquestador. Cómo detectarlo: revisa el grafo de agentes (o el JSON exportado); si un especialista tiene a otro especialista como tool, hay un ciclo posible. Cómo corregirlo: aplica la regla de la guía de chatbots —los trabajadores no se delegan entre sí; todo pasa por el orquestador—, que mantiene el grafo de agentes acíclico igual que la lección 3 mantiene acíclico el grafo de workflows. Sin ciclos, la delegación circular es imposible por construcción.
Ejercicios
Ejercicio 1 — Identifica la capa que falla. Para cada situación, di qué capa de defensa faltó —el prompt/consulta previa (eficiencia) o el efecto idempotente (garantía)— y cuál habría evitado el daño:
(a) El agente consultó el ledger, vio que no había reembolso, pero entre esa consulta y su acción otro agente ya lo había emitido; el agente emitió un segundo reembolso.
(b) El agente tenía una tool de reembolso idempotente por order_id, pero llamaba a la pasarela en cada intento igual; nunca hubo duplicado, solo llamadas de más a la pasarela que ella rechazó.
(c) No había consulta previa ni idempotencia; el bucle de redelegación giró seis veces y emitió seis reembolsos.
Ver solución
(a) Falló la garantía (el efecto idempotente). La consulta previa —capa 1— no alcanza, porque entre "consulté y no había" y "actué" pasó tiempo, y en ese hueco otro agente actuó. Este es exactamente el problema de "verificar y luego actuar" del Módulo 2: la verificación y la acción no son atómicas. Lo que lo habría evitado es la capa 2: si request_refund fuera idempotente por order_id, el segundo reembolso habría chocado con la clave y no se habría emitido, sin importar el hueco entre consulta y acción.
(b) Aquí no falló nada de correctitud —no hubo duplicado, la garantía funcionó—; lo que faltó fue la eficiencia de la capa 1. El agente no consultó antes, así que hizo llamadas de más que la pasarela tuvo que rechazar. No es un bug de correctitud, es desperdicio: la capa 2 protegió el resultado, pero sin la capa 1 se gastaron llamadas inútiles. Vale la pena agregar la consulta previa para no molestar a la pasarela, pero el sistema es correcto.
(c) Faltaron las dos capas. Sin consulta previa, cada vuelta del bucle intentó el reembolso; sin idempotencia, cada intento lo emitió de verdad. Seis vueltas, seis reembolsos. Cualquiera de las dos capas habría reducido el daño —la capa 1 habría evitado los intentos, la capa 2 habría deduplicado los efectos— pero la garantía es la capa 2: con ella, seis vueltas habrían dado un solo reembolso, aunque igual habría convenido cortar el bucle con Max Iterations.
Por qué funciona: distinguir cuál capa falló te dice qué arreglar. Si el problema es "trabajo/llamadas de más pero resultado correcto", falta eficiencia (capa 1). Si el problema es "efecto duplicado", falta la garantía (capa 2). El caso (a) es el más instructivo: muestra por qué la consulta previa no basta —no es atómica— y por qué la idempotencia del efecto es la que de verdad garantiza.
Ejercicio 2 — Diseña la tool de efecto de un agente. Cumbre quiere que order_agent pueda cancelar un pedido cuando el cliente lo pide, y cancelar un pedido dispara dos efectos: reponer el inventario reservado y notificar a la bodega. Diseña la tool cancel_order que le conectarías al agente, de forma que sea segura aunque el agente la llame varias veces. Di qué NO debe ser, qué SÍ debe ser, y qué claves de idempotencia usarías.
Ver solución
Qué no debe ser: cancel_order no debe ser un flujo que llame directo al sistema de inventario y a la bodega en el momento. Eso sería el efecto crudo: si el agente la llama dos veces (reintento, redelegación, bucle), repone el inventario dos veces y notifica dos veces.
Qué sí debe ser: un sub-workflow que, de forma atómica, registra la decisión de cancelación en el ledger y anota en el outbox las comandas de los dos efectos —reponer inventario y notificar bodega—, con ON CONFLICT DO NOTHING sobre la decisión para que dos llamadas no anoten dos juegos de comandas. El relay ejecuta cada comanda de forma idempotente. La tool devuelve "cancelación registrada" o "ya estaba cancelado".
Claves de idempotencia:
- La decisión de cancelar:
cancel:ORD-2041(una por pedido). - La reposición de inventario:
restock:ORD-2041:CF-ARA-500(una por línea, granularidad de la lección 4). - La notificación a bodega:
warehouse_notify:ORD-2041(una por pedido).
Así, si el agente llama cancel_order para ORD-2041 tres veces, la primera anota la decisión y las comandas, las otras dos chocan con el ON CONFLICT y no anotan nada; el relay ejecuta cada efecto una vez. Y como la cancelación es un efecto de estado, conviene además que el ledger permita a get_order_status reportar "cancelado", para que el agente consulte antes (capa 1) y no lo intente si ya está.
Por qué funciona: aplicaste la estrategia central —la tool del agente no es el efecto crudo, es el camino idempotente vía outbox— a un caso con dos efectos, con claves a la granularidad correcta, y con la idempotencia de la decisión (ON CONFLICT) protegiendo contra el disparo múltiple del agente. Es exactamente lo que blinda a un efecto de agente.
Ejercicio 3 — Corta el bucle de redelegación. En Cumbre, el caso "me cobraron el envío dos veces" cae en la frontera difusa entre billing_agent (hay un cargo) y order_agent (el envío es logística), y los dos se lo devuelven al orquestador diciendo "no es mío". Describe las dos defensas que pondrías —una de diseño y una de límite— para que este bucle no gire sin fin, y explica por qué, aunque el bucle llegara a girar, no se emitirían reembolsos duplicados.
Ver solución
Defensa de diseño (la causa raíz): trazar la frontera de forma explícita para este caso. Las Description de los dos especialistas deben resolver quién se queda "me cobraron el envío dos veces" —por ejemplo, decidir que todo lo que involucra un cargo duplicado es de billing_agent, y decirlo en ambas descripciones con un "no lo uses para... / úsalo cuando..." explícito—. Un bucle de redelegación casi siempre es una frontera mal trazada; arreglar la frontera lo elimina en su origen.
Defensa de límite (la red): un contador de redelegaciones. En el prompt del orquestador o en el ledger, llevar la cuenta de cuántas veces este caso ha rebotado entre especialistas; si pasa de un umbral (dos, por ejemplo), en vez de volver a delegar, escalarlo a un humano. Complementado con el Max Iterations del orquestador, que corta el bucle aunque el contador falle. La instrucción de honestidad ayuda: "si no puedes decidir de quién es el caso después de dos intentos, escálalo, no sigas delegando".
Por qué no habría reembolsos duplicados aunque el bucle girara: porque el efecto —request_refund— es idempotente por order_id. Aunque billing_agent emitiera el reembolso en una vuelta y otra vuelta intentara emitirlo de nuevo, la clave refund:ORD-XXXX deduplica: un solo reembolso. El bucle desperdicia dinero en llamadas al modelo —de ahí las dos defensas para cortarlo— pero el daño queda acotado a costo, no a efectos duplicados. Esa separación es la tesis de la lección: los frenos de agente controlan el costo y la eficiencia; la idempotencia del efecto controla la correctitud.
Por qué funciona: diste las dos defensas correctas (frontera clara para la causa, límite para la red) y —lo más importante— articulaste que la garantía de no duplicar no depende de cortar el bucle, sino de la idempotencia del efecto. Un sistema que corta el bucle pero no blinda el efecto sigue en riesgo; uno que blinda el efecto está a salvo aunque el bucle se le escape.
Resumen y siguiente paso
En esta lección aplicaste todo el módulo a los sistemas donde un agente delega en otro. Viste por qué un agente es más peligroso que un flujo determinista —es no determinista, así que dos corridas pueden decidir el mismo efecto por caminos distintos— y los tres caminos por los que un efecto de agente se duplica: el agente reintenta su tool, dos agentes deciden lo mismo, o el bucle de redelegación gira. La estrategia que lo resuelve es un cambio de mentalidad: no intentes que los agentes no dupliquen —no puedes garantizarlo por prompt— sino haz que sus efectos sean idempotentes para que no importe si duplican. En concreto, dos capas: el agente consulta el ledger antes de actuar (capa de eficiencia, evita trabajo inútil) y el efecto es idempotente de todas formas (capa de garantía, la que no falla). La tool de efecto de un agente nunca es el efecto crudo: es el camino idempotente —un sub-workflow que verifica el ledger o anota una comanda en el outbox de la lección 6—, con una clave derivada del negocio (refund:ORD-2041), no de la corrida del agente. Y los frenos propios de agentes —Max Iterations, fronteras claras entre especialistas, la regla de que los trabajadores no se delegan entre sí— controlan el costo y el bucle, mientras la idempotencia controla la correctitud.
Antes de avanzar a la lección 8 deberías poder: explicar por qué un prompt no basta para prevenir duplicados; describir las dos capas (consultar el ledger, efecto idempotente) y cuál da la garantía; explicar por qué la clave de idempotencia va por el negocio y no por la corrida del agente; y decir cómo un efecto idempotente acota el daño de un bucle de redelegación a costo en vez de efectos.
La lección 8 junta todo el módulo en un proyecto. Vas a construir un director, un outbox y un ejecutor idempotente que coordinen los tres sub-workflows dependientes de Cumbre —check-credit, issue-refund e inventory-sync— y vas a probar que una caída a mitad de la cadena no duplica ni pierde efectos al reintentar. El entregable son dos cosas: el grafo de dependencias que aprendiste a dibujar en la lección 3, y el sistema corriendo, con la evidencia de que sobrevive a los tres desastres. Es el módulo entero convertido en algo que puedes mostrar.
Recursos
- AI Agent Tool node — n8n Docs — el sub-nodo que conecta un agente completo como tool de otro; su
Description, su$fromAI()y suMax Iterations. La guía de chatbots (Módulo 5) lo enseña a fondo; aquí solo se blindan sus efectos. - AI Agent node — n8n Docs — el nodo del orquestador, con su parámetro
Max Iterations(por defecto 10) que acota los bucles de razonamiento y de redelegación. - Use AI for parameters ($fromAI) — n8n Docs — el mecanismo por el que el orquestador arma el encargo que le pasa al especialista; un encargo autocontenido y con el
order_idcorrecto es lo que deja derivar bien la clave de idempotencia. - Execute Sub-workflow node — n8n Docs — la forma de exponerle al agente un efecto como sub-workflow idempotente (
request_refund,cancel_order) en vez del efecto crudo. - Postgres node — n8n Docs — el nodo con el que la tool de lectura del agente consulta el ledger (memoria compartida) y con el que la tool de efecto anota la comanda idempotente en el outbox.