MemGPT | 把操作系统的虚拟内存管理搬进大模型,突破上下文窗口的天花板


这篇论文来自 UC Berkeley 的 Charles Packer、Sarah Wooders、Kevin Lin 等人,通讯作者为 Joseph E. Gonzalez 和 Ion Stoica。研究团队提出了 MemGPT(MemoryGPT)——一个借鉴操作系统虚拟内存分页机制的 LLM 记忆管理系统。核心思路很朴素:既然操作系统能通过在内存和硬盘之间来回搬运数据,让程序以为自己拥有远超物理内存容量的地址空间,那 LLM 为什么不能在有限的上下文窗口和外部存储之间做同样的事?

论文链接:https://arxiv.org/abs/2310.08560 代码:https://research.memgpt.ai

上下文窗口:大模型够不着的记忆天花板

大模型什么都好,就是「记性」不行。GPT-4 的上下文窗口只有 8192 个 token——大约能撑 140 轮对话。哪怕是 GPT-4 Turbo 的 128k,也不过 2600 轮左右。一份 SEC 年报(Form 10-K)动辄超过百万 token,远非任何现有模型能一口吞下。

更麻烦的是,直接扩展上下文窗口的代价极高。Transformer 的自注意力机制让计算量随序列长度呈二次方增长,想处理更长的文本,得付出指数级的算力。就算你有钱有卡把上下文拉到百万级,Liu 等人在「Lost in the Middle」研究中发现了一个更尴尬的事实:模型并不擅长利用超长上下文——它对开头和结尾的信息记得清楚,中间部分却经常「视而不见」。

换句话说,光靠暴力扩展上下文窗口,既贵又不好使。

那怎么办?MemGPT 的答案是不去硬改模型,而是像操作系统管理物理内存那样,在有限的上下文窗口之上构建一层「虚拟上下文」。程序不需要全部数据都在内存里才能运行——LLM 也不需要全部信息都在上下文里才能回答问题。

把操作系统的内存分页搬过来

MemGPT 的整体设计直接对标操作系统的内存管理。在传统 OS 里,程序面对的是「虚拟内存」,操作系统负责在物理内存(RAM)和硬盘之间来回搬运数据——程序要访问的数据不在内存里?触发缺页中断(Page Fault),OS 帮你从硬盘搬进来。MemGPT 对 LLM 做了同样的事:上下文窗口就是「物理内存」,外部数据库就是「硬盘」,LLM 自己通过函数调用来触发「换页」。

MemGPT 系统架构

两层记忆:主上下文当「内存」,外部存储当「硬盘」

主上下文(Main Context)就是 LLM 推理时实际能看到的 prompt token,分三段。系统指令(System Instructions)是只读的,告诉模型 MemGPT 的控制流程和函数用法。工作上下文(Working Context)是一块固定大小的可读写文本区,用来存放关键事实和用户偏好——类比操作系统里常驻内存的核心数据。最后是 FIFO 队列,存的是最近的消息历史,包括用户对话、系统消息和函数调用结果。队列的第一条消息是对已驱逐消息的递归摘要——老消息被踢出去了,但留了个「遗嘱」。

外部上下文(External Context)也分两种。「召回存储」(Recall Storage)是消息数据库,存着所有历史对话,支持按内容搜索。「归档存储」(Archival Storage)是一个支持向量搜索的数据库(底层用 PostgreSQL + pgvector),能存任意长度的文本。这两种存储的数据不在上下文窗口里,LLM 只能通过函数调用去查询和写入。

MemGPT 搜索外部数据

Queue Manager:上下文快满了怎么办

Queue Manager 负责管理 FIFO 队列和外部存储之间的数据搬运。当 prompt token 数量达到上下文窗口的 70% 时,它会往队列里插一条「内存压力警告」——提醒 LLM:你的上下文快满了,赶紧把重要信息通过函数调用存到工作上下文或归档存储里。如果模型没来得及处理,token 数量冲到 100%,Queue Manager 就直接动手,把队列里一半的消息踢出去,生成新的递归摘要。

这个过程和操作系统的内存页面置换很像。区别在于,MemGPT 会给 LLM 一个「预警期」(70% 到 100% 之间),让模型自己决定保留什么、丢弃什么——比操作系统粗暴的 LRU 策略要灵活得多。

MemGPT 收到内存压力警告后写入持久存储

函数调用:LLM 自己决定读什么、写什么

MemGPT 最精巧的设计在于:所有记忆管理操作都是 LLM 自己发起的。系统提供了一组函数(比如搜索归档存储、写入归档存储、搜索历史对话),LLM 在推理时生成函数调用,系统解析并执行。执行结果再送回 LLM,形成反馈循环。模型自主决定什么时候把信息存进归档存储,什么时候从历史对话里搜索相关内容,什么时候更新工作上下文里的用户画像。不需要人工干预。

有意思的是,MemGPT 还支持「函数链式调用」。有些任务需要连续多次查询——比如在归档存储里翻了好几页才找到需要的信息。MemGPT 允许 LLM 在函数调用中设置一个特殊标志(request_heartbeat = true),让系统在函数执行完后立即再次触发推理,而不是等用户发下一条消息。LLM 就可以一口气完成多步检索,把不同来源的信息拼凑在一起。

这套控制流的设计很关键。MemGPT 里的「事件」不只是用户消息,还包括系统消息(内存压力警告)、用户行为(登录、上传文档)和定时任务——让 MemGPT 可以在用户没说话的时候主动运行。事件驱动的架构和操作系统的中断机制如出一辙。

两个战场:对话和文档

研究团队选了两个最能体现「上下文不够用」这个痛点的场景来验证 MemGPT:多轮对话和文档分析。

深度记忆检索:准确率从 32% 跳到 93%

第一个任务是「深度记忆检索」(Deep Memory Retrieval, DMR)。基于 Multi-Session Chat(MSC)数据集,研究者让两个角色进行五轮对话,然后在第六轮问一个只有回顾之前对话才能回答的问题——测的是对话智能体的「记忆一致性」。基线模型只看到过去五轮对话的损失性摘要(类似递归摘要的压缩版),MemGPT 则可以搜索完整的对话历史。

结果差距很大。GPT-4 基线准确率只有 32.1%,加上 MemGPT 之后直接跳到 92.5%——绝对提升超过 60 个百分点。GPT-4 Turbo 的提升更夸张:从 35.3% 到 93.4%。即便是函数调用能力最弱的 GPT-3.5 Turbo,也从 38.7% 翻倍到了 66.9%。ROUGE-L 分数呈现出完全一致的趋势。

这说明一个关键事实:瓶颈不在于模型能不能理解信息,而在于信息有没有被放进上下文里。MemGPT 做的事情就是把对的信息在对的时间搬到上下文窗口中。

对话信息更新示例

对话开场白:写得比人还好

第二个任务测试的是「参与感」。一个有记忆的智能体在重新开始对话时,应该能自然地引用之前的共同经历来打招呼。研究者用角色相似度(CSIM)来评估开场白质量,对比 MemGPT 生成的开场白和人类手写的开场白。

结果显示 MemGPT 的开场白在角色匹配度上接近甚至超过了人类手写版本。研究者观察到 MemGPT 倾向于生成更详细的开场白,覆盖更多角色信息点——虽然有点「话多」,但信息量确实更丰富。而工作上下文里存储的信息是生成高质量开场白的关键。

文档 QA:上下文再长也不掉分

文档分析是另一个战场。研究者从 NaturalQuestions-Open 数据集中选了 50 个问题,用嵌入检索(embedding retrieval)选出相关 Wikipedia 文档,然后让模型基于检索到的文档回答问题。

基线模型的性能天花板受限于检索器的质量——如果嵌入搜索没把正确的文档排到前面,模型根本看不到它,再强的推理能力也没用。而 MemGPT 可以反复查询归档存储,翻页浏览更多文档,突破了「只看检索器返回的第一批结果」这个限制。

随着检索文档数量 K 的增加,基线模型因为上下文被截断导致准确率下降,而 MemGPT 的性能几乎不受影响。

文档 QA 性能对比

嵌套 KV 检索:只有 MemGPT 能做多跳查找

最精彩的实验是嵌套键值检索(Nested KV Retrieval)。研究者构建了一组 UUID 键值对,其中某些值本身也是键——要找到最终答案,必须连续查找多跳。

GPT-3.5 在 1 层嵌套时准确率就归零了——它倾向于直接返回第一个值就停下来。GPT-4 和 GPT-4 Turbo 在 3 层嵌套时也彻底失败。而 MemGPT + GPT-4 在所有嵌套层数上都保持了接近 100% 的准确率。它知道要反复查询,直到确认值不再是键为止。

嵌套 KV 检索性能

这个实验清晰地展示了函数链式调用的威力。基线模型只能「看一眼」上下文里的信息,而 MemGPT 可以反复搜索、跨数据源拼接信息——这本质上是一种 Agent 行为。不过研究团队也观察到,MemGPT + GPT-4 Turbo 的表现反而不如 MemGPT + GPT-4,在 2 层嵌套之后开始下滑。原因可能是 GPT-4 Turbo 在某些函数调用模式上不够稳定。

总结

MemGPT 的贡献可以概括为三点。一是提出了「虚拟上下文管理」的概念,把操作系统的分层内存设计引入 LLM 系统。二是设计了基于函数调用的自主席记忆管理机制——LLM 能在不需要人工干预的情况下管理自己的上下文。三是在对话和文档分析两个场景上验证了方法的有效性,多个指标大幅超越固定上下文基线。

从更广的视角看,MemGPT 代表了一种不同于「暴力扩展上下文」的技术路线。与其把上下文窗口做得越来越大,不如让模型学会在有限的窗口里高效管理信息。这种思路和 Agent 系统的设计天然契合——MemGPT 后来被扩展为开源 Agent 框架 Letta,支持多种存储后端和模型。

未来,如何设计更智能的记忆调度策略(比如基于注意力的「页面置换」算法)、如何处理多模态信息的记忆管理、以及如何在保证隐私的前提下实现跨会话的持久化记忆,都是值得探索的方向。