Multiple Dialog (多輪對話) - Slides
智慧客服:
- 要了解上下文 -> Multi-Turn Dialogue
- 盡量不要把過去太久的記憶忘掉 -> Context Compaction
動機: 上下文理解
使用者在詢問時容易出現
turn 1: 「我想找餐廳」
turn 2: 「它的電話是多少?」 ← 「它」是誰?不看前文就完全不知道
這就是單輪對話系統,每輪都是全新對話,沒有記憶
多輪對話?
希望可以解決這種 指代消解、上下文依賴 的問題
turn 1: 「我想找餐廳」
turn 2: 「它的電話是多少?」 ->「餐廳的電話是多少」
但是若不好好管理上下文,會遇到 Context Rot (上下文腐爛) 的問題
Context Rot = 上下文腐爛
LLM 對較早以前、不相關的資訊的注意力會下降
導致回覆品質退化的現象
Context Rot (上下文腐爛)
當輸入給 LLM 的 context 越來越長時,模型對這些內容的利用不是均勻的。
表現會逐漸變得不穩,資訊抓取、理解與推理精度會下降。
參考:Chroma|Context Rot
所以我們不能一股腦地把所有上下文都給 LLMs
應該要做取捨
一般做法:
把所有對話歷史塞進 context → context rot 嚴重
進階: select → write → compress → isolate
目前預想:
topic shift 偵測到 → 把舊 segment 壓縮存進 DB
→ context 只保留當前 segment
→ 需要時再從 DB 撈 → 避免 context rot
=> 先理解多輪對話長什麼樣,再談怎麼壓縮
多輪對話的類型
依語言行為分:
| 類型 | 說明 |
|---|---|
| Single-topic | 整段只討論一件事 |
| Multi-topic | 對話中途換主題 ← 研究重點 |
| Goal-shifting | 目標完全翻轉 |
→ 最有挑戰性的是 topic shift
為什麼 Multi-topic 難?
turn 1: 「我想找餐廳」
turn 2: 「營業時間?」
turn 3: 「附近有什麼景點?」 ← topic 換了
turn 4: 「景點評分?」
turn 5: 「那餐廳電話是多少?」 ← 又跳回 turn 1
- Context window 只記得最近幾輪(景點)
- 找不回 turn 1 的餐廳
- 不能單純截斷,也不能全部塞
方法脈絡
Context tracking
= 持續維護「目前有效的工作脈絡」
ReSum - Unlocking Long-Horizon Search Intelligence via Context Summarization
= 比較偏 context summarization / compressed reasoning state
定期把長軌跡摘要成緊湊狀態
讓 agent 可以在 context budget 有限下繼續推進。
Thread Labels (線索標籤) - Thread Detection
幫每一條子對話 / 子任務貼上的標籤
=> 用來分辨「現在這句是在接哪一條線」
同一個 session 裡,可能同時有多條線在跑:
- 線 A:查包裹
- 線 B:帳號登入
- 線 C:付款問題
這時每一句話都不一定是在接上一句,
而可能是在接回前面某一條尚未結束的 thread
U1: 我要查包裹進度 [Thread A]
U2: 另外我帳號登入不了 [Thread B]
U3: 那這個可以重設嗎 [Thread B]
U4: 包裹是 DHL 的 [Thread A]
資料集
Dataset - ZYS - Topic shift 相關
- 505 筆銀行客服電話紀錄,人工標註 topic segmentation
- 特色:中文 task-oriented,domain 是金融客服
- 評估:Pk、WindowDiff
- 缺點:domain 限定在銀行,不夠廣
call_id_0 ← 對話 ID
0 坐席:... ← segment label + 說話者 + 內容
1 客户:... ← segment label 換了 → topic boundary 在這裡
1 坐席:...
1 客户:...
2 客户:... ← segment label 換了 → 又一個 boundary
2 坐席:...
LongMemEval - 長記憶
多 session、多輪 user-assistant 互動
跨 session 本來就在討論不同事,不存在 topic shift 概念
而是「答案在哪個 session」的檢索任務
-> 適合評估有沒有找到對應記憶
A: 你有幾份工作?
B: 我有兩份,很累
A: 我剛看完一部恐怖片 ← 突然換題,沒有前文鋪墊
B: 我比較喜歡看書,今年看了20本
A: 你養寵物嗎? ← 又換題
核心技術
| # | 技術 | 做什麼 |
|---|---|---|
| 1 | Rewrite / Coreference | 補全當前句子 |
| 2 | Context Compression | **壓縮舊脈絡 ** |
| 3 | Thread Labels | 決定這句接哪條線 |
| 4 | Turn-level State Tracking | 每輪更新 state |
| 5 | Segment-level State Tracking | 各 segment 各自維護 |
| 6 | Retrieval Memory | 需要時再撈舊內容 |
| 7 | Long-term Memory | 使用者偏好、身份 |
→ Context Compression ?
上下文壓縮 是什麼
用戶:問餐廳
用戶:問景點
用戶:問酒店
用戶:「那餐廳的電話是多少?」 ← 跳回第一個 topic
挑戰在於:
- 純 sliding window 會忘記餐廳(被擠出 context)
- 純摘要 會丟失細節(電話號碼這種具體資訊摘掉就沒了)
- 所以需要有結構的壓縮策略
Context 壓縮方法
避免 context 無限增長的策略:
- Summary — 把舊對話摘要成幾句
- Structured summary — 結構化欄位(entity / slot / value)
- Key facts — 只保留關鍵事實
- State snapshot — 當前 belief state 快照
所以為什麼需要多輪對話呢?
| 做法 | 優點 | 缺點 |
|---|---|---|
| Sliding window | 簡單 | 忘掉舊 topic |
| 摘要 | 不爆 context | 丟失細節 |
| ⭐Segment-based 壓縮 | 各 topic 獨立保留 | 需要準確的 boundary |
當我們取用記憶時,只取用當前那個 Thread
→ 關鍵在於知道什麼時候 topic 換了,才能切得漂亮
對話流
↓
[Topic Shift Detection] ← 偵測換題點
↓
切成 segments
↓
每個 segment 獨立壓縮 → 存進 DB
↓
當前 context 只保留必要部分
↓
需要時從 DB 撈回對應 segment
segment A:餐廳
turn 1: 「我想找餐廳」
turn 2: 「營業時間?」
─────── [Topic Shift 偵測到] ───────
segment B:景點
turn 3: 「附近有什麼景點?」
turn 4: 「景點評分?」
→ 當前 context 只留 segment B(景點),舊的餐廳細節不佔 context
新問題:「那餐廳電話是多少?」
和景點無關
segment B:景點
turn 3: 「附近有什麼景點?」
turn 4: 「景點評分?」
─────── [Topic Shift 偵測到] ───────
turn 5: 「那餐廳電話是多少?」
turn 5 跳回舊 topic:
去把原本的主題撈回來,這是目前的 segment:
turn 1: 「我想找餐廳」
turn 2: 「營業時間?」
turn 5: 「那餐廳電話是多少?」
論文實作?
方法:Def-DTS
Def-DTS(ACL 2025 Findings)
Dialogue Topic Segmentation (DTS)
不 train classifier,直接用 LLM 推理:
**前文摘要(前面兩句話)** + 當前 utterance + **後文摘要(後面三句話)**
↓
LLM 判斷 intent
↓
intent ∈ {INTRODUCE_TOPIC, CHANGE_TOPIC}
↓
topic shift = YES
→ Prompting 策略取代 supervised training
( 但不適用,主要是 offline, 不是 online )
方法:DH-RAG
DH-RAG (2025)
把歷史存成 (query, passage, response) 三元組
- 查詢時:外部知識 + 對話記憶 同時查
- 動態淘汰:
- score 低於某個 threshold → 從記憶庫移除
Relevance(相關性) + Recency(新鮮度)
- score 低於某個 threshold → 從記憶庫移除
History 不是 prompt 固定內容,而是可檢索的記憶
現在這一輪,要怎麼用對話歷史把資料找得更準?
方法:MemGPT
MemGPT - Towards LLMs as Operating Systems
= 比較偏 memory architecture / external memory management
用分層記憶與虛擬 context management
把部分資訊移到外部或較慢的記憶層,不讓所有內容都塞在當前 context window整個 agent 長期運作時,要怎麼管理記憶,避免 context 爆掉?
方法:使用 Sub-Agent
Context-1
可把檢索、脈絡維護、摘要等工作拆給子代理處理
query decomposition
→ iterative search
→ self-editing context
→ 交給下游模型作答
研究方向
| 元件 | 核心 |
|---|---|
| Topic Shift Detection | 在 online 設定下找換題點 |
| Segment-based Memory | 依 topic 切分壓縮 |
| Cross-topic Retrieval | 跳 topic 時觸發記憶撈回 |
目標:讓長對話不會因為 context rot 而失效
總結
單輪對話問題(指代)
↓
多輪對話(塞 context)
↓
Context Rot(失焦)
↓
需要壓縮 + 取捨
↓
Topic Shift Detection
+ Segment-based Compression
↓
長對話仍維持穩定表現