一、MemGPT概述
當前,大型語言模型(LLMs)在處理擴展對話和文檔分析等任務時受到有限上下文限制,限制了它們在擴展對話和文檔分析等任務中的能發(fā)揮的作用。如何讓大語言模型擁有更強的上下文處理能力是業(yè)界非??粗氐臒狳c主題之一。
對此,UC Berkeley的研究者提出了一種虛擬上下文管理技術(shù),這種技術(shù)從傳統(tǒng)操作系統(tǒng)中汲取靈感,通過對快速和慢速內(nèi)存之間數(shù)據(jù)的管理,使得 LLMs 能夠在有限的上下文窗口中有效使用擴展上下文。并由此引出一個智能管理不同內(nèi)存層級的系統(tǒng)MemGPT。
MemGPT 的設(shè)計靈感來自傳統(tǒng)操作系統(tǒng)的層次內(nèi)存管理,它能夠在“內(nèi)存”(類似于操作系統(tǒng)中的內(nèi)存)和外部存儲之間移動信息。MemGPT 管理內(nèi)存管理、LLM 處理模塊和用戶之間的控制流。這種設(shè)計允許在單個任務中進行重復的上下文修改,使代理能夠更有效地利用其有限的上下文。
MemGPT 在兩個場景進行了評估:文檔分析和多會話聊天。在文檔分析場景,MemGPT 能夠分析遠遠超出基礎(chǔ) LLM 上下文窗口的大型文檔。在多會話聊天場景,MemGPT 可以創(chuàng)建記憶、反思和動態(tài)演變的對話代理,通過與用戶的長期互動獲取長期記憶。
二、MemGPT構(gòu)成

MemGPT 的設(shè)計包括幾個關(guān)鍵組件,這些組件共同支持其在處理擴展對話和文檔分析任務時動態(tài)管理和使用擴展上下文的能力:
1. 主上下文(Main Context)
- 這是模型可以直接訪問和操作的內(nèi)存區(qū)域。它類似于計算機的 RAM,并且受到模型的最大令牌限制。MemGPT的主上下文可以簡單的看成是一個消息流FIFO隊列,外加存儲用戶上下文、LLM角色上下文的Memory。
2. 外部上下文(External Context)
- 這是一個更大的存儲區(qū)域,用于存儲不立即需要但可能在將來需要的信息。它類似于計算機的硬盤存儲。在MemGPT中包含recall memory、archival memory
| 類型 | 說明 |
|---|---|
| recall memory | 持久化的歷史交互上下文 |
| archival memory | 可以是交互中的上下文,也可以是外部載入的數(shù)據(jù)、文檔等 |
3. 函數(shù)調(diào)用
- MemGPT 提供了一組函數(shù),允許模型執(zhí)行特定的內(nèi)存管理任務,如從外部上下文檢索信息或更新主上下文。通過在prompt里面指導LLMs去使用這些函數(shù)來達到自主更新上下文、搜索上下文、向用戶發(fā)送消息等目的。
- 例如在多會話聊天場景,LLMs可以使用以下函數(shù)
| 函數(shù) | 說明 |
|---|---|
| send_message | LLM向用戶發(fā)送消息 |
| core_memory_append | 新增當前交互會傳遞的上下文 |
| core_memory_replace | 編輯當前交互會傳遞的上下文,如將用戶的名字從“John”修改為“Mike” |
| conversation_search | 搜索recall memory歷史 |
| conversation_search_date | 時間范圍條件搜索recall memory歷史 |
| archival_memory_insert | 往已歸檔的memory新增數(shù)據(jù) |
| archival_memory_search | 從已歸檔的上下文中搜索數(shù)據(jù) |
4. 內(nèi)存管理算法
- 用于內(nèi)存管理,確定何時和如何在主上下文和外部上下文之間移動信息。
- 例如在發(fā)送給LLMs達到token上限時,按一定的規(guī)則將core memory送給LLMs作總結(jié)并替換掉
- 再比如當LLMs需要找不到所需上下文時通過調(diào)用相關(guān)function從recall memory、archival memory搜索到所需上下文并加入到core memory
5. 控制流管理
- MemGPT 能夠管理與用戶的交互流程,確定何時接收輸入,何時提供輸出,以及何時執(zhí)行內(nèi)存管理任務。讓我們看看相關(guān)的核心流程:
async def step():
try:
# Step 0: add user message
packed_user_message = {'role': 'user', 'content': user_message}
input_message_sequence = self.messages + [packed_user_message]
# Step 1: send the conversation and available functions to GPT
response = await get_ai_reply_async(model=self.model, message_sequence=input_message_sequence, functions=self.functions)
# Step 2: check if LLM wanted to call a function
# (if yes) Step 3: call the function
# (if yes) Step 4: send the info on the function call and function response to LLM
response_message = response.choices[0].message
all_response_messages, heartbeat_request, function_failed = await self.handle_ai_response(response_message)
# Add the extra metadata to the assistant response
# (e.g. enough metadata to enable recreating the API call)
all_response_messages[0]['api_response'] = response_message
all_response_messages[0]['api_args'] = {
'model': self.model,
'messages': input_message_sequence,
'functions': self.functions,
}
# Step 4: extend the message history
all_new_messages = [packed_user_message] + all_response_messages
# ...
except Exception as e:
printd(f"step() failed\nuser_message = {user_message}\nerror = {e}")
# If we got a context alert, try trimming the messages length, then try again
if 'maximum context length' in str(e):
# A separate API call to run a summarizer
await self.summarize_messages_inplace()
# Try step again
return await self.step(user_message, first_message=first_message)
else:
raise e

舉個實際交互的例子
| MemGPT | assistant/LLMs | user | 說明 |
|---|---|---|---|
| pre-prompt | |||
| [send_message]Hi, is anyone there? | |||
| [send_message]Hello! I'm Sam, your new virtual companion. How can I assist you today? | |||
| my name is john, I took the day off today, my mom Brenda baked me a birthday cake. It was my favorite chocolate lava! | |||
| [send_message]Happy birthday, John! It sounds like you had a wonderful day off. How was the chocolate lava cake? Did you enjoy it? | |||
| sure, but, my name is mike | |||
| [send_message]Oops, I apologize for the confusion, Mike! Happy belated birthday. How was the chocolate lava cake? I hope it was absolutely delicious! | |||
| sure, do you remember that time when i talk about my mom with you | |||
| [conversation_search]query: mom | LLM嘗試從外部上下文歷史記錄中搜索 | ||
| [conversation_search] reutn "my name is john, I took the day off today, my mom Brenda baked me a birthday cake. It was my favorite chocolate lava!" | |||
| what is my name | |||
| [core_memory_replace] update name from Chad to Mike | LLMs發(fā)起記憶修正 | ||
| core_memory_replace | |||
| [send_message]I apologize for the confusion, Mike! Happy belated birthday. How was the chocolate lava cake? By the way, I remember when you mentioned your mom, Brenda, baking you the cake. Such a lovely gesture! |

三、總結(jié)
對于LLMs token限制的問題,MemGPT通過提供上下文管理、上下文搜索的function,用prompt指導LLMs去進行外部上下文的調(diào)取以及上下文的管理。使得其具備以下優(yōu)點:
- 動態(tài)上下文管理:MemGPT 能夠動態(tài)管理和使用擴展的上下文,這有助于處理更復雜和連貫的對話和文檔分析任務。
- 長期記憶能力:MemGPT 可以記住和使用長期對話中的信息,提高對話的連貫性和相關(guān)性。
- 自我導向的內(nèi)存管理:MemGPT 可以自主更新和搜索其內(nèi)存,使其能夠更加智能和靈活地響應用戶的需求。
與此同時,缺點也是很明顯的
- 復雜性:MemGPT 的設(shè)計和實現(xiàn)可能相對復雜,需要更多的資源和技術(shù)支持來實現(xiàn)系統(tǒng)集成。
- 計算資源:MemGPT 需要多次跟LLMs進行交互來實現(xiàn)相關(guān)的功能,可能需要更多的計算資源來執(zhí)行動態(tài)內(nèi)存管理和其他高級功能以完成跟用戶的單次交互。
- 可解釋性:MemGPT 的上下文管理決策依賴于LLMs,可能不太容易解釋和理解。
- 局限性:MemGPT通過上下文的交換一定程度上解決了token受限的問題,但如果單次所需的上下文token超出LLMs限制,仍然會有存在這個問題。
四、參考
github:https://github.com/cpacker/MemGPT
論文:https://arxiv.org/abs/2310.08560