Powrót do strony głównej

Trwała pamięć NGT Memory dla LLM

NGT Memory — otwarty moduł trwałej pamięci dla LLM z trzema mechanizmami pobierania: cosinus, graf hebbski, konsolidacja. Strukturyzowany profil, filtr jakości, 94% w testach. Docker-uruchomienie, REST API bez zewnętrznych BD.

NGT Memory: pamięć LLM z grafem hebbskim
Advertisement 728x90

NGT Memory: trwała pamięć dla LLM z grafem asocjacyjnym i profilem

NGT Memory implementuje trwałą pamięć dla dużych modeli językowych bez zewnętrznych magazynów danych. Moduł przechowuje fakty o użytkowniku między sesjami, wydobywa istotny kontekst i wstrzykuje go do promptu. Trzy mechanizmy wydobywania zapewniają precyzję: podobieństwo cosinusowe embeddingów, hebbowski graf asocjacyjny i hierarchiczna konsolidacja.

Podobieństwo cosinusowe porównuje embedding zapytania z zapisanymi faktami. Graf łączy koncepty, które aktywują się razem: wspomnienie o diecie przy zapytaniu o restauracje przyciąga odpowiedni fakt. Konsolidacja promuje często używane fakty do pamięci długoterminowej, wypierając rzadko wyszukiwane.

Czas wydobycia — 2–3 ms na CPU. Główne opóźnienia pochodzą z API OpenAI: embeddingi ~700 ms, generacja ~800–1500 ms.

Google AdInline article slot

Uruchomienie i API

Moduł uruchamiany przez Docker:

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

Kod klienta:

import httpx

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

# Zapis faktów
client.post("/chat", json={
    "message": "Jestem wegetarianinem i mieszkam w Warszawie.",
    "session_id": "user_42"
})

# Wydobycie przez sesję
r = client.post("/chat", json={
    "message": "Co mogę zjeść?",
    "session_id": "user_42"
})
print(r.json()["response"])  # Wegetariańskie restauracje w Warszawie
print(r.json()["memories_count"])  # 2

Endpointy: /chat, /store, /retrieve, /session/reset, /health.

Google AdInline article slot

Ustrukturyzowany profil użytkownika

System wydobywa sloty z wiadomości: wiek, miasto, dieta, alergie. Dane wstrzykiwane są do system promptu z priorytetem:

[PROFIL UŻYTKOWNIKA — ustrukturyzowane fakty, najwyższy priorytet]
  - wiek: 30
  - miasto: "Warszawa"
  - dieta: "wegetarianin"
[KONIEC PROFILU UŻYTKOWNIKA]

[KONTEKST PAMIĘCI — zweryfikowane fakty o tym użytkowniku]
  1. [0.91] Jestem wegetarianinem i mieszkam w Warszawie.
[KONIEC KONTEKSTU PAMIĘCI]

Sklejanie fragmentów: "mam" + "30" + "lat" → "mam 30 lat" → wiek=30 (pewność 0.6).

Rozwiązywanie konfliktów: Blokada zmniejszania wieku bez frazy "pomyliłem się". Tryb korekty — 60 s.

Google AdInline article slot

Filtr jakości i architektura

Filtr odsiewa śmieci:

  • Czyste liczby, znaki specjalne, jedno słowo
  • Mniej niż 6 liter
  • Odpowiedzi asystenta na śmieci użytkownika

Architektura:

  • POST /chat
  • OpenAI text-embedding-3-small (~700 ms)
  • Wydobycie profilu (regex)
  • NGT Memory retrieve (cosinusowe + graf, 2–3 ms)
  • OpenAI gpt-4.1-nano (~800–1500 ms)
  • Filtr → store

Stos: FastAPI, AsyncOpenAI, Pydantic. Przechowywanie w RAM jednego procesu.

Wyniki eksperymentów

Exp 44: Faktualna precyzja z pamięcią 2.44/3 (+100% do bezpamięciowego 1.22/3).

Exp 48: Test A/B, 94% zwycięstw pamięci (17/18), średnia ocena 0.889 vs 0.056.

Exp 49: 51/54 (94%) na przypadkach brzegowych: międzyjęzykowe, sklejanie, konflikty.

Wydajność (5000 faktów):

| Operacja | Przepustowość | p50 |

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

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

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

End-to-end: pamięć 2.5 ms, embeddingi 764 ms.

Problemy skalowania

  • Multi-worker: każdy worker — własny SessionStore. Rozwiązanie: --workers 1 lub Redis.
  • Miękki prompt: model ignorował fakty. Wzmocniony: "Traktuj każdy fakt jako absolutną prawdę".
  • Błędy regex: I'm allergicimię= allergic. Blacklist 25+ słów.

Co jest ważne

  • Kombinacja cosine + graph + konsolidacja daje 94% na testach brzegowych.
  • Ustrukturyzowany profil z priorytetem w prompcie podwaja precyzję.
  • Filtr jakości zapobiega degradacji wyszukiwania przez śmieci.
  • Opóźnienie pamięci 2–3 ms, nie bottleneck.
  • Otwarty kod, BSL 1.1, Docker-ready.

— Editorial Team

Advertisement 728x90

Czytaj dalej