DEV Community

Silviu Technology
Silviu Technology

Posted on

Agentes LLM: un recibo para emails de prueba

Un agente LLM puede decir “prueba completada” aunque nadie pueda demostrar que el email salió, llegó al inbox correcto o contenía el enlace esperado. Ese mensaje sirve para una demo, pero es una señal muy floja para un pipeline.

En workflows de onboarding, recuperación de cuenta o activación de un trial, el email es parte del producto. Mi enfoque reciente es tratar cada ejecución como una pequeña transacción: el agente recibe una intención, hace acciones limitadas y entrega un recibo verificable. No es una traza gigante ni un log lleno de ruido; es un contrato que otro proceso puede leer.

El problema: el agente dice que terminó, pero no deja evidencia

Imaginemos un agente que crea un usuario, solicita un código de verificación y revisa un email. Hay varios resultados distintos que suelen terminar resumidos como ok:

  • El mensaje nunca salió porque la cola estaba detenida.
  • Salió, pero terminó en otro inbox.
  • Llegó con un asunto correcto y un enlace de producción, un fallo bastante serio.
  • El agente leyó un mensaje viejo y creyó que era el de esta ejecución.
  • El proveedor respondió tarde y el timeout ocultó el estado real.

La solución no es pedirle al modelo que sea “más cuidadoso”. Es separar la decisión del modelo de la evidencia del sistema. El agente puede explicar el resultado, pero los hechos importantes deben venir de eventos observables.

Para un caso de signup, también ayuda probar un signup sin un inbox real cuando el objetivo es aislar la API y no repetir toda la experiencia de correo.

Qué debe contener un recibo de email

Un recibo útil es pequeño. Estos campos suelen ser suficientes:

{
  "run_id": "signup-8f31",
  "intent": "verify_signup",
  "recipient_ref": "inbox-qa-42",
  "message_id": "msg-1902",
  "subject_match": true,
  "link_host": "staging.example.test",
  "observed_at": "2026-09-23T08:00:12Z",
  "status": "verified"
}
Enter fullscreen mode Exit fullscreen mode

run_id conecta el recibo con el intento, mientras message_id evita confundir dos emails parecidos. recipient_ref debe ser una referencia controlada, no una dirección personal escrita en cada log. link_host hace visible una frontera de seguridad que normalmente se pierde en un simple “email recibido”.

El campo status conviene que tenga pocos valores: sent, observed, verified, timeout y ambiguous. Un estado ambiguous es mejor que una falsa certeza. Parece obvio, pero muchos agentes convierten cualquier contenido no vacío en éxito.

Diseño mínimo del contrato

El contrato debe responder tres preguntas: ¿qué se intentó?, ¿qué evidencia se observó?, ¿se puede repetir sin contaminar otra ejecución?

Una regla práctica es que el agente no pueda escribir verified por sí mismo. Solo un verificador que compruebe asunto, destinatario lógico, enlace y antigüedad del mensaje puede emitirlo. El modelo puede seleccionar el siguiente paso o redactar el resumen, pero no sustituye esas comprobaciones.

También conviene hacer explícita la idempotencia. Si el agente reintenta después de un timeout, el sistema debe conservar el mismo run_id y registrar el intento nuevo. Así sabremos si hay dos mensajes o si solo cambió la lectura. Un tem email en una nota de pruebas no arregla esta ambigüedad; el identificador sí.

Para flujos SaaS, el mismo criterio se aplica al momento de activar trials sin correos ciegos: la activación debe depender de una señal validada, no de que el agente haya pulsado el botón correcto.

Dónde entra un inbox efímero

En staging, un inbox efímero reduce el riesgo de usar cuentas personales y permite que el test tenga un destinatario propio. Un correo temporal desechable puede encajar como una pieza de ese entorno si la política del equipo permite ese proveedor y se revisan sus límites de retención.

No lo usaría para validar una cuenta de producción, secretos reales o recuperación de clientes. El inbox es un accesorio de prueba, no un almacén de identidad. La dirección debe tener alcance corto, el contenido no debe copiarse a logs y el run debe expirar. Es una frontera simple, pero se rompe rapido cuando el equipo reutiliza la misma dirección para todos los tests.

Implementación por checkpoints

Un flujo razonable tiene cuatro checkpoints:

  1. Preparar: crear run_id, inbox lógico y expectativas de asunto y host.
  2. Actuar: el agente ejecuta signup o solicita el email, con un timeout definido.
  3. Observar: un adaptador consulta el inbox y devuelve solo mensajes candidatos, su edad y su message_id.
  4. Verificar: código determinista compara las expectativas y escribe el recibo inmutable.

El LLM puede ayudar a interpretar un error o decidir si debe pedir otra observación, pero la comparación principal debe ser código. Si el proveedor tarda, el estado pasa a timeout; no se rellena el hueco con una suposición. Luego un proceso aparte puede reintentar con backoff y dejar la relación entre ambos recibos.

En CI, guardaría el recibo y una versión sanitizada del asunto, pero no el cuerpo completo por defecto. Eso da suficiente contexto para depurar y mantiene los datos mas pequeños. Si hay que guardar el cuerpo por una investigación, debe existir una retención explícita.

Tradeoffs y límites

Este diseño añade campos, estados y una etapa de verificación. Para una prueba manual rápida puede sentirse excesivo. Su valor aparece cuando hay paralelismo, reintentos o varios agentes trabajando sobre el mismo entorno.

Hay otra limitación: un recibo prueba lo observado por el adaptador, no garantiza que todos los usuarios recibirán el mismo email. Las pruebas de proveedor, entregabilidad y plantillas siguen siendo necesarias. El contrato solo evita que un workflow automatizado confunda “vi algo” con “el producto funciona”.

Checklist para el siguiente workflow

  • ¿Cada ejecución tiene un run_id nuevo y rastreable?
  • ¿El mensaje observado es más reciente que el inicio del run?
  • ¿El enlace apunta al host de staging esperado?
  • ¿verified lo emite código determinista y no el modelo?
  • ¿Los reintentos conservan la relación entre recibos?
  • ¿La retención del inbox y del log está definida?
  • ¿Un timeout queda visible como timeout, sin maquillaje?

El patrón es deliberadamente modesto: intención, observación y verificación. Cuando un agente LLM comparte ese recibo, el equipo puede revisar una decisión con evidencia y no solo con prosa convincente. Para automatización que toca email, esa diferencia vale mas que otro prompt largo.

Top comments (0)