Gauntlet: ¿Qué sucede si las herramientas del agente se revelan?

Hackatón de Elasticsearch Agent Builder

gauntlet-blog_(1).png

Dos días antes de la fecha límite del hackathon, tomé la decisión de retroceder y replantear mi enfoque desde cero.

La idea original se llamaba Rehearse: un agente que ensaya acciones en un sandbox simulado por otro agente antes de ejecutarlas en el mundo real. El concepto era sólido, pero la falla era obvia en retrospectiva. El entorno puede cambiar entre el ensayo y la ejecución. El agente ensaya el envío de un email, pero cuando se ejecuta, la bandeja de entrada se ve diferente. La simulación diverge de la realidad, y todo se desmorona.

Pero existe una clase de problemas que no tiene este inconveniente: las pruebas de fuzz adversario. Si un agente falla en la simulación, también puede fallar en la vida real. Así surgió Gauntlet: 48 horas antes de la fecha límite y reutilizando la misma información central (un agente que usa la búsqueda para desarrollar memoria y mantener la creatividad) dirigida a un problema donde la estocasticidad no importa.

El problema de probar agentes en el camino ideal

La mayoría de nosotros hemos oído hablar de OpenClaw, el asistente personal de IA que se volvió viral. Si conoces los asistentes de IA de agentes con acceso amplio a herramientas, también conoces los obstáculos de seguridad. Los agentes se olvidan de lo que no deben hacer o nunca lo supieron desde el principio. La razón es sencilla: probamos el camino ideal. Verificamos que el agente haga lo que debe. Rara vez comprobamos lo que sucede cuando alguien intenta hacer que haga lo que no debería.

Existen entornos aislados para pruebas adversarias, pero son engorrosos de desarrollar. Los vectores de ataque se diseñan a mano. Los datos maliciosos se introducen a mano. La infraestructura de prueba se configura para cada caso. Es lento, no escala y solo encuentra los errores previstos.

Yo buscaba algo diferente: un sistema en el que el entorno en sí fuera automáticamente adversarial y se volviera más creativo con el tiempo.

La idea: simular el entorno de pruebas con otro agente

En vez de desarrollar un entorno de prueba, Gauntlet emplea un agente simulado que intercepta las llamadas de herramientas del agente principal y encuentra formas creativas de romperlo. Cuando el agente llama a search_emails, el agente simulado ve el resultado y decide si mutarlo inyectando un prompt en el cuerpo del correo, devolviendo datos con errores sutiles o alimentando información falsa para ver si el agente principal lo detecta. El agente principal nunca sabe que está en una simulación.

La interfaz consta de dos decoradores:

@function_tool
@gauntlet.query
def search_emails(folder: str = "inbox") -> str:
    """Search emails in the given folder."""
    return json.dumps(fetch_emails(folder))

Hay @gauntlet.query para las operaciones de lectura y @gauntlet.mutation para las de escritura. Esa es toda la interfaz de integración. Cuando termina la ejecución, evaluate() revisa lo que pasó y almacena los errores confirmados.

Es fácil de usar, pero hay dos problemas subyacentes serios.

Dos problemas que lo vuelven una cuestión de búsqueda

En primer lugar, el agente simulado debe mantener un modelo coherente del mundo a lo largo de toda la conversación. Si le dijo al agente principal que un correo electrónico era de Alice, no puede contradecirlo después. Un correo electrónico mutado que obviamente es falso no te enseña nada. La plausibilidad es fundamental.

Segundo, el agente de simulación necesita encontrar fallas nuevas. Redescubrir el mismo patrón de inyección de prompt 50 veces no sirve. Necesita recordar lo encontrado y explorar en nuevas direcciones mientras se mantiene fundamentado en lo que las herramientas realmente hacen.

Ambos son problemas de búsqueda. Y ahí es donde Elasticsearch se convierte en la columna vertebral del sistema.

Dos circuitos de memoria

El agente simulado se ejecuta en dos circuitos de memoria, ambos ubicados en Elasticsearch.

La memoria a corto plazo registra todo lo que ocurre durante la sesión actual: cada llamada a una herramienta interceptada, el resultado original, en qué se transformó y qué hizo el agente principal en respuesta. Esta es la capa de coherencia. El agente simulado puede consultar sus propias decisiones recientes y mantener la coherencia interna sin dejar de actuar de forma adversaria. Equilibrar la creatividad con la coherencia fue el problema de diseño más difícil de todo el proyecto.

La memoria a largo plazo es donde la creatividad se acumula. Almacena errores confirmados con incrustaciones para búsqueda de similitud, implementaciones completas de herramientas para que el agente pueda razonar sobre los modos de falla y resultados históricos de ejecuciones anteriores. Cuando el agente de simulación necesita una nueva idea de ataque, busca en la memoria a largo plazo lo que se ha intentado antes, encuentra lagunas e hipotetiza algo nuevo.

Todo esto forma parte de un ciclo cerrado: plantear hipótesis sobre los errores que podrían existir, crear las condiciones necesarias para comprobarlas y volver a almacenar los errores confirmados en el índice. El inventario aumenta. Los ataques se vuelven más creativos. La brecha entre Gauntlet y la configuración manual de sandbox se amplía con el tiempo.

Todo se ejecuta dentro de Elastic Agent Builder

El agente de simulación completo está construido dentro de Elastic Agent Builder: las instrucciones, los enlaces de herramientas y el estado de conversación de múltiples turnos a través de la API de Amazon Bedrock Converse; no se necesita orquestación externa.

La herramienta de la que estoy más orgulloso es `generate-hypothesis`. Es una sola instrucción ES|QL que toma muestras de errores existentes, los agrega con `MV_CONCAT` y llama a `COMPLETION` en línea para proponer una nueva hipótesis de ataque. Gestiona la ejemplificación, la agregación, el razonamiento LLM y la generación de resultados en una sola consulta, sin salir del ES|QL pipeline. Al principio pensé que sería necesario transferir datos entre Elasticsearch y un script externo, pero no lo fue.

La función de ES|QL COMPLETION fue la mayor sorpresa. Entre COMPLETION, STATS, MV_CONCAT y SAMPLE, pude crear pipelines de razonamiento completos como consultas únicas. El almacenamiento de errores emplea los flujos de trabajo de Kibana, y un dashboard de Kibana creado mediante programación ofrece visibilidad en tiempo real del número de errores, los desgloses de gravedad y los mapas de calor de patrones de ataque.

La API de Converse resolvió otro problema que temía. El agente simulado necesita recordar lo que ya le dijo al agente principal en una sola ejecución. Asumí que tendría que buscar historiales de conversaciones de índices y recargarlos en el agente en cada llamada. Pero resulta que la API de Converse maneja el estado de varias vueltas de forma nativa. No he escrito ninguna lógica de gestión de conversaciones. Si sigues llamando a Converse, se mantiene coherente.

¿Cómo me beneficia?

La configuración manual de la sandbox adversaria toma aproximadamente una hora por caso. Con Gauntlet, el mismo proceso toma de 2 a 10 minutos, y su memoria a largo plazo significa que cada ejecución está informada por cada ejecución anterior. Cuanto más lo uses, más aprende sobre los puntos débiles de tu agente y más se esfuerza por encontrar otros nuevos.

¿Qué sigue?

En este momento, Gauntlet es un 1v1: un agente simulado por un agente principal. Pero el problema es vergonzosamente diferente. Se podrían ejecutar 20 sesiones de ataque al mismo tiempo en sesiones independientes sin necesidad de cambios en la arquitectura. El escalado es el siguiente paso obvio.

La cuestión más interesante que queda por resolver es la diferencia entre exploración y explotación en la memoria a largo plazo. El agente simulado necesita equilibrar las variaciones de ataques exitosos conocidos (explotación) frente a hipótesis completamente nuevas (exploración). Este es un problema que se ha estudiado a fondo en otros ámbitos, pero su aplicación a las pruebas con agentes adversarios parece un terreno aún por explorar. Quizás haya algo que merezca la pena explorar más allá de este proyecto.

También sigo pensando en Rehearse. Gauntlet es un caso especial: las pruebas de fuzz funcionan porque el fallo en la simulación implica un posible fallo en la realidad. Pero hay otros ámbitos donde el entorno es lo suficientemente estable entre el ensayo y la ejecución como para que el concepto original de Rehearse funcione. Todavía no los he encontrado, pero estoy buscando.

La conclusión

Si estás construyendo agentes con acceso a herramientas del mundo real, prueba lo que sucede cuando esas herramientas contraatacan. No solo una vez manualmente, sino continuamente, con un sistema que recuerda lo que se ha probado y se vuelve más creativo con el tiempo. Eso es lo que Gauntlet hace.

Kavish Sathia

Estudiante, National University of Singapore

Kavish Sathia es un estudiante de informática en NUS que trabaja en sistemas de agentes.

GitHub · Demo · Sitio web · LinkedIn

El momento del lanzamiento de cualquiera de las características o funcionalidades descritas en esta publicación queda a exclusivo criterio de Elastic. Es posible que algunas características o funcionalidades que no estén disponibles en este momento no se lancen a tiempo o no se lancen en absoluto.

En esta publicación del blog, es posible que hayamos usado o nos hayamos referido a herramientas de AI generativa de terceros, que son propiedad de sus respectivos propietarios y están gestionadas por ellos. Elastic no tiene ningún control sobre las herramientas de terceros y no tenemos ninguna responsabilidad por su contenido, operación o uso, ni por ninguna pérdida o daño que pueda surgir de tu uso de dichas herramientas. Ten cuidado al usar herramientas de AI con información personal, sensible o confidencial. Cualquier dato que envíes puede usarse para el entrenamiento de la AI u otros fines. No se garantiza que la información que proporciones se mantenga segura o confidencial. Debes familiarizarte con las prácticas de privacidad y los términos de uso de cualquier herramienta de IA generativa antes de usarla. 

Elastic, Elasticsearch y las marcas asociadas son marcas comerciales, logotipos o marcas comerciales registradas de Elasticsearch B.V. en los Estados Unidos y otros países. Todos los demás nombres de empresas y productos son marcas comerciales, logotipos o marcas comerciales registradas de sus respectivos dueños.