Agentis Memory : Protocole compatible Redis avec recherche vectorielle native et inférence locale
Six sous-agents enquêtent sur un incident : l'un détecte OOMKilled dans les logs, un autre repère un pic CPU dans Grafana, un troisième extrait le contexte de Slack. Sans mémoire partagée, ils génèrent des hypothèses concurrentes. La solution est un stockage compatible Redis avec recherche sémantique intégrée. Un seul binaire GraalVM, des embeddings locaux via ONNX, tout client Redis se connecte sans modification.
Pourquoi les solutions existantes étaient insuffisantes
Mem0 et Zep reposent sur des API REST, des bases de données vectorielles externes (Qdrant, Postgres) et des embeddings cloud (OpenAI). Chaque MEMSAVE implique trois sauts réseau avec des latences en millisecondes. Redis Stack prend en charge la recherche vectorielle via RediSearch mais nécessite une inférence vectorielle externe. Un service sans dépendance était nécessaire : protocole RESP, vectorisation asynchrone, indexation HNSW dans un seul processus.
La première tentative était un fork de Redis avec un module C et ONNX Runtime. Résultat : des segfaults en concurrence, gestion manuelle de la mémoire à la limite de l'allocateur. Passage à Java : GraalVM native-image compile en un binaire de 150 Mo avec le modèle all-MiniLM-L6-v2 intégré (384 dimensions, inférence en 2-5 ms).
Stack technique pour des performances élevées
- GraalVM native-image : démarrage <1s, latence prévisible sans préchauffage JIT.
- Java Vector API (Project Panama) : SIMD pour la similarité cosinus dans les recherches HNSW.
- Project Loom (Virtual Threads) : connexions RESP dans des threads légers sans motif réacteur.
- ONNX Runtime : inférence d'embedding locale.
- jvector : HNSW pour la recherche ANN.
Benchmark avec memtier_benchmark : version JVM — 0,5x Redis (60k op/s). Après native-image + Vector API — 1,36x Redis (168k op/s) sur les opérations de chaînes.
Architecture : Couche KV + Vectorielle
Moteur KV classique (90+ commandes Redis : chaînes, hachages, listes, ensembles, ensembles triés, TTL, SCAN, pub/sub) + couche vectorielle.
redis-cli -p 6399 MEMSAVE "agent:fact:stack" "Nous utilisons Python 3.12 avec FastAPI"
# → OK (asynchrone : chunks → embeddings → HNSW)
MEMQUERY vectorise la requête, recherche HNSW par cosinus, renvoie clé+texte+score :
redis-cli -p 6399 MEMQUERY "Problème mémoire Python FastAPI" TOPK 3
# 1) "agent:fact:stack" "Nous utilisons Python 3.12 avec FastAPI" 0.92
MEMDEL supprime de HNSW+KV. MEMSIM pour le score de similarité entre textes. Traitement asynchrone : KV OK instantanément, indexation en arrière-plan (5-10 ms/chunk).
Scénario : Investigation d'incident
- LogsInvestigator :
MEMSAVE "logs:pod:payment" "Pod OOMKilled payment-service". - MetricsInvestigator :
MEMQUERY "pression mémoire payment-service"→ trouve OOM, ajuste l'hypothèse. - SlackContextInvestigator :
MEMQUERY "déploiement payment-service hier"→ lie au déploiement.
Synthesizer agrège un rapport cohérent sans bruit.
Benchmarks et optimisations
| Opération | Redis (op/s) | Agentis Memory (op/s) | Accélération |
|-----------|---------------|------------------------|---------|
| SET/GET | 120k | 168k | 1,36x |
| MEMSAVE | N/A | 12k (avec inférence) | - |
| MEMQUERY | N/A | 8k TOPK=10 | - |
Vector API accélère la similarité cosinus de 2,5x par rapport au scalaire. Virtual Threads monte à 10k connexions sans épuisement des threads.
Points clés à retenir
- Compatibilité : 90% API Redis + 4 commandes sémantiques (MEMSAVE, MEMQUERY, MEMDEL, MEMSIM).
- Performance : 1,36x Redis sur KV, inférence locale sans réseau.
- Zéro dépendance : binaire natif avec modèle, pas de Docker/clés.
- Cas d'usage : mémoire partagée en temps réel pour systèmes multi-agents.
- Ouverture : code source sur GitHub pour expérimentation.
— Editorial Team
Aucun commentaire pour le moment.