大模型拥有上下文,不等于 Agent 拥有记忆。上下文只表示某一次调用能看到什么;记忆还要回答:什么值得保存,何时失效,谁可以看到,冲突如何处理,旧经验如何被召回,以及它是否真的改善了任务结果。
本文结合 Letta、Mem0、Graphiti、Cognee、Claude-Mem、Hindsight、OpenViking、OpenAI Agents SDK、Claude Code、OpenClaw 和云端 Memory Service 的最新公开实现,沿着一条统一生命周期展开:
01 六层心智模型
记忆系统可以拆成六层:工作记忆、情景记忆、语义记忆、程序记忆、结构记忆和控制记忆。
工作记忆是当前 prompt、工具结果和未完成任务;情景记忆记录某次会话发生了什么;语义记忆保存稳定事实和用户偏好;程序记忆保存 skill、流程和策略;结构记忆记录来源、时间、作用域、版本、置信度和权限;控制记忆则记录哪些内容被召回、使用后是否有帮助以及何时巩固或遗忘。
向量库只覆盖其中一部分。它能按相似度找候选,却不能天然表示事实何时生效、谁说的、后来是否被推翻。
02 一条记忆的写入和读取生命周期
写路径是事件捕获、候选抽取、作用域和来源标记、冲突处理、持久化与索引。读路径是关键词、向量和图谱召回,再经过时间、权限、重要性和新鲜度过滤,最后在预算内注入当前上下文。
写入和读取都需要门控。默认全写会制造噪声和隐私风险,默认全召回会挤压上下文并把不相关事实带入决策。
03 短期状态:Session、Checkpoint 与 Compaction
Session 是事件序列,保存用户消息、模型响应、工具调用和结果。Checkpoint 是执行状态快照,适合恢复工作流。Compaction 是把长历史投影成更小的上下文,三者不能混为一谈。
安全的压缩摘要至少包含目标、完成事实、文件变化、失败尝试、待办事项和未决问题,并保留原始 transcript 的引用。摘要不是事实源,只是当前窗口的视图。
OpenAI Agents SDK、LangGraph、Pi 和 Codex 都在不同程度上把 session、turn、checkpoint、compaction 或 rollout 分开,说明长任务的核心问题已经从“上下文有多大”转向“状态如何恢复”。
04 长期写入:事实抽取和两阶段巩固
Mem0 的典型路径是从对话中抽取候选事实,再通过更新、合并或删除决策写入长期存储。作用域、用户 ID、agent ID 和 run ID 决定隔离边界。
另一种路径是在线捕获、离线巩固:在线阶段只记录事件或候选观察,后台 worker 再调用模型做摘要、分类、去重和 embedding。Claude-Mem 正是这种 hook、observer 和 search 的 coding agent 旁路架构;最新 server-beta 又加入 Postgres、BullMQ、tenant identity、audit log 和生成 worker,把单机 SQLite 扩展到团队共享记忆。
两阶段的好处是主请求不被慢的生成任务阻塞,也便于重试和审计;代价是记忆有延迟,并需要处理 outbox、重复 job 和 worker 崩溃。
05 不同系统保存的对象不同
| 项目 | 主要对象 | 典型机制 |
|---|---|---|
| Letta | core memory、archival memory、persona | Agent 主动读写,外部长期存储 |
| Mem0 | 结构化 facts | 抽取、更新与向量/图存储 |
| Graphiti | 带时间的实体和关系 | 双时态图、增量写入、混合检索 |
| Cognee | 认知图谱和 session distillation | 数据摄取、图谱化、任务上下文 |
| Claude-Mem | coding observations | hooks、后台压缩、渐进式召回 |
| Hindsight | retain、recall、reflect | 记忆保留、检索和反思分离 |
| OpenViking | memory、resource、skill | 分层上下文数据库 |
Letta 适合强调 Agent 自己管理状态的系统,Graphiti 适合实体关系和时间变化,Claude-Mem 适合低摩擦捕获 coding 过程,OpenViking 则把记忆、资源和技能放进统一上下文空间。
06 检索:Dense Top-k 只是起点
生产检索通常是关键词、embedding、实体图、时间、重要性和权限过滤的混合路径,之后再 rerank 并控制 context budget。向量相似不等于任务相关。用户问“上次部署失败的原因”时,关键词、时间和 session scope 可能比语义相似度更重要。
召回结果还要携带来源和时间,让模型知道它是在读事实、推测还是过期信息。渐进式召回先返回短摘要和 ID,确认相关后再取完整观察或文件片段,适合 coding agent。
07 时间、冲突和遗忘
Graphiti 的双时态思路很有代表性:区分事实发生的时间和系统知道它的时间。这样可以表示“用户曾经使用 A,现在改成 B”,而不是简单覆盖旧值。
冲突处理要考虑来源可信度、时间、新旧版本、用户纠正和任务作用域。遗忘也不是简单删除:可以降低权重、设置 TTL、归档原文、撤销 embedding、删除敏感字段,或让用户直接删除。
记忆系统需要类似数据库垃圾回收的生命周期管理:active、stale、archived、deleted,以及被新事实替代的 superseded。
08 安全:记忆是长期 Prompt Injection 载体
长期记忆会把一次恶意输入带到未来。攻击者可以伪造用户偏好、让系统保存错误指令,或利用跨用户召回泄露资料。因此记忆内容不能自动获得系统级信任。
至少需要来源和 actor、租户/用户/项目 scope、写入规则、敏感字段过滤、召回后的权限重检、可审计删除和 injection 识别。事实和指令也应分开存储,不能把检索到的文本直接当作系统消息。
09 评测:记住了不等于帮助了
评测应覆盖写入准确率、更新准确率、召回准确率、注入质量和最终任务收益。最后一项要比较带 memory 与不带 memory 的成功率、工具调用、成本、延迟和用户纠正次数,而不是只看向量 top-k。
10 一套生产级参考架构
第一阶段先做可靠短期状态:append-only session、checkpoint、compaction、resume 和敏感日志处理。第二阶段增加长期事实:write gate、scope、source、timestamp、version、conflict resolution 和用户删除。第三阶段再引入 hybrid recall、reranker、graph traversal、异步 observation worker、skill promotion 和离线评测。
不要一开始就搭知识图谱。没有稳定的事件、作用域和评测,复杂存储只会放大错误。
11 最后的判断
Agent memory 的终点不是“更多内容进入 prompt”,而是一个可治理的 Context Database:它保存带来源和时间的状态,按任务预算召回,能处理冲突和遗忘,并用真实任务证明记忆是否有用。