DEV Community

Silviu Technology
Silviu Technology

Posted on

Agentes LLM: evalúa la intención antes del email

Los agentes LLM ya pueden leer una instrucción, elegir una herramienta y actuar sobre un flujo de email. El problema aparece cuando la intención que interpretaron no coincide con la que el sistema necesitaba. Un agente puede consultar el inbox equivocado, reutilizar una dirección de otra corrida o intentar enviar un mensaje cuando solo debía verificar un estado.

En mis pruebas de workflows con modelos LLM, el cambio más útil no fue escribir un prompt más largo. Fue colocar una frontera pequeña entre la intención y la acción. Esa frontera clasifica qué se quiere hacer, qué evidencia hace falta y qué operaciones quedan prohibidas. Ahi el email deja de ser una caja negra del agente y pasa a ser una dependencia con contrato.

El problema: un agente puede ejecutar la intención equivocada

Una petición como “confirma el alta del usuario” parece clara para una persona, pero contiene varias acciones posibles:

  1. Buscar un mensaje ya enviado.
  2. Solicitar un nuevo email de verificación.
  3. Abrir un enlace recibido.
  4. Reportar que el alta terminó.

Si la herramienta expone solo una función genérica, el agente puede saltar del paso uno al tres, o enviar de nuevo el mensaje porque no encontró evidencia a tiempo. El resultado parece un fallo de entrega, aunque el problema original era de interpretación.

El diseño que mejor me ha funcionado separa tres estados: intencion_detectada, accion_autorizada y evidencia_obtenida. Cada estado tiene un identificador de ejecución. Así se puede responder una pregunta simple durante un incidente: ¿el modelo decidió mal, la herramienta ejecutó mal o el inbox todavía no tenía el mensaje?

Un filtro de intención antes de tocar el email

Pienso este flujo como un diagrama en palabras:

solicitud -> clasificación -> política -> herramienta de email -> evidencia -> respuesta

La clasificación no necesita ser sofisticada. Puede devolver un objeto pequeño y verificable:

{
  "intent": "verify_existing_message",
  "run_id": "signup-1842",
  "mailbox_scope": "signup-1842",
  "max_reads": 3,
  "can_send": false
}
Enter fullscreen mode Exit fullscreen mode

La política valida que run_id exista, que el buzón pertenezca a esa corrida y que la acción solicitada esté permitida. Si can_send es falso, no hay prompt que pueda convertir una consulta en un envío. Ese límite es mas importante que añadir otra instrucción al system prompt.

Para la parte de herramientas, me gusta mantener contratos cortos para el uso de herramientas: entradas tipadas, estados explícitos y errores que el agente pueda distinguir. Un timeout no significa “mensaje inexistente”; significa que todavía no hay evidencia concluyente.

El contrato mínimo de la herramienta

Una herramienta de email para un agente debería devolver al menos:

  • status: found, not_found, expired, forbidden o timeout.
  • run_id: la corrida a la que pertenece la consulta.
  • message_id: un identificador estable si hubo coincidencia.
  • observed_at: cuándo se tomó la decisión.
  • next_action: qué puede hacer el workflow a continuación.

Con esto, el agente no tiene que inventar una explicación. Si recibe not_found, puede finalizar la verificación o hacer un único polling adicional según la política. Si recibe forbidden, debe detenerse. Reintentar en ese caso solo produce ruido y puede mezclar datos.

Un buzón temporal aislado también ayuda a reducir el alcance de una prueba. Si el equipo usa un generador de correos falsos para crear datos de staging, la dirección debe quedar ligada a un run_id, una fecha de expiración y un objetivo. No es una solución para identidad real ni una excusa para enviar datos sensibles; es un fixture que debe caducar.

Hay búsquedas que parecen pequeñas, pero dañan bastante el diagnóstico. Por ejemplo, “fake e mail com” o “tamp mail com” pueden entrar desde una consulta mal formada. Las trato como entrada no confiable y no como una señal para cambiar de herramienta.

Cómo probar la frontera con evidencia

La prueba principal no es “el agente respondió correctamente”. Es comprobar que cada transición dejó evidencia. Para cada caso guardo:

  1. La solicitud original y la versión del prompt.
  2. La clasificación de intención.
  3. La decisión de la política.
  4. La llamada a la herramienta, sin contenido privado innecesario.
  5. El estado final y la razón de terminación.

También pruebo casos negativos: un run_id de otra corrida, una acción de envío cuando solo se permite leer, un mensaje expirado y dos mensajes parecidos. En la interfaz, los estados deben ser comprensibles; los errores de email sin ruido visual son parte del contrato porque una pantalla ambigua puede inducir otro intento del agente o del operador.

El test más valioso para mí es el de aislamiento: ejecuto dos escenarios casi idénticos al mismo tiempo y verifico que ningún mensaje pueda satisfacer la consulta del otro. Si falla, no arreglo el prompt. Arreglo el alcance de la herramienta, la clave de búsqueda o la política de autorización.

Tradeoffs y checkpoints de implementación

Este patrón añade una capa y algo de latencia. A cambio, reduce la clase de fallos difíciles de explicar: acciones válidas en el buzón equivocado. No intentaría implementarlo todo de una vez. Los checkpoints pueden ser:

  • Primero, registrar run_id y separar lectura de envío.
  • Después, devolver estados tipados en vez de texto libre.
  • Luego, aplicar límites de lectura, envío y reintento.
  • Finalmente, guardar evidencia suficiente para reproducir la decisión.

El coste también es real. Un contrato estricto puede rechazar solicitudes legítimas que todavía no tienen una categoría. Para esos casos prefiero un estado needs_review antes que una acción implícita. En equipos pequeños esto parece mas lento al principio, pero hace que el incidente sea investigable.

Preguntas frecuentes

¿Hace falta un modelo adicional para clasificar la intención?

No siempre. Un esquema validado y unas pocas reglas pueden separar lectura, envío y revisión. Un segundo modelo tiene sentido si las solicitudes son muy variadas, pero introduce otra fuente de latencia y errores.

¿Un correo temporal resuelve el problema de seguridad?

No. Reduce la persistencia de los datos de prueba, pero no sustituye autorización, expiración ni control de acceso. El agente nunca debería recibir más contenido del inbox del que necesita.

¿Qué hago cuando el mensaje tarda?

Devuelve timeout, conserva la evidencia y aplica una política de polling con límite. No conviertas cada demora en un reenvío. Esa diferencia es pequena en código, pero enorme en producción.

¿Cuál es el primer indicador que revisaría?

La tasa de consultas que terminan en forbidden, timeout o en un run_id inconsistente. Esos estados muestran problemas de contrato antes de que aparezcan como fallos genéricos del agente.

Validar la intención antes del email no vuelve inteligente al workflow por sí solo. Lo vuelve más legible. Cuando una acción externa tiene alcance, evidencia y límites visibles, el agente puede ayudar sin convertirse en la única fuente de verdad.

Top comments (0)