大模型调用本身没有传统意义上的“记忆”。它更像一个无状态函数:输入一段文本,生成一段文本;这次调用结束后,模型不会自动保存本次内容。但应用把历史消息、检索结果或持久化文件重新放进下一次输入时,用户就会获得“它记得我”的体验。
先分清三个概念:上下文窗口是一次调用能看到的工作记忆,对话历史是可回放的原始记录,长期记忆是跨会话保存并按需召回的信息。压缩解决窗口容量,检索解决跨会话访问,写入与更新策略决定记忆是否可靠。本文沿着这条链路,解释 Claude Code 的实现方式,再比较几种通用方案。
一、上下文窗口:每次调用的工作记忆
上下文窗口是模型一次调用可读取的 token 上限,不等于模型拥有了持久记忆。一次请求的输入预算通常由系统指令、历史消息、工具定义和输出、当前输入、检索片段共同消耗,还要为模型输出预留空间。具体上限和计费随模型与服务商变化,不应把某个版本的数字当成架构结论。
模型在本轮只能访问窗口中的内容。所谓“记得上一轮”,通常是应用把上一轮消息重新拼进输入;窗口之外的内容不会因为模型曾经读过就自动可见。
窗口越大,单次能带入的材料越多,但成本、延迟和注意力分散也会增加。长上下文可以减少压缩频率,却不能替代跨会话存储,更不能保证模型会正确使用窗口里的每一条信息。
二、对话历史:先保存,再谈记忆
最朴素的做法是把历史消息按轮次拼成列表,每条消息带角色和内容。下面的 JSON 是说明输入形态的最小示意,不是某个 SDK 的完整请求体。
[ {"role": "system", "content": "你是一个助手"}, {"role": "user", "content": "我叫张三"}, {"role": "assistant", "content": "你好,张三"}, {"role": "user", "content": "我叫什么?"}]模型在本轮看到了“张三”这条历史,所以可以回答问题;它并没有在调用之间保留一个隐藏变量。要支持回放、分支和恢复,生产系统通常把消息作为不可变事件追加保存,并为事件分配 ID。消息之间的父子关系可以形成可恢复的会话链,但这是存储实现,不是模型记忆的特殊能力。Claude Code 提供 --resume 继续既有会话,具体文件格式仍属于产品内部实现,不能直接当成通用标准。
对话历史和长期记忆也不是一回事。历史记录追求完整和可审计,长期记忆追求少量、稳定、可复用;把所有原始消息都当作记忆,召回时很快会遇到容量、噪声和冲突问题。
三、压缩:窗口装不下时保留什么
当历史接近窗口上限,应用需要裁剪旧消息,或让模型把一段历史压缩成摘要。裁剪便宜但容易丢失关键细节;摘要能保留主线,却会丢掉原话、参数和工具输出。压缩因此是有损变换,不应被当作可靠的事实数据库。
压缩策略至少要回答三个问题:
- 哪些内容可以压缩:已经完成的闲聊、重复解释和中间推理通常可以合并。
- 哪些内容必须保留:当前目标、约束、未完成任务、关键文件路径、工具调用结果和用户明确纠正,应该以短条目重新注入窗口。
- 失败如何处理:摘要调用可能超时或失败,需要重试、回退到裁剪,并限制连续失败的重试次数,避免压缩本身耗尽预算。
不同产品的触发阈值和摘要格式会变化。工程上更稳妥的做法是把压缩前后的消息边界、摘要版本和丢弃范围记录下来,出现错误时能定位“信息在哪一步消失”。
压缩只解决单次会话的容量问题。摘要仍然占用上下文,下一轮还可能再次被压缩;要跨会话保留信息,必须把它写入窗口之外的持久化存储。
四、跨会话记忆:文件、索引与更新
Claude Code 当前文档把跨会话知识分成两类:CLAUDE.md 是人维护的持久指令,自动记忆(auto memory)是工具在工作过程中写下的经验和偏好。自动记忆目录包含 MEMORY.md 入口文件和按主题拆分的 Markdown 文件;入口保持精简,详细主题按需读取。文件可由人直接审阅和修改,且默认保存在本机,不会自动同步到其他机器或云环境。
这套设计的关键不是“把所有内容写下来”,而是控制启动时注入的内容:
- 写入:只记录未来任务可能复用的偏好、项目约束和已验证的排错结论。
- 索引:入口文件说明主题文件在哪里,避免每次把全部历史塞入窗口。
- 召回:根据当前任务读取相关主题,读取结果仍要经过权限和上下文预算检查。
- 维护:新事实需要与旧事实对账,过时内容要更新、删除或标注来源与有效期。
“追加一条就算记住”只适合非常小的系统。以 Mem0 论文描述的流程为例,系统先从对话中提取候选记忆,再检索相似的已有记录,由模型决定 ADD、UPDATE、DELETE 或 NOOP。用户从北京搬到上海时,更新旧地址比同时保留两条矛盾记录更可靠。这四种操作是一个实现策略,不是长期记忆的统一标准;生产系统还需要保存来源、时间和置信度,方便人工追溯。
五、如何评估记忆质量
“能不能记住”要拆成可验证的能力,否则很容易把偶然答对当成记忆系统有效。
- 事实回忆:能否准确保存并返回用户直接提供的、结构化且无歧义的信息,例如订单号或明确偏好。
- 跨会话检索:信息分散在不同时间、对象或渠道时,能否找全相关记录并处理歧义,而不是随便选一条。
- 主动服务:没有明确提问时,能否基于长期信息给出有用提醒。该层必须同时评估误报成本,过度主动会比不提醒更糟。
评测至少应记录召回是否命中、答案是否引用了正确来源、冲突信息如何处理,以及额外消耗了多少 token 和延迟。客服 Agent 可能做到前两层就够,个人助理才需要投入第三层;能力目标不同,记忆架构也不应照搬。
六、长期记忆的通用方案
长期记忆没有单一最佳实现。下面按载体和召回方式列出常见取舍。
| 方案 | 记忆载体 | 召回方式 | 主要优点 | 主要代价 |
|---|---|---|---|---|
| 滑动窗口 + 摘要 | 最近消息和摘要 | 直接装入窗口 | 实现简单、延迟低 | 会话结束后通常丢失,摘要有损 |
| RAG | 分块后的文本和向量 | 相似度或混合检索 | 容量大,适合海量资料 | 分块、索引、重排和召回质量都要维护 |
| MemGPT 式分层记忆 | 主上下文 + 外部存储 | 模型或调度器按需调入 | 能处理超出窗口的长任务 | 调度复杂,工具调用和 token 成本更高 |
| 持久化文件 | Markdown、JSON 等文件 | 索引后按需读取 | 可读、可编辑、可版本管理 | 文件规模增大后需要索引和冲突治理 |
| 结构化存储 | 关系表、事件表、知识图谱 | SQL、图查询或规则 | 适合精确查询和约束检查 | 需要设计 schema,语义检索不够自然 |
RAG:向量检索只是召回层
下面的流程图只保留 RAG 的主路径:把输入向量化、从外部存储召回候选,再把候选放回本轮上下文。
RAG 的容量不受上下文窗口大小直接限制,但召回不到的内容本轮仍不可见。实际系统通常还要处理分块、混合检索、重排序、去重和权限过滤;向量相似并不等于事实正确,也不等于用户希望模型主动想起。
执行化记忆:把事实变成状态和规则
User as Code 论文探索了另一条路:用带类型的 Python 对象表示用户状态,把对话事实先写入日志,再周期性生成结构化代码。聚合统计和约束检查交给解释器执行,能减少让模型“心算”的错误;代价是需要代码生成、沙箱执行、版本迁移和人工审核。论文中的准确率来自特定基准和实现,不能直接外推到所有记忆系统。
User as Engram 则尝试把用户事实写入模型的局部参数槽位,由模型内部的门控机制决定何时读取。这类参数化记忆更新紧凑,但可编辑性、隔离、回滚和跨模型迁移都更困难,目前更适合作为研究方向,而不是默认的生产方案。
七、工程落地:记忆系统要管理什么
不论使用文件、向量库还是结构化数据库,长期记忆最终都要在推理时变成模型可访问的输入,或变成可调用的状态与工具。设计时可以按下面的顺序检查:
- 写入边界:哪些信息值得长期保存,哪些只属于当前会话;敏感信息是否默认不写入。
- 数据形态:事实、偏好、事件、规则和原始对话是否分开建模,是否保存来源、时间和有效期。
- 召回预算:每轮最多注入多少条、如何去重和排序、召回失败时是否有明确回退路径。
- 冲突与删除:新旧事实矛盾时谁优先,用户如何纠正或删除,删除是否会从索引和缓存中同步清理。
- 隔离与审计:多用户、多项目之间是否严格隔离,谁写入了什么,模型回答引用了哪条记忆。
- 效果评测:同时测命中率、事实准确率、误报率、延迟、token 成本和删除成功率。
这些约束比“选哪个向量数据库”更先决定系统能否长期运行。记忆不是一个单独的组件,而是一条包含写入、维护、召回和验证的生命周期。
小结
上下文窗口是一次调用的工作记忆,对话历史是可回放的原始记录,压缩负责在窗口变满时保留主线,长期记忆负责跨会话保存并按需访问。Claude Code 的 CLAUDE.md 与自动记忆展示了文件化方案;RAG、MemGPT 和结构化存储分别代表语义召回、分层调度和精确查询。判断方案时,先明确要记什么、怎样更新和如何验证,再决定记忆载体。模型“看见”记忆只是起点,能否在正确时间用对、改对、删干净,才是长期记忆的工程难题。
参考资料
- Claude Code 官方文档:Memory -
CLAUDE.md与自动记忆的加载和存储方式 - MemGPT: Towards LLMs as Operating Systems - 分层上下文与外部记忆
- Retrieval-Augmented Generation for Large Language Models: A Survey - RAG 综述
- Mem0: Building Production-Ready AI Agents with Scalable Long-Term Memory - 记忆提取、更新与删除流程
- User as Code: Executable Memory for Personalized Agents - 可执行用户状态
- User as Engram: Internalizing Per-User Memory as Local Parametric Edits - 局部参数化记忆
- Anthropic:Effective context engineering for AI agents - 上下文窗口与 Agent 设计
支持与分享
如果这篇文章对你有帮助,欢迎支持作者或分享给更多人
部分信息可能已经过时








