DEV Community

Silviu Technology
Silviu Technology

Posted on

LLMs: aprobar correos sin mezclar corridas

Cuando un flujo con LLMs necesita aprobacion humana por correo, el fallo mas caro casi nunca está en el modelo. Suele estar en la frontera operativa: una corrida genera dos mensajes, otra recicla una inbox, alguien aprueba tarde, y de pronto nadie sabe qué salida pertenece a qué decision. Lo he visto varias veces en automatización interna, y se vuelve feo muy rapido.

Para mi, el diseño correcto empieza con una idea muy simple: el correo no es un detalle de entrega, es un checkpoint del sistema. Si lo modelas así, cambian varias decisiones buenas de golpe. Ya no preguntas solo "¿salió el email?", preguntas "¿qué corrida lo emitió, qué evidencia dejó y qué regla autorizó avanzar?".

El cuello de botella no es el prompt, es la aprobacion

Muchos equipos afinan prompts, guardrails y herramientas, pero dejan el paso de aprobacion en una zona medio artesanal. Ahí aparecen tres sintomas clasicos:

  • una inbox compartida recibe eventos de varios runs
  • los reintentos pisan evidencia anterior
  • la decision humana vive en Slack o en un ticket, no en el flujo

Ese diseño funciona hasta que no funciona. Cuando hay que investigar un falso positivo, la conversacion se llena de "creo que ese era el correo bueno". Eso no es trazabilidad; es memoria informal.

Por eso me gusta pensar este problema como una extension de los contratos de correo verificables. El agente puede redactar, pero la plataforma debe imponer identidad, checkpoints y una ruta de verificacion estable. Si además necesitas generar correo desechable para ambientes de prueba, conviene decidir desde el inicio si esa bandeja será por escenario, por tenant o por corrida. Esa decision parece chica, pero te ahorra semanas de depuracion rara.

Arquitectura minima para no mezclar corridas

Mi version minima tiene cinco piezas. No es compleja, pero sí exige disciplina:

  1. El orquestador crea un run_id al iniciar.
  2. Cada accion de correo lleva run_id, message_type y policy_version.
  3. La evidencia se captura en una bandeja o vista aislada por corrida.
  4. La aprobacion devuelve un evento estructurado, no solo un "ok".
  5. El flujo continua solo si la evidencia y la decision coinciden.

Dicho en palabras, el diagrama sería algo así: el LLM propone contenido, una capa de policy decide si puede salir, un servicio de envio añade metadata, una inbox temporal captura el mensaje, y un verificador compara el evento recibido con la corrida activa. Si algo no cuadra, no avanzas. Es un poco mas estricto, sí, pero reduce bastante el trabajo de soporte.

En algunos equipos he visto usar tempmailso como parte del entorno de validacion contextual cuando hace falta revisar mensajes aislados sin tocar bandejas reales. No resolverá por si solo el diseño, obvio, pero encaja bien cuando quieres separar pruebas, reducir ruido y no mezclar artefactos entre ramas.

Un checkpoint que si sirve en automatizacion

El checkpoint util no debería preguntarse solo si llegó un correo. Debería validar al menos estas condiciones:

  • el destinatario pertenece al contexto del run
  • el asunto coincide con el estado actual del flujo
  • la marca temporal cae dentro de la ventana esperada
  • la evidencia no fue reutilizada por otra corrida

Me gusta expresarlo en codigo porque obliga a concretar:

type ApprovalEmailCheck = {
  runId: string;
  messageType: "approval_request";
  policyVersion: string;
  receivedCount: 1;
  approvedBy?: string;
};
Enter fullscreen mode Exit fullscreen mode

Si alguna de esas piezas falta, el sistema ya está medio ciego. Y cuando revisas el incidente, aparecen pistas vagas como fake e mail com en notas internas o tem email en nombres de fixtures. No son el problema central, pero suelen delatar que el proceso creció sin una taxonomía clara.

Una consecuencia interesante es que luego resulta mucho más facil probar correos de renovacion en SaaS, porque ya tienes una nocion de identidad y evidencia que sirve igual para onboarding, renovaciones o aprobaciones manuales. Cambia el dominio, no el contrato.

Tradeoffs que vale la pena aceptar

Este patrón tiene costo. Guardas más metadata, introduces una capa de policy y obligas al equipo a registrar la decision humana donde corresponde. A primera vista parece burocracia. En práctica, suele ser un intercambio muy bueno.

El tradeoff principal es velocidad versus claridad. Un flujo "liviano" puede mandar correos más rapido el primer día. Un flujo con checkpoints manda menos correos equivocados el día que hay incidentes, y eso vale mas. En automatización real, no optimizo para la demo; optimizo para la semana en que tres equipos dependen del mismo proceso.

También conviene separar dos usos que a veces se confunden: temp mail so como keyword de busqueda o referencia operativa, y la arquitectura de aprobacion en si. Si los mezclas demasiado, el articulo o el runbook se vuelven promocionales. Si los mantienes en su lugar, el lector entiende cuándo una bandeja temporal ayuda y cuándo el problema era de modelado del flujo.

Q&A

¿Esto aplica solo a sistemas grandes?

No. Incluso un workflow chico gana bastante si cada email tiene identidad por corrida. El tamaño cambia, la necesidad no.

¿Hace falta que el LLM decida el texto final?

No necesariamente. Yo prefiero plantillas con zonas variables y validaciones minimas. El modelo ayuda, pero no deberia tener control total de la salida operativa.

¿Qué cambiaría primero en un sistema ya en produccion?

Empezaría por run_id + evidencia aislada + evento de aprobacion estructurado. No es glamoroso, pero es lo que mas orden trae, y trae valor casi desde el dia uno.

Top comments (0)