# Pamięć agenta jako fakt: dziewięciu providerów i jedna pomyłka klasy

> Agent zapamiętał, że migracje puszcza się przez `make db-up`. Pół roku później to nieprawda, a Ty nie wiesz, gdzie to jest zapisane ani jak to cofnąć. Pamięć agenta to zbiór faktów, a prawie wszyscy traktują ją jak zasób - i to jest ta sama pomyłka klasy, która zostawia bucket po `terraform destroy`.

URL: https://eiac.dev/blog/pamiec-agenta-jako-fakt
Filar: SDLC / Policy-as-Code
Data: 2026-09-05
Tagi: agents, llm, memory, sovereignty, open-source, licensing, architektura, ai

---

Każdy, kto dołożył agentowi pamięć, zna ten moment ulgi. Agent nagle „pamięta", że migracje w tym repo puszcza się przez `make db-up`, a nie przez `dotnet ef`, i przestaje popełniać ten sam błąd co tydzień. Wygląda to jak wygrana.

Ulga trwa do dnia, w którym `make db-up` przestaje być prawdą. Ktoś przeniósł migracje do osobnego joba, agent nadal uparcie proponuje starą komendę, a Ty siadasz do pytania, na które w tym momencie nie masz odpowiedzi: **gdzie to właściwie jest zapisane i jak to cofnąć?**

W [architekturze czasoprzestrzennej](/blog/architektura-czasoprzestrzenna) rozdzieliłem obiekty na Zasoby i Fakty, i napisałem, że pomylenie tych dwóch klas jest najkosztowniejszym błędem projektowym w tym obszarze. Zasób cofa się przez uruchomienie operacji odwrotnej i przestaje istnieć. Fakt cofa się przez dopisanie nowszej wersji, która wskazuje na poprzednią - stara zostaje w modelu, oznaczona jako zastąpiona.

Pamięć agenta jest zbiorem Faktów. To ocena, wniosek, wynik obserwacji, coś, co było prawdziwe w kwietniu i przestało być w sierpniu. A prawie wszyscy dostawcy pamięci obsługują ją mechanizmem właściwym dla Zasobów: nadpisaniem albo skasowaniem wiersza. **To jest ta sama pomyłka klasy, która zostawia bucket z danymi po `terraform destroy`, tylko przeniesiona o piętro wyżej i dużo trudniejsza do zauważenia.**

Ten artykuł jest przeglądem dziewięciu providerów pamięci dla agentów, ale nie rankingiem. Interesuje mnie cztery rzeczy, których żaden benchmark nie mierzy, i jedna, która wynika wprost z powyższego rozróżnienia.

## Gdzie naprawdę przecieka

W [suwerennym AI](/blog/suwerenne-ai-open-weight) postawiłem tezę, że asystent w cyklu wytwarzania jest wektorem wycieku własności intelektualnej, a data residency bez modelu open-weight na własnej infrastrukturze jest iluzją. Pamięć agenta jest tej tezy przypadkiem szczególnym, tylko gorszym pod dwoma względami.

Po pierwsze, przecieka **ciągle**, a nie przy pojedynczym zapytaniu. Po drugie, i to jest właściwa różnica: przecieka **w miejscu, w którym nikt nie patrzy**, bo wszyscy patrzą na bazę.

Domyślna ścieżka zapisu wygląda tak:

<figure>
<svg viewBox="0 0 640 312" role="img" aria-label="Ścieżka zapisu do pamięci agenta. Rozmowa z agentem, zawierająca kod, ścieżki, nazwy usług i wklejone fragmenty, trafia najpierw do kroku ekstrakcji, czyli wywołania modelu, który widzi całą surową treść. Dopiero wynik tej ekstrakcji, czyli fakty i encje, jest zapisywany do bazy stojącej u Ciebie. Jeśli model jest cudzy, dwa pierwsze kroki dzieją się poza Twoją infrastrukturą, a granica, którą sprawdza większość porównań, obejmuje wyłącznie krok trzeci.">
  <g font-family="'Poppins', system-ui, sans-serif" text-anchor="middle">
    <text x="12" y="20" fill="var(--color-rust)" font-size="12" text-anchor="start">Poza Twoją infrastrukturą, gdy model jest cudzy</text>
    <rect x="12" y="32" width="616" height="140" rx="8" fill="none" stroke="var(--color-rust)" stroke-width="1" stroke-dasharray="4 4"/>
    <rect x="60" y="48" width="520" height="46" rx="6" fill="none" stroke="currentColor" stroke-width="1.5"/>
    <text x="320" y="70" fill="currentColor" font-size="13">rozmowa z agentem</text>
    <text x="320" y="87" fill="var(--color-muted)" font-size="10" font-family="'JetBrains Mono Variable', monospace">kod &#183; ścieżki &#183; nazwy usług &#183; wklejony stack trace</text>
    <line x1="320" y1="94" x2="320" y2="112" stroke="currentColor" stroke-width="1.5"/>
    <path d="M320 112 l-4 -7 h8 z" fill="currentColor"/>
    <rect x="60" y="112" width="520" height="48" rx="6" fill="none" stroke="var(--color-rust)" stroke-width="1.5"/>
    <text x="320" y="134" fill="var(--color-rust)" font-size="13">ekstrakcja: wywołanie LLM</text>
    <text x="320" y="152" fill="var(--color-muted)" font-size="10" font-family="'JetBrains Mono Variable', monospace">model widzi całą surową treść</text>
    <line x1="320" y1="172" x2="320" y2="222" stroke="var(--color-rust)" stroke-width="1.5"/>
    <path d="M320 222 l-4 -7 h8 z" fill="var(--color-rust)"/>
    <text x="320" y="188" fill="var(--color-muted)" font-size="10" font-family="'JetBrains Mono Variable', monospace" dx="86">fakty i encje</text>
    <text x="12" y="207" fill="var(--color-muted)" font-size="12" text-anchor="start">Granica, którą wszyscy sprawdzają</text>
    <rect x="12" y="222" width="616" height="76" rx="8" fill="none" stroke="var(--color-muted)" stroke-width="1" stroke-dasharray="4 4"/>
    <rect x="60" y="236" width="520" height="48" rx="6" fill="none" stroke="currentColor" stroke-width="1.5"/>
    <text x="320" y="258" fill="currentColor" font-size="13">baza u Ciebie</text>
    <text x="320" y="276" fill="var(--color-muted)" font-size="10" font-family="'JetBrains Mono Variable', monospace">Postgres &#183; graf &#183; katalog plików</text>
  </g>
</svg>
<figcaption>Baza stoi u Ciebie, a treść i tak wyszła - dwa kroki wcześniej. Etykieta „self-hosted" opisuje dolną ramkę, nie górną.</figcaption>
</figure>

Prawie każdy provider z tej dziewiątki robi ekstrakcję przez model przy zapisie: bierze surową rozmowę, wysyła ją do LLM i dopiero ustrukturyzowany wynik zapisuje lokalnie. Postawienie bazy u siebie **nie oznacza**, że dane zostały u siebie. Jeśli tym modelem jest cudze API, to przez zewnętrzny system przeszła cała treść - fragmenty kodu, nazwy wewnętrznych usług, ścieżki, adresy, i to, co ktoś wkleił w panice o 23:40 - niezależnie od tego, gdzie stoi Postgres.

Marketing tej kategorii konsekwentnie utożsamia „self-hosted" z „suwerenny", bo mówi wyłącznie o warstwie składowania. To dwa różne pytania i trzeba je zadać osobno.

## Cztery pytania zamiast benchmarku

Benchmarki zostawiam na później, bo zasługują na osobną sekcję i na dużo mniej zaufania, niż się im daje. Najpierw filtr, który realnie zawęża dziewięć opcji do dwóch albo trzech.

**1. Czy licencja pozwala Ci to uruchomić tak, jak chcesz?**
Nie „czy jest open source", tylko czy ta konkretna licencja przy tym konkretnym sposobie integracji nie generuje obowiązku. W [open source ≠ suwerenność](/blog/open-source-a-suwerennosc) opisałem cztery sposoby, w jakie otwarte przestaje być wolne. W tej kategorii dochodzi piąty, którego tam nie było, i wracam do niego niżej.

**2. Dokąd wypływa treść przy zapisie?**
Osobno od tego, gdzie leży baza. Pytanie brzmi: czy da się podmienić endpoint modelu na własny, czy jest to udokumentowane, i czy provider zachowuje wtedy jakość.

**3. Ile stanowych komponentów dokładasz?**
Każda dodatkowa baza to backup, monitoring, ścieżka aktualizacji i osobna decyzja licencyjna. Wbudowany Postgres w jednym kontenerze to inny koszt operacyjny niż klaster grafowy, a ten koszt płaci ktoś inny niż ten, kto wybierał.

**4. Czy fakt da się cofnąć?**
Nie „czy da się skasować wiersz", tylko czy system rozróżnia zastąpienie od usunięcia i czy potrafi powiedzieć, co uważał za prawdę trzy miesiące temu. To jest pytanie z poprzedniej sekcji, przełożone na cechę produktu.

## Dziewięć providerów przez cztery pytania

| Provider | Licencja | Self-host | Stanowe komponenty | Odwracanie faktu | Pamięć czytelna dla człowieka |
|---|---|---|---|---|---|
| **Honcho** | AGPL-3.0 | tak, ale copyleft | Postgres + pgvector | nadpisanie | częściowo, przez API |
| **Hindsight** | MIT | tak, jeden kontener | 1 (wbudowany Postgres) | zakres czasowy faktu | fakty i encje, przez API |
| **Mem0** | Apache-2.0 | tak, tryb OSS | 2 w produkcji | nadpisanie | fakty, przez API |
| **Letta** | Apache-2.0 | tak, cały runtime | 1-2 | jawna edycja bloku | **tak**, to zwykły tekst |
| **Zep / Graphiti** | Apache-2.0 (silnik) | silnik tak, produkt nie | 2 (+ Neo4j / FalkorDB) | **unieważnienie, nie nadpisanie** | tak, zapytaniem do grafu |
| **OpenViking** | AGPL-3.0 (CLI Apache) | wymagany | 1 + modele embed/VLM | nadpisanie pliku | **tak**, hierarchia plików |
| **Holographic** | open source | w pełni lokalny | 0 (SQLite w procesie) | trust scoring, wygaszanie | tak, ale to transkrypt |
| **RetainDB** | zamknięta | **brak** | 0 u Ciebie | kompresja delta | nie |
| **ByteRover** | zamknięta | local-first | 0 (pliki) | **`git revert`** | **tak**, Markdown w repo |

Kolumna czwarta jest tą, której nie ma w żadnym innym zestawieniu, a która po pół roku eksploatacji zaważy najbardziej. Dwa rozwiązania implementują mechanizm właściwy dla faktów: Graphiti unieważnia zamiast nadpisywać, ByteRover deleguje to do Gita. Reszta nadpisuje, czyli traktuje fakt jak zasób.

## Dziewięć providerów, po kolei

### Honcho

Referencyjna implementacja pamięci, która modeluje rozmówcę, a nie tylko fakty. Rozdziela warstwę zapisu, czyli synchroniczne API, od warstwy wnioskowania, czyli asynchronicznego procesu budującego reprezentacje w tle.

**Za.** Jedyny z tej listy, który buduje reprezentację *peera*, w tym to, co jeden peer wie o drugim. Przy [wyższych poziomach agentowego wytwarzania](/blog/cztery-poziomy-agentowego-wytwarzania), gdzie kontekst przechodzi między agentami, nie ma bezpośredniego odpowiednika. Rozdział zapisu od wnioskowania jest architektonicznie czysty: da się odciąć wnioskowanie, nie tracąc zapisu. Hybrydowe wyszukiwanie łączące BM25 z wektorami i endpoint zwracający gotowe pakiety kontekstu przycięte do limitu tokenów. Trzy tryby wdrożenia, w tym SaaS, który akurat omija problem opisany niżej.

**Przeciw.** **AGPL-3.0 na kodzie serwera**, o czym osobno w dalszej części. Wnioskowanie jest asynchroniczne, więc świeżo zapisana wiadomość nie od razu wpływa na odpowiedzi; do odczytów o niskiej latencji trzeba iść endpointem reprezentacji zamiast chatu. Całość wymaga klucza do zewnętrznego LLM, czyli pytanie drugie wypada źle, dopóki nie podmienisz endpointu. Reprezentacje są nadpisywane w miarę napływu nowych obserwacji, więc pytanie czwarte wypada źle na stałe. I paradygmat modelowania rozmówcy bywa zwyczajnie nadmiarowy, jeśli potrzebujesz trwałych faktów o systemie, a nie profilu człowieka.

### Hindsight

Projekt Vectorize.io z opublikowaną pracą naukową i najwyższymi wynikami w zestawieniu. Organizuje pamięć w cztery sieci: fakty o świecie, doświadczenie agenta, opinie z wagami pewności i obserwacje o encjach.

**Za.** **MIT**, czyli najbardziej permisywna licencja w stawce i zero pytań o copyleft. **Jeden stanowy komponent**: pojedyncza komenda Dockera z wbudowanym Postgresem, bez zewnętrznej bazy wektorowej ani grafowej. To różnica między jednym StatefulSetem a trzema i przewaga, która nie ma nic wspólnego z benchmarkiem, a najbardziej zdecyduje o tym, czy za pół roku ktoś tego nie wyłączy z powodu kosztu utrzymania. Pamięć jest wyłącznie zewnętrzna wobec modelu i przechowywana jako fakty, encje i relacje, więc da się prześledzić, co agent „wie" i skąd. Fakty mają zakresy czasowe, co jest połowicznym spełnieniem pytania czwartego. Operacja `reflect` syntetyzuje wnioski w poprzek pamięci, zamiast tylko odzyskiwać fragmenty.

I liczba, która w kontekście suwerenności znaczy więcej niż rekord benchmarku: **z modelem 20B open-weight osiąga 83,6% przy 39% dla pełnego kontekstu bez pamięci**. Czyli cała pętla ekstrakcji może zostać na Twojej infrastrukturze bez katastrofalnego spadku jakości. Żaden inny provider nie pokazuje tej liczby wprost, a to jest dokładnie ta liczba, która rozstrzyga pytanie drugie.

**Przeciw.** Młody projekt jednego dostawcy, wszystkie benchmarki publikuje Vectorize, brak niezależnej weryfikacji. Publikacja opisuje architekturę, ale **nie podaje latencji, kosztu ani testów skalowalności** poza samym benchmarkiem, ani współczynnika błędów ekstrakcji i rozwiązywania koreferencji. Ekstrakcja jest kosztowna po stronie zapisu, bo każda rozmowa przechodzi przez model. „Sieć opinii" z wagami pewności i parametrami behawioralnymi, w tym poziomem sceptycyzmu i dosłowności, to ciekawy pomysł badawczy i dodatkowa powierzchnia, którą trzeba świadomie skonfigurować albo wyłączyć. Agent z konfigurowalnym poziomem sceptycyzmu wobec Twojego kodu to nie jest rzecz, którą chcesz odkryć przypadkiem podczas incydentu.

### Mem0

Najdojrzalszy ekosystem w kategorii i najczęstszy pierwszy wybór, zwykle dlatego, że działa po pięciu minutach.

**Za.** Apache-2.0 bez copyleft, czyli najbezpieczniejsza licencja z całej dziewiątki. Największa społeczność, najlepiej utrzymane SDK w Pythonie i TypeScripcie, najwięcej gotowych integracji; jeśli cokolwiek ma już wtyczkę do Twojego frameworka, to zwykle Mem0. Uruchomienie w minuty czyni z niego **naturalny baseline**: włączasz, sprawdzasz, czy pamięć w ogóle poprawia zachowanie agenta na Twoich danych, i dopiero potem inwestujesz w coś cięższego. Dwupoziomowy zakres, sesja plus użytkownik, pokrywa typową personalizację bez konfiguracji.

**Przeciw.** **67,6% na LongMemEval**, najniżej ze wszystkich, które mają publiczny wynik. Ekstrakcja plus dopasowanie wektorowe gubi się przy pytaniach obejmujących wiele sesji. Brak rozumowania temporalnego: odpowie, co jest prawdą teraz, nie co było prawdą w marcu, a przy fakcie, który się zmienił, to jest źródło cichych błędów, nie brakujących odpowiedzi. Nadpisuje fakty, czyli podręcznikowo myli klasę. Domyślnie cloud-first; tryb OSS istnieje, ale to osobna ścieżka konfiguracji, nie flaga. I produkcyjnie dochodzi zewnętrzna baza wektorowa, więc pytanie trzecie wypada gorzej, niż sugeruje `pip install`.

### Letta

Dawniej MemGPT. Formalnie na tej liście, kategorialnie gdzie indziej: to nie warstwa pamięci, tylko **pełny runtime agenta**, w którym agent sam edytuje własną pamięć przez wywołania narzędzi.

**Za.** Najlepszy ślad decyzji pamięciowych w całym zestawieniu. Agent nie „ma" pamięci w tle, tylko jawnie wywołuje narzędzie edycji bloku, więc każda zmiana stanu zostawia wpis w logu. To jedyny provider, w którym *dlaczego agent to zapamiętał* jest tak samo widoczne jak *co zapamiętał*, a przy [wymaganiach na nadzór](/blog/ai-act-a-agentowy-sdlc) to nie jest drobiazg. Memory blocks są czytelnym tekstem stale obecnym w kontekście: człowiek może je przejrzeć i poprawić ręcznie, bez odpytywania bazy wektorowej. Do tego rodowód badawczy MemGPT i Apache-2.0.

**Przeciw.** Kupujesz cały framework, nie komponent. Wpięcie samej pamięci do istniejącej orkiestracji jest nienaturalne, bo to konkurencyjny runtime, nie plugin; Letta nie uzupełni Twojego agenta, tylko go zastąpi. Retrieval z modelem w pętli oznacza dodatkowe wywołanie LLM przy każdym sięgnięciu do archiwum, czyli wyższa latencja i wyraźnie wyższy koszt tokenów. Lock-in jest architektoniczny, nie kontraktowy, a to gorszy rodzaj: wyjście z Letty to przepisanie agenta, nie podmiana biblioteki. Z perspektywy [exit-by-design](/blog/suwerenny-idp-exit-by-design) jest to najdroższe wyjście w całej dziewiątce.

### Zep / Graphiti

Bitemporalny graf wiedzy: osobno „kiedy fakt obowiązywał" i osobno „kiedy system się o nim dowiedział".

**Za.** To jest **jedyny provider, który implementuje odwracanie faktu tak, jak fakt należy odwracać**. Fakty są unieważniane przez nowsze wersje, nie nadpisywane, więc historia zmian przekonań systemu zostaje odtwarzalna, a stan wiedzy agenta da się zrekonstruować na dowolny moment w przeszłości. To jest `git log` dla pamięci i dokładnie ten mechanizm, który opisałem jako właściwy dla klasy Fakt. Do tego najlepsze rozumowanie wieloskokowe i po encjach oraz graf inspekcyjny zwykłym Cypherem, bez czarnej skrzynki embeddingów. Silnik Graphiti pozostaje otwarty na Apache-2.0 i działa niezależnie od produktu.

**Przeciw.** **Zep Community Edition zostało zdeprecjonowane.** Otwarty jest silnik, produkt jest SaaS-em, czyli mamy podręcznikowy open-core drift, opisany jako wzorzec pierwszy w [open source ≠ suwerenność](/blog/open-source-a-suwerennosc). Przy komponencie, który ma żyć latami i gromadzić stan nie do odtworzenia, to ryzyko strategiczne, nie licencyjne. Poza tym wymaga zewnętrznej bazy grafowej, a Neo4j to osobna decyzja licencyjna, GPL albo komercyjna, i inna liga operacyjna niż Postgres. Budowa grafu przez LLM jest droga i wolna przy ingestcie, więc koszt rośnie z objętością rozmów, a nie z liczbą zapytań; rośnie zatem wtedy, kiedy najmniej na to patrzysz.

### OpenViking

Projekt volcengine, pozycjonowany jako „context database": pamięć, RAG na wiedzy i skille w jednym, zorganizowane jak system plików.

**Za.** **Self-hosting jest wymagany, nie opcjonalny**, więc suwerenność wynika z konstrukcji, nie z konfiguracji. Trójstopniowe ładowanie kontekstu, od abstraktu przez przegląd do pełnej treści, daje deklarowane 80-90% redukcji zużycia tokenów; przy flocie agentów to pozycja w budżecie, nie mikrooptymalizacja. Hierarchia plikowa jest ludzko czytelna i przeglądalna, więc **odpowiedź na pytanie, co agent miał w kontekście, brzmi `ls` i `cat`**, a do tego dochodzi wizualizacja trajektorii retrievalu. To najczystsze spełnienie zasady everything-as-code spośród rozwiązań serwerowych: pamięć jest drzewem plików, które da się zserializować do repozytorium. Istnieje też udokumentowana ścieżka wdrożenia na OpenShift AI, co w tej kategorii jest rzadkością.

**Przeciw.** AGPL-3.0 na rdzeniu, tym razem bez wentyla w postaci SaaS-u. Ciężki łańcuch budowania: Python 3.10+, toolchain Rusta i kompilator C++, więc obraz kontenera i przegląd łańcucha dostaw to osobny projekt, nie `pip install`. Wymaga modelu embedującego i wizyjno-językowego, czyli dwóch dodatkowych zależności do wystawienia u siebie. Pliki są nadpisywane, więc mimo czytelności pytanie czwarte wypada przeciętnie, chyba że sam wersjonujesz to drzewo. I najbardziej złożona konfiguracja z całej stawki, co przy komponencie do pamięci jest kosztem, który trzeba czymś odkupić.

### Holographic

Lokalny SQLite z wyszukiwaniem pełnotekstowym FTS5, algebrą HRR do zapytań kompozycyjnych i oceną zaufania do zapisów. Wbudowany w Hermesa.

**Za.** Odpowiedź na pytanie o rezydencję danych brzmi „nigdzie", bo nie ma dokąd; działa w środowisku odciętym od sieci, czyli przechodzi [ostateczny test suwerenności](/blog/suwerenny-idp-exit-by-design). **Zero dodatkowych stanowych komponentów** i zero zależności ponad to, co runtime już ma. Odczyt poniżej milisekundy, bez wywołania modelu, więc pytanie drugie w ogóle nie powstaje. Trust scoring stopniowo koryguje zapisy, zamiast trzymać wszystko z równą wagą na zawsze. To właściwy baseline dla każdego, kto chce najpierw sprawdzić, ile pamięć w ogóle wnosi: włączasz jednym przełącznikiem i masz z czym porównywać resztę.

**Przeciw.** **Brak ekstrakcji przez LLM**, więc przechowuje treść rozmowy, nie strukturę wiedzy. Nie zbuduje grafu, nie rozwiąże koreferencji między sesjami i nie odpowie na pytanie wymagające złożenia trzech faktów z trzech tygodni. Dwa narzędzia, czyli najmniejsza powierzchnia funkcjonalna z dziewiątki. SQLite oznacza jeden proces na jednej maszynie, więc nie ma sensownej ścieżki do współdzielonej pamięci klastra agentów. Test czytelności formalnie zdaje, ale to czytelność transkryptu, nie wiedzy, a to dwie różne rzeczy.

### RetainDB

Chmura, kod zamknięty, brak darmowego progu.

**Za.** Hybryda wektor plus BM25 plus reranking gotowa z pudełka, a to nie jest błaha rzecz. Czyste wektory notorycznie gubią identyfikatory, nazwy kluczy konfiguracyjnych, sygnatury błędów i wszystko, co trzeba dopasować **dosłownie**. Warstwa keywordowa z rerankingiem to łapie i przy pamięci dla agenta pracującego na kodzie robi realną różnicę. Do tego siedem typów pamięci z kompresją delta, czyli najbardziej dopracowany model zapisu wśród opcji komercyjnych, i zero pracy operacyjnej po Twojej stronie.

**Przeciw.** Odpada na pierwszym pytaniu i nie ma sensu udawać inaczej: **brak self-hostingu przy komponencie, który z definicji gromadzi treść Twoich rozmów o kodzie.** Kod zamknięty i brak niezależnych benchmarków oznacza, że nie da się zweryfikować ani jakości, ani tego, co dzieje się z danymi. Brak darmowego progu to brak ścieżki ewaluacji bez umowy. I jedyny w zestawieniu bez ścieżki wyjścia, bo nie ma wersji lokalnej, do której można się wycofać, gdy zmieni się cennik albo warunki.

### ByteRover

Local-first, kod zamknięty, pamięć trzymana jako Markdown w `.brv/context-tree/`.

**Za.** Pamięć to zwykłe pliki tekstowe. Wchodzą do repozytorium, przechodzą przez review, mają historię zmian i cofają się przez `git revert`. **To jedyny provider, w którym mechanizm odwracania faktu jest dokładnie tym, którego używasz do wszystkiego innego** - a przy okazji jedyny, który zdaje test everything-as-code dosłownie, bez interpretacji: pamięć agenta staje się plikiem w MR, o którym można się pokłócić na review. Do tego hook ekstrakcji **przed** kompresją kontekstu, czyli wyciąga wiedzę, zanim okno zostanie podsumowane, i łapie dokładnie to, co reszta bezpowrotnie traci w długich sesjach. Chmura jest opcją, nie warunkiem.

**Przeciw.** Lokalny storage nie oznacza otwartego kodu. Wynik jest czytelny, ale algorytm ekstrakcji pozostaje czarną skrzynką, więc kontrolujesz *co* zostało zapisane, a nie *dlaczego akurat to*. Wymaga dodatkowego CLI `brv` w łańcuchu narzędzi, czyli kolejnego binarnego artefaktu do zatwierdzenia i utrzymania w obrazach. Markdown nie skaluje się do dużych korpusów ani do współbieżnego zapisu z wielu agentów. I model freemium bez gwarancji open source oznacza, że „local-first" jest decyzją produktową dostawcy, którą dostawca może zmienić.

## Benchmark, którego nie warto kupować

Liczby chodzą po tej kategorii jak po wybiegu: 91,4%, 94,6%, 92,2%, 89,6%. Wyglądają porównywalnie i nie są.

Po pierwsze, **LongMemEval i LoCoMo testują różne zadania na różnych danych**. Pierwszy sprawdza przypominanie przez wiele sesji, drugi rozumowanie wieloskokowe w długiej konwersacji. Zestawienie wyniku z jednego z wynikiem z drugiego nie znaczy nic, a robi się to notorycznie, łącznie z materiałami dostawców. Dlatego w tabeli wyżej nie ma kolumny z wynikiem.

Po drugie, **niemal wszystkie te liczby publikują zainteresowani**. Wokół wyników LoCoMo toczył się publiczny spór metodologiczny między Mem0 a Zep, w którym obie strony miały sporo racji co do błędów przeciwnika. Vectorize publikuje benchmarki Hindsighta i jednocześnie sprzedaje Hindsighta. To nie znaczy, że liczby są zmyślone; znaczy, że są mierzone w warunkach, które komuś odpowiadały.

Po trzecie, i to jest najważniejsze: **rekord benchmarku nie jest zmienną, która zdecyduje o powodzeniu wdrożenia**. O tym, czy pamięć zostanie w systemie za pół roku, zdecyduje raczej to, czy ktoś zechce utrzymywać trzy stanowe komponenty, czy błędny fakt da się poprawić bez `DELETE FROM`, i czy rozmowy zespołu przechodzą przez cudze API. Różnica 67% do 91% jest realna i istotna, ale różnica między jednym kontenerem a klastrem grafowym rozstrzyga częściej.

Traktuj te liczby jak filtr wstępny: odsiewają rozwiązania wyraźnie słabsze, nie wskazują zwycięzcy. **Zwycięzcę wskaże test na Twoim własnym korpusie sesji**, i to jest jedyny benchmark, którego wyniku nikt inny za Ciebie nie opublikuje.

## AGPL, czyli piąty sposób

W [open source ≠ suwerenność](/blog/open-source-a-suwerennosc) opisałem cztery mechanizmy, przez które otwarte narzędzie przestaje być wolne: open-core, zmianę licencji na BSL lub SSPL, repackaging przez chmurę i przejęcie. Ta kategoria dokłada piąty, jakościowo inny, bo nie jest ruchem dostawcy, tylko cechą licencji od pierwszego dnia.

Dwóch z dziewięciu providerów - Honcho i OpenViking - jest na AGPL-3.0. Ta licencja rozszerza obowiązek copyleft na **użycie przez sieć**. Jeśli osadzisz taki serwer wewnątrz aplikacji dostępnej sieciowo, licencja może wymagać udostępnienia źródeł Twojej aplikacji. Granica tego, co jest jedną pracą, a co dwoma osobnymi procesami rozmawiającymi po HTTP, jest sporna i zależy od sposobu integracji.

I to jest właśnie powód, dla którego nazywam to decyzją architektoniczną, a nie formalnością. **Rozstrzyga ją to, jak wpinasz komponent, a nie to, którą bibliotekę dopisałeś do `requirements.txt`.** Ta sama zależność w dwóch różnych architekturach daje dwa różne wyniki prawne, więc odpowiedź „sprawdziliśmy licencje" bez opisu integracji nic nie znaczy.

Praktyczny wniosek jest za to prosty: **jeśli AGPL jest u Ciebie problemem, rozstrzygnij to przed PoC, nie po.** Trzy tygodnie porównań, po których dwóch faworytów odpada z powodów licencyjnych, to trzy tygodnie w plecy. A jeśli AGPL problemem nie jest, i dla wielu projektów naprawdę nie jest, to Honcho i OpenViking wracają do gry jako mocni kandydaci.

## Który provider odwraca fakty

Wróćmy do pytania czwartego, bo jest najciekawsze i najmniej omawiane. Uszereguję wprost, według mechanizmu, nie deklaracji:

1. **ByteRover** - `git revert`. Fakt jest plikiem, historia jest w Gicie, mechanizm odwracania jest ten sam, którego używasz do wszystkiego innego w platformie.
2. **Zep / Graphiti** - unieważnienie przez nowszą wersję, z zachowaniem poprzedniej i możliwością odtworzenia stanu wiedzy na dowolny moment. Podręcznikowa obsługa klasy Fakt.
3. **Letta** - jawna edycja bloku przez agenta, z wpisem w logu. Historia jest w logu, nie w modelu danych, ale jest.
4. **Hindsight** - fakty mają zakresy czasowe, więc częściowo rozróżnia „już nieaktualne" od „nigdy nie było".
5. **Holographic** - trust scoring stopniowo wygasza zapisy. To nie jest odwracanie, tylko zanik, ale przynajmniej nie jest to nadpisanie.
6. **Honcho, Mem0, OpenViking** - nadpisanie. Stara wartość znika bez śladu.
7. **RetainDB** - nie wiadomo, bo kod jest zamknięty, a to samo w sobie jest odpowiedzią.

I teraz rzecz, która wychodzi z tego zestawienia, a której się nie spodziewałem: **ranking odwracalności jest niemal odwrotny do rankingu benchmarków.** Najlepsze wyniki mają systemy z najgęstszą i najbardziej nieprzeźroczystą reprezentacją. Najlepiej odwracalne systemy mają wyniki słabsze albo żadnych. To jest realny trade-off tej kategorii i dziś nie ma w niej rozwiązania, które wygrywa oba rankingi naraz.

Jeśli mam wskazać kierunek: **odwracalność wygrywa tam, gdzie pamięć ma być poprawiana, a benchmark tam, gdzie ma być tylko skuteczna.** Większość zespołów wdrażających to po raz pierwszy potrzebuje tego pierwszego, a kupuje drugie, bo pierwszego nikt nie mierzy.

## Ścieżka, którą bym poszedł

1. **Odsiej RetainDB.** Brak self-hostingu przy komponencie gromadzącym treść rozmów o kodzie to nie kompromis, tylko inna kategoria produktu.
2. **Rozstrzygnij AGPL, zanim zaczniesz.** Honcho i OpenViking albo są w grze, albo ich nie ma. Dowiedz się tego w tygodniu pierwszym, nie czwartym.
3. **Włącz baseline.** Holographic albo Mem0 w trybie OSS, na jeden tydzień. Bez tego nie wiesz, czy droższy system cokolwiek poprawia, i będziesz porównywał liczby dostawców zamiast własnych.
4. **Główny kandydat: Hindsight.** MIT, jeden stanowy komponent, najlepsze publikowane wyniki, a przede wszystkim 83,6% z modelem 20B open-weight, czyli cała pętla ekstrakcji zostaje u Ciebie. Jeśli szukasz jednej rekomendacji, to jest ta.
5. **Kontrkandydat zależnie od tego, co boli.** Graphiti, jeśli musisz odtwarzać stan wiedzy w czasie. ByteRover, jeśli pamięć ma żyć w repo i przechodzić przez review. Letta, jeśli i tak budujesz runtime agenta od zera.
6. **Zanim cokolwiek podpiszesz, przetestuj podmianę endpointu ekstrakcji.** Honcho, Hindsight, Mem0, Zep i OpenViking wywołują LLM przy zapisie. „Teoretycznie wspierany" własny endpoint to nie to samo co udokumentowany i przetestowany.
7. **Zaplanuj wyjście.** Jak wyeksportujesz pamięć przy zmianie providera? Jeśli odpowiedź brzmi „nijak", to nie jest komponent, tylko zobowiązanie.

## Wnioski dla EIAC

**Pamięć agenta to Fakt, nie Zasób.** Sprawdzaj mechanizm odwracania, zanim sprawdzisz benchmark. Provider, który nadpisuje, popełnia tę samą pomyłkę klasy co `terraform destroy` zostawiający bucket, tylko w miejscu, w którym nikt nie patrzy.

**Stan agenta to też infrastruktura.** Jeśli infrastruktura, konfiguracja i polityki żyją jako kod, a pamięć agenta żyje jako blob w cudzej bazie, to platforma ma dziurę dokładnie tam, gdzie gromadzi się najwięcej wiedzy o systemie.

**Suwerenność ma tu dwie warstwy i obie trzeba sprawdzić osobno.** Gdzie leży baza to pytanie łatwe i marketing chętnie na nie odpowiada. Dokąd wychodzi treść przy ekstrakcji to pytanie właściwe.

**Licencja rozstrzyga się w architekturze integracji, nie w pliku zależności.** AGPL to piąty sposób, w jaki otwarte przestaje być wolne, i jedyny widoczny od pierwszego dnia. Tym łatwiej go rozstrzygnąć wcześnie.

**Liczba stanowych komponentów jest realnym kosztem wyboru.** Zwykle większym niż różnica w benchmarku, i zawsze płaconym przez kogoś innego niż ten, kto wybierał.

**Agent zapamięta coś błędnie.** To nie ryzyko, tylko pewność. Pytanie brzmi wyłącznie, czy będziesz umiał to znaleźć i cofnąć, czy poczekasz, aż samo wypadnie z rankingu podobieństwa.

## W sieci

- [Hindsight is 20/20: Building Agent Memory that Retains, Recalls, and Reflects](https://arxiv.org/html/2512.12818v1) - publikacja opisująca TEMPR i CARA
- [vectorize-io/hindsight](https://github.com/vectorize-io/hindsight) - repozytorium, licencja MIT
- [plastic-labs/honcho](https://github.com/plastic-labs/honcho) - repozytorium, AGPL-3.0
- [volcengine/OpenViking](https://github.com/volcengine/OpenViking) - repozytorium, AGPL-3.0 z CLI na Apache-2.0
- [Best Open-Source Agent Memory Systems (Self-Hosted, 2026)](https://hindsight.vectorize.io/blog/2026/08/11/open-source-agent-memory-systems) - przegląd z perspektywy liczby stanowych komponentów
- [Hermes Agent: Memory Providers](https://hermes-agent.nousresearch.com/docs/user-guide/features/memory-providers/) - dokumentacja integracji dziewięciu providerów
- [Best AI Agent Memory Providers in 2026](https://www.developersdigest.tech/blog/best-ai-agent-memory-providers-2026) - porównanie licencji i cenników
- [Deploy OpenViking on OpenShift AI](https://developers.redhat.com/articles/2026/04/23/deploy-openviking-openshift-ai-improve-ai-agent-memory) - Red Hat Developer