一、「重要イベント」とは
「重要イベント」は GPTBots に組み込まれた長期業務メモリ機能です。ユーザーと Bot の複数ターンの対話の中で、プラットフォームは LLM を呼び出し、対話から業務価値のあるイベント(出金、クレーム、予約、返金など)を自動的に識別し、ユーザー次元で構造化して保存します。後続の対話ではコンテキストとして Bot に再注入され、Bot が「このユーザーが過去に何があったか、現在のイベントがどの段階まで処理されているか」を「覚えている」ようにします。
解決する核心的な課題は以下の通りです。
- 会話間メモリの欠落:従来の LLM は現在の会話の短期メモリウィンドウしか参照できず、会話間または長会話で重要な業務アクションが忘れられる。
- 構造化データの蓄積:散在する対話を、検索可能・統計可能・監査可能なイベントストリームとして蓄積し、リスク管理、カスタマーサポート品質チェック、ユーザープロファイルに再利用できる。
- 状態進行の追跡:各イベントには
PENDING / IN_PROGRESS / RESOLVED / CLOSEDのステータスがあり、複数の対話間で継続的に進めることができる。
二、設計理念
1. 「対話」を「イベントストリーム」として蓄積する
対話は非構造化、イベントは構造化されています。重要イベントは「ユーザーが何を話したか、何をしたか」を「分類 + 要約 + エンティティ + ステータス + 優先度 + 信頼度」というイベントレコードに翻訳し、LLM 以外の下流システム(統計、リスク管理、人手品質チェック)でもこのメモリを利用できるようにします。
2. デュアルレール起動で取りこぼしも過抽出も防ぐ
1 回の対話の中でイベントは途中で発生する場合もあれば、ユーザーが離脱した後に補抽出が必要となる場合もあります。システムはメッセージ閾値(リアルタイム)+ アイドルタイムアウト(バッチ)+ 手動トリガー(フォールバック)の三段構成を採用し、開発者がパラメータでコストとタイミングを調整できます。
3. デフォルトで LLM 抽出を有効化、安価モデルへのダウングレードも可能
イベント抽出自体には LLM の推論が必要で、Token を消費します。そのため、抽出モデルと Bot のメイン対話モデルは独立して設定できます。例えばメイン対話には Claude / GPT を、抽出にはより安価な小型モデルを使用し、課金と最適化を分離できます。
4. ユーザー識別の二重ルートでフォールバック
イベントはユーザー次元で集約されます。優先的に開発者が透過的に渡した userId(最上位識別子)を使用し、ない場合はプラットフォームが生成した anonymousId(未ログインユーザーなど)にフォールバックします。開発者が userId を渡さない場合でも、匿名訪問者の対話でイベントを蓄積できます。
5. ユーザースコープの厳密な隔離、LLM ハルシネーションによる汚染を防止
LLM は UPDATE / DELETE / MERGE 時に他ユーザーの eventId を「捏造」する可能性があります。コード内部では各操作に対し matchesUserScope 検証を行い、userId / anonymousId を強制的にハードフィルタ条件として、ユーザー間のイベント汚染を防ぎます。
6. Prompt 注入の明示的経路と暗黙的経路の二系統
- 明示的:Prompt 内に
{{key_event_<eventType>}}プレースホルダーを記述し、イベントタイプごとに正確に値を取得。 - 暗黙的:プレースホルダーが記述されない場合、自動的に
## Recent Key Eventsセクションを Prompt 末尾に追加。ゼロコンフィグで利用可能。
三、コア原理
3.1 データモデル
| 役割 | 備考 |
|---|---|
| 重要イベントメインテーブル | ユーザー / タイプ / 時刻の多次元インデックス |
| Bot レベル設定(各 Bot に 1 件) | スイッチ、閾値、抽出ルールを制御 |
| 会話レベル抽出ステータス | 抽出待ちメッセージ数、アイドル時間、並行ステータスを記録 |
| 抽出実行記録 | 各抽出の監査 + Token / クレジット消費 |
イベントメイン構造(BotEventEntity)の主要フィールド:
| フィールド | 意味 |
|---|---|
eventType |
イベント分類。Bot 設定の辞書と厳密に一致(例:withdrawal / complaint) |
summary |
イベント要約、200 字以内 |
status |
PENDING(未処理)/ IN_PROGRESS(処理中)/ RESOLVED(解決済み)/ CLOSED(終了) |
priority |
LOW / MEDIUM / HIGH / CRITICAL |
confidence |
LLM の自己評価による信頼度:HIGH(API データ)/ MEDIUM(双方確認済み)/ LOW(ユーザーの一方的な主張) |
credibilityLabel |
自然言語の真実性ラベル(「システム API 確認済み」/「ユーザー主張未確認」/「双方確認済み」) |
disputeFlag |
矛盾情報の有無(ユーザー陳述 ↔ システムデータの衝突) |
entities |
柔軟な KV 構造のエンティティ(金額、注文番号、時刻などを格納可能) |
relatedEventIds |
関連イベント ID(典型的には MERGE 後のソースポインタとして使用) |
sourceMsgIds |
このイベントをトリガーしたメッセージ ID リスト |
createdBy |
由来:LLM / API / UI |
3.2 三段階トリガーメカニズム
┌── Level 1:リアルタイムトリガー ─────────────┐
│ ユーザーメッセージ毎に +1 カウント │
│ pendingMessageCount ≥ messageThreshold │
│ 即座に LLM 抽出を呼び出し │
└──────────────────────────────────────┘
┌── Level 2:アイドルトリガー ─────────────────┐
│ 定期スキャン(30/60/300 秒に 1 ラウンド) │
│ ヒット条件: │
│ - lastMessageTime > idleTimeout 以前 │
│ - pendingMessageCount > 0 │
│ - extractionStatus == IDLE │
└──────────────────────────────────────┘
┌── Level 3:手動トリガー ─────────────────┐
│ API 呼び出し: │
│ POST /bot/event/execute/.../retry │
│ または実行記録ページで「リトライ」をクリック │
└──────────────────────────────────────┘
3 つの入口は最終的に同じパイプライン(BotEventExtractionService.extract)に入り、Redis ロック(bot:event:extract:{botId}:{conversationId}、5 分タイムアウト)により同一会話で抽出が並行しないことを保証します。
3.3 抽出パイプライン
1. スイッチ確認 → Redis ロック取得
2. Track / Redis / c_conversation の三段フォールバックでアイデンティティ読み込み
3. lastExtractedMessageTime 以降の新規メッセージ取得(≤100 件)
+ 上方向に過去 10 件を追加して文脈を完全保持
+ リアルタイムトリガー時は短期メモリウィンドウ末尾を切り落とす(メイン対話ウィンドウと整合)
4. 当該ユーザーの直近 N 件の過去イベントを取得(recentEventCount)
5. テンプレートに従い Prompt を構築:
- ユーザー定義の抽出ルール
- 許可されたイベント分類(name + description)
- 過去イベント(重複比較用)
- 分析対象の対話
6. 抽出モデルを選択し、JSON Schema を発行(OpenAI 系のみ有効)
7. LLM が返した operations 配列を解析:
CREATE → 新規イベント作成
UPDATE → 既存イベントのステータス/要約を進める
MERGE → 冗長な複数イベントをマージ
DELETE → ソフト削除(ユーザー撤回 / 否定)
8. ユーザースコープ越境を強制検証
9. クレジット消費を書き込み(CONSUME_KEY_EVENT タイプ)
10. 実行記録を書き込み + Track をリセット
3.4 注入メカニズム
モード A:自動追加(ゼロコンフィグ)
Bot で重要イベントが有効になっており、Prompt 内に {{key_event_*}} プレースホルダーが存在しない場合、システムは LLM を呼び出すたびに直近 N 件のイベントを以下のフォーマットで自動的に Prompt 末尾に追加します。
## Recent Key Events
eventType: withdrawal | summary: 用户申请提现 5000 元 | status: 处理中 | priority: 高 | confidence: 高 | updateTime: 2026-04-28 09:21:33 | entities: {"amount":5000,"channel":"bank"}
eventType: complaint | summary: 用户投诉客服响应慢 | status: 已解决 | priority: 中 | confidence: 中 | updateTime: 2026-04-27 18:02:11
モード B:プレースホルダー置換(精密制御)
Prompt / ワークフローコンポーネント / ルールに以下を記述します。
{{key_event_withdrawal}} ← 「出金」タイプのイベントのみを注入
{{key_event_complaint}} ← 「クレーム」タイプのイベントのみを注入
プラットフォームは eventType ごとにグループ化して対応する変数を生成し、マッチしないイベントタイプは注入されません。最大注入数は 30 件 / 変数です。
Flow Bot:コンポーネント単位の独立制御
ワークフローの各 LLM ノードはそれぞれ独自の FlowKeyEventConfig を持ちます。個別にスイッチ、個別にイベントタイプ選択、個別に recentEventCount(デフォルト 5 件)を設定できます。同一会話内ではイベントは 1 度のみ照会され(ChatContext にキャッシュ)、複数ノードがデータを共有します。
四、使用ガイド
4.1 Bot 設定パネルで有効化
アクセス経路:開発者コンソール → Bot 詳細 → ユーザー管理(User Manage) → 「重要イベント」ドロワー
操作手順:
- メインスイッチをオン
- 抽出モデル:オプション。未選択時は Bot のデフォルト対話モデルを使用。安価モデルの選択を推奨(例:GPT-4o-mini / Haiku シリーズ)。
- 抽出ルール(2000 字以内):自然言語で LLM にこの Bot シーンで「何が重要イベントとみなされるか」を伝えます。例:只抽取与资金相关的业务动作(取款、存款、转账、退款)。 忽略闲聊和情绪表达。 实体字段必须包含金额(amount)、币种(currency)、订单号(orderId)。
只抽取与资金相关的业务动作(取款、存款、转账、退款)。 忽略闲聊和情绪表达。 实体字段必须包含金额(amount)、币种(currency)、订单号(orderId)。このコードブロックをポップアップで表示 - 直近イベント数(0〜50):対話毎に Prompt に注入するイベント数。0 は注入しないことを意味し、5〜10 が一般的。
- トリガータイミング:
- メッセージ閾値(5〜50):デフォルト 10。
- アイドルタイムアウト(2〜60 分):デフォルト 3。
- イベント分類辞書(最大 10 個):各分類は「名称」(10 字以内)と「説明」(100 字以内、LLM にこの分類が何を含むかを伝える)を持つ。
- 保存をクリック。
⚠️ 警告:分類名は一度公開されたら安易に変更しないでください ── 過去のイベントは引き続き旧名で保存されており、
{{key_event_<旧名>}}で値が取得できなくなる場合があります。フロントエンドでは分類が既に存在する場合にオレンジ色の警告が表示されます。
4.2 Prompt でイベントを参照
通常 Bot Prompt
你是一个资金客服助手。
【该用户最近的资金动作】
{{key_event_withdrawal}}
【该用户最近的投诉】
{{key_event_complaint}}
请基于上述上下文回答用户问题。
Flow Bot コンポーネント Prompt
- キャンバスで LLM 駆動ノードをクリック → 設定パネルで「メモリ-重要イベント」設定を見つける。
enableをチェックし、当該ノードに注入したいイベントタイプを選択し、リコールする直近イベント数(デフォルト 5)を設定。
4.3 抽出実行記録の監視
アクセス経路:開発者コンソール → Bot 詳細 → ユーザー管理 → 実行記録タブ
参照可能な情報:
- 各抽出のステータス(PENDING / RUNNING / COMPLETED / FAILED)
- トリガー由来(REALTIME / SCHEDULED / MANUAL)
- 処理メッセージ数 / 抽出されたイベント数
- Token 消費 / クレジット消費
- 失敗理由 + 「リトライ」ボタン
- 詳細ドロワー:今回の抽出で生成 / 変更されたすべてのイベントを一覧表示
4.4 課金と料金
重要イベントの LLM 呼び出し費用は請求書の 重要イベント 項目に計上され、対話メインフローの課金とは別途集計されるため、コストを個別に管理しやすくなっています。
五、典型的な適用シーン
| シーン | イベントタイプ例 | 価値 |
|---|---|---|
| 金融 / 海外送金カスタマーサポート | withdrawal 出金 / deposit 入金 / kyc 本人確認 / dispute 異議 |
会話間で資金アクションを追跡。リスク管理および人間オペレーター引き継ぎ時に当該ユーザーの過去業務フローが一目でわかる |
| EC アフターサービス | refund 返金 / return 返品 / complaint クレーム |
ユーザーのアフターサービスステートマシンを自動維持。複数対話で継続的に進める |
| 予約 / スケジュール | appointment 予約 / cancellation キャンセル |
Bot がユーザーが何回時間を変更したか、現在確定している時間帯を記憶できる |
| HR / 社内 IT アシスタント | leave_request 休暇申請 / it_ticket チケット |
対話を検索可能なチケットフローとして蓄積 |
| 教育 / 学習支援 | homework_submission / quiz_score / weak_topic |
学生の学習状況を長期記録し、個別最適化された復習計画を生成 |
| 医療 / 健康相談 | symptom 症状 / medication 服薬 / appointment 再診 |
相談間で病歴情報を保持し、問診の連続性を向上 |
六、ベストプラクティス
✅ 設定面
- 分類辞書には説明を書く ──
name+descriptionの両方を記入してください。LLM は主にdescriptionで「この対話がこの分類に該当するか」を判断します。descriptionが空欄だと分類精度が著しく低下します。 - 分類数は 5〜10 個に抑える。多すぎると LLM が抽出時に分類で迷い、Prompt サイズも肥大化します。同義の分類はマージしてください(「出金」と「引き出し」を 1 つに)。
- 抽出ルールには「やること」と「やらないこと」を両方書く。例:只抽取已确认完成或正在进行的业务动作。 排除:假设性讨论("如果...怎么办")、纯情绪、闲聊。
只抽取已确认完成或正在进行的业务动作。 排除:假设性讨论("如果...怎么办")、纯情绪、闲聊。このコードブロックをポップアップで表示 - 抽出モデルは小型を選ぶ。抽出は構造化出力タスクであり、推論能力への要求は低いです。GPT-4o-mini / Claude Haiku / DeepSeek-V3 で通常十分。1 回あたりのコストはメイン対話モデルより 1 桁低く抑えられます。
- 最初から
recentEventCountを最大値にしない。注入するイベントが多すぎるとメイン対話のコンテキストを圧迫します。5 から始め、Bot がよく「思い出せない」と感じたら増やしてください。
✅ トリガーパラメータ
- 長会話 / カスタマーサポートシーン:
messageThreshold = 10、idleTimeoutMinutes = 3が一般的に適切。 - 短いインタラクション / タスク型 Bot:
idleTimeoutMinutesを 2 に下げ、ユーザー対話終了後にイベント抽出が遅延しないようにする。 - 高頻度低価値の対話(一般的な Q&A など):
messageThresholdを 20〜30 に上げ、毎ターン LLM 抽出が走ってコストが膨らむのを防ぐ。
✅ Prompt 参照
- 自動追加に頼るより、プレースホルダーを優先する。プレースホルダーは制御可能でタイプ別に正確に切り出せます。自動追加は「全部欲しい」フォールバック向けです。
- Flow Bot で全ノードに有効化しない。本当にイベントコンテキストが必要なノード(カスタマーサポート応答ノード、リスク判定ノードなど)でのみ有効にしてください。意図認識 / ルーティングノードでは不要です。
{{key_event_xxx}}をシステムレベル Prompt の冒頭に置かない ── 過去イベントは時間とともに増加し、Token を圧迫するとメイン指示が切り捨てられる場合があります。Prompt の中盤または Few-shot の前に配置することを推奨。
✅ データガバナンス
- LOW 信頼度のイベントは定期的に人手レビュー。LLM は「ユーザーの一方的な主張」も抽出します。業務側で
confidence=LOW+disputeFlag=trueでフィルタリングし、確認することを推奨。 - 重要な業務フローは API 書き込みと併用。注文システムなどに既に構造化データがある場合、
createdBy=APIで直接書き込む方が LLM に対話から抽出させるより正確です。LLM 抽出結果と共存可能です。 - MERGE 操作は慎重に。LLM は時にマージすべきでないイベントをマージしてしまうことがあります。実行記録で MERGE 操作に注目し、必要に応じて API で分割復元してください。
entitiesフィールドを活用する。抽出ルールで LLM に重要な KV(金額、注文番号、時刻など)の抽出を明示的に要求すれば、後続で構造化クエリが直接可能となり、summary テキストを解析するより信頼できます。
⚠️ トラブルシューティングチェックリスト
| 現象 | 確認パス |
|---|---|
| イベントが抽出されない | ① メインスイッチが ON か ② Bot にクレジット残高があるか ③ 実行記録に FAILED があるか ④ 抽出ルールが厳しすぎないか |
| 特定タイプの重要イベント内容が空 | ① そのユーザーに該当タイプのイベントがあるか ② 該当タイプのイベントが正しく作成されているか ③ 分類名のスペルが一致しているか |
| ユーザー間の混在 | 正しい userId が渡されているか確認。未ログインユーザーの場合は anonymousId が安定しているか確認 |
| 抽出費用が高め | ① 抽出頻度を下げる ② より安価な抽出モデルに切り替える |
| 抽出結果の分類が乱れる | ① 分類により正確な説明を付ける ② 抽出ルール欄に複数の few-shot 例を記述 |
七、機能の境界と注意事項
- 抽出はリアルタイムではありません。Level 1 のリアルタイムトリガーであっても、メッセージが閾値に達してから抽出されます。厳密な強整合性が要求される業務(取引など)はイベントストリームに依拠して判断すべきではありません ── イベントは補助的な記憶であり、真理の源ではありません。
- 抽出ウィンドウは最大 100 件(
MAX_MESSAGES_PER_BATCH)。超長会話は複数ウィンドウに分割して処理され、ウィンドウ間の因果関係は「過去イベント比較」によって呼び戻されます。 - イベント照会には 500ms タイムアウト保護があります。スロークエリがチャットチェーンを遅延させることはありませんが、極端な場合にはイベント注入が行われないことがあります。
- 匿名 ID は端末でクリア後にリセットされます。匿名ユーザーがデバイスを切り替えたりキャッシュをクリアしたりすると新規ユーザーとして扱われ、イベントは引き継がれません。
- multi-agent モードではイベントストリームは関与しません(oversea-ailab CLAUDE.md の廃止宣言を参照)。
