标签归档:上下文记忆

聊下 AI Agent 的上下文记忆和遗忘

最近 DeepSeek 的 OCR 论文里有个有趣的想法:用光学压缩来模拟人类的记忆遗忘机制。

这个思路很巧妙。他们注意到人类记忆和视觉感知都有个共同特点:距离越远,信息越模糊。一小时前的事记得清楚,一年前的事几乎忘光;10 厘米的东西看得清楚,20 米外的东西就模糊了。

DeepSeek 把这个生物学现象转化成了工程实现:近期对话用高分辨率保存,一周前的对话降到中等分辨率,久远的记忆压缩到最小。信息随时间自然衰减,就像人类遗忘一样。

这让我想到 Agent 记忆系统设计的本质问题。

1. 为什么 Agent 需要记忆

上下文窗口和记忆是两码事。

上下文窗口只是让模型一次看到更多对话,像是扩大了工作台。但记忆不同,它让 Agent 能保存、更新和选择性回忆信息。没有记忆,Agent 就像得了失忆症,每次对话都从零开始。

现在大家都在追求更大的上下文窗口,从 8K 到 32K,再到 128K、1M。但这种暴力扩张有个问题:计算成本呈二次方增长。处理 100K tokens 的成本是 10K tokens 的百倍。而且,把所有信息一股脑塞给模型,反而可能让它迷失在细节中。

记忆系统的价值在于选择性保留。

不是所有信息都值得记住,也不是所有信息都需要同样的精度。

2. Agent 记忆的层次结构

AI Agent 的记忆系统可以分成几个层次:

短期记忆(工作记忆)
这是 Agent 的记事本,保存当前对话和正在处理的任务。典型容量在几千到几万 tokens。没有它,Agent 会在对话中途失去思路,问你刚才说了什么。

长期记忆
这是跨会话的持久化存储。用户下次回来,Agent 还记得之前的交互。长期记忆又可以细分:

  • 事实记忆:保存确定的信息,比如用户姓名、偏好、角色定义。这些信息需要随情况更新,保持”当前真实状况”。
  • 情景记忆:记录具体经历,什么时候发生了什么,结果如何。这给 Agent 一种时间连续感,能回顾过去的决策。
  • 语义记忆:组织概念和关系的知识网络。让 Agent 理解”数据库慢”和”查询延迟高”是相关问题。

3. 遗忘机制是有用的

人类会遗忘,不是大脑容量不够,而是遗忘让我们更高效。

想象一下,如果你记得生活中的每个细节:每顿饭的味道、每次呼吸的感觉、路过的每个行人的脸。这些信息会淹没真正重要的记忆。遗忘是一种过滤机制,帮我们保留有价值的信息。

Agent 也需要这种机制。随着交互增加,历史数据会无限增长。如果不加选择地保存所有内容,会面临几个问题:

  1. 存储成本:每个用户的历史数据都完整保存,存储需求会爆炸式增长。
  2. 检索效率:在海量历史中找到相关信息越来越慢。
  3. 注意力分散:太多无关信息会干扰 Agent 的决策。
  4. 隐私风险:永久保存所有对话增加了数据泄露的风险。

4. 用分辨率模拟时间衰减

DeepSeek 的做法是:把历史对话渲染成图像,然后用不同的分辨率来编码。

近期对话用高分辨率(Gundam 模式,800+ tokens),保留完整细节。

一周前的对话用中等分辨率(Base 模式,256 tokens),保留主要内容。

久远的历史用低分辨率(Tiny 模式,64 tokens),只留个大概印象。

这样做的好处是:

  1. 不需要丢弃历史信息,所有对话都保留着
  2. 但远期信息自然”淡化”,占用的 token 越来越少
  3. 模拟了人类记忆的衰减曲线

具体实现上,他们会:

  1. 把超过一定长度的历史对话渲染成图像
  2. 第一次压缩,让 token 减少 10 倍
  3. 上下文再次超长时,进一步降低分辨率,再压缩 10 倍
  4. 随着时间推移,图像越来越小,内容越来越模糊,模型也就逐渐”读不清”了

这种方式不是简单的截断或删除,而是让信息随时间衰减——就像人类记忆一样。

5. 理论上无限的上下文

如果这个思路走通了,就能实现”理论上无限的 context window”。

这里的无限不是真的无限,而是通过分层压缩,让历史信息的存储成本趋近于常数。

我们不需要保持所有信息的高保真度,只需要让信息按重要性和时效性衰减。

最近的对话,全保留。
一周前的,压缩一次。
一个月前的,再压缩一次。
半年前的,只留个印象。

这样,计算资源始终聚焦在最重要的”近期”信息上,而久远的历史虽然还在,但只占用很少的 token。

从成本角度看,这比无脑扩大上下文窗口要合理得多。

6. 记忆管理的工程实践

在实际的 Agent 系统里,记忆管理通常分几个层次:

会话级记忆——当前对话的上下文,存在内存里,对话结束就清空。这部分可以直接用模型的上下文窗口。

用户级记忆——持久化存储,用向量数据库或 KV 存储。每次对话时,根据当前问题检索相关的历史记忆,注入到 prompt 里。

全局知识库——所有用户共享的知识,比如产品文档、技术规范、FAQ。这部分通常用 RAG(检索增强生成)来处理。

关键是如何在这些层次之间做好信息流转和优先级管理。

比如,用户刚说过的话,优先级最高,直接放在 prompt 前面。一周前的对话,需要检索后才注入。一个月前的,可能只保留摘要。

这种分层策略,和 DeepSeek 的分辨率衰减思路是一致的——让资源消耗和信息重要性成正比。

7. 遗忘不是丢失

这里需要明确的是,遗忘不等于删除。

人类的遗忘,是提取变难了,不是信息消失了。在特定的提示下,很多”遗忘”的记忆还能被唤起。

Agent 的记忆也应该这样设计。

低分辨率的历史对话,在大部分场景下不会被激活,但如果用户明确提到某个时间点的事情,系统可以重新加载那段历史的高分辨率版本。

这需要一个索引机制,能根据时间、主题、关键词快速定位到历史片段。

像 Manus 所使用的文件系统就是这样一种索引机制。

遗忘是常态,召回是特例。这样才能在效率和完整性之间找到平衡。

8. 什么值得记住

并不是所有对话都需要长期保存。

大量的对话是重复的、临时的、没有上下文依赖的。比如简单的问候、重复的确认、无关紧要的闲聊。

这些内容可以在会话结束后直接丢弃,不需要进入长期记忆。

真正值得记住的,是那些包含决策、偏好、关键信息的交互。

比如:

  • 用户明确表达的需求和偏好
  • 重要的决策节点和原因
  • 反复出现的问题和解决方案
  • 用户的角色、职责、技术栈等基础信息

这需要在记忆写入时做判断和过滤。可以用一个小模型或规则引擎,评估每轮对话的重要性,决定是否持久化。 Gemini Code 就是这么干的。

不是所有东西都值得记住,筛选本身就是一种优化。

9. 记忆的更新和冲突

长期记忆不是只写不改的日志,它需要能更新。

用户的偏好会变,角色会变,之前的信息可能过时或错误。

比如用户之前说喜欢中古风的家具,后来又说喜欢北欧风,这个信息需要更新,而不是简单地追加一条新记录。

如果只追加不更新,记忆会越来越冗余,甚至出现矛盾。

一个好的记忆系统,需要能识别冲突,做合并和覆盖。

这可以通过实体识别和关系抽取来实现。把对话内容结构化成三元组(主体-关系-客体),然后在写入时检查是否和已有记忆冲突。

如果冲突,可以根据时间戳、置信度等因素决定是更新还是保留多个版本。

记忆管理的复杂度,不亚于写一个小型数据库。

10. 压缩不只是技术问题

回到 DeepSeek 的光学压缩思路,它的价值不只是技术实现,更重要的是提供了一个思维框架。

我们习惯于把上下文长度当作硬指标——越长越好。但这个论文提醒我们,长度和质量不是一回事。

有时候,适度的遗忘反而能提升系统的整体表现。

有如下的好处:

  1. 减少了无关信息的干扰
  2. 降低了计算成本
  3. 让模型专注于最相关的内容

这和人类的认知机制是一致的。我们不会带着所有历史记忆去做每一个决策,而是根据当前情境激活最相关的那部分。

Agent 应该学会做同样的事。

11. 成本和效果的平衡

从成本角度看,无限扩展上下文是不可持续的。

假设一个 Agent 系统,每天处理 1000 次对话,每次对话平均 10 轮,每轮 500 tokens。

如果所有历史对话都全量保留,一个月下来,单个用户的上下文就会达到 1500k tokens。

如果有 1000 个活跃用户,每次推理都带上完整上下文,token 消耗会是天文数字。

但如果用分层记忆 + 遗忘机制:

  • 最近 3 天的对话,全保留
  • 一周到一个月的,压缩 50%
  • 一个月以上的,压缩 90%

token 消耗可能降低到原来的 10%-20%,而对实际效果的影响很小。

因为大部分场景下,用户关心的就是最近的对话。

12. 记忆应该是系统能力

很多团队把记忆功能当作一个独立的我来开发——加个数据库,存一下历史,检索一下注入。

但这样做的效果往往不好。

因为记忆不是一个功能模块,而是整个 Agent 系统的底层能力。

它需要和 prompt 设计、工具调用、推理链路、错误处理深度集成。

比如:

  • Prompt 需要为记忆预留位置和格式
  • 工具调用的结果需要写回记忆
  • 推理过程中需要动态检索记忆
  • 错误发生时需要回溯历史上下文

记忆管理做得好,Agent 的整体表现会有质的提升。做得不好,就只是一个会话机器人。

13. 一些建议

以下是一些可以尝试落地的建议:

1. 不要把所有历史都塞进 prompt

很多团队的做法是,每次调用都把所有历史对话拼接到 prompt 里。这在对话轮数少的时候没问题,但规模上去后会成为瓶颈。

改成检索式注入——根据当前问题,从历史记忆里检索最相关的几条,而不是全量加载。(这里就会考量检索的能力了)

2. 区分会话记忆和持久记忆

当前对话的上下文,存在内存里就行,不需要持久化。

只有那些需要跨会话保留的信息,才写入数据库。

这样可以大幅减少存储和检索的开销。

3. 给记忆加上过期时间

就像缓存一样,记忆也可以有 TTL(Time To Live)。

一般性的对话,可以设置 7 天或 30 天过期。重要的信息,可以标记为永久保留。

定期清理过期记忆,防止数据无限膨胀。

4. 用好向量数据库

向量检索是目前最适合做语义记忆的技术。

把历史对话做 embedding,存到向量数据库里,每次根据当前问题做相似度检索。

但要注意,向量检索的召回率不是 100%,需要结合关键词索引和时间过滤。

5. 记忆要能解释

用户问”你为什么这么回答”,Agent 应该能说清楚是基于哪段历史记忆做的判断。

这需要在记忆检索时保留溯源信息——这条记忆来自什么时间、什么对话、可信度如何。

可解释性不仅是用户体验问题,也是调试和优化的基础。

14. 最后

上下文记忆和遗忘,本质上是资源分配问题。

我们只有有限的 token 预算,有限的计算资源,有限的响应时间,需要在这些约束下做出最优决策。

无限扩展上下文听起来很美好,但实际上不可行。

真正的解决方案,是学习人类的记忆机制——让重要的信息留下来,让次要的信息自然衰减。

DeepSeek 的光学压缩思路提供了一个很好的启发:遗忘不是缺陷,而是一种优化策略。

如果能把这个思路落地到 Agent 系统里,不仅能降低成本,还能提升整体的智能水平。

因为真正的智能,不是记住所有东西,而是知道什么值得记住,什么可以忘记。