今天要來探索 AI 的記憶係統是怎麼實現的
我們都知道 AI 一次可以讀取的 Prompt 長度是有最大限制的
所以才發展出了 RAG, Prompt 優化檢索這一類的技術
目的就是為了解決讀取超出 Context Length 長度的技術問題
上面這張圖是 Grok 的 Maximum Context Length 長度
下面這張是 OpenAI 不同模型的 Context Length 長度比較
於是乎, AI 到達 Max Context 的時候
就無法再繼續處理你的資訊了
如果你的內容對話非常非常的龐大, 如果是無限制的不斷聊天
不管怎麼樣, 總有一天會到達極限
所以我們需要額外處理 AI 的記憶係統
在 ChatGPT 免費版的處理方式
可以看到它額外的把聊天的對話內容抽出來,
保存了一個長期記憶的系統
但是免費版還是會額滿, Pro 版本就不會:
除了 ChatGPT 官方的解決方法之外
其實也有一些公司跳出來解決這個問題
比較知名的是 Mem0.ai
專門提供記憶係統給開發者進行串接:
但仔細思考原理之後,
其實自己也可以設計一套自己的 AI 記憶係統
就跟人類的記憶運作差不多
我們也不可能記得所有的事情,
只會記得近期發生 + 重要的事
當有需要用到的時候, 再回想, 或是翻看當時的日記
所以我們可以偷偷壓縮篡改每次餵給 AI 的 Context Length
(這也就是為什麼人類的記憶不可靠, 因為大腦會偷偷修改來節省空間)
舉個例子, 下面是一個模擬 AI 對話的 Json Prompt:
[
{
"role": "user",
"content": "我今天吃了漢堡和薯條,覺得超級好吃。"
},
{
"role": "assistant",
"content": "聽起來很不錯!你平常喜歡吃速食嗎?"
},
{
"role": "user",
"content": "我不常吃,不過今天心情很好,就想犒賞自己。"
},
{
"role": "assistant",
"content": "了解~偶爾吃點喜歡的食物是種慰勞方式。"
},
{
"role": "user",
"content": "我的名字叫小明,我今天遇到了一隻流浪貓,看起來很餓。"
},
{
"role": "assistant",
"content": "你有幫牠做什麼嗎?"
},
{
"role": "user",
"content": "有,我給牠一點牛奶和餅乾,牠看起來開心多了。"
},
{
"role": "assistant",
"content": "你真溫暖,小明。那隻貓一定很感謝你。"
},
{
"role": "user",
"content": "我最近在學 Unity,用它開發一個小遊戲。"
},
{
"role": "assistant",
"content": "太棒了!是什麼類型的遊戲?"
},
{
"role": "user",
"content": "有點像動作冒險遊戲,玩家需要探索地圖,打敗怪物。"
},
{
"role": "assistant",
"content": "聽起來很酷,你打算上架到哪個平台?"
},
{
"role": "user",
"content": "我想先上 Steam 試試看。"
},
{
"role": "user",
"content": "我昨天心情有點低落,因為工作壓力太大了。"
},
{
"role": "assistant",
"content": "辛苦了。最近的工作發生了什麼嗎?"
},
{
"role": "user",
"content": "專案一直延期,團隊也有點混亂,我覺得自己沒辦法放鬆。"
},
{
"role": "assistant",
"content": "理解,面對壓力時,別忘了照顧自己的狀態。"
}
]
假設我們設定現在已經差不多快抵達 Context Length 了
那我們接下來可以對這個對話進行壓縮
變成這樣:
[
{
"role": "system",
"content": "使用者名為小明,是個溫暖且感性的人。近期因工作壓力感到低落與疲憊,但仍持續學習 Unity 開發動作冒險遊戲,計畫上架 Steam。平時不常吃速食,但在心情好時會以漢堡薯條犒賞自己。曾幫助一隻飢餓的流浪貓,展現出善良與同理心。整體人格特質:創造力強、富有同情心、對自我要求高。"
}
]
當然, 為了不要顯得不太自然, 我們可以保留最新的3筆對話內容
或是一些你認為比較重要的系統資訊, 就不進行壓縮更改:
[
{
"role": "system",
"content": "使用者名為小明,是個溫暖且感性的人。近期因工作壓力感到低落與疲憊,但仍持續學習 Unity 開發動作冒險遊戲,計畫上架 Steam。平時不常吃速食,但在心情好時會以漢堡薯條犒賞自己。曾幫助一隻飢餓的流浪貓,展現出善良與同理心。整體人格特質:創造力強、富有同情心、對自我要求高。"
},
{
"role": "user",
"content": "我昨天心情有點低落,因為工作壓力太大了。"
},
{
"role": "assistant",
"content": "辛苦了。最近的工作發生了什麼嗎?"
},
{
"role": "user",
"content": "專案一直延期,團隊也有點混亂,我覺得自己沒辦法放鬆。"
}
]
然後當 Context Length 持續變超長的時候,
我們就繼續進行壓縮, 來實現無限長的記憶對話係統。
壓縮的方法, 就是把這段餵給 AI, 請它來幫忙壓縮 ~
但是這樣壓縮, 還是會有資料遺失的風險
如果這些對話內容或資訊是非常重要的
建議在壓縮之前, 完整的把這些內容都儲存在資料庫之中
日後有什麼需要的時候也可以再調用出來查看。
但是不管怎麼壓縮, 感覺總有一天 …
還是會壓縮不完, 那怎麼辦 ?
我們可以使用之前學到的 RAG 檢索技術
把所有的對話資訊, 透過程式自動整理成 Txt 或是 PDF 檔案
上傳到 OpenAI 的 Vector 資料庫之中
這樣一來, 當使用者提問問題的時候
就會在這份記憶文檔之中找出對應的片段, 塞到 Context 裡面去
再進行回答。
事實上, 還有許多有趣的記憶機制可以繼續自由的發揮
像是可以加上記憶權重的衰退(Memory Decay), 如果長期沒有提到這個關鍵詞
我們可以把這段記憶慢慢的衰退遺忘掉等等 …
不過這樣一來, 基本上就可以解決 80% 的記憶問題了