🎯 什麼情境該想到我
當你「做的聊天機器人對話一長,就忘了前面發生的事或使用者講過的細節」的時候。
⚙️ 怎麼用(步驟 / 公式)
先認清問題:模型不是記性不好,是那段文字根本沒送進去——超過 context 上限的舊訊息被截掉了。「長期記憶」在工程上的意思是:用更便宜的形式,把放不下的過去重新塞回這一次的 prompt。
三層各治一種遺忘,互補不替代:
| 層 | 做法 | 治什麼 | 保真度 | token 成本 |
|---|---|---|---|---|
| 1. 滾動摘要 | 每 N 則用 LLM 把舊對話壓成摘要 | 整體脈絡丟失 | 低(有損) | 低 |
| 2. 向量召回 | 訊息做 embedding,生成前用語意找回原文 | 特定細節丟失(「我生日 3/15」) | 高(原文) | 中 |
| 3. 外部知識庫 | 上傳文件分塊向量化,生成前查詢 | 角色缺對話以外的背景知識 | 高 | 可能很高 |
1. 滾動摘要
- 觸發:距上次摘要滿 N 則(SillyTavern 預設 10)。
- ★ 要把上一次的摘要一起餵進去:摘要 A(1–10)→ 摘要 B(A+11–20)→ 摘要 C(B+21–30)。整段歷史就累積壓縮在一段固定長度的文字裡。只看最近 10 則的話,新摘要會忘掉更早的事。
- 摘要別存在最後一則訊息上:最後一則可能被重新生成,摘要會跟著被覆蓋。
2. 向量召回
- 寫入:用 hash 比對找出新增/刪除的訊息(不必全量重算),長訊息切成約 400 字元,再做 embedding。
- 查詢:拿最近 2 則當查詢文字,丟掉相似度低於門檻(0.25)的結果,最多取 3 則注入。
- ★ 最近 5 則永遠保留原位,不被召回結果取代,對話才連貫。
- 換 embedding 模型等於換一套索引,不同模型的向量不能混比。
3. 外部知識庫
- 約 2500 字元分塊,取前 5 塊。作用域分全域/角色/單一聊天三層。本質上是以角色為中心的 RAG(見 工具-RAG檢索增強生成)。
★ 寫入和讀出分開兩個時機:摘要、embedding 掛在「新訊息進來」時做(貴的先做掉),召回掛在「生成請求」時做(只查詢,便宜)。生成路徑因此不會被拖慢(推測)。
怎麼選:短對話都不用。長對話先上摘要(最便宜);使用者開始抱怨「忘了我講過的細節」再加向量;角色需要讀文件才加知識庫。三層都要跟 工具-長對話的Token預算分配 一起算帳。
機制細節 → 長期記憶三層架構
🧪 我實際套用的紀錄
- (尚無)
⚠️ 注意 / 什麼時候不適用
- 摘要會漂移(推論):每次都是舊摘要再壓一次,早期的錯誤會被一路繼承。重要事實不要只靠摘要,允許人工修正並凍結。
- 摘要要多花一次 LLM 呼叫:產品化時通常改成非同步、用便宜模型(我的判斷)。
- 向量只看語意、不看時序和真偽(推論):可能撈回已經被後續劇情推翻的舊話(「我不喜歡你」後來已經和好)。
- 查詢文字太短就撈不到東西(推論):最近兩句是「嗯」「然後呢」時,查詢語意太弱。
- 知識庫很吃 token:5 塊 × 2500 字元,一次就可能上萬字元。
🔗 相關工具
- 長期記憶三層架構 —— 參數、儲存位置、觸發時序的完整說明
- 工具-RAG檢索增強生成 —— 第 2、3 層的通用版;這張講的是「對話記憶」這個特定用途
- 工具-長對話的Token預算分配 —— 記憶是用來補預算切掉的部分,兩者要一起設計
- 工具-關鍵字觸發的設定注入 —— 另一種按需載入:用字面觸發,不用語意