Zarządzanie sesjami i kompaktowanie (szczegółowe omówienie)
Ten dokument wyjaśnia, jak OpenClaw zarządza sesjami od początku do końca:- Trasowanie sesji (jak wiadomości przychodzące są mapowane na
sessionKey) - Magazyn sesji (
sessions.json) i co śledzi - Trwałość transkryptów (
*.jsonl) i ich struktura - Higiena transkryptów (poprawki specyficzne dla dostawcy przed uruchomieniami)
- Limity kontekstu (okno kontekstu a śledzone tokeny)
- Kompaktowanie (ręczne + automatyczne kompaktowanie) oraz miejsca, w których można podpiąć działania przed kompaktowaniem
- Ciche porządki (na przykład zapisy pamięci, które nie powinny generować widocznych dla użytkownika wyników)
- /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 interfejs 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:-
Magazyn 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 tylko do dopisywania o strukturze drzewa (wpisy mają
id+parentId) - Przechowuje rzeczywistą rozmowę + wywołania narzędzi + podsumowania kompaktowania
- Jest używany do odtworzenia kontekstu modelu dla przyszłych tur
- Transkrypt tylko do dopisywania o strukturze drzewa (wpisy mają
Lokalizacje na dysku
Dla każdego agenta, na hoście Gateway:- Magazyn:
~/.openclaw/agents/<agentId>/sessions/sessions.json - Transkrypty:
~/.openclaw/agents/<agentId>/sessions/<sessionId>.jsonl- Sesje tematów Telegrama:
.../<sessionId>-topic-<threadId>.jsonl
- Sesje tematów Telegrama:
src/config/sessions.ts.
Utrzymanie magazynu i kontrola dysku
Trwałość sesji ma automatyczne mechanizmy utrzymania (session.maintenance) dla sessions.json i artefaktów transkryptów:
mode:warn(domyślnie) alboenforcepruneAfter: granica wieku nieaktualnych wpisów (domyślnie30d)maxEntries: limit wpisów wsessions.json(domyślnie500)rotateBytes: rotacjasessions.json, gdy jest zbyt duży (domyślnie10mb)resetArchiveRetention: retencja archiwów transkryptów*.reset.<timestamp>(domyślnie: taka sama jakpruneAfter;falsewyłącza czyszczenie)maxDiskBytes: opcjonalny budżet katalogu sesjihighWaterBytes: opcjonalny cel po czyszczeniu (domyślnie80%zmaxDiskBytes)
mode: "enforce"):
- Najpierw usuń najstarsze zarchiwizowane lub osierocone artefakty transkryptów.
- Jeśli nadal przekraczasz cel, 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 magazynu/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 z magazynu 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 rozmowy jest używany (trasowanie + izolacja).
Typowe wzorce:
- Główna/czat bezpośredni (na agenta):
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 bieżący sessionId (plik transkryptu, który kontynuuje rozmowę).
Praktyczne zasady:
- Reset (
/new,/reset) tworzy nowysessionIddla tegosessionKey. - Reset dzienny (domyślnie o 4:00 czasu lokalnego na hoście gateway) 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 skonfigurowane są jednocześnie tryb dzienny i bezczynność, wygrywa to, które wygaśnie wcześniej. - Strażnik rozwidlenia od rodzica wątku (
session.parentForkMaxTokens, domyślnie100000) pomija rozwidlanie z transkryptu rodzica, gdy sesja nadrzędna jest już zbyt duża; nowy wątek zaczyna od zera. Ustaw0, aby wyłączyć.
initSessionState() w src/auto-reply/reply/session.ts.
Schemat magazynu sesji (sessions.json)
Typ wartości magazynu 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 zasadom wysyłania)provider,subject,room,space,displayName: metadane do etykiet grup/kanałów- Przełączniki:
thinkingLevel,verboseLevel,reasoningLevel,elevatedLevelsendPolicy(nadpisanie dla danej sesji)
- Wybór modelu:
providerOverride,modelOverride,authProfileOverride
- Liczniki tokenów (best-effort / zależne od dostawcy):
inputTokens,outputTokens,totalTokens,contextTokens
compactionCount: ile razy automatyczne kompaktowanie zakończyło się dla tego klucza sesjimemoryFlushAt: znacznik czasu ostatniego zrzutu pamięci przed kompaktowaniemmemoryFlushCompactionCount: liczba kompaktowań w momencie ostatniego zrzutu
Struktura transkryptu (*.jsonl)
Transkryptami zarządza 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 wstrzyknięte przez rozszerzenie, które wchodzą do kontekstu modelu (mogą być ukryte przed 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/zapisu.
Okna kontekstu a śledzone tokeny
Znaczenie mają dwa różne pojęcia:- Okno kontekstu modelu: twardy limit dla modelu (tokeny widoczne dla modelu)
- Liczniki magazynu sesji: kroczące statystyki zapisywane w
sessions.json(używane przez /status i panele)
- Okno kontekstu pochodzi z katalogu modeli (i może zostać nadpisane przez konfigurację).
contextTokensw magazynie to wartość szacunkowa/raportowa w czasie działania; nie traktuj jej jako ścisłej gwarancji.
Kompaktowanie: czym jest
Kompaktowanie podsumowuje starszą część rozmowy do zapisanego wpisucompaction w transkrypcie i zachowuje nienaruszone najnowsze wiadomości.
Po kompaktowaniu przyszłe tury widzą:
- Podsumowanie kompaktowania
- Wiadomości po
firstKeptEntryId
Granice fragmentów kompaktowania i parowanie narzędzi
Gdy OpenClaw dzieli długi transkrypt na fragmenty kompaktowania, utrzymuje sparowanie wywołań narzędzi asystenta z odpowiadającymi im wpisamitoolResult.
- Jeśli podział według udziału tokenów wypada pomiędzy wywołaniem narzędzia a jego wynikiem, OpenClaw przesuwa granicę do wiadomości asystenta z wywołaniem narzędzia, zamiast rozdzielać tę parę.
- Jeśli końcowy blok wyniku narzędzia w przeciwnym razie wypchnąłby fragment ponad zakładany cel, 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.
Kiedy następuje automatyczne kompaktowanie (środowisko Pi)
W osadzonym agencie Pi automatyczne 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) → skompaktuj → 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 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).
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 verbose:
🧹 Auto-compaction complete+ liczba kompaktowań
Ciche porządki (NO_REPLY)
OpenClaw obsługuje „ciche” tury dla zadań w tle, gdy użytkownik nie powinien widzieć pośrednich wyników.
Konwencja:
- Asystent rozpoczyna swoje wyjście od dokładnego cichego tokenu
NO_REPLY/no_reply, aby wskazać „nie dostarczaj odpowiedzi użytkownikowi”. - OpenClaw usuwa/tłumi to w warstwie dostarczania.
- Tłumienie dokładnego cichego tokenu jest nieczułe na wielkość liter, więc
NO_REPLYino_replysą uznawane, gdy cały ładunek to wyłącznie cichy token. - Jest to przeznaczone wyłącznie dla prawdziwych tur w tle/bez dostarczenia; nie jest to skrót dla zwykłych, wykonalnych żądań użytkownika.
2026.1.10 OpenClaw tłumi również strumieniowanie wersji roboczych/typing, gdy
częściowy fragment zaczyna się od NO_REPLY, aby ciche operacje nie ujawniały
częściowego wyjścia w środku tury.
„Zrzut pamięci” przed kompaktowaniem (zaimplementowane)
Cel: zanim nastąpi automatyczne kompaktowanie, uruchomić cichą agentową turę, która zapisze trwały stan na dysk (na przykładmemory/YYYY-MM-DD.md w workspace agenta), aby kompaktowanie nie mogło
usunąć krytycznego kontekstu.
OpenClaw używa podejścia zrzutu przed progiem:
- Monitoruj użycie kontekstu sesji.
- Gdy przekroczy „miękki próg” (poniżej progu kompaktowania Pi), uruchom cichą dyrektywę „zapisz pamięć teraz” dla agenta.
- Użyj dokładnego cichego tokenu
NO_REPLY/no_reply, aby użytkownik niczego nie zobaczył.
agents.defaults.compaction.memoryFlush):
enabled(domyślnie:true)softThresholdTokens(domyślnie:4000)prompt(wiadomość użytkownika dla tury zrzutu)systemPrompt(dodatkowy prompt systemowy dołączany dla tury zrzutu)
- Domyślny prompt/system prompt zawiera wskazówkę
NO_REPLY, aby tłumić dostarczanie. - Zrzut uruchamia się raz na cykl kompaktowania (śledzone w
sessions.json). - Zrzut działa tylko dla osadzonych sesji Pi (backendy CLI go pomijają).
- Zrzut jest pomijany, gdy workspace sesji jest tylko do odczytu (
workspaceAccess: "ro"lub"none"). - Zobacz Pamięć, aby poznać układ plików workspace i wzorce zapisu.
session_before_compact w API rozszerzeń, ale logika zrzutu w OpenClaw
obecnie znajduje się po stronie Gateway.
Lista kontrolna rozwiązywania problemów
- Nieprawidłowy klucz sesji? Zacznij od /concepts/session i potwierdź
sessionKeyw/status. - Niezgodność magazynu i transkryptu? Potwierdź host Gateway i ścieżkę magazynu z
openclaw status. - Spam kompaktowania? Sprawdź:
- okno kontekstu modelu (zbyt małe)
- ustawienia kompaktowania (
reserveTokensustawione zbyt wysoko względem okna modelu może powodować wcześniejsze kompaktowanie) - rozrost wyników narzędzi: włącz/dostrój przycinanie sesji
- Ciche tury przeciekają? Potwierdź, że odpowiedź zaczyna się od
NO_REPLY(dokładny token, nieczuły na wielkość liter) i że używasz wersji zawierającej poprawkę tłumienia strumieniowania.