Używamy cookies, żeby zwiększyć Twoje doświadczenia na stronie
CodeWorlds
Powrót do kolekcji
Przewodnik11 min czytania

Letta, agent zarządzający własną pamięcią

Letta to środowisko agentów, które same edytują swoją pamięć narzędziami. Bloki pamięci, stronicowanie kontekstu i różnica wobec bibliotek pamięci.

Letta, agent zarządzający własną pamięcią

Letta to środowisko uruchomieniowe dla agentów, w którym pamięć nie jest warstwą dołożoną z boku, tylko czymś, co agent edytuje sam, wywołując narzędzia. Wyrosło z badań nad projektem MemGPT i zachowało jego podstawowy pomysł: potraktować okno kontekstu jak pamięć operacyjną, którą trzeba zarządzać.

Jedna rzecz wymaga wyjaśnienia od razu, bo zmienia obraz projektu. Pythonowy serwer, czyli repozytorium letta-ai/letta wraz z pakietem letta z PyPI, autorzy 3 lipca 2026 roku opisali w repozytorium jako przestarzały i utrzymywany wyłącznie awaryjnie. Ostatnie wydanie tego pakietu nosi numer 0.16.8 z 14 maja 2026 roku i wymaga Pythona w przedziale od 3.11 do 3.13. Rozwój przeniósł się do Letta Code, czyli pakietu @letta-ai/letta-code instalowanego z npm, oraz do Letta Agent SDK, a samodzielne postawienie serwera odbywa się dziś przez App Server. Licencja w obu repozytoriach to Apache 2.0.

Sam pomysł, opisany niżej, pozostaje ten sam, więc warto go poznać. Zmieniło się to, czym go uruchamiasz: zamiast pythonowego serwera API dostajesz powłokę agenta w Node.js z tymi samymi blokami pamięci i tym samym przetwarzaniem w tle.

Najważniejsza różnica wobec bibliotek pamięci

Warto ją nazwać na początku, bo decyduje o tym, czy w ogóle warto czytać dalej.

Biblioteka pamięci dokłada się do agenta, którego już masz. Wywołujesz jej funkcję przed odpowiedzią, dostajesz fakty, wklejasz je do promptu. Twój kod nadal steruje przebiegiem.

Letta odwraca ten układ. Agent jest bytem po stronie serwera, ma własną tożsamość, własny stan i sam decyduje, kiedy zapisać coś do pamięci i kiedy z niej skorzystać. Ty rozmawiasz z tym agentem, a nie budujesz pętli, w której model jest jednym z kroków.

Konsekwencja jest poważna: nie dokładasz Letty do swojej aplikacji, tylko budujesz agenta w Letcie. To jest znacznie większe zobowiązanie niż dodanie zależności, i właśnie dlatego porównywanie tego rozwiązania z Mem0 albo Zep jak równorzędnych opcji jest mylące. Rozwiązują ten sam problem na zupełnie innym poziomie.

Bloki pamięci

Podstawowym elementem jest blok pamięci: nazwany fragment tekstu, który stale siedzi w kontekście agenta i który agent może zmienić.

Umowne są dwa. Blok opisujący rozmówcę zbiera to, czego agent się o nim dowiedział. Blok opisujący samego agenta trzyma jego rolę, styl i ograniczenia. Do tego możesz dodać własne, na przykład blok z bieżącym stanem sprawy, nad którą agent pracuje.

Agent dysponuje narzędziami do dopisywania i podmieniania treści bloków. To jest sedno tego podejścia: pamięć zmienia się w wyniku decyzji modelu, a nie w wyniku wywołania Twojego kodu.

Zaleta jest realna. Agent, który usłyszał, że rozmówca zmienił pracę, może sam poprawić odpowiedni blok, a nie czekać, aż zewnętrzna warstwa wykryje tę zmianę. Nie potrzeba do tego reguł opisujących, co jest warte zapamiętania.

Wada jest równie realna i trzeba ją znać. Model, który zarządza pamięcią, robi to niedoskonale: zapisuje rzeczy nieistotne, gubi istotne i czasem nadpisuje coś, co było potrzebne. Bloki mają ograniczoną wielkość, więc miejsce się kończy i wtedy zapada decyzja, co wypada. Przy dłuższej pracy warto oglądać zawartość bloków, bo to jest jedyny sposób, żeby stwierdzić, czy pamięć rzeczywiście działa.

Stronicowanie kontekstu

Drugi pomysł przeniesiony z badań dotyczy tego, co się dzieje, gdy rozmowa nie mieści się w oknie modelu.

Analogia jest wprost systemowa. To, co siedzi w kontekście, przypomina pamięć operacyjną: szybkie i ograniczone. Reszta leży w magazynie zewnętrznym, do którego agent sięga wywołaniem narzędzia, tak jak system sięga na dysk.

Agent ma więc narzędzia do przeszukiwania własnej historii rozmów i archiwum. Gdy potrzebuje czegoś, czego nie ma w kontekście, wywołuje wyszukiwanie i wciąga fragment z powrotem.

Ten mechanizm rozwiązuje problem realny, natomiast wprowadza koszt, który łatwo przeoczyć. Każde sięgnięcie do archiwum to dodatkowa tura z modelem, więc odpowiedź wymagająca dwóch takich wywołań trwa trzy razy dłużej niż odpowiedź bez nich. Przy asystencie prowadzącym rozmowę na żywo to jest zauważalne.

Warto też wiedzieć, że model nie zawsze sięgnie po archiwum, gdy powinien. Jeśli uzna, że wie wystarczająco, odpowie z tego, co ma w kontekście, i będzie to odpowiedź pewna siebie oraz niepełna. To jest ta sama klasa problemu co przy każdym mechanizmie opartym na decyzji modelu.

Przetwarzanie w czasie bezczynności

Trzecim pomysłem jest przeniesienie porządkowania pamięci poza moment odpowiadania.

Rzecz polega na tym, że osobny agent pracuje w tle: przegląda to, co się wydarzyło, streszcza, porządkuje bloki i wyciąga wnioski. Dzieje się to wtedy, gdy nikt nie czeka na odpowiedź.

Zysk jest podwójny. Odpowiedź dla użytkownika nie jest obciążona pracą nad pamięcią, więc przychodzi szybciej. A porządkowanie może być dokładniejsze, bo nie ma presji czasu i można na nie przeznaczyć mocniejszy model.

Cena to koszt tokenów za pracę, której nikt nie zamawiał. Agent przetwarzający w tle zużywa je niezależnie od tego, czy ktoś z nim rozmawia, więc przy wielu agentach ta pozycja rośnie w sposób trudny do przewidzenia z liczby rozmów. To jest miejsce do zmierzenia przed uruchomieniem czegokolwiek na skalę.

Narzędzia i to, co agent potrafi zrobić

Pamięć jest tu najgłośniejszym elementem, natomiast agent zarządzający wyłącznie własną pamięcią nie jest do niczego przydatny. Właściwa praca zaczyna się przy narzędziach sięgających do Twoich systemów.

Narzędzie definiujesz jako zwykłą funkcję Pythona z opisem, a agent decyduje, kiedy ją wywołać. Mechanizm jest ten sam co przy pamięci, tyle że skutki wychodzą poza agenta: zapytanie do bazy, wysłanie wiadomości, zmiana rekordu.

Tu pojawia się rzecz, którą trzeba przemyśleć wcześniej niż przy zwykłej aplikacji. Agent ma trwały stan i działa też wtedy, gdy nikt nie patrzy, więc uprawnienia narzędzi muszą być ograniczone niezależnie od tego, co model przeczytał w rozmowie. Narzędzie kasujące dane albo wysyłające pieniądze wymaga potwierdzenia po stronie systemu, a nie zaufania do oceny modelu.

Druga rzecz dotyczy opisów. Model widzi wyłącznie nazwę, opis i schemat argumentów, więc zdanie mówiące wprost, kiedy narzędzie wywołać, działa lepiej niż samo stwierdzenie, co ono robi. Przy agencie długo żyjącym ta różnica narasta, bo błędny wybór narzędzia trafia do historii i wpływa na kolejne decyzje.

Trzecia to obsługa błędów. Narzędzie, które rzuca wyjątkiem, zwraca agentowi komunikat, a agent na tej podstawie decyduje, co dalej. Komunikat opisujący, co poszło nie tak i co można zrobić zamiast tego, zamienia awarię w krok pośredni. Komunikat techniczny zwykle prowadzi do powtarzania tej samej próby.

Wielu agentów i podział pracy

Skoro agent jest bytem trwałym, naturalnie pojawia się pytanie o kilku naraz, i tu warto rozróżnić dwa układy.

Pierwszy to agent na użytkownika. Każda osoba dostaje własnego, z własną pamięcią o sobie. To jest układ oczywisty przy asystentach i zarazem ten, który rośnie liniowo z liczbą użytkowników, więc plan na usuwanie i archiwizację powinien powstać przed pierwszym wdrożeniem.

Drugi to agenci wyspecjalizowani, dzielący pewne bloki pamięci. Wspólny blok z zasadami firmy albo z bieżącym stanem projektu widziany przez kilku agentów pozwala im pracować na tej samej wiedzy bez powielania jej. Zmiana wprowadzona przez jednego jest natychmiast widoczna dla pozostałych.

Ten drugi układ bywa kuszący i warto podchodzić do niego ostrożnie. Wspólny stan zmieniany przez kilka niezależnych bytów to klasyczne źródło kłopotów, znane spoza tej dziedziny. Jeśli dwaj agenci mogą jednocześnie nadpisać ten sam blok, prędzej czy później to zrobią.

Praktyczna rada brzmi: bloki wspólne trzymaj do odczytu, a zapis zostaw jednemu agentowi albo swojemu kodowi. Dzielenie wiedzy jest wtedy zaletą, a nie zagrożeniem.

Letta kontra alternatywy

RozwiązanieCzym jestKto zarządza pamięciąKiedy wybrać
LettaŚrodowisko agentówSam agent narzędziamiBudujesz agenta od zera
ZepWarstwa pamięciZewnętrzny silnik grafowyFakty zmieniają się w czasie
Mem0Warstwa pamięciZewnętrzna warstwaProste preferencje użytkownika
Własna implementacjaKod w projekcieTyWiesz dokładnie, co zapamiętać

Pierwszy wiersz różni się od pozostałych zakresem, a nie jakością. Wybierając to rozwiązanie, wybierasz sposób budowania agenta, a nie tylko sposób trzymania pamięci. To bywa właściwe przy nowym projekcie i kłopotliwe przy dokładaniu pamięci do czegoś, co już działa.

Ostatni wiersz warto rozważyć uczciwie. Przy asystencie, który ma pamiętać trzy rzeczy o użytkowniku, tabela w bazie z trzema kolumnami wygrywa z każdym z powyższych. Wartość tych narzędzi zaczyna się tam, gdzie nie wiesz z góry, co będzie warte zapamiętania.

Warto też zauważyć, że przetwarzanie w tle i stronicowanie kontekstu można odtworzyć samodzielnie. To nie są mechanizmy zamknięte, tylko pomysły, a ich implementacja w prostszej postaci bywa dla konkretnego projektu wystarczająca.

Uruchomienie i wdrożenie

Code
Bash
npm install -g @letta-ai/letta-code
letta server --backend local --listen ws://127.0.0.1:4500

Tak wygląda dzisiejsza droga. Instalujesz narzędzie wiersza poleceń z npm, co wymaga Node.js w wersji 22.19 lub nowszej, a potem uruchamiasz App Server, czyli usługę, z którą Twoja aplikacja rozmawia po WebSocket, najwygodniej przez Letta Agent SDK. Uruchomienie u siebie jest w pełni dostępne dzięki licencji Apache 2.0, a alternatywą pozostaje chmura dostawcy.

Starsza droga, oparta na pip install letta i pythonowym serwerze API, nadal działa i obsługuje SDK pierwszej generacji. Jej repozytorium jest jednak w trybie utrzymania, więc przy nowym projekcie nie ma powodu, żeby po nią sięgać.

W wariancie lokalnym stan agenta razem z blokami pamięci leży na maszynie, na której uruchomiłeś serwer, i jest wersjonowany gitem. W wariancie chmurowym stan zostaje po stronie dostawcy, a sama powłoka agenta może działać na Twoim sprzęcie, co pozwala trzymać narzędzia i dane blisko siebie.

Stan agenta jest trwały, więc agent utworzony raz istnieje dalej i pamięta poprzednie rozmowy. To brzmi oczywiście, a ma konsekwencję operacyjną: agentów przybywa, każdy zajmuje miejsce i każdy ma własną historię. Przy aplikacji tworzącej agenta na użytkownika warto od początku wiedzieć, jak ich usuwać i co się dzieje z ich pamięcią przy prośbie o usunięcie danych.

Podglądanie tego, co agent trzyma w pamięci, jest tu ważniejsze niż przy zwykłej aplikacji, bo pamięć zmienia sam model. Wpięcie narzędzia śledzącego, na przykład Arize Phoenix, pozwala zobaczyć, które wywołania narzędzi doprowadziły do bieżącego stanu bloków.

Kiedy to jest właściwy wybór

Trzy warunki warto sprawdzić przed decyzją.

Pierwszy: budujesz coś nowego. Przy istniejącej aplikacji z własną pętlą agenta przejście na to środowisko oznacza przepisanie, a nie dodanie zależności.

Drugi: agent ma żyć długo i uczyć się rozmówcy. Przy zadaniach jednorazowych, gdzie każde wywołanie jest niezależne, cały ten mechanizm jest zbędnym kosztem.

Trzeci: akceptujesz, że pamięcią zarządza model. To znaczy zgodę na pewną nieprzewidywalność w zamian za brak konieczności opisywania reguł zapamiętywania. Przy zastosowaniach, gdzie musisz dokładnie wiedzieć, co zostało zapisane, na przykład ze względu na zgodność z przepisami, ta zgoda bywa niemożliwa.

Jeśli któryś warunek nie jest spełniony, prostsza warstwa pamięci albo własna tabela dadzą to samo mniejszym kosztem i przy większej kontroli.

Typowe błędy

Pierwszy to traktowanie tego jako biblioteki do dołożenia. To jest środowisko uruchomieniowe agenta, więc wybór dotyczy architektury całej aplikacji.

Drugi to brak zaglądania do bloków pamięci. Model zarządza nimi niedoskonale, a bez oglądania zawartości nie dowiesz się, że zapisał rzeczy bez znaczenia i zgubił istotne.

Trzeci to pominięcie kosztu przetwarzania w tle. Tokeny zużywają się wtedy, gdy nikt nie rozmawia, więc rachunek nie wynika z liczby rozmów.

Czwarty to ignorowanie opóźnienia przy sięganiu do archiwum. Każde takie wywołanie to dodatkowa tura z modelem, co przy rozmowie na żywo jest odczuwalne.

Piąty to tworzenie agenta na użytkownika bez planu na ich usuwanie. Trwały stan znaczy, że rosną i zostają, także po odejściu użytkownika.

Szósty to zakładanie, że agent zawsze sięgnie po archiwum, gdy powinien. Jeśli uzna, że wie dość, odpowie z kontekstu, pewnie i niepełnie.

FAQ

Czym Letta różni się od Mem0 i Zep?

Zakresem. Mem0 i Zep są warstwami pamięci, które dokładasz do własnego agenta i wywołujesz ze swojego kodu. Letta jest środowiskiem, w którym agent istnieje po stronie serwera i sam edytuje swoją pamięć narzędziami, więc wybór dotyczy architektury, nie zależności.

Czym są bloki pamięci?

Nazwanymi fragmentami tekstu stale obecnymi w kontekście agenta, które agent może dopisywać i podmieniać własnymi narzędziami. Umowne bloki opisują rozmówcę oraz samego agenta, a własne można dodać, na przykład na bieżący stan sprawy.

Czy da się uruchomić Letta u siebie?

Tak, licencja to Apache 2.0. Służy do tego App Server, uruchamiany poleceniem letta server z pakietu @letta-ai/letta-code, do którego aplikacja łączy się po WebSocket. Stary pythonowy serwer API z pakietu letta też da się postawić samodzielnie, ale jego repozytorium jest w trybie utrzymania od lipca 2026 roku.

Czy to ma związek z MemGPT?

Tak, produkt wyrósł z badań nad tym projektem i zachował jego podstawowy pomysł: traktowanie okna kontekstu jak pamięci operacyjnej, z resztą trzymaną w magazynie zewnętrznym, do którego agent sięga narzędziem.

Ile to kosztuje?

Uruchomienie u siebie jest bezpłatne, płacisz za tokeny u dostawcy modelu. Istnieje też wariant hostowany z progiem darmowym i planami płatnymi, a przed decyzją warto sprawdzić aktualny cennik, bo pozycja za przetwarzanie w tle rośnie niezależnie od liczby rozmów.

Dokumentacja stoi na stronie produktu, a kod i wydania w repozytorium na GitHubie.