Zarządzanie sesjami i kompaktowanie (szczegółowe omówienie)
Ten dokument wyjaśnia, jak OpenClaw zarządza sesjami od początku do końca:- Routowanie sesji (jak wiadomości przychodzące mapują się na
sessionKey) - Store sesji (
sessions.json) i co śledzi - Trwałość transkryptu (
*.jsonl) i jego struktura - Higiena transkryptu (poprawki specyficzne dla dostawcy przed uruchomieniami)
- Limity kontekstu (okno kontekstu vs śledzone tokeny)
- Kompaktowanie (ręczne + automatyczne kompaktowanie) i gdzie podpiąć pracę wykonywaną przed kompaktowaniem
- Ciche porządki (np. zapisy do pamięci, które nie powinny generować widocznego dla użytkownika wyjścia)
- /concepts/session
- /concepts/compaction
- /concepts/memory
- /concepts/memory-search
- /concepts/session-pruning
- /reference/transcript-hygiene
Źródło prawdy: Gateway
OpenClaw został zaprojektowany wokół pojedynczego procesu Gateway, który zarządza stanem sesji.- Interfejsy użytkownika (aplikacja macOS, webowy Control UI, TUI) powinny odpytywać Gateway o listy sesji i liczniki tokenów.
- W trybie zdalnym pliki sesji znajdują się na zdalnym hoście; „sprawdzanie lokalnych plików na Macu” nie odzwierciedli tego, czego używa Gateway.
Dwie warstwy trwałości
OpenClaw zapisuje sesje w dwóch warstwach:-
Store sesji (
sessions.json)- Mapa klucz/wartość:
sessionKey -> SessionEntry - Mały, mutowalny, bezpieczny do edycji (lub usuwania wpisów)
- Śledzi metadane sesji (bieżący identyfikator sesji, ostatnią aktywność, przełączniki, liczniki tokenów itd.)
- Mapa klucz/wartość:
-
Transkrypt (
<sessionId>.jsonl)- Transkrypt typu append-only o strukturze drzewa (wpisy mają
id+parentId) - Przechowuje właściwą konwersację + wywołania narzędzi + podsumowania kompaktowania
- Służy do odbudowy kontekstu modelu dla przyszłych tur
- Transkrypt typu append-only o strukturze drzewa (wpisy mają
Lokalizacje na dysku
Dla każdego agenta, na hoście Gateway:- Store:
~/.openclaw/agents/<agentId>/sessions/sessions.json - Transkrypty:
~/.openclaw/agents/<agentId>/sessions/<sessionId>.jsonl- Sesje tematów Telegram:
.../<sessionId>-topic-<threadId>.jsonl
- Sesje tematów Telegram:
src/config/sessions.ts.
Utrzymanie store i kontrola dysku
Trwałość sesji ma automatyczne mechanizmy utrzymania (session.maintenance) dla sessions.json i artefaktów transkryptów:
mode:warn(domyślnie) lubenforcepruneAfter: próg wieku dla starych wpisów (domyślnie30d)maxEntries: limit wpisów wsessions.json(domyślnie500)rotateBytes: rotacjasessions.json, gdy plik jest zbyt duży (domyślnie10mb)resetArchiveRetention: retencja dla archiwów transkryptów*.reset.<timestamp>(domyślnie: taka sama jakpruneAfter;falsewyłącza czyszczenie)maxDiskBytes: opcjonalny limit budżetu katalogu sesjihighWaterBytes: opcjonalny cel po czyszczeniu (domyślnie80%zmaxDiskBytes)
mode: "enforce"):
- Najpierw usuń najstarsze zarchiwizowane lub osierocone artefakty transkryptów.
- Jeśli nadal jest powyżej celu, usuń najstarsze wpisy sesji i ich pliki transkryptów.
- Kontynuuj, aż użycie spadnie do
highWaterByteslub niżej.
mode: "warn" OpenClaw zgłasza potencjalne usunięcia, ale nie modyfikuje store ani plików.
Uruchom utrzymanie na żądanie:
Sesje cron i logi uruchomień
Izolowane uruchomienia cron również tworzą wpisy sesji/transkrypty i mają dedykowane mechanizmy retencji:cron.sessionRetention(domyślnie24h) usuwa stare sesje izolowanych uruchomień cron ze store sesji (falsewyłącza).cron.runLog.maxBytes+cron.runLog.keepLinesprzycinają pliki~/.openclaw/cron/runs/<jobId>.jsonl(domyślnie:2_000_000bajtów i2000linii).
Klucze sesji (sessionKey)
sessionKey identyfikuje który koszyk konwersacji jest używany (routowanie + izolacja).
Typowe wzorce:
- Główny/bezpośredni czat (per agent):
agent:<agentId>:<mainKey>(domyślniemain) - Grupa:
agent:<agentId>:<channel>:group:<id> - Pokój/kanał (Discord/Slack):
agent:<agentId>:<channel>:channel:<id>lub...:room:<id> - Cron:
cron:<job.id> - Webhook:
hook:<uuid>(chyba że nadpisano)
Identyfikatory sesji (sessionId)
Każdy sessionKey wskazuje na bieżący sessionId (plik transkryptu, który kontynuuje konwersację).
Praktyczne zasady:
- Reset (
/new,/reset) tworzy nowysessionIddla tegosessionKey. - Codzienny reset (domyślnie o 4:00 czasu lokalnego na hoście gatewaya) tworzy nowy
sessionIdprzy następnej wiadomości po przekroczeniu granicy resetu. - Wygaśnięcie bezczynności (
session.reset.idleMinuteslub starszesession.idleMinutes) tworzy nowysessionId, gdy wiadomość nadejdzie po oknie bezczynności. Gdy skonfigurowano jednocześnie reset dzienny i bezczynność, wygrywa ten, który wygaśnie wcześniej. - Zabezpieczenie przed rozwidleniem z rodzica dla wątków (
session.parentForkMaxTokens, domyślnie100000) pomija forking transkryptu rodzica, gdy sesja nadrzędna jest już zbyt duża; nowy wątek zaczyna się od zera. Ustaw0, aby wyłączyć.
initSessionState() w src/auto-reply/reply/session.ts.
Schemat store sesji (sessions.json)
Typ wartości store to SessionEntry w src/config/sessions.ts.
Kluczowe pola (lista niepełna):
sessionId: bieżący identyfikator transkryptu (nazwa pliku jest z niego wyprowadzana, chyba że ustawionosessionFile)updatedAt: znacznik czasu ostatniej aktywnościsessionFile: opcjonalne jawne nadpisanie ścieżki transkryptuchatType:direct | group | room(pomaga interfejsom użytkownika i polityce wysyłania)provider,subject,room,space,displayName: metadane do etykietowania grup/kanałów- Przełączniki:
thinkingLevel,verboseLevel,reasoningLevel,elevatedLevelsendPolicy(nadpisanie per sesja)
- Wybór modelu:
providerOverride,modelOverride,authProfileOverride
- Liczniki tokenów (best-effort / zależne od dostawcy):
inputTokens,outputTokens,totalTokens,contextTokens
compactionCount: jak często auto-kompaktowanie zakończyło się dla tego klucza sesjimemoryFlushAt: znacznik czasu ostatniego opróżnienia pamięci przed kompaktowaniemmemoryFlushCompactionCount: licznik kompaktowań, przy którym uruchomiono ostatnie opróżnienie
Struktura transkryptu (*.jsonl)
Transkrypty są zarządzane przez SessionManager z @mariozechner/pi-coding-agent.
Plik ma format JSONL:
- Pierwsza linia: nagłówek sesji (
type: "session", zawieraid,cwd,timestamp, opcjonalnieparentSession) - Następnie: wpisy sesji z
id+parentId(drzewo)
message: wiadomości użytkownika/asystenta/toolResultcustom_message: wiadomości wstrzykiwane przez rozszerzenie, które wchodzą do kontekstu modelu (mogą być ukryte w UI)custom: stan rozszerzenia, który nie wchodzi do kontekstu modelucompaction: zapisane podsumowanie kompaktowania zfirstKeptEntryIditokensBeforebranch_summary: zapisane podsumowanie przy nawigacji po gałęzi drzewa
SessionManager do ich odczytu i zapisu.
Okna kontekstu vs śledzone tokeny
Znaczenie mają dwa różne pojęcia:- Okno kontekstu modelu: twardy limit per model (tokeny widoczne dla modelu)
- Liczniki store sesji: statystyki kroczące zapisywane do
sessions.json(używane przez /status i dashboardy)
- Okno kontekstu pochodzi z katalogu modeli (i może być nadpisane przez konfigurację).
contextTokensw store to wartość szacunkowa/raportowana przez runtime; nie traktuj jej jako ścisłej gwarancji.
Kompaktowanie: czym jest
Kompaktowanie podsumowuje starszą część konwersacji do zapisanego wpisucompaction w transkrypcie i zachowuje nienaruszone ostatnie wiadomości.
Po kompaktowaniu przyszłe tury widzą:
- Podsumowanie kompaktowania
- Wiadomości po
firstKeptEntryId
Granice chunków kompaktowania i parowanie narzędzi
Gdy OpenClaw dzieli długi transkrypt na chunki do kompaktowania, utrzymuje sparowanie wywołań narzędzi asystenta z odpowiadającymi im wpisamitoolResult.
- Jeśli podział według udziału tokenów wypada między wywołaniem narzędzia a jego wynikiem, OpenClaw przesuwa granicę do wiadomości asystenta z wywołaniem narzędzia zamiast rozdzielać parę.
- Jeśli końcowy blok z wynikiem narzędzia w przeciwnym razie przekroczyłby docelowy rozmiar chunku, OpenClaw zachowuje ten oczekujący blok narzędzia i pozostawia niepodsumowany ogon bez zmian.
- Przerwane/błędne bloki wywołań narzędzi nie utrzymują oczekującego podziału otwartego.
Kiedy następuje auto-kompaktowanie (runtime Pi)
W osadzonym agencie Pi auto-kompaktowanie uruchamia się w dwóch przypadkach:- Odzyskiwanie po przepełnieniu: model zwraca błąd przepełnienia kontekstu
(
request_too_large,context length exceeded,input exceeds the maximum number of tokens,input token count exceeds the maximum number of input tokens,input is too long for the model,ollama error: context length exceededoraz podobne warianty zależne od dostawcy) → kompaktuj → ponów próbę. - Utrzymanie progu: po udanej turze, gdy:
contextTokens > contextWindow - reserveTokens
Gdzie:
contextWindowto okno kontekstu modelureserveTokensto zapas zarezerwowany na prompty + następne wyjście modelu
Ustawienia kompaktowania (reserveTokens, keepRecentTokens)
Ustawienia kompaktowania Pi znajdują się w ustawieniach Pi:
- Jeśli
compaction.reserveTokens < reserveTokensFloor, OpenClaw go podnosi. - Domyślny próg minimalny to
20000tokenów. - Ustaw
agents.defaults.compaction.reserveTokensFloor: 0, aby wyłączyć ten próg. - Jeśli wartość jest już wyższa, OpenClaw pozostawia ją bez zmian.
ensurePiCompactionReserveTokens() w src/agents/pi-settings.ts
(wywoływane z src/agents/pi-embedded-runner.ts).
Wymienni dostawcy kompaktowania
Wtyczki mogą rejestrować dostawcę kompaktowania przezregisterCompactionProvider() w API wtyczek. Gdy agents.defaults.compaction.provider jest ustawione na identyfikator zarejestrowanego dostawcy, rozszerzenie safeguard deleguje podsumowywanie do tego dostawcy zamiast do wbudowanego potoku summarizeInStages.
provider: identyfikator zarejestrowanej wtyczki dostawcy kompaktowania. Pozostaw nieustawione dla domyślnego podsumowywania przez LLM.- Ustawienie
providerwymuszamode: "safeguard". - Dostawcy otrzymują te same instrukcje kompaktowania i politykę zachowywania identyfikatorów co ścieżka wbudowana.
- Safeguard nadal zachowuje kontekst ostatnich tur i końcówki podzielonej tury po wyjściu dostawcy.
- Jeśli dostawca zawiedzie lub zwróci pusty wynik, OpenClaw automatycznie wraca do wbudowanego podsumowywania przez LLM.
- Sygnały przerwania/timeoutu są ponownie rzucane (nie są przechwytywane), aby respektować anulowanie przez wywołującego.
src/plugins/compaction-provider.ts, src/agents/pi-hooks/compaction-safeguard.ts.
Powierzchnie widoczne dla użytkownika
Kompaktowanie i stan sesji można obserwować przez:/status(w dowolnej sesji czatu)openclaw status(CLI)openclaw sessions/sessions --json- Tryb szczegółowy:
🧹 Auto-compaction complete+ liczba kompaktowań
Ciche porządki (NO_REPLY)
OpenClaw obsługuje „ciche” tury dla zadań działających w tle, gdy użytkownik nie powinien widzieć pośredniego wyjścia.
Konwencja:
- Asystent rozpoczyna wyjście od dokładnego cichego tokena
NO_REPLY/no_reply, aby wskazać „nie dostarczaj odpowiedzi użytkownikowi”. - OpenClaw usuwa/tłumi to w warstwie dostarczania.
- Tłumienie dokładnego cichego tokena nie rozróżnia wielkości liter, więc
NO_REPLYino_replyliczą się tak samo, gdy cały ładunek to tylko ten cichy token. - Służy to wyłącznie do prawdziwych tur działających w tle / bez dostarczenia; nie jest to skrót dla zwykłych, wymagających działania żądań użytkownika.
2026.1.10 OpenClaw tłumi także streaming wersji roboczych/pisania, gdy
częściowy chunk zaczyna się od NO_REPLY, aby ciche operacje nie ujawniały częściowego
wyjścia w połowie tury.
„Opróżnianie pamięci” przed kompaktowaniem (zaimplementowane)
Cel: zanim nastąpi auto-kompaktowanie, uruchomić cichą agentową turę, która zapisze trwały stan na dysk (np.memory/YYYY-MM-DD.md w obszarze roboczym agenta), aby kompaktowanie nie mogło
usunąć krytycznego kontekstu.
OpenClaw używa podejścia opróżniania przed progiem:
- Monitoruje użycie kontekstu sesji.
- Gdy przekroczy ono „miękki próg” (poniżej progu kompaktowania Pi), uruchamia cichą dyrektywę „zapisz pamięć teraz” do agenta.
- Używa dokładnego cichego tokena
NO_REPLY/no_reply, aby użytkownik niczego nie widział.
agents.defaults.compaction.memoryFlush):
enabled(domyślnie:true)softThresholdTokens(domyślnie:4000)prompt(wiadomość użytkownika dla tury opróżniania)systemPrompt(dodatkowy prompt systemowy dołączany dla tury opróżniania)
- Domyślny prompt/system prompt zawierają wskazówkę
NO_REPLY, aby tłumić dostarczanie. - Opróżnianie uruchamia się raz na cykl kompaktowania (śledzone w
sessions.json). - Opróżnianie działa tylko dla sesji osadzonego Pi (backendy CLI je pomijają).
- Opróżnianie jest pomijane, gdy obszar roboczy sesji jest tylko do odczytu (
workspaceAccess: "ro"lub"none"). - Zobacz Pamięć, aby poznać układ plików obszaru roboczego i wzorce zapisu.
session_before_compact w API rozszerzeń, ale logika
opróżniania OpenClaw znajduje się obecnie po stronie Gateway.
Lista kontrolna rozwiązywania problemów
- Nieprawidłowy klucz sesji? Zacznij od /concepts/session i potwierdź
sessionKeyw/status. - Niezgodność store i transkryptu? Potwierdź host Gateway i ścieżkę store z
openclaw status. - Spam kompaktowania? Sprawdź:
- okno kontekstu modelu (za małe)
- ustawienia kompaktowania (
reserveTokenszbyt wysokie względem okna modelu mogą powodować wcześniejsze kompaktowanie) - nadmiar
toolResult: włącz/dostrój przycinanie sesji
- Wyciekają ciche tury? Potwierdź, że odpowiedź zaczyna się od
NO_REPLY(dokładny token, bez rozróżniania wielkości liter) i że używasz kompilacji zawierającej poprawkę tłumienia streamingu.