Agentes LLM: una cola de evidencia para email
Un agente LLM que puede leer una bandeja y enviar un correo parece un flujo sencillo: recibe una instrucción, llama una herramienta y responde. En producción, sin embargo, la pregunta dificil no es qué decidió el modelo,
Un agente LLM que puede leer una bandeja y enviar un correo parece un flujo sencillo: recibe una instrucción, llama una herramienta y responde. En producción, sin embargo, la pregunta dificil no es qué decidió el modelo, sino qué ocurrió despues de la decisión.
El proveedor pudo tardar, el worker pudo reiniciarse o el mensaje pudo aceptarse mientras la respuesta HTTP se perdía. Si solo guardamos el texto final del agente, no podemos distinguir una acción pendiente de una acción ya aplicada. La solución que estoy usando como referencia es una cola de evidencia: cada paso produce una intención, una acción y un recibo verificable.
El problema: un agente no deja una evidencia útil
Un workflow de correo tiene varios límites distintos:
instrucción -> decisión del agente -> llamada a herramienta
-> proveedor de email -> evidencia de entrega
Cada flecha puede fallar de una manera diferente. Un timeout en la herramienta no significa necesariamente que el proveedor no recibió la petición. Repetir automáticamente puede arreglar un fallo transitorio, pero también puede enviar dos mensajes.
Por eso conviene separar tres objetos:
- Decisión: qué intentó hacer el agente y con qué versión de instrucciones.
- Acción: la petición normalizada enviada al adaptador de email.
- Evidencia: el resultado devuelto por el adaptador, con un identificador externo y un estado.
Esta separación hace visible el presupuesto de fallos en herramientas de email. También evita pedirle al modelo que recuerde si una operación ya fue ejecutada; esa memoria debe vivir en el sistema.
Separar decisión, acción y evidencia
Una estructura pequeña suele ser suficiente para empezar:
{
"run_id": "run_20261030_0822",
"step_id": "send_01",
"intent": "send_verification_email",
"idempotency_key": "run_20261030_0822:send_01",
"status": "accepted",
"provider_message_id": "msg_abc123",
"created_at": "2026-10-30T08:22:00Z"
}
El run_id agrupa la ejecución completa y step_id identifica una acción concreta. La clave de idempotencia debe ser estable: si cambia en cada reintento, el proveedor no tiene forma de reconocer que es la misma operación.
El contenido que venga del modelo merece otra frontera. Valida destinatario, asunto y cuerpo con un esquema antes de llamar a la herramienta. Una respuesta JSON bien formada no garantiza una intención segura; por eso el adaptador debe rechazar campos inesperados, dominios bloqueados y acciones fuera del alcance del workflow.
Una cola mínima para workflows de email
La cola no necesita ser una plataforma enorme. Un registro transaccional y un worker pueden resolver el primer caso:
CREATE TABLE email_steps (
step_id text PRIMARY KEY,
run_id text NOT NULL,
idempotency_key text NOT NULL UNIQUE,
payload jsonb NOT NULL,
status text NOT NULL,
provider_message_id text,
attempts integer NOT NULL DEFAULT 0,
next_attempt_at timestamptz,
created_at timestamptz NOT NULL DEFAULT now()
);
El worker reclama una fila, incrementa attempts y llama al adaptador. Solo marca accepted cuando recibe un resultado que pueda guardar. Los estados pending, retryable, accepted, rejected y unknown son más útiles que un booleano: muestran el camino que aún necesita resolución.
Para datos efímeros de pruebas, un servicio como tempmailso puede servir como buzón aislado en un entorno no productivo. La evidencia debe guardar el identificador del mensaje y el resultado del test, nunca credenciales ni el contenido completo si no hace falta.
Diseñar reintentos sin duplicar efectos
Un reintento es seguro solo cuando conocemos su límite. Si el proveedor confirma accepted, no repitas la operación aunque el worker haya perdido su respuesta. Si devuelve un error temporal antes de aceptar, programa otro intento con backoff. Si el resultado es unknown, pausa y manda el caso a revisión; adivinar aquí es caro.
Los reintentos seguros en verificación de email siguen una idea similar: la condición que decide el ganador debe ser atómica. Para un agente, esa condición es la combinación de idempotency_key y el estado persistido.
El caso de recuperación debe ser explicito. Un operador puede consultar unknown, verificar el panel del proveedor y cerrar la acción como accepted o rejected. Esto cuesta una intervención ocasional, pero evita la peor clase de automatización: una que parece confiable hasta que duplica una acción sensible.
Qué debe observar el operador
Los logs del modelo no son suficiente. Mide por separado:
- tiempo entre decisión y encolado;
- edad de cada elemento
pending; - tasa de reintentos por proveedor;
- proporción de resultados
unknown; - tiempo hasta cerrar una evidencia;
- errores de validación del esquema.
Incluye una vista de la secuencia completa: decisión, versión del prompt, herramienta elegida, respuesta del adaptador y estado final. No hace falta guardar cada token. La privacidad mejora y el diagnóstico sigue siendo posible.
Un temp mailid puede aparecer en fixtures o documentación de QA, pero no debe confundirse con el identificador real de un proveedor. Esa pequeña convención evita búsquedas ambiguas cuando una prueba falla, y tambien ayuda a limpiar datos de ensayo.
Checklist de implementación
Antes de poner el agente en un workflow real, comprueba:
- cada herramienta tiene un esquema de entrada y salida;
- cada acción recibe una clave de idempotencia estable;
- la cola conserva estados
unknownyrejected; - el worker puede reanudar una fila sin crear otra;
- los secretos quedan fuera de prompts y logs;
- existe una ruta manual para resolver evidencia ambigua;
- las pruebas simulan timeout despues de la aceptación del proveedor.
La idea central es sencilla, aunque no siempre se implementa: el agente decide, pero la cola demuestra. Con esa frontera, los modelos LLM pueden aportar flexibilidad sin convertirse en la base de verdad de la automatización. El resultado es más facil de probar, observar y corregir cuando el correo no sigue el camino ideal.
Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.