DEV Community

Silviu Technology
Silviu Technology

Posted on

Agentes LLM: límites seguros para el email

Un agente LLM puede leer un mensaje, decidir que falta un dato y pedir un reenvío. Esa flexibilidad es útil, pero se vuelve peligrosa cuando el mismo workflow tiene permiso para enviar emails, crear cuentas o reutilizar una bandeja compartida.

El problema no es que el agente se equivoque una vez. El problema es que una decisión razonable en el contexto equivocado puede producir un efecto externo dificil de deshacer. En pruebas, además, un inbox de usar y tirar puede hacer que el equipo confunda una acción del agente con una señal del producto.

En mis flujos de automatización aplico una regla sencilla: el agente puede proponer una acción, pero una capa determinista decide si esa acción cruza la frontera de ejecución. Este diseño deja al LLM con suficiente espacio para razonar y reserva los efectos secundarios para un contrato que se puede probar.

El riesgo no es que el agente envíe un email

Imaginemos un agente que prueba un registro:

  1. crea una identidad de prueba;
  2. completa el formulario;
  3. espera el correo de verificación;
  4. abre el enlace y valida el resultado;
  5. resume lo ocurrido.

Visto como una secuencia, parece pequeño. En realidad contiene tres clases de operaciones: observación, decisión y efecto externo. Leer un mensaje es observación. Elegir reintentar es decisión. Enviar otro correo o cambiar el estado de una cuenta es un efecto.

Si todas esas operaciones viven en las mismas herramientas, el prompt se convierte en la única frontera de seguridad. Eso es una mala frontera: cambia con el contexto, no deja siempre una evidencia clara y puede interpretar "ayúdame a verificar" como "haz lo que sea necesario".

La solución tampoco es quitar al LLM del flujo. Es separar sus permisos. El agente debe poder explicar por que quiere una acción, pero no debería poder ejecutarla sin que los datos mínimos y el modo de ejecución sean válidos.

Un límite de ejecución en cuatro capas

Pienso en el diseño como un diagrama de cuatro cajas, conectadas de izquierda a derecha:

Intención → política → adaptador → evidencia

La primera caja transforma la salida del agente en una intención estructurada. No acepta texto libre como comando final. La segunda valida límites: dominio permitido, inbox asignado, número de reintentos y modo dry-run o live. La tercera es el único lugar que conoce el cliente de correo. La cuarta registra qué se pidió, qué se permitió y qué ocurrió.

Una intención mínima puede verse así:

type EmailIntent = {
  action: "send" | "read" | "wait";
  inbox: string;
  purpose: "verification-test" | "recovery-test";
  correlationId: string;
  mode: "dry-run" | "live";
};
Enter fullscreen mode Exit fullscreen mode

El campo purpose parece repetitivo, pero evita que una bandeja usada para verificar un registro termine recibiendo un mensaje de recuperación. El correlationId hace posible juntar logs, intentos y mensajes sin depender solo del asunto del email.

En esta capa también conviene fijar un presupuesto: por ejemplo, un máximo de tres lecturas y un reenvío por caso. Si el LLM pide el cuarto intento, el adaptador devuelve una negativa explicable. No hace falta otro prompt para negociar con el agente.

El contrato mínimo para un workflow de email

Un workflow de prueba necesita más que una dirección temporal. Debe declarar quién posee el inbox, cuándo empezó la operación y qué cuenta puede tocar. Un contrato práctico contiene:

  • inboxId y una dirección aislada por ejecución;
  • testRunId compartido por navegador, API y correo;
  • triggeredAt, para no aceptar mensajes antiguos;
  • una lista de acciones permitidas;
  • límites de tiempo y reintentos;
  • un modo de simulación explícito;
  • una política de retención de la evidencia.

Este contrato complementa bien las ideas de alertas de trial que sí orientan y un contrato simple para emails de prueba. La diferencia aquí es que el contrato no solo describe el correo: también limita lo que el agente puede decidir sobre ese correo.

El nombre del inbox no debería ser el único identificador. En una suite paralela, dos ejecuciones pueden leer mensajes parecidos y tomar la misma dirección por error. El sistema debe comparar testRunId, la hora de recepción y el propósito. Si falta uno, se registra un rechazo, no un reintento silencioso.

Durante una depuración alguien puede escribir "tempail mail" en una nota o buscar una bandeja temporal a mano. Es una señal de que el flujo perdió su contexto, no una instrucción que el agente deba seguir. La evidencia debe mostrar el contrato original y la razón exacta de cada decisión.

Cómo probar la frontera sin perder evidencia

Primero pruebo la política sin correo real. Dado un conjunto de intenciones, verifico que dry-run nunca llame al adaptador externo, que un inbox ajeno sea rechazado y que el cuarto reintento produzca el mismo error en cada ejecución.

Después pruebo el adaptador con un cliente falso. El fake responde con mensajes controlados: uno antiguo, uno de otro testRunId y uno válido. Así se comprueba que el agente no "adivina" cuál debe abrir. Tambien se puede simular un timeout sin gastar una operación externa.

Finalmente ejecuto un caso pequeño con una bandeja aislada. No necesito pedirle al LLM que sea creativo. Le doy una tarea acotada, guardo la intención emitida y comparo el resultado con el contrato. Si la acción no está permitida, el resultado esperado es una negativa con datos, no un correo enviado.

Los logs deben distinguir cuatro estados: proposed, allowed, executed y rejected. Mezclarlos en una sola línea hace dificil saber si falló el razonamiento, la política o el proveedor. Para una incidencia, esa diferencia ahorra bastante tiempo.

Q&A: decisiones frecuentes

¿El agente puede elegir la dirección del inbox?

Puede seleccionar un identificador dentro de un conjunto ya asignado. No debería inventar una dirección ni reutilizar una que no esté vinculada al testRunId. La asignación es una decisión del sistema.

¿Conviene permitir modo live en desarrollo?

Sí, pero detrás de una política explícita y con un dominio de prueba. El valor de live no debe saltarse validaciones; solo cambia el adaptador que se ejecuta. Si el modo cambia demasiadas cosas, el contrato esta mal definido.

¿Qué aporta un LLM si las reglas son tan estrictas?

Aporta interpretación y diagnóstico: puede leer el contexto, proponer el siguiente paso y resumir por qué una prueba no llegó a un estado válido. La política conserva el control de los efectos. Son responsabilidades distintas, y separarlas hace el sistema más claro.

El checkpoint que uso antes de publicar

Antes de conectar un agente a un workflow de email, reviso cinco puntos: intención estructurada, inbox aislado, límite de reintentos, modo de ejecución visible y evidencia correlacionada. Si uno falta, todavía no hay una automatización confiable, aunque el demo funcione.

La arquitectura no elimina todos los errores. Hace que cada error tenga un lugar donde mirar y un límite que lo contenga. Para agentes LLM, ese es un intercambio sano: menos libertad en el efecto externo y más claridad en el razonamiento que lo precede.

Top comments (0)