Cómo reintentar acciones de un agente sin duplicarlas
Diseña claves de operación, estados pendientes y reconciliación para que los reintentos de una integración LLM no dupliquen acciones externas.
Un agente crea un ticket de soporte. El proveedor acepta la petición, pero la respuesta se pierde. La aplicación interpreta el timeout como un fallo y vuelve a crear el ticket. Ahora hay dos incidencias para el mismo trabajo.
En este ejemplo hipotético, el problema aparece entre una acción y su confirmación. Para poder reintentar necesitas identificar la operación original y averiguar qué efecto produjo. El texto que el modelo genera después no resuelve esa incertidumbre.
Identifica una intención de negocio
Asigna un identificador cuando la aplicación acepta una operación concreta. Consérvalo durante sus reintentos, aunque el modelo vuelva a proponer la llamada o el proceso se reinicie. El identificador de una llamada del modelo puede cambiar entre ejecuciones y no tiene por qué representar esa intención persistente.
Dos peticiones con el mismo contenido pueden ser legítimamente distintas. Por ejemplo, una persona puede querer abrir dos tickets similares. Generar la clave únicamente a partir del texto confunde coincidencia de datos con identidad de la operación. La guía de API idempotentes de AWS explica por qué el cliente debe expresar esa intención con un identificador propio.
Define también su ámbito. Una clave debe pertenecer al tenant y a la operación para los que fue creada. Un usuario no puede reutilizar una clave ajena para consultar el resultado de otro cliente.
Guarda la operación antes de enviarla
Un registro mínimo puede contener:
operation_id
tenant_id
action_type
arguments_fingerprint
status
provider_reference
Los nombres son ilustrativos. Añade la identidad que autoriza la acción, los tiempos necesarios para reconciliarla y la versión de la propuesta aprobada. La huella de los argumentos permite detectar que alguien intenta reutilizar una clave con un contenido diferente; no sustituye los permisos.
Evita que dos procesos reclamen simultáneamente la misma operación. La persistencia debe aplicar una restricción única y una transición de estado atómica. Si un segundo intento encuentra un resultado confirmado, devuelve ese resultado. Si encuentra trabajo en curso, informa de que sigue pendiente o consulta su estado.
En PostgreSQL, INSERT con ON CONFLICT permite resolver de forma atómica una inserción o actualización sobre una clave única. La llamada al proveedor y la escritura en tu base de datos suelen pertenecer a sistemas distintos, por lo que todavía existe un intervalo de fallo entre ambas.
Usa el contrato de idempotencia de cada API
Si la API acepta una clave de idempotencia, envíala y conserva exactamente la misma en los reintentos de esa operación. Revisa qué respuestas guarda, cómo trata argumentos diferentes y durante cuánto tiempo recuerda la clave. Esas reglas dependen del proveedor y del endpoint.
No generes una clave nueva porque el intento anterior devolvió un error de red. Tampoco reutilices automáticamente una clave antigua cuando haya vencido la ventana del proveedor. En ese caso hay que comprobar si el efecto ya existe antes de decidir otra acción.
Cuando el servicio no ofrece idempotencia, busca una referencia externa que permita consultar el resultado. Si no existe una consulta fiable y el resultado sigue siendo desconocido, conserva el estado pendiente y pide reconciliación humana. Repetir una escritura a ciegas puede convertir una interrupción temporal en un duplicado permanente.
Separa rechazo de resultado desconocido
Una validación rechazada antes de ejecutar y una respuesta perdida después de ejecutar requieren decisiones distintas. El runtime debería conservar esa diferencia en su estado y en lo que comunica al usuario.
Distingue al menos una operación pendiente de enviar, otra en ejecución y otra confirmada. Añade un estado de resultado desconocido para los casos que necesiten reconciliación. A continuación, define quién puede resolverlo y con qué evidencia del proveedor.
Los reintentos necesitan límites y una espera entre intentos. Aplica la política del servicio para errores transitorios y límites de uso. Un error de permisos o un argumento inválido normalmente exige corregir la causa. Repetir la misma solicitud sin cambios no aporta información útil.
En la interfaz, «no se ha podido confirmar» debe conservar su significado. No equivale a «no se ha creado». Esa precisión evita que el usuario repita una acción basándose en un mensaje incorrecto.
Comprueba las ventanas de fallo
Prueba el flujo con un servicio simulado que pueda aceptar la operación y perder su respuesta. Reinicia después el proceso y comprueba qué clave vuelve a usar. Cuenta los efectos producidos en el servicio simulado, además de inspeccionar los logs de la aplicación.
Incluye dos procesos concurrentes, una respuesta tardía y argumentos distintos bajo la misma clave. Prueba también una revocación de permisos mientras la acción espera aprobación. Verifica qué ocurre al vencer la ventana de idempotencia del proveedor.
La prueba debe poder explicar por qué existe un único ticket para una intención concreta y cuándo hace falta intervención humana. No convierte cualquier integración distribuida en un sistema con ejecución exactamente una vez; demuestra el comportamiento bajo las condiciones que has ensayado.
Acota una entrega de integración
Para una primera revisión, elige una sola herramienta que modifique datos. Identifica el contrato del proveedor y acuerda los estados y pruebas que deben quedar implementados. Incluye el procedimiento para resolver operaciones atascadas.
La integración de LLM debe cubrir este comportamiento de backend. La guía del runtime de un agente sitúa la operación dentro del flujo completo.
Envía el nombre de la API y describe una acción que no deba duplicarse. Se puede delimitar un cambio con pruebas de reintento y reconciliación antes de ampliar la autonomía del agente.
Servicio relacionado
Flujos de agentes
Conectar herramientas con permisos, estado y revisión humana.