コンパクション内部
セッション管理詳細解説
このドキュメントでは、OpenClawがセッションをエンドツーエンドで管理する方法を説明します:
- セッションルーティング (着信メッセージが
sessionKeyにマッピングされる仕組み) - セッションストア (
sessions.json) とその追跡内容 - トランスクリプト永続化 (
*.jsonl) とその構造 - トランスクリプトの整理 (実行前のプロバイダー固有の修正)
- コンテキスト制限 (コンテキストウィンドウ vs 追跡トークン)
- コンパクション (手動 + 自動コンパクション) と事前コンパクション作業をフックする場所
- サイレントハウスキーピング (ユーザーに表示される出力を生成すべきでないメモリ書き込みなど)
より高レベルの概要を最初に知りたい場合は、以下から始めてください:
信頼できる情報源: ゲートウェイ
OpenClawは、セッション状態を所有する単一のゲートウェイプロセスを中心に設計されています。
- UI (macOSアプリ、WebコントロールUI、TUI) は、セッションリストとトークン数を取得するためにゲートウェイにクエリを実行する必要があります。
- リモートモードでは、セッションファイルはリモートホスト上にあります。「ローカルのMacファイルを確認する」ことは、ゲートウェイが使用しているものを反映しません。
2つの永続化レイヤー
OpenClawはセッションを2つのレイヤーで永続化します:
- セッションスト ア (
sessions.json)- キー/値マップ:
sessionKey -> SessionEntry - 小さく、可変的、編集(またはエントリ削除)が安全
- セッションメタデータを追跡 (現在のセッションID、最終アクティビティ、トグル、トークンカウンターなど)
- キー/値マップ:
- トランスクリプト (
.jsonl)- ツリー構造を持つ追記専用のトランスクリプト (エントリは
id+parentIdを持つ) - 実際の会話 + ツール呼び出し + コンパクション要約を保存
- 将来のターンのためにモデルコンテキストを再構築するために使用
- ツリー構造を持つ追記専用のトランスクリプト (エントリは
ディスク上の場所
エージェントごと、ゲートウェイホスト上:
- ストア:
~/.openclaw/agents//sessions/sessions.json - トランスクリプト:
~/.openclaw/agents//sessions/.jsonl- Telegramトピックセッション:
.../-topic-.jsonl
- Telegramトピックセッション:
OpenClawはこれらを src/config/sessions.ts 経由で解決します。
ストアのメンテナンスとディスク制御
セッション永続化には、sessions.json とトランスクリプトアーティファクトのための自動メンテナンス制御 (session.maintenance) があります:
mode:warn(デフォルト) またはenforcepruneAfter: 古いエントリのカットオフ期間 (デフォルト30d)maxEntries:sessions.json内のエントリ数の上限 (デフォルト500)rotateBytes:sessions.jsonが大きすぎる場合にローテート (デフォルト10mb)resetArchiveRetention:*.reset.トランスクリプトアーカイブの保持期間 (デフォルト:pruneAfterと同じ;falseでクリーンアップ無効化)maxDiskBytes: オプションのセッションディレクトリ予算highWaterBytes: クリーンアップ後のオプションの目標値 (デフォルトmaxDiskBytesの80%)
ディスク予算クリーンアップの実施順序 (mode: "enforce"):
- まず最も古いアーカイブ済みまたは孤立したトランスクリプトアーティファクトを削除。
- それでも目標値を超える場合、最も古いセッションエントリとそのトランスクリプトファイルを削除。
- 使用量が
highWaterBytes以下になるまで続行。
mode: "warn" では、OpenClawは潜在的な削除を報告しますが、ストア/ファイルを変更しません。必要に応じてメンテナンスを実行:
openclaw sessions cleanup --dry-run
openclaw sessions cleanup --enforce
Cronセッションと実行ログ
分離されたcron実行もセッションエントリ/トランスクリプトを作成し、専用の保持制御があります:
cron.sessionRetention(デフォルト24h) は、古い分離cron実行セッションをセッションストアから削除します (falseで無効化)。cron.runLog.maxBytes+cron.runLog.keepLinesは~/.openclaw/cron/runs/.jsonlファイルを削除します (デフォルト:2_000_000バイトと2000行)。
セッションキー (sessionKey)
sessionKey は、どの会話バケットにいるかを識別します (ルーティング + 分離)。一般的なパターン:
- メイン/直接チャット (エージェントごと):
agent::(デフォルトmain) - グループ:
agent:::group: - ルーム/チャンネル (Discord/Slack):
agent:::channel:または...:room: - Cron:
cron:<job.id> - Webhook:
hook:(上書きされない限り)
正規のルールは /concepts/session に文書化されています。
セッションID (sessionId)
各 sessionKey は、現在の sessionId (会話を継続するトランスクリプトファイル) を指します。経験則:
- リセット (
/new,/reset) は、そのsessionKeyに対して新しいsessionIdを作成します。 - 日次リセット (デフォルトはゲートウェイホストの現地時間で午前4:00) は、リセット境界後の次のメッセージで新しい
sessionIdを作成します。 - アイドル期限切れ (
session.reset.idleMinutesまたはレガシーsession.idleMinutes) は、アイドルウィンドウ後にメッセージが到着したときに新しいsessionIdを作成します。日次とアイドルの両方が設定されている場合、どちらか早く期限切れになる方が優先されます。 - スレッド親フォークガード (
session.parentForkMaxTokens, デフォルト100000) は、親セッション が既に大きすぎる場合、親トランスクリプトのフォークをスキップします。新しいスレッドは新規に開始します。0に設定すると無効化されます。
実装詳細: 決定は src/auto-reply/reply/session.ts の initSessionState() で行われます。
セッションストアスキーマ (sessions.json)
ストアの値の型は src/config/sessions.ts の SessionEntry です。主要なフィールド (網羅的ではありません):
sessionId: 現在のトランスクリプトID (sessionFileが設定されていない限り、ファイル名はこれから派生)updatedAt: 最終アクティビティタイムスタンプsessionFile: オプションの明示的なトランスクリプトパス上書きchatType:direct | group | room(UIと送信ポリシーに役立つ)provider,subject,room,space,displayName: グループ/チャンネルラベリングのためのメタデータ- トグル:
thinkingLevel,verboseLevel,reasoningLevel,elevatedLevelsendPolicy(セッションごとの上書き)
- モデル選択:
providerOverride,modelOverride,authProfileOverride
- トークンカウンター (ベストエフォート / プロバイダー依存):
inputTokens,outputTokens,totalTokens,contextTokens
compactionCount: このセッションキーに対して自動コンパクションが完了した回数memoryFlushAt: 最後の事前コンパクションメモリフラッシュのタイムスタンプmemoryFlushCompactionCount: 最後のフラッシュが実行されたときのコンパクション回数
ストアは編集しても安全ですが、ゲートウェイが権限を持ちます:セッション実行時にエントリを書き換えたり再ハイドレートしたりする可能性があります。
トランスクリプト構造 (*.jsonl)
トランスクリプトは @mariozechner/pi-coding-agent の SessionManager によって管理されます。ファイルはJSONL形式です:
- 最初の行: セッションヘッダー (
type: "session",id,cwd,timestamp, オプションparentSessionを含む) - その後:
id+parentIdを持つセッションエントリ (ツリー)
注目すべきエントリタイプ:
message: ユーザー/アシスタント/toolResultメッセージcustom_message: モデルコンテキストに入る拡 張機能注入メッセージ (UIから非表示にできる)custom: モデルコンテキストに入らない拡張機能状態compaction:firstKeptEntryIdとtokensBeforeを持つ永続化されたコンパクション要約branch_summary: ツリーブランチをナビゲートする際の永続化された要約
OpenClawは意図的にトランスクリプトを「修正」しません。ゲートウェイは SessionManager を使用してトランスクリプトを読み書きします。
コンテキストウィンドウ vs 追跡トークン
2つの異なる概念が重要です:
- モデルコンテキストウィンドウ: モデルごとのハードキャップ (モデルから見えるトークン)
- セッションストアカウンター:
sessions.jsonに書き込まれるローリング統計 (/status とダッシュボードで使用)
制限を調整する場合:
- コンテキストウィンドウはモデルカタログから来ます (設定で上書き可能)。
- ストア内の
contextTokensは実行時の推定/報告値です。厳密な保証として扱わないでください。
詳細は /token-use を参照してください。