はじめに
マルチチャンネル・マルチユーザーのAIゲートウェイにおいて、セッション管理は最も重要な基盤能力の一つです。OpenClawはJSONLベースの永続化方式を採用し、ツリー型メッセージ構造と組み合わせて、セッションブランチ、履歴の遡及、自動圧縮などの高度な機能を実現しています。本記事では、低レベルのストレージから上位の戦略まで、OpenClawのセッション管理メカニズムを全面的に解析します。
セッションの保存場所
各Agentのセッションデータはそれぞれのディレクトリに独立して保存されます。
~/.openclaw/agents/<agentId>/sessions/
├── telegram_123456.jsonl
├── discord_789012.jsonl
├── whatsapp_345678.jsonl
└── web_dashboard.jsonl
ファイル名の形式は <channel>_<userId>.jsonl で、各ファイルは1人のユーザーの1つのチャンネルでの完全な会話履歴に対応します。この設計により、異なるチャンネル・異なるユーザーのセッションが自然に隔離され、データの混信を防ぎます。
JSONLストレージ形式
OpenClawはJSONL(JSON Lines)形式で各メッセージを保存し、1行が1つのJSONオブジェクトです。
{"id":"msg_001","parentId":null,"role":"user","content":"こんにちは","timestamp":1710000000,"channel":"telegram"}
{"id":"msg_002","parentId":"msg_001","role":"assistant","content":"こんにちは!何かお手伝いできることはありますか?","timestamp":1710000001,"channel":"telegram"}
コアフィールドの説明
| フィールド | 型 | 説明 |
|---|---|---|
id |
string | メッセージの一意識別子、自動生成 |
parentId |
string/null | 親メッセージID、ルートメッセージはnull |
role |
string | ロール:user、assistant、system |
content |
string | メッセージテキスト内容 |
timestamp |
number | Unixタイムスタンプ |
channel |
string | ソースチャンネル |
metadata |
object | オプション、付加メタデータ(メディア情報など) |
JSONLを選択した理由として、ファイル追記書き込みの高パフォーマンス、外部依存不要、バックアップと移行の容易さ、人間が直接読んでデバッグ可能であることが挙げられます。
ツリー型セッション構造
OpenClawのセッション管理で最もユニークな設計はツリー構造です。id と parentId フィールドを通じてメッセージ間に親子関係を構成し、単純な線形リストではありません。
なぜツリー構造を使うのか
実際の使用では、ユーザーは「ある地点に戻って会話をやり直したい」ことがよくあります。ユーザーがあるメッセージから分岐を作成すると、OpenClawはそのメッセージを新しいブランチの起点として独立したコンテキストパスを構築します。モデルが見る会話履歴には他のブランチの内容は含まれません。
Dashboardでのブランチ使用
Web Dashboardでは、セッションのツリー構造を視覚的に確認できます。任意の履歴メッセージの「ここから分岐」ボタンをクリックして、新しい会話ブランチを作成できます。各ブランチは独立してコンテキストを維持し、互いに干渉しません。
コンテキスト構築戦略
OpenClawがモデルAPIを呼び出す際、現在のメッセージノードから parentId チェーンに沿って上方に遡り、祖先メッセージをコンテキストとして収集します。このプロセスは以下の設定で制御されます。
{
"sessions": {
"maxHistoryMessages": 50,
"maxHistoryTokens": 8000
}
}
自動圧縮メカニズム
会話が非常に長くなり、モデルのコンテキストウィンドウを超えそうになると、OpenClawは自動的に圧縮(compaction)をトリガーします。
summary戦略(デフォルト)
古い会話履歴をモデルに送信して要約を生成させます。この要約が system ロールのメッセージとしてコンテキストの先頭に挿入され、元の履歴メッセージを置き換えます。重要な情報を保持しつつ、トークン消費を大幅に削減します。
truncate戦略
単純な切り捨てで、最も古いメッセージを直接破棄し、最新のN件のみを保持します。追加のモデル呼び出しは発生しませんが、重要なコンテキストが失われる可能性があります。コストに敏感で会話の一貫性要件が高くないシナリオに適しています。
チャンネルタイプ別の差別化設定
異なるチャンネルの使用パターンは大きく異なります。DMは通常長い会話で、グループチャットは断片的な短いインタラクションです。OpenClawはチャンネルタイプごとにセッション設定を上書きすることをサポートしています。
{
"sessions": {
"maxHistoryMessages": 50,
"channelOverrides": {
"dm": { "maxHistoryMessages": 100, "maxHistoryTokens": 16000 },
"group": { "maxHistoryMessages": 20, "maxHistoryTokens": 4000 }
}
}
}
DM(dm)はより長い履歴を保持して一貫した会話を維持し、グループチャット(group)は短めに制限してコストを削減し、無関係なメッセージの干渉を減らします。
セッションデータのメンテナンス
手動クリーンアップ
openclaw session clear --agent default --session telegram_123456
openclaw session clear --agent myagent --all
openclaw session export --session telegram_123456 --format json > history.json
自動クリーンアップ
{
"sessions": {
"retention": { "maxAge": "30d", "maxSize": "100mb" }
}
}
30日を超えたか、合計サイズが100MBを超えた古いセッションデータは、OpenClaw起動時に自動的にアーカイブされます。
マルチデバイス同期
セッションデータはファイルシステムに保存されるため、マルチインスタンスデプロイ時には同期の問題に注意が必要です。単一マシンデプロイでは追加設定は不要です。マルチマシンデプロイでは、共有ストレージ(NFSなど)で ~/.openclaw/agents/ ディレクトリをマウントするか、Redisストレージバックエンドに切り替えることを推奨します。
まとめ
OpenClawのセッション管理システムはJSONLファイルを基盤とし、id/parentId でツリー構造を構築して、セッションブランチと柔軟なコンテキスト遡及をサポートします。自動圧縮メカニズムにより長い会話がモデルの制限を超えることを防ぎ、チャンネルタイプ別の差別化設定でリソース配分をより合理的にします。これらのメカニズムを理解した上で、実際の使用シナリオに応じてセッションパラメータを精密に調整し、会話品質とコストのバランスを取ることができます。