logo
開發者文件
搜尋
關鍵事件

一、什麼是「關鍵事件」

「關鍵事件」是 GPTBots 內建的長程業務記憶能力:在用戶與 Bot 多輪對話過程中,平台會調用 LLM 自動從對話裡識別出有業務價值的事件(如取款、投訴、預約、退款……),按用戶維度結構化儲存下來,並在後續對話中作為上下文回注給 Bot,讓 Bot「記得」這位用戶過去發生了什麼、當前事件處理到哪一步。

解決的核心問題是:

  • 跨會話記憶缺失:傳統 LLM 只能看到當前會話的短期記憶視窗,跨會話或長會話中關鍵業務動作被遺忘。
  • 結構化資料沉澱:把零散對話沉澱為可查詢、可統計、可稽核的事件流,供風控、客服質檢、用戶畫像複用。
  • 狀態推進追蹤:每條事件有 PENDING / IN_PROGRESS / RESOLVED / CLOSED 狀態,能夠在多次對話間持續推進。
    alt text

二、設計理念

1. 把「對話」沉澱為「事件流」

對話是非結構化的,事件是結構化的。關鍵事件把「用戶說過什麼、做過什麼」翻譯成「分類 + 摘要 + 實體 + 狀態 + 優先級 + 置信度」的事件記錄,讓 LLM 之外的下游系統(統計、風控、人工質檢)也能消費這份記憶。

2. 雙軌觸發,避免漏抓也避免狂抓

單次對話裡事件可能在中途出現,也可能在用戶離開之後才需要補抽。系統採用訊息閾值(即時)+ 空閒逾時(批次)+ 手動觸發(兜底)的三級方案,開發者可調參數權衡成本與時效。

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 唯一) 控制開關、閾值、提取規則
會話級提取狀態 記錄待抽訊息數、空閒時間、並發狀態
提取執行記錄 每次抽取的稽核 + 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 秒一輪) │ │ 命中條件: │ │ - lastMessageTime > idleTimeout 前 │ │ - pendingMessageCount > 0 │ │ - extractionStatus == IDLE │ └──────────────────────────────────────┘ ┌── Level 3:手動觸發 ─────────────────┐ │ 調 API: │ │ POST /bot/event/execute/.../retry │ │ 或在執行記錄頁點「重試」 │ └──────────────────────────────────────┘
                      
                      ┌── Level 1:即時觸發 ─────────────────┐
│ 每條用戶訊息 +1 計數                 │
│ pendingMessageCount ≥ messageThreshold │
│ 立即調 LLM 抽取                      │
└──────────────────────────────────────┘
┌── Level 2:空閒觸發 ─────────────────┐
│ 定時掃描(30/60/300 秒一輪)         │
│ 命中條件:                           │
│   - lastMessageTime > idleTimeout 前 │
│   - pendingMessageCount > 0          │
│   - extractionStatus == IDLE         │
└──────────────────────────────────────┘
┌── Level 3:手動觸發 ─────────────────┐
│ 調 API:                             │
│   POST /bot/event/execute/.../retry  │
│ 或在執行記錄頁點「重試」             │
└──────────────────────────────────────┘

                    
此代碼塊在浮窗中顯示

三個入口最終都會進入同一個 pipeline(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
                      
                      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
                      
                      ## 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}} ← 僅注入「投訴」類事件
                      
                      {{key_event_withdrawal}}     ← 僅注入「取款」類事件
{{key_event_complaint}}      ← 僅注入「投訴」類事件

                    
此代碼塊在浮窗中顯示

平台按 eventType 分組產生對應變數,未匹配的事件類型不會被注入。最多注入 30 條 / 變數。

Flow Bot:元件級獨立控制

工作流的每個 LLM 節點都有自己的 FlowKeyEventConfig:可單獨開關、單獨選事件類型、單獨設 recentEventCount(預設 5 條)。同一會話內事件只查一次(快取在 ChatContext),多個節點共享資料。


四、使用指南

4.1 在 Bot 配置面板啟用

進入路徑:開發者控制台 → Bot 詳情 → 用戶管理(User Manage) → 「關鍵事件」抽屜

操作步驟:

  1. 開啟總開關
  2. 提取模型:可選項;不選時使用 Bot 預設對話模型。建議選一個便宜模型(例如 GPT-4o-mini / Haiku 系列)。
  3. 提取規則(≤2000 字元):用自然語言告訴 LLM 這個 Bot 場景下「什麼算關鍵事件」。例:
    只抽取與資金相關的業務動作(取款、存款、轉帳、退款)。 忽略閒聊和情緒表達。 實體欄位必須包含金額(amount)、幣種(currency)、訂單號(orderId)。
                          
                          只抽取與資金相關的業務動作(取款、存款、轉帳、退款)。
    忽略閒聊和情緒表達。
    實體欄位必須包含金額(amount)、幣種(currency)、訂單號(orderId)。
    
                        
    此代碼塊在浮窗中顯示
  4. 最近事件數(050):每次對話注入 Prompt 的事件數。0 表示不注入,常見 510。
  5. 觸發時機
    • 訊息閾值(5~50):預設 10。
    • 空閒逾時(2~60 分鐘):預設 3。
  6. 事件分類字典(最多 10 個):每個分類含「名稱」(≤10 字)和「描述」(≤100 字,告訴 LLM 這個分類裝什麼)。
  7. 點儲存。

⚠️ 警告:分類名一旦上線就不要隨意改名 —— 歷史事件依然存的是舊名字,會出現 {{key_event_<舊名>}} 取不到值的情況。前端在分類已存在時會彈出橙色警示。

4.2 在 Prompt 中引用事件

通用 Bot Prompt

你是一個資金客服助手。 【該用戶最近的資金動作】 {{key_event_withdrawal}} 【該用戶最近的投訴】 {{key_event_complaint}} 請基於上述上下文回答用戶問題。
                      
                      你是一個資金客服助手。

【該用戶最近的資金動作】
{{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 爭議 跨會話追蹤資金動作;風控與人工坐席接管時一眼看到該用戶的歷史業務流
電商售後 refund 退款 / return 退貨 / complaint 投訴 自動維護用戶售後狀態機,多次對話中持續推進
預約 / 排程 appointment 預約 / cancellation 取消 讓 Bot 記得用戶改過幾次時間、當前確認的是哪個時段
HR / 內部 IT 助手 leave_request 請假 / it_ticket 工單 把對話沉澱為可查詢的工單流
教育 / 學習陪伴 homework_submission / quiz_score / weak_topic 長期記錄學生學習狀態,產生個人化複習計畫
醫療 / 健康諮詢 symptom 症狀 / medication 用藥 / appointment 複診 跨次諮詢保留病程資訊,提升問診連貫性

六、最佳實踐

✅ 配置層

  1. 分類字典寫描述——name + description 都要填。LLM 主要靠 description 判斷「這條對話是不是這個分類」。description 留空會顯著降低分類準確率。
  2. 分類數量控制在 5~10 個。太多會讓 LLM 抽取時糾結歸類,且 Prompt 體積膨脹。同義類合併(「取款」 和 「提現」 用一個)。
  3. 抽取規則要寫「做什麼」也要寫「不做什麼」。例如:
    只抽取已確認完成或正在進行的業務動作。 排除:假設性討論(「如果...怎麼辦」)、純情緒、閒聊。
                          
                          只抽取已確認完成或正在進行的業務動作。
    排除:假設性討論(「如果...怎麼辦」)、純情緒、閒聊。
    
                        
    此代碼塊在浮窗中顯示
  4. 抽取模型選小不選大。抽取是結構化輸出任務,對推理能力要求低。GPT-4o-mini / Claude Haiku / DeepSeek-V3 通常夠用,單次成本可比主對話模型低一個數量級。
  5. 不要一開始就把 recentEventCount 拉滿。注入太多事件會擠占主對話上下文。從 5 起步,發現 Bot 經常「想不起來」再加。

✅ 觸發參數

  1. 長會話 / 客服場景messageThreshold = 10idleTimeoutMinutes = 3 一般合適。
  2. 短互動 / 任務型 Bot:把 idleTimeoutMinutes 調到 2,避免用戶對話結束後事件抽取遲遲不發生。
  3. 高頻低價值對話(如普通問答)messageThreshold 提到 20~30,避免每輪都跑 LLM 抽取燒成本。

✅ Prompt 引用

  1. 優先用佔位符而不是依賴自動追加。佔位符可控、可按類型精確切片,自動追加適合「什麼都想要」的兜底場景。
  2. Flow Bot 中不要每個節點都啟用。只在真正需要事件上下文的節點(如客服回覆節點、風控判斷節點)啟用,意圖識別 / 路由節點沒必要。
  3. 避免 {{key_event_xxx}} 出現在系統級 Prompt 頂部——歷史事件往往會隨時間增長,如果它撐爆 Token,主指令會被截斷。建議放在 Prompt 中段或 Few-shot 之前。

✅ 資料治理

  1. 定期人工 review LOW 置信度事件。LLM 把「用戶單方聲稱」的內容也會抽出來,業務方應該過濾一遍——可以按 confidence=LOW + disputeFlag=true 篩查。
  2. 重要業務流配合 API 寫入。如訂單系統已經有結構化資料時,直接 createdBy=API 寫入比讓 LLM 從對話裡抽取更準確,與 LLM 抽取結果共存。
  3. MERGE 操作小心使用。LLM 偶爾會把不該合併的事件合併掉。建議在執行記錄裡關注 MERGE 類操作,必要時透過 API 拆分恢復。
  4. 善用 entities 欄位。在抽取規則裡明確要求 LLM 抽出關鍵 KV(金額、訂單號、時間等),後續可直接結構化查詢,比解析 summary 文字可靠。

⚠️ 排查清單

現象 排查路徑
事件沒抽出來 ① 總開關是否開 ② Bot 是否有積分餘額 ③ 執行記錄是否有 FAILED ④ 提取規則是否過嚴
某類型關鍵事件內容為空 ① 該用戶是否有該類型事件 ② 是否正確建立該類型的事件 ③ 分類名拼寫是否一致
跨用戶串擾 檢查是否傳了正確的 userId;如未登入用戶,檢查 anonymousId 是否穩定
抽取費用偏高 ① 降低提取頻率 ② 切換更便宜的提取模型
抽取結果亂歸類 ① 給分類更準確的描述資訊 ② 在提取規則欄裡給若干 few-shot 範例

七、能力邊界與注意事項

  • 抽取不是即時的。即使是 Level 1 即時觸發,也是在訊息累計到閾值後才抽。嚴格強一致的業務(如交易)不能依賴事件流來下決策——事件是輔助記憶,不是真理之源。
  • 抽取視窗最多 100 條訊息MAX_MESSAGES_PER_BATCH)。超長會話被切成多個視窗處理,跨視窗的因果關係靠「歷史事件比對」召回。
  • 事件查詢有 500ms 逾時保護。慢查詢不會拖慢聊天鏈路,但極端情況下會無事件注入。
  • 匿名 ID 在端清理後會重置。匿名用戶切換裝置 / 清快取後視為新用戶,事件不會跟隨。
  • multi-agent 模式下事件流不參與(參見 oversea-ailab CLAUDE.md 的廢棄聲明)。