Session-Management & Kompaktierung (Deep Dive)¶
Dieses Dokument erläutert, wie OpenClaw Sessions Ende-zu-Ende verwaltet:
- Session-Routing (wie eingehende Nachrichten einem
sessionKeyzugeordnet werden) - Session-Store (
sessions.json) und was er erfasst - Transkript-Persistenz (
*.jsonl) und ihre Struktur - Transkript-Hygiene (anbieterspezifische Korrekturen vor Läufen)
- Kontextlimits (Kontextfenster vs. erfasste Tokens)
- Kompaktierung (manuell + Auto-Kompaktierung) und wo Vorarbeiten vor der Kompaktierung einzuhängen sind
- Stilles Housekeeping (z. B. Speicher-Schreibvorgänge, die keine nutzersichtbare Ausgabe erzeugen sollen)
Wenn Sie zunächst eine Übersicht auf höherer Ebene wünschen, beginnen Sie mit:
Quelle der Wahrheit: das Gateway¶
OpenClaw ist um einen einzelnen Gateway-Prozess herum konzipiert, der den Session-Status besitzt.
- UIs (macOS-App, Web-Control-UI, TUI) sollten das Gateway nach Session-Listen und Token-Zählungen abfragen.
- Im Remote-Modus liegen Session-Dateien auf dem Remote-Host; ein „Prüfen Ihrer lokalen Mac-Dateien“ spiegelt nicht wider, was das Gateway verwendet.
Zwei Persistenzschichten¶
OpenClaw persistiert Sessions in zwei Schichten:
-
Session-Store (
sessions.json) - Key/Value-Map:sessionKey -> SessionEntry- Klein, veränderlich, sicher zu bearbeiten (oder Einträge zu löschen) - Erfasst Session-Metadaten (aktuelle Session-ID, letzte Aktivität, Toggles, Token-Zähler usw.) -
Transkript (
<sessionId>.jsonl) - Append-only-Transkript mit Baumstruktur (Einträge habenid+parentId) - Speichert die eigentliche Konversation + Tool-Aufrufe + Kompaktierungszusammenfassungen - Wird verwendet, um den Modellkontext für zukünftige Turns neu aufzubauen
Ablageorte auf Datenträger¶
Pro Agent, auf dem Gateway-Host:
- Store:
~/.openclaw/agents/<agentId>/sessions/sessions.json - Transkripte:
~/.openclaw/agents/<agentId>/sessions/<sessionId>.jsonl - Telegram-Themen-Sessions:
.../<sessionId>-topic-<threadId>.jsonl
OpenClaw löst diese über src/config/sessions.ts auf.
Session-Schlüssel (sessionKey)¶
Ein sessionKey identifiziert, in welchem Konversations-Bucket Sie sich befinden (Routing + Isolation).
Gängige Muster:
- Haupt-/Direktchat (pro Agent):
agent:<agentId>:<mainKey>(Standardmain) - Gruppe:
agent:<agentId>:<channel>:group:<id> - Raum/Kanal (Discord/Slack):
agent:<agentId>:<channel>:channel:<id>oder...:room:<id> - Cron:
cron:<job.id> - Webhook:
hook:<uuid>(sofern nicht überschrieben)
Die kanonischen Regeln sind unter /concepts/session dokumentiert.
Session-IDs (sessionId)¶
Jeder sessionKey verweist auf eine aktuelle sessionId (die Transkriptdatei, die die Konversation fortsetzt).
Faustregeln:
- Reset (
/new,/reset) erstellt eine neuesessionIdfür diesensessionKey. - Täglicher Reset (Standard 4:00 Uhr Ortszeit auf dem Gateway-Host) erstellt eine neue
sessionIdbei der nächsten Nachricht nach der Reset-Grenze. - Leerlaufablauf (
session.reset.idleMinutesoder legacysession.idleMinutes) erstellt eine neuesessionId, wenn nach dem Leerlauffenster eine Nachricht eintrifft. Wenn täglich + Leerlauf beide konfiguriert sind, gewinnt der zuerst ablaufende.
Implementierungsdetail: Die Entscheidung erfolgt in initSessionState() in src/auto-reply/reply/session.ts.
Schema des Session-Stores (sessions.json)¶
Der Werttyp des Stores ist SessionEntry in src/config/sessions.ts.
Wichtige Felder (nicht vollständig):
sessionId: aktuelle Transkript-ID (Dateiname wird hiervon abgeleitet, sofernsessionFilenicht gesetzt ist)updatedAt: Zeitstempel der letzten AktivitätsessionFile: optionale explizite Überschreibung des TranskriptpfadschatType:direct | group | room(hilft UIs und der Sende-Policy)provider,subject,room,space,displayName: Metadaten für Gruppen-/Kanalbeschriftung- Toggles:
thinkingLevel,verboseLevel,reasoningLevel,elevatedLevelsendPolicy(Override pro Session)- Modellauswahl:
providerOverride,modelOverride,authProfileOverride- Token-Zähler (Best-Effort / anbieterabhängig):
inputTokens,outputTokens,totalTokens,contextTokenscompactionCount: wie oft die Auto-Kompaktierung für diesen Session-Schlüssel abgeschlossen wurdememoryFlushAt: Zeitstempel des letzten Pre-Kompaktions-Memory-FlushmemoryFlushCompactionCount: Kompaktierungszähler beim letzten Flush
Der Store ist sicher zu bearbeiten, aber das Gateway ist die Autorität: Es kann Einträge beim Ausführen von Sessions neu schreiben oder rehydrieren.
Transkriptstruktur (*.jsonl)¶
Transkripte werden von @mariozechner/pi-coding-agent’s SessionManager verwaltet.
Die Datei ist JSONL:
- Erste Zeile: Session-Header (
type: "session", enthältid,cwd,timestamp, optionalparentSession) - Danach: Session-Einträge mit
id+parentId(Baum)
Bemerkenswerte Eintragstypen:
message: user/assistant/toolResult-Nachrichtencustom_message: von Extensions injizierte Nachrichten, die in den Modellkontext eingehen (können in der UI verborgen sein)custom: Extension-Status, der nicht in den Modellkontext eingehtcompaction: persistierte Kompaktierungszusammenfassung mitfirstKeptEntryIdundtokensBeforebranch_summary: persistierte Zusammenfassung beim Navigieren eines Baumzweigs
OpenClaw „korrigiert“ Transkripte absichtlich nicht; das Gateway verwendet SessionManager zum Lesen/Schreiben.
Kontextfenster vs. erfasste Tokens¶
Zwei unterschiedliche Konzepte sind relevant:
- Modell-Kontextfenster: harte Obergrenze pro Modell (für das Modell sichtbare Tokens)
- Session-Store-Zähler: rollierende Statistiken, die in
sessions.jsongeschrieben werden (verwendet für /status und Dashboards)
Wenn Sie Limits feinjustieren:
- Das Kontextfenster stammt aus dem Modellkatalog (und kann per Konfiguration überschrieben werden).
contextTokensim Store ist ein Laufzeit-Schätzwert für Reporting; behandeln Sie ihn nicht als strikte Garantie.
Weitere Details unter /token-use.
Kompaktierung: was sie ist¶
Kompaktierung fasst ältere Konversationen in einen persistierten compaction-Eintrag im Transkript zusammen und belässt aktuelle Nachrichten unverändert.
Nach der Kompaktierung sehen zukünftige Turns:
- Die Kompaktierungszusammenfassung
- Nachrichten nach
firstKeptEntryId
Kompaktierung ist persistent (im Gegensatz zum Session-Pruning). Siehe /concepts/session-pruning.
Wann Auto-Kompaktierung stattfindet (Pi-Runtime)¶
Im eingebetteten Pi-Agenten wird die Auto-Kompaktierung in zwei Fällen ausgelöst:
- Overflow-Recovery: Das Modell liefert einen Kontext-Overflow-Fehler → komprimieren → erneut versuchen.
- Schwellenwert-Wartung: nach einem erfolgreichen Turn, wenn:
contextTokens > contextWindow - reserveTokens
Dabei gilt:
contextWindowist das Kontextfenster des ModellsreserveTokensist der reservierte Puffer für Prompts + die nächste Modellausgabe
Dies sind Semantiken der Pi-Runtime (OpenClaw konsumiert die Events, aber Pi entscheidet, wann komprimiert wird).
Kompaktierungseinstellungen (reserveTokens, keepRecentTokens)¶
Pis Kompaktierungseinstellungen befinden sich in den Pi-Einstellungen:
{
compaction: {
enabled: true,
reserveTokens: 16384,
keepRecentTokens: 20000,
},
}
OpenClaw erzwingt außerdem einen Sicherheits-Mindestwert für eingebettete Läufe:
- Wenn
compaction.reserveTokens < reserveTokensFloor, erhöht OpenClaw diesen. - Standard-Mindestwert sind
20000Tokens. - Setzen Sie
agents.defaults.compaction.reserveTokensFloor: 0, um den Mindestwert zu deaktivieren. - Ist er bereits höher, lässt OpenClaw ihn unverändert.
Warum: genügend Puffer für mehrturniges „Housekeeping“ (wie Memory-Schreibvorgänge) lassen, bevor Kompaktierung unvermeidlich wird.
Implementierung: ensurePiCompactionReserveTokens() in src/agents/pi-settings.ts
(aufgerufen von src/agents/pi-embedded-runner.ts).
Nutzersichtbare Oberflächen¶
Sie können Kompaktierung und Session-Status beobachten über:
/status(in jeder Chat-Session)openclaw status(CLI)openclaw sessions/sessions --json- Verbose-Modus:
🧹 Auto-compaction complete+ Kompaktierungszähler
Stilles Housekeeping (NO_REPLY)¶
OpenClaw unterstützt „stille“ Turns für Hintergrundaufgaben, bei denen der Nutzer keine Zwischenausgaben sehen soll.
Konvention:
- Der Assistent beginnt seine Ausgabe mit
NO_REPLY, um „keine Antwort an den Nutzer ausliefern“ zu signalisieren. - OpenClaw entfernt/unterdrückt dies in der Auslieferungsschicht.
Seit 2026.1.10 unterdrückt OpenClaw außerdem Draft/Typing-Streaming, wenn ein partieller Chunk mit NO_REPLY beginnt, sodass stille Operationen keine Teilausgaben während des Turns preisgeben.
Pre-Kompaktions-„Memory-Flush“ (implementiert)¶
Ziel: Bevor Auto-Kompaktierung stattfindet, einen stillen agentischen Turn ausführen, der dauerhaften Zustand auf Datenträger schreibt (z. B. memory/YYYY-MM-DD.md im Agent-Workspace), damit Kompaktierung keinen kritischen Kontext löschen kann.
OpenClaw verwendet den Ansatz des Pre-Threshold-Flush:
- Überwachen der Session-Kontextnutzung.
- Beim Überschreiten einer „Soft-Schwelle“ (unterhalb von Pis Kompaktierungsschwelle) einen stillen „Jetzt Speicher schreiben“-Befehl an den Agenten ausführen.
NO_REPLYverwenden, sodass der Nutzer nichts sieht.
Konfiguration (agents.defaults.compaction.memoryFlush):
enabled(Standard:true)softThresholdTokens(Standard:4000)prompt(User-Nachricht für den Flush-Turn)systemPrompt(zusätzlicher System-Prompt, der für den Flush-Turn angehängt wird)
Hinweise:
- Der Standard-Prompt/System-Prompt enthält einen
NO_REPLY-Hinweis zur Unterdrückung der Auslieferung. - Der Flush läuft einmal pro Kompaktierungszyklus (nachverfolgt in
sessions.json). - Der Flush läuft nur für eingebettete Pi-Sessions (CLI-Backends überspringen ihn).
- Der Flush wird übersprungen, wenn der Session-Workspace schreibgeschützt ist (
workspaceAccess: "ro"oder"none"). - Siehe Memory für das Layout der Workspace-Dateien und Schreibmuster.
Pi stellt außerdem einen session_before_compact-Hook in der Extension-API bereit, aber OpenClaws
Flush-Logik befindet sich heute auf der Gateway-Seite.
Checkliste zur Fehlerbehebung¶
- Session-Schlüssel falsch? Beginnen Sie mit /concepts/session und bestätigen Sie den
sessionKeyin/status. - Store vs. Transkript inkonsistent? Bestätigen Sie den Gateway-Host und den Store-Pfad aus
openclaw status. - Kompaktierungs-Spam? Prüfen Sie:
- Modell-Kontextfenster (zu klein)
- Kompaktierungseinstellungen (
reserveTokenszu hoch für das Modellfenster kann frühere Kompaktierung verursachen) - Tool-Result-Aufblähung: Session-Pruning aktivieren/feinjustieren
- Stille Turns lecken? Bestätigen Sie, dass die Antwort mit
NO_REPLY(exaktes Token) beginnt und Sie eine Build-Version mit dem Streaming-Unterdrückungs-Fix verwenden.