Módulo 2: Idempotencia: que repetir no duplique
7. Idempotencia para acciones de un AI Agent nativo
Descripción
Al terminar esta lección vas a poder hacer idempotentes las herramientas que un nodo AI Agent llama por su cuenta, para que el bucle de un agente —que puede decidir llamar la misma herramienta dos veces, o dar decisiones ligeramente distintas en cada corrida— no ejecute el mismo efecto (cobrar, enviar, crear) más de una vez. Vas a entender las dos fuentes nuevas de duplicado que aparecen con los agentes —el reintento del bucle y el no-determinismo del modelo— y por qué la clave de idempotencia de un agente tiene que derivarse de la entrada estable, nunca de lo que el modelo decide.
Esto importa porque los agentes cambian la ecuación del riesgo. Hasta ahora, los efectos los disparaba un nodo que tú colocaste, en un orden que tú definiste. Con un AI Agent, es el modelo el que decide qué herramienta llamar y cuándo, y esa decisión no es perfectamente predecible: puede llamar una herramienta que ya llamó, puede reintentar tras un error que no ve, puede clasificar el mismo pedido distinto dos veces. Todo lo que aprendiste en el módulo sigue valiendo, pero ahora hay un actor autónomo apretando los botones. Si esos botones no son idempotentes, el agente los va a duplicar, y no de forma que puedas prever leyendo el workflow.
Conexión con el módulo: esta lección aplica todo lo anterior a un contexto nuevo. La clave (lección 3), el upsert (lección 4), la cabecera (lección 5) y la advertencia de verificar-y-actuar (lección 6) no cambian; lo que cambia es quién invoca el efecto. En Cumbre, el AI Agent de order-triage clasifica el pedido y decide llamar a la herramienta que cobra. Vas a hacer esa herramienta idempotente para que, sin importar cuántas veces el agente la invoque, ORD-2041 se cobre una vez. El proyecto de la lección 8 cierra el módulo con el flujo completo, agente incluido.
Qué cambia cuando el que actúa es un agente
Repasemos rápido qué es el nodo AI Agent en n8n, porque el resto de la lección se apoya en esto.
Un AI Agent es un nodo al que le conectas un modelo de lenguaje y un conjunto de herramientas (tools). Le das una tarea —"clasifica este pedido y procésalo"— y el agente, en lugar de seguir un orden fijo que tú programaste, razona sobre la tarea y decide, paso a paso, qué herramientas usar. Cada herramienta es una acción que el agente puede invocar: consultar el inventario, buscar al cliente, cobrar, enviar un correo. El agente llama una herramienta, mira el resultado, razona de nuevo, llama otra, y así hasta que considera la tarea terminada. Ese ciclo de "razona → llama herramienta → observa → razona" es el bucle del agente (agent loop).
En order-triage, el AI Agent de Cumbre recibe el pedido, y entre sus herramientas tiene una que llamaremos charge_customer —cobra al cliente— y otra send_confirmation —envía el correo—. El agente clasifica el pedido y decide invocar charge_customer. Hasta aquí, todo bien.
El problema es que un agente introduce dos fuentes de duplicado nuevas, que se suman a las tres del módulo 1 (reintento del proveedor, doble clic, reintento de n8n):
Cuarta fuente: el bucle del agente reintenta la herramienta. El agente puede llamar charge_customer, no estar seguro de si funcionó —quizás la respuesta tardó, o el agente "olvidó" en su razonamiento que ya la llamó— y llamarla otra vez dentro de la misma ejecución. No es un reintento de n8n ni del proveedor; es el propio razonamiento del modelo decidiendo invocar dos veces. Un agente es, en el fondo, un asistente muy capaz pero a veces olvidadizo, y un asistente olvidadizo al que le dijiste "cobra este pedido" puede, un momento después, dudar y cobrarlo de nuevo "por si acaso".
Quinta fuente: el no-determinismo del modelo. Un modelo de lenguaje no es una función determinista: dale la misma entrada dos veces y puede darte salidas ligeramente distintas. Clasifica ORD-2041 como "prioridad alta" en una corrida y "prioridad media" en otra; extrae el monto como 1780 una vez y como 1780.00 otra; redacta el correo con palabras diferentes. Esto tiene una consecuencia crítica para la idempotencia que vamos a desarrollar: si tu clave de idempotencia dependiera de lo que el agente decide, cambiaría entre corridas, y la idempotencia se rompería —exactamente el error de la clave inestable de la lección 3, pero ahora la inestabilidad la mete el modelo—.
Las dos fuentes empujan a la misma conclusión: las herramientas que un agente puede invocar tienen que ser idempotentes por su cuenta, de modo que dé igual cuántas veces el agente las llame y sin depender de que el agente "se acuerde" de no repetir. No puedes confiar en que el modelo se comporte; tienes que hacer que su comportamiento no importe. Es la misma filosofía del módulo entero —no evites la repetición, hazla inofensiva— aplicada a un actor que repite por razones nuevas.
La regla de oro: la clave viene de la entrada, no de la decisión del agente
Aquí está el concepto que hace idempotente a un agente, y es lo más importante de la lección.
La clave de idempotencia de una acción del agente tiene que derivarse de algo estable y anterior al agente: el pedido que entró, su order_id, su contenido. Nunca de lo que el agente produce —su clasificación, su texto, su razonamiento—, porque eso es no-determinista y cambia entre corridas.
Piénsalo así. El pedido ORD-2041 es un hecho fijo: llegó con ese order_id, ese customer_id, ese amount. Eso no cambia por más veces que el agente lo procese. La clasificación del agente ("prioridad alta") es una opinión que puede variar. Si construyes la clave de idempotencia del cobro a partir del hecho fijo (order_id), la clave es la misma en todas las corridas y la idempotencia funciona. Si la construyes a partir de la opinión variable, la clave baila y duplicas.
En la práctica, esto significa que la idempotency_key que ya calculaste en la lección 3 —a partir del pedido, antes de que el agente hiciera nada— es exactamente la que la herramienta del agente debe usar. La calculaste temprano, después del webhook, justo por esto: para tenerla lista, derivada de la entrada estable, antes de que el modelo meta su no-determinismo. El agente puede clasificar como quiera; la clave del cobro sigue siendo la de ORD-2041.
La regla, en una frase para tatuártela: la identidad de un efecto la define el evento que lo motivó, no la decisión del agente que lo disparó.
Cómo se hace idempotente una herramienta del agente
Una herramienta del agente, en n8n, suele ser un sub-workflow o un nodo de acción (un HTTP Request como herramienta, un nodo de base de datos, un sub-workflow llamado como herramienta). Hacerla idempotente es aplicar dentro de la herramienta las técnicas que ya conoces, tomando la clave de la entrada estable. No hay magia nueva; hay las mismas tres herramientas de siempre, encapsuladas donde el agente no las pueda evitar.
La estructura conceptual es esta:
AI Agent
│ decide: "cobra al cliente de ORD-2041"
│ invoca la herramienta, pasándole la idempotency_key del pedido
▼
Herramienta charge_customer (idempotente por dentro)
│ recibe idempotency_key = clave estable de ORD-2041
│ hace el POST /charges con la cabecera Idempotency-Key
▼ (la pasarela deduplica atómicamente)
Las tres formas de blindar la herramienta, según el efecto, son las que ya dominas:
Si la herramienta llama una API con cabecera de idempotencia (como charge_customer sobre la pasarela): la herramienta manda la Idempotency-Key con la clave del pedido. Llámela el agente una o cinco veces, la pasarela crea un solo cobro. Es la lección 5, encapsulada en la herramienta.
Si la herramienta escribe en tu base de datos: la herramienta hace un upsert ON CONFLICT sobre la clave del pedido. Llámela el agente las veces que quiera, hay una sola fila. Es la lección 4, encapsulada.
Si la herramienta dispara un efecto sin cabecera ni upsert posible (un correo, una API terca): la herramienta primero gana el permiso con un upsert atómico sobre tu propia tabla —el patrón de la lección 6— y solo dispara el efecto si ganó. Es la lección 6, encapsulada.
En los tres casos, el patrón es el mismo: la idempotencia vive dentro de la herramienta, no en el agente. El agente es libre de invocar; la herramienta es la que garantiza que invocar dos veces no duplica. Nunca le pidas al agente que "recuerde no repetir" —olvidará—; haz que repetir no tenga consecuencias.
Ejemplo trabajado: charge_customer idempotente
Vamos a blindar la herramienta de cobro de Cumbre. Recuerda el flujo: el AI Agent clasifica y puede invocar charge_customer, quizás más de una vez.
Paso 1 — La clave ya está lista. Antes del agente, el nodo Code de la lección 3 ya calculó la idempotency_key de ORD-2041 a partir del pedido. Esa clave viaja con el item y está disponible para el agente y sus herramientas. No la recalcules dentro de la herramienta, y sobre todo no la derives de la clasificación del agente.
Paso 2 — La herramienta usa la clave, no la inventa. La herramienta charge_customer (sea un sub-workflow o un HTTP Request como herramienta) hace el cobro pasando la cabecera de idempotencia con la clave del pedido:
POST /charges
Idempotency-Key: {{ la idempotency_key de ORD-2041, la de la lección 3 }}
{ "customer_id": "CUST-118", "amount": 1780, "currency": "MXN" }
Fíjate en lo que no hicimos: no usamos el monto que el agente "extrajo" ni la prioridad que "decidió" para construir la clave. Usamos la clave derivada del pedido original. Si el agente, en una corrida, leyera el monto como 1780.00 en vez de 1780, la clave no cambiaría, porque no depende de la lectura del agente.
Paso 3 — Probar el doble llamado del agente. Esto es lo nuevo respecto de la lección 5. Antes probábamos disparando el workflow dos veces (reintento del webhook). Ahora, además, hay que considerar que el agente llame charge_customer dos veces dentro de una sola ejecución. Para provocarlo en una prueba, puedes darle al agente una instrucción ambigua que lo tiente a reintentar, o simplemente observar sus ejecuciones reales; el punto es verificar el resultado.
Qué esperar: sin importar si el cobro se disparó por dos ejecuciones del workflow o por dos invocaciones del agente en la misma ejecución, al revisar la pasarela hay un solo cobro para ORD-2041. La cabecera de idempotencia, con la clave estable, absorbe todas las repeticiones —vengan de donde vengan—. El agente puede ser tan olvidadizo como quiera; el cobro es uno.
Puesto en tabla, para ver que las tres fuentes de repetición convergen en el mismo resultado seguro:
| Cómo se repitió el cobro | Sin cabecera (frágil) | Con cabecera + clave estable |
|---|---|---|
| El workflow corrió dos veces (reintento del webhook) | 2 cobros | 1 cobro |
| El agente invocó la herramienta dos veces en una ejecución | 2 cobros | 1 cobro |
| n8n reintentó el nodo tras una falla de red | 2 cobros | 1 cobro |
La columna de la derecha es la meta: da igual por qué se repitió el cobro; la clave estable en la cabecera lo colapsa a uno. No estás defendiéndote de una fuente concreta de duplicado, sino de todas a la vez, porque la defensa está en la identidad del efecto, no en la causa de la repetición.
Esa es la meta: una herramienta que es segura de invocar N veces, para que la autonomía del agente —que es su virtud— no se convierta en un riesgo de duplicado.
Sobre el modelo: elige uno vigente, pero no es lo que hace idempotente
Una nota necesaria, porque es fácil confundirse. El nodo AI Agent necesita un modelo de lenguaje conectado, y debes elegir uno vigente al momento de construir tu workflow. Los modelos se actualizan y se retiran con frecuencia; un modelo que era el estándar hace un año puede estar descontinuado hoy. Cuando configures el agente, abre el selector de modelos de n8n y elige uno de los disponibles en ese momento —verifica la lista vigente, no copies un nombre de modelo de un tutorial viejo, porque podría estar retirado y tu workflow fallaría al no encontrarlo—.
Dicho esto, aquí está lo importante para esta lección: la elección del modelo no tiene nada que ver con la idempotencia. Un modelo más nuevo, más grande o más listo no hace que tu herramienta de cobro sea idempotente. La idempotencia la da la clave estable y el mecanismo dentro de la herramienta —la cabecera, el upsert—, no el modelo. De hecho, es al revés: como ningún modelo es perfectamente determinista, la idempotencia tiene que venir de la estructura que rodea al agente, no del agente. No esperes que "un modelo mejor" resuelva el duplicado; lo resuelve la ingeniería de idempotencia que le pones alrededor. El modelo decide qué hacer; tu diseño garantiza que hacerlo dos veces no duele.
El no-determinismo más allá del duplicado
Vale la pena un matiz honesto, porque la idempotencia no cura todo lo que el no-determinismo trae, y prometer que sí sería engañarte.
La idempotencia garantiza que el efecto no se duplique: un cobro, un correo, un registro. Lo hace muy bien. Pero no garantiza que las decisiones del agente sean consistentes entre corridas. Si el agente clasifica ORD-2041 como "prioridad alta" hoy y "prioridad media" mañana, la idempotencia del cobro no arregla esa inconsistencia —son cosas distintas—. El cobro será uno solo (bien), pero la prioridad asignada puede variar (otro problema).
¿Por qué lo menciono aquí? Para que no salgas con la idea de que "hago idempotentes las herramientas y ya, el agente es confiable". La idempotencia es una capa necesaria pero no suficiente. La consistencia de las decisiones de un agente es otro tema —involucra cómo escribes sus instrucciones, cómo restringes sus salidas, cómo validas lo que produce— y pertenece a la guía de agentes de IA del ecosistema, no a esta. Aquí resolvemos lo que este módulo promete: que los efectos no se dupliquen. Es una pieza real y valiosa del rompecabezas de confiabilidad de un agente, y es la que te toca dominar ahora.
La frontera, dicha con claridad: esta lección hace que las acciones del agente sean seguras de repetir. No hace que las decisiones del agente sean deterministas. Lo primero es idempotencia; lo segundo es diseño de agentes, y vive en otra guía.
Hay una consecuencia de diseño que conviene sacar de aquí, porque te va a guiar cada vez que le des una herramienta a un agente: dale a un agente solo herramientas que sean seguras de repetir. Piénsalo como equipar a un asistente muy capaz pero impulsivo. No le entregas una herramienta que cobra de forma irreversible y confías en su prudencia; le entregas una herramienta de cobro que, por dentro, ya es idempotente, de modo que su impulsividad no pueda hacer daño. Cuando construyas el catálogo de herramientas de un agente, la pregunta de admisión de cada herramienta es la misma que la de todo este módulo: "¿qué pasa si el agente la invoca dos veces?". Si la respuesta es "duplica", esa herramienta no está lista para dársela a un agente hasta que la vuelvas idempotente. Es un filtro de diseño simple y poderoso.
Un caso más difícil: cuando el agente compone varios efectos
Hasta aquí miramos una herramienta a la vez. Pero el AI Agent de Cumbre no dispara un solo efecto: clasifica y luego puede cobrar (charge_customer), y enviar el correo (send_confirmation), y escribir el registro en el CRM. Tres efectos, orquestados por el razonamiento del agente. Esto agrega una capa que conviene ver, aunque su solución completa sea del módulo 5.
El punto clave: cada efecto necesita su propia idempotencia, con su propia clave por tipo de efecto. No basta una sola "clave del pedido" compartida a ciegas, porque cobrar y enviar el correo son efectos distintos que se deduplican por separado. Si el agente reintenta y solo repite el correo (no el cobro), quieres que el correo se deduplique sin bloquear nada del cobro. Por eso, en el ejercicio 3 de esta lección, la tabla de deduplicación usa (idempotency_key, kind): la clave del pedido identifica el evento, y el kind distingue "cobro" de "correo" de "registro CRM". Cada efecto tiene su propia entrada de idempotencia, todas ancladas al mismo pedido.
Y hay un peligro nuevo que el agente hace más probable: un efecto puede tener éxito y otro fallar dentro de la misma invocación. El agente cobra bien, pero el correo falla. Si reintenta, ¿repite el cobro (que ya salió) al reintentar el correo? Aquí es donde la idempotencia por efecto salva el día: como el cobro es idempotente por su cuenta, reintentar la secuencia completa no vuelve a cobrar —la cabecera absorbe el segundo intento— y sí completa el correo que faltaba. Cada efecto avanza hacia "hecho una vez" independientemente de los demás.
La coordinación fina de "decidir todo primero y ejecutar los efectos por separado, cada uno idempotente" tiene nombre —el patrón outbox— y es un tema central del módulo 5. No lo construyas aquí. Pero reconoce la forma del problema: un agente que compone varios efectos es un mini-sistema de coordinación, y la regla de este módulo se aplica a cada efecto por separado —clave estable de la entrada, idempotencia dentro de cada herramienta, una entrada de deduplicación por tipo de efecto—. Domina un efecto idempotente aquí; el módulo 5 te enseña a coordinar varios sin que se pisen.
Errores comunes
Derivar la clave de idempotencia de la salida del agente (conceptual). Qué pasa: alguien construye la clave del cobro a partir de algo que el agente produjo —la prioridad que clasificó, el resumen que redactó, el monto que extrajo del texto— pensando "así la clave refleja lo que el agente decidió". Como el agente es no-determinista, esa clave cambia entre corridas, y la idempotencia se rompe: dos corridas del mismo pedido generan dos claves y dos cobros. Por qué pasa: parece natural que la clave del efecto salga de quien decide el efecto (el agente). Pero el agente es justo la parte inestable del sistema. Cómo detectarlo: rastrea de dónde sale el valor de la clave; si en algún punto de su origen hay una salida del modelo (clasificación, texto generado, extracción), está contaminada por el no-determinismo. Cómo corregirlo: deriva la clave de la entrada estable —el order_id, el contenido del pedido tal como llegó— antes de que el agente actúe. La identidad del efecto la define el evento, no la decisión del agente.
Confiar en que el agente "no llame la herramienta dos veces" (conceptual). Qué pasa: se le da al agente una herramienta con efecto no idempotente y se confía en que su razonamiento evite invocarla de más —quizás incluso se le instruye "no cobres dos veces"—. El agente, siendo un modelo, a veces la invoca dos veces igual, y duplica. Por qué pasa: se trata al agente como si fuera código determinista que sigue instrucciones al pie de la letra; no lo es. Una instrucción en el prompt es una sugerencia fuerte, no una garantía. Cómo detectarlo: si tu defensa contra el duplicado es una frase en las instrucciones del agente ("llama esto solo una vez"), no tienes defensa. Cómo corregirlo: haz la herramienta idempotente por dentro (clave estable + cabecera o upsert), para que invocarla dos veces no tenga consecuencias. La idempotencia vive en la herramienta, no en la buena conducta del agente. Diseña asumiendo que el agente va a repetir.
Esperar que un modelo mejor resuelva el duplicado (conceptual). Qué pasa: aparecen cobros duplicados con un agente, y la reacción es "cambiemos a un modelo más nuevo/más grande, este se equivoca". El modelo nuevo también duplica, porque el problema nunca fue el modelo. Por qué pasa: se atribuye el duplicado a la "calidad" del agente, cuando es un problema estructural: la herramienta no es idempotente. Cómo detectarlo: pregúntate si el duplicado desaparecería con una herramienta idempotente aunque el modelo fuera el mismo. Si sí (y casi siempre es sí), el modelo no es la causa. Cómo corregirlo: invierte el esfuerzo en la idempotencia de las herramientas, no en cambiar de modelo. Ningún modelo es determinista, así que ninguno te da idempotencia; esa la construyes tú alrededor del agente. Elige un modelo vigente por sus otras cualidades, pero no le pidas que resuelva un problema de ingeniería de sistemas.
Ejercicios
Ejercicio 1 — ¿De dónde sale la clave? Para cada propuesta de clave de idempotencia para el cobro que dispara el agente, di si es correcta o no y por qué:
(a) La clave se deriva del order_id del pedido que entró por el webhook.
(b) La clave se deriva de la clasificación de prioridad que el agente asignó.
(c) La clave es un randomUUID() que la herramienta genera cada vez que el agente la invoca.
(d) La clave se deriva de un hash del customer_id y el amount tal como venían en el pedido original.
Ver solución
(a) Correcta. El order_id es un hecho fijo de la entrada, estable entre corridas e invocaciones. Es la clave natural ideal. La identidad del cobro la define el pedido, y order_id lo identifica.
(b) Incorrecta. La clasificación de prioridad es una salida del agente, y el agente es no-determinista: puede clasificar "alta" en una corrida y "media" en otra. La clave cambiaría entre corridas y duplicarías. Nunca derives la clave de lo que el agente decide.
(c) Incorrecta. randomUUID() genera un valor nuevo en cada invocación —es el error de la clave inestable de la lección 3, agravado porque aquí el agente puede invocar la herramienta varias veces en una sola ejecución, y cada invocación tendría su propio UUID—. Cero idempotencia.
(d) Correcta. Es una clave sintética derivada de la entrada estable (customer_id y amount tal como llegaron, no como el agente los interpretó). Es la misma en todas las corridas e invocaciones. Es válida, aunque si existe un order_id, ese es preferible por legible.
Por qué funciona: las cuatro se deciden con la regla de oro —¿la clave viene de la entrada estable o de la decisión del agente?—. (a) y (d) vienen de la entrada; (b) viene de la decisión del agente; (c) viene del azar. Solo las que anclan en el hecho fijo del pedido son estables.
Ejercicio 2 — El agente que cobra dos veces. El equipo de Cumbre observa que, en algunas ejecuciones, el agente invoca charge_customer dos veces dentro de la misma ejecución del workflow, y el cliente recibe dos cargos. La herramienta hace un POST /charges sin cabecera de idempotencia. ¿Por qué pasa, y cuál es el arreglo? ¿Ayudaría instruir al agente "cobra solo una vez"?
Ver solución
Por qué pasa: el bucle del agente decidió invocar charge_customer dos veces —quizás no estuvo seguro de si la primera invocación funcionó, o su razonamiento lo llevó a repetir—. Como la herramienta hace un POST /charges sin cabecera de idempotencia, cada invocación crea un cobro nuevo. La no-idempotencia de la herramienta convierte la doble invocación del agente en un doble cargo.
El arreglo: hacer la herramienta idempotente. Agregar la cabecera Idempotency-Key con la clave estable de ORD-2041 (la de la lección 3). Así, la primera invocación crea el cobro y la segunda, con la misma clave, recupera el existente sin crear otro. El agente puede invocar charge_customer las veces que quiera; hay un solo cobro.
¿Ayudaría instruir "cobra solo una vez"? No de forma confiable. Una instrucción en el prompt es una sugerencia, no una garantía: el agente es un modelo no-determinista y a veces la ignorará. Puede reducir la frecuencia del doble cobro, pero no lo elimina, y "casi nunca duplica" no es aceptable cuando se trata de dinero. La defensa real es estructural —la herramienta idempotente—, no conductual. Diseña asumiendo que el agente va a repetir, y haz que repetir no importe.
Por qué funciona: separaste la causa (herramienta no idempotente) de la solución robusta (idempotencia en la herramienta) de la solución ilusoria (pedirle buena conducta al agente). El módulo entero insiste en lo mismo: no controles el comportamiento del que repite; neutraliza la repetición.
Ejercicio 3 — Diseña una herramienta de envío idempotente. El agente de Cumbre tiene una herramienta send_confirmation que envía el correo de confirmación por una API que no ofrece cabecera de idempotencia. El agente a veces la invoca dos veces. Diseña la herramienta para que el cliente reciba un solo correo, usando lo que aprendiste en las lecciones 6 y 7.
Ver solución
Como la API de correo no ofrece cabecera de idempotencia y un correo es irreversible (no se puede des-enviar), la protección tiene que vivir en tu lado, ganando el permiso de enviar de forma atómica antes de enviar. La herramienta send_confirmation, por dentro, hace:
1. Upsert atómico en una tabla propia:
INSERT INTO sent_emails (idempotency_key, kind)
VALUES ('<clave de ORD-2041>', 'confirmation')
ON CONFLICT (idempotency_key, kind) DO NOTHING
RETURNING idempotency_key; -- devuelve algo SOLO si insertó
2. If: ¿el upsert devolvió una fila? (¿ESTA invocación ganó el permiso?)
- SÍ → llama a la API de correo y envía
- NO → otra invocación ya envió → no hagas nada
La clave (idempotency_key) se deriva de ORD-2041 —la entrada estable—, no de nada que el agente produzca. La restricción de unicidad sobre (idempotency_key, kind) es el árbitro atómico: de dos invocaciones del agente (o dos ejecuciones del workflow) concurrentes, solo una gana el upsert y envía; la otra choca con la unicidad, no obtiene fila de vuelta, y no envía. El correo sale una sola vez.
Notas de diseño:
- El
kinddistingue "correo de confirmación" de otros correos del mismo pedido, para que enviar la confirmación no bloquee un correo distinto legítimo. - Como el correo es irreversible, es esencial ganar el permiso antes de enviar, no después. Registrar el envío después del
POST(como en el ejercicio 1 de la lección 6) dejaría escapar el segundo correo. El upsert va primero. - Esto es exactamente el ledger de deduplicación que el módulo 4 formaliza. Aquí lo aplicaste en pequeño, dentro de una herramienta del agente.
Por qué funciona: uniste la lección 6 (el árbitro atómico propio cuando no hay cabecera) con la lección 7 (la clave viene de la entrada, la idempotencia vive en la herramienta). Para un efecto irreversible invocado por un actor autónomo, esa combinación es la única defensa sólida.
Resumen y siguiente paso
En esta lección llevaste la idempotencia al terreno de los agentes. Viste que un nodo AI Agent introduce dos fuentes nuevas de duplicado —el bucle del agente, que puede invocar la misma herramienta dos veces dentro de una ejecución, y el no-determinismo del modelo, que da salidas ligeramente distintas entre corridas— sobre las tres que ya conocías. Aprendiste la regla de oro que hace idempotente a un agente: la clave se deriva de la entrada estable (el order_id, el pedido), nunca de lo que el agente decide, porque la decisión es la parte inestable del sistema. Y viste que la solución no es pedirle buena conducta al agente —olvidará— sino hacer las herramientas idempotentes por dentro, encapsulando la cabecera (lección 5), el upsert (lección 4) o el árbitro atómico propio (lección 6) donde el agente no los pueda evitar. Cerraste con dos honestidades: que la elección del modelo no tiene nada que ver con la idempotencia —ningún modelo la regala, la construyes tú alrededor—, y que la idempotencia protege los efectos pero no vuelve consistentes las decisiones del agente, que es otro tema de otra guía.
Antes de avanzar a la lección 8 deberías poder: nombrar las dos fuentes de duplicado que agrega un agente; explicar por qué la clave nunca debe derivarse de la salida del modelo; y diseñar una herramienta idempotente para un efecto que el agente invoca, con y sin cabecera de API disponible.
Ya tienes todas las piezas del módulo: la definición (2), la clave (3), el upsert (4), la cabecera (5), la trampa que hay que evitar (6) y la aplicación a agentes (7). La lección 8 no introduce nada nuevo: las junta. Vas a tomar un flujo de Cumbre que inserta un registro y llama a una API —el order-triage frágil que abrió el módulo—, le vas a asignar su clave de idempotencia, convertir la inserción en upsert, blindar la llamada a la API, y —lo más importante— vas a probar que re-ejecutarlo dos veces deja un solo registro y un solo efecto. Es el entregable que puedes defender en una entrevista: la demostración, no la promesa, de que tu workflow sobrevive al duplicado.
Recursos
- AI Agent node — n8n Docs — el nodo
AI Agent: cómo se le conectan el modelo y las herramientas, y cómo funciona su bucle de razonamiento. La base de esta lección. - Tools in n8n AI Agents — n8n Docs — qué es una herramienta para un agente y cómo se construye (sub-workflow, HTTP Request como herramienta, nodos de acción); el lugar donde encapsulas la idempotencia.
- Chat models — n8n Docs — el selector de modelos que conectas al agente; consulta ahí la lista vigente al construir tu workflow y evita nombres de modelo de tutoriales viejos, que pueden estar retirados.
- Idempotent requests — Stripe API reference — la cabecera que encapsulas dentro de una herramienta de cobro del agente; verifica el nombre y las condiciones vigentes.