Retour à l'accueil

Mémoire persistante NGT Memory pour LLM

NGT Memory — module de mémoire persistante ouvert pour LLM avec trois mécanismes de récupération : cosinus, graphe Hebbian, consolidation. Profil structuré, filtre de qualité, 94 % sur les tests. Lancement Docker, REST API sans bases de données externes.

NGT Memory : mémoire LLM avec graphe Hebbian
Advertisement 728x90

NGT Memory : Mémoire persistante pour LLM avec graphe associatif et profil utilisateur

NGT Memory implémente une mémoire persistante pour les grands modèles de langage sans stockage externe. Le module conserve les informations utilisateur entre les sessions, récupère le contexte pertinent et l'injecte dans l'invite. Trois mécanismes de récupération garantissent la précision : la similarité cosinus des embeddings, un graphe associatif hebbien et une consolidation hiérarchique.

La similarité cosinus compare l'embedding de la requête avec les faits stockés. Le graphe relie les concepts qui s'activent ensemble : mentionner un régime alimentaire avec une requête sur les restaurants fait remonter le fait pertinent. La consolidation promeut les faits fréquemment utilisés en mémoire à long terme, déplaçant ceux rarement sollicités.

Le temps de récupération est de 2 à 3 ms sur CPU. Les principaux délais proviennent de l'API OpenAI : embeddings ~700 ms, génération ~800–1500 ms.

Google AdInline article slot

Installation et API

Le module s'exécute via Docker :

git clone https://github.com/ngt-memory/ngt-memory
cd ngt-memory
cp .env.example .env  # OPENAI_API_KEY
docker-compose up -d

Code client :

import httpx

client = httpx.Client(base_url="http://localhost:9190")

# Stockage des faits
client.post("/chat", json={
    "message": "Je suis végétarien et j'habite à Moscou.",
    "session_id": "user_42"
})

# Récupération par session
r = client.post("/chat", json={
    "message": "Que devrais-je manger ?",
    "session_id": "user_42"
})
print(r.json()["response"])  # Restaurants végétariens à Moscou
print(r.json()["memories_count"])  # 2

Points de terminaison : /chat, /store, /retrieve, /session/reset, /health.

Google AdInline article slot

Profil utilisateur structuré

Le système extrait des champs des messages : âge, ville, régime alimentaire, allergies. Les données sont injectées dans l'invite système avec priorité :

[PROFIL UTILISATEUR — faits structurés, priorité maximale]
  - âge : 30
  - ville : "Moscou"
  - régime : "végétarien"
[FIN PROFIL UTILISATEUR]

[CONTEXTE MÉMOIRE — faits vérifiés sur cet utilisateur]
  1. [0.91] Je suis végétarien et j'habite à Moscou.
[FIN CONTEXTE MÉMOIRE]

Assemblage de fragments : "Je suis" + "30" + "ans" → "J'ai 30 ans" → âge=30 (confiance 0.6).

Résolution des conflits : Empêche la diminution de l'âge sans la phrase "Je me suis trompé." Mode correction — 60 secondes.

Google AdInline article slot

Filtre de qualité et architecture

Le filtre élimine les données inutiles :

  • Nombres purs, caractères spéciaux, mots uniques
  • Moins de 6 lettres
  • Réponses de l'assistant aux données inutiles de l'utilisateur

Architecture :

  • POST /chat
  • OpenAI text-embedding-3-small (~700 ms)
  • Extraction du profil (regex)
  • Récupération NGT Memory (cosinus + graphe, 2–3 ms)
  • OpenAI gpt-4.1-nano (~800–1500 ms)
  • Filtre → stockage

Stack : FastAPI, AsyncOpenAI, Pydantic. Stockage en RAM d'un processus unique.

Résultats des expériences

Exp 44 : Précision factuelle avec mémoire 2.44/3 (+100% vs sans mémoire 1.22/3).

Exp 48 : Test A/B, 94% de victoires mémoire (17/18), score moyen 0.889 vs 0.056.

Exp 49 : 51/54 (94%) sur les cas limites : interlangue, assemblage, conflits.

Performances (5000 faits) :

| Opération | Débit | p50 |

|-----------|------------|-----|

| store() | 3450/s | 0.29 ms |

| retrieve()| 150/s | 6.3 ms |

End-to-end : mémoire 2.5 ms, embeddings 764 ms.

Défis de mise à l'échelle

  • Multi-worker : chaque worker a son propre SessionStore. Solution : --workers 1 ou Redis.
  • Invite douce : le modèle ignorait les faits. Renforcée : "Considérez chaque fait comme une vérité absolue."
  • Bugs regex : Je suis allergiquenom= allergique. Liste noire 25+ mots.

Points clés à retenir

  • Combiner cosinus + graphe + consolidation atteint 94% sur les tests limites.
  • Le profil structuré avec priorité dans l'invite double la précision.
  • Le filtre de qualité empêche la dégradation de la recherche par les données inutiles.
  • Latence mémoire 2–3 ms, pas un goulot d'étranglement.
  • Open source, BSL 1.1, prêt pour Docker.

— Editorial Team

Advertisement 728x90

Lire ensuite