Un ingeniero comprueba los registros guardados y detiene a un asistente de IA que sostiene un sobre duplicado junto a una notificación ya completada.

Recuperar flujos de trabajo de agentes sin repetir efectos secundarios

26 de octubre de 2026

Un punto de control deja constancia de lo que ha guardado tu flujo de trabajo. No es un comprobante del CRM.

Esa distinción sale cara cuando un agente modifica un registro, espera una respuesta y se agota el tiempo de espera. Reiniciar desde el último punto de control puede repetir una acción que ya se completó correctamente. Una explicación elocuente del modelo no resuelve la incertidumbre. Tampoco lo hace una marca verde junto al nodo anterior.

Yo definiría la lógica de recuperación en la interfaz con las herramientas antes de añadir más pasos autónomos. El modelo puede proponer la siguiente acción; el código, respaldado por almacenamiento persistente, debe decidir si una acción anterior está confirmada, si es seguro reintentarla o si sigue sin resolverse. El diseño que sigue es una integración hipotética.

El fallo se produce entre dos confirmaciones

Imagina un agente que cierra un caso de incorporación de un cliente. Actualiza el CRM y después envía un correo al responsable de la cuenta. El CRM confirma la actualización, pero la respuesta se pierde. El proceso de trabajo falla antes de guardar el resultado. Al reiniciarse, el punto de control sigue indicando que la actualización está pendiente.

Añade ahora otro intervalo en el que puede producirse un fallo: se guarda el resultado de la actualización, el proveedor de correo acepta el mensaje y el proceso termina antes de registrar su identificador. El paso del CRM y el de la notificación necesitan decisiones de recuperación independientes. Volver a ejecutar todo el nodo agrupa dos incertidumbres independientes en un cómodo error.

La documentación actual del sistema de puntos de control de LangGraph describe la persistencia del estado del grafo y la reanudación, mientras que volver a ejecutar desde un punto de control anterior repite las llamadas posteriores a las API. La persistencia síncrona de los puntos de control reduce la pérdida de progreso local; no crea una transacción compartida con un CRM remoto. Trata la recuperación de la orquestación y la de los efectos externos como contratos separados.

Guarda la intención antes de cruzar la frontera

Crea un registro persistente de la operación antes de enviarla. Asigna a cada efecto previsto un identificador de operación estable y opaco. Conserva el identificador del cliente o tenant, el destino, la versión de la acción, el resumen criptográfico de la carga de datos canónica, la referencia de autorización, el proveedor y el estado. Almacena las cargas de datos sensibles solo donde el acceso y la conservación sean adecuados; los identificadores no deben contener datos del cliente.

operation_id: op-7d4c...
workflow_id: onboarding-42
action: crm.close_case.v1
target: case-318
payload_digest: sha256(...)
status: prepared | dispatching | confirmed | rejected | unknown
provider_request_id: ...
provider_result_id: ...
evidence_checked_at: ...
record_version: ...

Estos son campos propuestos para la aplicación, no un esquema de un framework. Un reintento reutiliza la operación original y la carga de datos fijada. Un cambio de destinatario, importe o intención de negocio crea una operación con su propia autorización. Generar un identificador de operación nuevo en cada intento anula la deduplicación. Utilizar solo un hash de la carga de datos puede fusionar por error dos acciones que se han hecho idénticas de forma intencionada.

La guía de AWS sobre API idempotentes establece la misma distinción de intención mediante identificadores de solicitud proporcionados por quien realiza la llamada. También exige atomicidad al servicio que implementa la deduplicación: registrar el token y aplicar la modificación deben formar parte de una única confirmación fiable. Un registro en el lado del cliente no puede ofrecer esa garantía para cualquier endpoint de terceros.

Haz explícita la decisión de reintentar

En el CRM hipotético, el adaptador debería dar prioridad a una API del proveedor que consulte el estado de las operaciones o a un contrato de idempotencia limitado a la cuenta correcta. Tras agotarse el tiempo de espera, consulta pruebas concluyentes sobre esa misma operación. Un comprobante que coincida confirma el resultado; un rechazo definitivo registra el fallo; una consulta no concluyente deja la operación en estado desconocido.

La ausencia de un resultado en una búsqueda con consistencia eventual no es concluyente. Tampoco lo es encontrar un caso cuyo estado final coincida por casualidad con el valor solicitado: otro usuario podría haberlo cambiado. Una prueba más sólida vincula el identificador de la operación, el destino, la carga de datos y la versión resultante. Si la solicitud original pudiera seguir ejecutándose, no permitas que una consulta sin resultados justifique un segundo intento simultáneo.

Cuando el proveedor admita explícitamente reintentos seguros, reutiliza la misma clave y la misma carga de datos dentro de su plazo de conservación. Comprueba el endpoint concreto y la versión de la API. Stripe ofrece una advertencia útil y concreta: su API v1 almacena la primera respuesta ejecutada, incluida una respuesta 500, y las claves pueden eliminarse una vez transcurridas al menos 24 horas. Reutilizar una clave eliminada puede crear una solicitud nueva. Esos detalles son específicos del proveedor, no una regla universal de reintento.

Cuando el proveedor no ofrece ni deduplicación fiable ni conciliación concluyente, ninguna configuración ingeniosa de los puntos de control elimina la ambigüedad. Deja la acción afectada pendiente de revisión. Muestra al operador qué se intentó, qué pruebas se recopilaron y cuáles serían las posibles consecuencias de reintentarlo. No marques un resultado desconocido como fallido solo para que la cola siga avanzando.

Separa el estado del negocio de la entrega de notificaciones

Si controlas la base de datos, confirma el cambio de negocio y un evento de la bandeja de salida en la misma transacción local. Después, un proceso de envío puede intentar la entrega de forma independiente. Este patrón propuesto cierra la brecha entre ese cambio local y la intención de notificar; no convierte al proveedor de correo en parte de la transacción de la base de datos.

Asigna a la notificación su propio identificador de operación y guarda de inmediato cualquier comprobante del proveedor. Que un mensaje haya sido aceptado no demuestra que se haya entregado en una bandeja de entrada. Si el proveedor no tiene un contrato de envío idempotente, un marcador determinista y una búsqueda en Enviados ayudan a investigar, pero dejan lagunas por la concurrencia y el retraso de las búsquedas. Un envío incierto debe seguir siendo incierto hasta que las pruebas lo resuelvan.

Evita compensar automáticamente solo porque falte la confirmación. Reabrir el caso del CRM es otro efecto secundario y no puede deshacer el envío de un correo. La compensación necesita sus propias reglas de negocio, permisos y un resultado registrado.

Evita condiciones de carrera entre los procesos de recuperación

Utiliza actualizaciones condicionales del registro de la operación para decidir qué proceso puede hacerla avanzar. Para las concesiones temporales que caducan, añade un valor de exclusión (fencing) que aumente de forma monótona y exige que todas las vías de escritura bajo tu control rechacen los valores obsoletos. Comprobar una concesión una sola vez al arrancar no impide que un proceso bloqueado se reactive después de que su sustituto haya empezado.

Es posible que una API de terceros no aplique tu valor de exclusión. Esa frontera sigue necesitando deduplicación por parte del proveedor o envíos serializados con un tratamiento explícito de las solicitudes que ya estén en curso. La caducidad de una concesión, por sí sola, no demuestra que la llamada anterior se haya detenido. Durante la recuperación, vuelve a comprobar la autorización vigente antes de una nueva escritura; una autorización revocada puede detener el trabajo posterior sin borrar las pruebas de las acciones completadas.

Prueba los intervalos en los que puede producirse un fallo

La guía de Anthropic para evaluar agentes distingue lo que dice un agente del estado final de su entorno. Aplica esa distinción a la recuperación. Los siguientes son casos propuestos de inyección de fallos, no resultados de pruebas comparativas:

  • Fallo antes del envío: reanuda la operación preparada sin inventar una segunda intención de negocio.
  • Confirma el cambio en el CRM, descarta su respuesta y reinicia: concilia la operación original y verifica que la modificación se aplicó una sola vez.
  • Acepta la notificación y pierde su comprobante: conserva el estado desconocido salvo que unas pruebas concluyentes o el contrato de reintentos del proveedor lo resuelvan.
  • Reanuda dos procesos a la vez: verifica que un proceso que haya perdido la titularidad no pueda hacer avanzar las escrituras bajo tu control, incluso después de que caduque una concesión.
  • Cambia la carga de datos, deja caducar la clave del proveedor o retrasa la aparición de los resultados en las búsquedas: rechaza los reintentos inseguros y deriva los casos sin resolver a revisión.

Mide los efectos duplicados y las operaciones sin resolver, además de la tasa de finalización. Una implementación que complete menos casos automáticamente y mantenga como inciertos los que lo son puede estar funcionando correctamente. De lo contrario, la forma más fácil de mejorar el gráfico de éxitos es redefinir la incertidumbre como éxito. Los clientes suelen darse cuenta.

En los agentes integrados en la infraestructura de negocio, la recuperación forma parte del diseño de la integración. Empieza por una acción con consecuencias, documenta su contrato de reintento y conciliación, y provoca fallos en el proceso en cada frontera. Amplía la autonomía solo cuando las pruebas demuestren que la reanudación preserva tanto la intención de negocio como los resultados confirmados.

Ideas clave

  • Un punto de control persistido no demuestra que una acción externa haya fallado o se haya completado correctamente.
  • Fija cada efecto previsto bajo un identificador de operación estable y exige un contrato de reintentos específico del proveedor.
  • Mantén explícitos los resultados inciertos; la ausencia de resultados en una búsqueda y la coincidencia del estado final pueden no identificar la operación original.
  • Utiliza registros de operación separados para las actualizaciones de negocio y las notificaciones, con titularidad condicional y guardado inmediato de los comprobantes.
  • Prueba los tiempos de espera agotados tras confirmaciones remotas, la recuperación simultánea y los plazos de deduplicación caducados antes de aumentar la autonomía.
Daniel Arroyo
Por Daniel Arroyo
Chief Technical Officer