Hoy, en infraestructura para agentes, la propuesta más sólida es la ejecución durable: un agente puede correr horas o días, sobrevivir a una caída a mitad de camino y retomar exactamente donde estaba sin perder el estado. Es ingeniería difícil, los equipos que la hacen bien son muy buenos, y nada de lo que sigue va en su contra. Si tu problema es no perder avance en un proceso largo, inestable y de muchos pasos, es la herramienta indicada.

La ejecución durable conserva el estado durante la pausa. Si las reglas siguen valiendo cuando la pausa termina, eso queda a cargo de otro. Y el motivo más común por el que un agente serio se detiene es justo el caso en que esa diferencia más pesa: está esperando que una persona apruebe algo.

Una pausa que no es un problema de estado

Un agente, en un turno con consecuencias, llega a un paso que necesita aprobación humana: liberar el pago, aprobar la excepción, autorizar el cambio. Entonces se detiene. Pueden ser treinta segundos o puede ser hasta el lunes.

La ejecución durable responde muy bien una pregunta sobre esa pausa: ¿cuando se reanude, vamos a tener exactamente el mismo estado? Sí. Pero lo que decide si reanudar es seguro son otras preguntas:

Los motores de ejecución durable responden la tercera a su manera: Temporal, por ejemplo, garantiza que una actividad "se va a ver completada exactamente una vez" [1], aclara que "puede ejecutarse varias veces" [2] y recomienda que las actividades sean idempotentes. Las otras tres son preguntas de gobernanza, y la ejecución durable, como primitiva, se las deja al código que escribas encima.

Reanudar es una operación gobernada

En un runtime gobernado, la intervención humana es un estado persistido de la máquina del flow: una aprobación que bloquea el avance, restringida por rol, guardada en la base de datos, que sobrevive a reinicios, traspasos y reintentos. Durante toda la pausa el turno queda pausado como estado durable, y mientras espera no ocupa ningún proceso ni ninguna conexión.

Un flow se pausa en un bloqueo de aprobación humana; al reanudar, el runtime vuelve a leer los roles del actor original antes de ejecutar ningún paso y, si el flow declara una política resume, falla cerrado cuando esa política ya no admite al actor.

La reanudación que dispara la aprobación corre como una operación gobernada:

Como el turno nunca mantuvo una conexión abierta, el resultado se avisa por fuera de la conexión original cuando se resuelve: un evento propio del runtime (un webhook o un stream en vivo) le avisa a quien llamó que el nuevo turno está listo para leer, en lugar de una solicitud bloqueada hasta el lunes.

Dos sentidos de "reanudar"

Dos sistemas pueden "reanudar un agente después de una pausa larga" y querer decir cosas distintas. Uno garantiza que sobrevivieron los bytes. El otro, además, verifica la autoridad y el actor, mantiene un único dueño de la reanudación y escribe el registro. Para una automatización interna de larga duración, con lo primero alcanza. Para una acción que mueve dinero o una decisión regulada, y que esperó la aprobación de una persona, las preguntas de compliance están en lo que separa a uno del otro.

Los límites, dichos con honestidad

No pretendemos ser más durables que un motor de ejecución durable. Para orquestaciones de propósito general, de semanas y muchos pasos, con las garantías de recuperación más fuertes posibles, una plataforma dedicada es más madura, y para ese trabajo es la herramienta indicada. Nuestra durabilidad se limita a turnos de agente gobernados y a flows declarados en el contrato: filas de Postgres y una cola de jobs, no un motor de workflows general.

El control de la reanudación es tan estricto como la política del flow, y solo en el camino de la aprobación. Un flow sin política resume se reanuda para cualquiera. Cuando una ejecución pausada se retoma desde el próximo mensaje del usuario en el chat, el runtime lee la copia de los roles que guarda la sesión en vez de volver a leer las asignaciones; si la política niega, desvincula la ejecución de la conversación y la deja en paused, sin darla por fallida.

La reanudación sin modelo es un recorte deliberado. Si el resto del flow declara un paso de modelo, la reanudación que dispara la aprobación no lo ejecuta: le avisa al usuario que el paso se resolvió y espera su próximo mensaje, y es ese turno común, que pasa por los controles de siempre, el que ejecuta el resto.

El lease del claim resuelve una carrera puntual. Garantiza que un solo worker a la vez sea dueño de una reanudación, porque distingue un worker vivo de uno muerto. No vuelve inocua una caída: un worker que muere a mitad de camino todavía no anotó en la fila de la ejecución los pasos que completó, y el que lo reemplaza los vuelve a ejecutar. Un worker desalojado mientras sigue vivo se detiene entre un paso y otro, así que el paso que estaba ejecutando en ese momento todavía puede completarse.

Lo que está en juego

Un auditor que mira un agente de larga duración va mucho más allá de "¿perdieron el estado?": "esta acción esperó cuatro días una aprobación; demuéstrenme que la aprobación fue real, que la persona seguía autorizada, que se ejecutó con el actor correcto y que se ejecutó una sola vez". El log de un motor de ejecución durable puede mostrar que el workflow se reanudó. Un runtime gobernado responde el resto con sus propios registros y con los chequeos que corrió, dentro de los límites de arriba: la cadena registra la decisión y quién la tomó; la autoridad de quien aprobó es la que chequeó la barrera de roles al decidir, contra un contrato versionado; y la reanudación volvió a chequear al actor original antes de ejecutar ningún paso. El rol de quien aprobó no queda registrado como un dato aparte.

Esto es lo que pasa en el caso de la revocación. En un flow cuya política resume nombra los roles que pueden reanudarlo, bloqueá un turno en una aprobación humana, sacale el rol al actor durante la pausa y después aprobá: la reanudación vuelve a leer los roles, termina la ejecución en failed con resume_denied antes de ejecutar ningún paso y deja la falla registrada en la cadena. La demo pública todavía no está disponible y no incluye ningún flow de aprobación; si querés ver este caso funcionando, escribinos. En Cómo funciona se ve cómo se controla una acción antes de ejecutarla.

Este es el caso de larga duración de una línea más amplia: la comunicación y la propuesta pueden ser probabilísticas, pero la autoridad, la consecuencia y el registro de ambas tienen que ser determinísticos y declarados, también a través de una pausa. El argumento general está en No se combate el probabilismo con probabilismo; el de la aplicación estructural, en El agente propone; el runtime aprieta el botón; el de la capa de prueba, en Una auditoría en la que no hace falta confiar.


Las citas están traducidas por el autor. Los originales, en inglés:

  1. Temporal, documentación de Activity Definition: "will be observed as completed exactly once".
  2. Temporal, documentación de Activity Definition: "may be executed multiple times".

Nicolás Moreno construye Zarel: operaciones de IA gobernadas, donde la IA propone y el contrato dispone.