
Rango de pruebas local para el envenenamiento de memoria de agentes: observa cómo una memoria implantada dirige a un agente y luego demuestra la reparación. Objetivos sintéticos, agente determinista programado.
Tu agente lo recordó. ¿Debería haberlo hecho?
Un entorno de pruebas local para el envenenamiento de memoria de agentes: la memoria persistente como superficie de ataque. Alimenta la memoria de un agente con escrituras no confiables controladas, observa cómo una memoria implantada cambia lo que hace el agente, luego intenta detenerlo, y demuestra que la reparación funcionó.
Alcance, en claro. Objetivos sintéticos, un agente determinista con guion. Este repositorio demuestra la mecánica del envenenamiento de memoria, la defensa y la reparación a partir de investigación publicada, sobre backends de memoria reales. No es evidencia sobre la seguridad de ningún LLM real, servicio de memoria alojado o sistema en producción. Nunca apuntes nada de aquí a un sistema que no sea tuyo.
Las capas de memoria de agentes se están desplegando rápidamente, y las clases de ataque contra ellas están documentadas en la investigación (ver Fuentes). Este repositorio es un lugar pequeño y local para observar cómo ocurren esos ataques y probar una solución. Los primeros cuatro escenarios se construyen a partir de la taxonomía publicada; A5 extiende el alcance a la propia ventana de ranking, y A6 a una segunda decisión para la que el propietario nunca escribió una política:
| Escenario | Clase de ataque | Mecánica bajo prueba |
|---|---|---|
| A1 - Inyección directa | Contenido con forma de instrucción en una escritura no confiable de herramienta | La recencia ingenua permite que la "preferencia" más reciente gane sobre la política del propietario |
| A2 - Blanqueo por resumen | La carga útil sobrevive a la compactación | La sumarización extractiva reetiqueta la escritura como summary; la etiqueta parece confiable, pero el verdadero origen sigue siendo la fuente no confiable |
| A3 - Repetición | La misma afirmación, tres veces | La fusión de duplicados eleva la confianza de la afirmación por encima de la propia política del propietario |
| A4 - Importación blanqueada | El veneno llega preetiquetado como summary desde otro sistema | El filtrado limitado a escrituras de herramientas nunca lo ve, y el verdadero origen previo a la importación es irrecuperable; la denegación por defecto sobre afirmaciones que no son del propietario es lo que lo detiene |
| A5 - Inundación de recuperación | Diez escrituras no confiables con alta superposición de tokens de consulta | La política del propietario queda expulsada de la ventana de recall top-k del agente, de modo que incluso una afirmación débil por escritura gana por desalojo; el filtrado pone en cuarentena la inundación, y la política de origen es la red de seguridad |
| A6 - Injerto de preferencias | Una escritura no confiable injerta una preferencia sobre un sujeto que el propietario nunca estableció (el mensajero) | Nada con forma de instrucción que filtrar, y ninguna afirmación del propietario que contradecir, así que la denegación por defecto según el origen lo bloquea, pero la reparación limitada al conflicto por sí sola no puede eliminarlo. Una vez que el propietario declara una política, la misma pasada de reparación elimina el injerto |
Cada escenario se ejecuta de tres formas contra backends nuevos y reales, sin mocks:
repair(), y la decisión debe volver a la línea base. A6 es la excepción deliberada: sin ninguna afirmación del propietario sobre el sujeto injertado, la reparación limitada al conflicto no tiene nada a lo que anclarse y no elimina nada; el escenario fija ese límite y la remediación (el propietario declara una política, la reparación elimina el injerto).Marcador actual, verificado por la suite de pruebas: 6/6 ataques alteran al agente sin defensas, 6/6 se bloquean con las defensas activadas, 5/6 se restauran solo con la reparación; A6 documenta el límite de la reparación y se restaura una vez que el propietario declara una política de mensajería.
Los ataques y las defensas son propiedades del contrato de memoria, no de una implementación concreta, por lo que todo el alcance se ejecuta contra tres backends:
ReferenceMemory - almacén en memoria sin dependencias. Útil para leer la mecánica.ChromaMemory (mpolab/adapters.py) - un adaptador sobre ChromaDB, un almacén vectorial local real con su modelo de embeddings ONNX por defecto. Sin servidor, sin clave de API, sin llamadas de pago: pip install chromadb y los mismos seis ataques se reproducen contra embeddings y recuperación por vecinos más cercanos. Una advertencia: la primera ejecución de ChromaDB descarga su modelo de embeddings ONNX por defecto (unos 80 MB) desde internet; tras esa descarga única, funciona completamente sin conexión.SQLiteVecMemory (mpolab/adapters.py) - un adaptador sobre sqlite-vec, recuperación vectorial por vecinos más cercanos dentro de SQLite (KNN exacto, sin índice): sin servidor, sin descarga de modelo alguna. Genera embeddings con una bolsa de palabras con hash determinista (solo biblioteca estándar), por lo que ejercita la infraestructura real de recuperación vectorial sin conexión; no es una medida de la calidad de los embeddings semánticos. pip install sqlite-vec.tests/test_adapters.py ejecuta un contrato de conformidad más cada escenario registrado contra cada backend instalado. Añadir tu propio adaptador (mem0, Zep, Letta, pgvector - cualquier cosa con retain/recall) hereda toda la suite de ataques.
Cada entrada de memoria lleva dos campos de procedencia: trust (la etiqueta de almacenamiento que reporta el backend, que la compactación y las importaciones pueden reescribir) y origin (la fuente registrada en el momento de la escritura y que nunca se reescribe). Las defensas razonan sobre origin. Esa separación es donde el blanqueo de resúmenes vive y muere. Una nota de honestidad: el origin de una entrada importada es tan honesto como el sistema que la importó - la procedencia previa a la importación es irrecuperable. Es exactamente por eso que la política defendida permite que solo las afirmaciones con origen owner establezcan política (A4), en lugar de confiar en cualquier origen declarado.
python3 scripts/build_demo.py # regenerates demo/index.html from real runs
open demo/index.html # no server, no dependencies
Reproduce las escrituras en memoria, haga clic en la tarjeta que cree que es el veneno y luego revele: la decisión invertida, la ejecución de defensa y la pasada de reparación. Los estados enlazables directamente (#reveal=A2, #defense=A4) permiten compartir cualquier resultado como una URL.
Python 3.10+. La suite de referencia no tiene dependencias:
python3 -m unittest discover -s tests -v
Para incluir el backend de ChromaDB:
Verificado en una copia limpia:
python3 -m venv .venv && source .venv/bin/activate
pip install '.[chroma]' # local checkout extra; pulls chromadb
pip install '.[sqlitevec]' # or the sqlite-vec backend; no model download
python3 -m unittest discover -s tests -v