简体中文 English 繁體中文 日本語 Русский
本文为静态镜像,内容以交互版为准 在交互式文档中心打开 →

会話トランザクト(Transcript)

会話トランザクトは、プラットフォーム:詳細タイプ:ターゲットIDという会話キーで整理された、ロボットが送受信したメッセージを自動的に記録します。
この記録は、対話の復元(event.history)、影分身モジュールのdiff、冷起動時の再現などに使用される履歴データを提供します。
本ドキュメントでは、ストレージモデル、各保留ポリシーのスイッチが何を保護しているか、および、実行時のオーバーライドAPIと制限の緩和がもたらす実際のコストについて説明します。

制限を変更する前に、「リスクと監査」セクションを必ずお読みください。各スイッチには、その存在理由があります。

動作原理

メッセージ ──append()──▶ 書き込みバッファ(メモリ deque、ハード上限 4096 行)
                        │  1 秒ごとにバッチで一時保存(1 バッチ ≤64 行、1 トランザクション)
                        ▼
              storage バックエンドの transcript テーブル(デフォルトは sqlite)
                        │  約 32 行追加ごとに遅延実行で保持クリーンアップをトリガー
                        ▼
              ┌─ セッションごとに FIFO で裁断(max_per_session、デフォルト 50 行)
              └─ グローバルな TTL 削除(ttl_hours、デフォルト 168 = 7 日)

3 つの階層の保護が、それぞれ異なるリスクを防いでいます:

旋钮 デフォルト値 保護対象 無効化(=0)時の結果
書き込みバッファ上限 4096 行(定数、設定不可) メモリ:ストレージ利用不能時の蓄積が RAM をオーバーフローしないように 無効化不可——これはメモリの防衛線です
単条テキストの切り詰め 2000 文字(定数、設定不可) 単条メッセージのメモリ/ディスク使用量 無効化不可
max_per_session 50 条/セッション ディスク成長:1 セッションの履歴が無限に蓄積されるのを防ぐ そのセッションの履歴が無限に成長します
ttl_hours 168(7 日) ディスク成長:全セッションの長期蓄積を防ぐ transcript テーブルが無限に成長します

重要な認識:書き込みバッファにはハード上限があるため、保持戦略を緩めても直接メモリがオーバーフローすることはありません; 本当のリスクはストレージ層と下流のコンシューマー(次節参照)にあります。

設定

[ErisPulse.transcript]
enabled = true          # 自動記録を有効にするかどうか
max_per_session = 50    # 1セッションに保持する件数(0 = セッションのクリッピングを無効化)
ttl_hours = 168.0       # グローバルな保持期間(時間、0 = 保持期間なし)

環境変数による上書きも有効です:ERISPULSE_TRANSCRIPT_MAX_PER_SESSION、ERISPULSE_TRANSCRIPT_TTL_HOURS。
設定の変更はホットで有効になります(バッファリングの書き込み間隔内で、最大で約1秒の遅延)。

[docs/ja/quick-start.md]

実行時オーバーライド API

実行時に動的に調整する必要がある場合(例:特定のシナリオで一時的に保持期間を延長する):

from ErisPulse import transcript

# オーバーライド(設定値を上書き;メモリ内に保持されるため、再起動後に設定値に戻る)
transcript.set_retention(max_per_session=500, ttl_hours=24 * 30)

# 有効な値とそのソースを取得
transcript.get_retention()
# {'max_per_session': 500, 'ttl_hours': 720.0, 'overridden': ['max_per_session', 'ttl_hours']}

# 設定に従って復元
transcript.reset_retention()

風険と監査:制限を解放する前に必ず読む

max_per_session / ttl_hours を無効化(または大幅に大きく設定)した後、transcript テーブルはメッセージ量に応じて無制限に成長します。その結果は以下のとおりです。

  1. ディスクがいっぱいになる —— sqlite の単一ファイルが継続的に膨張し、ディスクが枯渇した後はフレームワークのストレージ層が利用できなくなります。
  2. クエリの性能低下 —— get() / recent() / get_by_trace() のスキャンコストはテーブルの成長に伴って増加します。
  3. 下流のメモリ圧力(OOM の本当の原因) —— 歴史セッション全体をメモリに読み込むコンシューマー(セッションの履歴付き再開、パネルの全量取得、および get(session, n) で大きな n を取得するあなたの業務コード)はテーブルの成長とともにメモリを消費し、極端な状況では OOM kill を引き起こします。

解放する前に自問すべき3つの質問:どのくらいの期間の履歴が必要ですか?どのくらいの容量が必要ですか?誰がデータの削除を行う予定ですか?もし「削除しない」という答えが依存している場合は、正しい方法は通常、外部アーカイブ(定期的に古いデータを専用のデータベースに移す)です。受信箱に無制限にデータを保持するのではなく、適切な管理を行うべきです。

監査手段(定期的にテーブルのサイズを確認する方法):

# ORM/SQL ビルダーを経由して行数とサイズを確認(sqlite 例)
from ErisPulse import storage

row = storage.Table("transcript").raw_sql("SELECT COUNT(*) AS n FROM transcript")
-- sqlite ファイルに対して直接クエリを実行(テーブルのサイズ)
SELECT COUNT(*) FROM transcript;

保留戦略が無効化されました という warning ログが記録された場合 = 0 で戦略を無効化した人がいることを意味します。これは自分の操作であることを確認してください。

他のメカニズムとの境界