Agent Memory 技术综述(二):工程架构、生命周期与安全治理
1. 工程问题:记忆系统到底要解决什么
从产品视角看,Agent Memory 让智能体“记得住”。从工程视角看,它要解决的是一组长期状态管理问题:
- 如何判断一条信息是否值得长期保存。
- 如何把原始对话、工具调用和外部事件转成可检索记忆。
- 如何在不阻塞主交互的情况下完成写入和整理。
- 如何把高相关、低噪音的记忆注入上下文。
- 如何处理重复、冲突、过期、隐私和安全风险。
- 如何评估记忆系统对质量、延迟和成本的影响。
因此,Markdown、SQLite、向量库或图数据库都只是存储层选择,真正决定可用性的,是围绕存储建立的完整生命周期管线。
2. Pull 与 Push:两种数据流范式
记忆系统的数据流可以分为 Pull 和 Push。
Pull 是检索驱动。Agent 在需要历史信息时主动查询记忆库,再把相关结果用于当前推理。这是最常见模式,和 RAG 很接近。它的优势是简单、按需、成本可控;缺点是强依赖查询质量,如果 Agent 没意识到该检索,就可能漏掉关键历史。
Push 是事件驱动。外部事件、会话结束、上下文压缩、定时任务或文件变更会主动触发记忆写入、整理或索引更新。它让 Agent 更接近长期服务系统,能响应异步变化;缺点是架构更复杂,后台任务会带来持续成本和一致性问题。
成熟系统通常是混合模式:回答历史相关问题时 Pull;对话结束、压缩前、用户显式要求、文件变更、定时整理时 Push。
3. 存储模型:从“记忆即文件”到服务化记忆层
3.1 Markdown 源文件
Claude Code 和 OpenClaw 都强调本地 Markdown 文件。它人类可读、可编辑、可审计,可以用普通文件工具、Git 或 IDE 查看。对个人 Agent、编码 Agent、实验系统来说,这种透明性很重要。
这类系统通常会把文件分层:
- 用户画像、人格、长期偏好:如 USER.md、SOUL.md、MEMORY.md。
- 每日日志或会话归档:如 memory/YYYY-MM-DD.md。
- 团队或项目规则:如 AGENTS.md、CLAUDE.md、team memory。
- 审计和整理日志:如 DREAMS.md 或类似文件。
Markdown 的问题是查询能力有限,海量用户和并发写入时也会遇到一致性挑战。因此很多系统会把 Markdown 作为 source of truth,再建立索引数据库负责查询。
3.2 Markdown + SQLite 索引
OpenClaw 展示了一种轻量但完整的本地架构,写入使用 Markdown 简单可靠,查询使用 SQLite 索引提升检索性能。索引中可以包含文件表、分块表、向量缓存表、全文搜索表和向量搜索虚拟表。
这种设计本质上是命令查询责任分离。再可审计的文件中写入,检索走优化后的数据库。它避免了引入 Redis、Pinecone 或独立向量数据库的运维复杂度,又能获得混合检索能力。
典型流程是:文件发生变化后,监听器批量触发分块;每个 chunk 计算 hash,复用 embedding cache;再写入 SQLite 的文本索引和向量索引。这样可以支持增量更新,减少重复向量化成本。
3.3 向量库、图数据库与服务化存储
Mem0、Zep 等系统更像独立记忆中间件。它们会组合向量库、图数据库、KV 存储和后端服务,提供实体抽取、关系抽取、增量更新、元数据过滤、rerank、合规治理等能力。
服务化方案适合企业级场景,多用户、多 Agent、多业务线、权限隔离、审计、扩缩容等要求更强。但它也会牺牲一部分透明性,调试时需要更多观测工具。
4. 写入机制
记忆写入是最容易低估的环节。简单地把对话都存起来会制造大量噪音,完全依赖在与用户交互时触发又可能会漏掉隐含经验。较成熟的系统会组合多种触发方式。
第一种是用户显式触发。用户明确要求保存偏好、规则或背景信息时,Agent 直接写入对应文件或记忆库。这类触发信号强,但需要识别是否真的适合长期保存。
第二种是 Agent 自主判断。主 Agent 在对话中发现用户偏好、重要决策、非显而易见的项目背景、长期可复用经验时,可以直接写入。Claude Code 的设计强调:代码结构、文件路径、当前任务临时状态、PR 列表等可通过代码或工具重新查询的信息,不应该轻易写入长期记忆。
第三种是后台提取。一次对话结束后,系统 fork 一个受限子 Agent,回顾上下文并提取值得保存的信息。它不阻塞用户交互,权限也可以限制在记忆目录内,降低误写风险。
第四种是压缩前刷新。当上下文窗口接近压缩或重置时,系统先把易丢失但持久有价值的信息刷入当天日志或长期记忆,再进行上下文压缩。OpenClaw 的 pre-compaction memory flush 就体现了这种思路。
第五种是外部事件或定时任务触发。例如文件变更、会话启动、周期性 heartbeat、后台 dreaming 都可以触发索引同步或记忆整理。
写入目标也要分层。日常流水适合追加到日期日志;长期事实和规则适合进入 MEMORY.md 或主题文件;团队共识适合进入 team memory;当前任务进度更适合 session memory,不应污染长期记忆。
5. 整理机制
长期记忆不是越多越好。系统必须持续整理:合并重复、删除过时、抽象高频经验、压缩索引入口、处理冲突。
Claude Code 的 Auto-Dream 偏向后台维护:定期扫描记忆文件,识别重复和过期内容,把零散记录整理为主题化记忆,并更新索引入口。它还使用锁和时间门控,避免频繁并发整理。
OpenClaw 的 dreaming 更强调从短期日志向长期记忆晋升。它会扫描 daily memory,从日常信息中归纳反思内容,再基于频率、相关性、多样性、近期性、跨天稳定性、知识密度等维度评分,只有超过门槛的内容才进入长期记忆。
这种机制的工程意义很大:长期记忆不应该只是用户或模型“觉得重要”的瞬时判断,而应当结合后续是否被频繁召回、是否跨场景有用、是否仍然新鲜来动态调整。
6. 检索与注入:高信噪比比高召回更重要
记忆检索可以分成召回、精读、组装三步。
召回阶段用 memory_search 或类似工具从记忆库中找到候选。常见策略包括:
- BM25 或全文搜索:适合精确词、ID、日期、名称。
- 向量搜索:适合语义近似问题。
- 混合检索:按权重融合语义分数和关键词分数。
- 图遍历:适合实体关系、事件链和多跳推理。
- 时间衰减:让较新记忆在同等相关度下优先。
- MMR:减少结果之间的重复,提高多样性。
精读阶段用 memory_get 或文件读取工具读取候选片段的上下文。直接把搜索 snippet 注入回答往往不够可靠,因为片段可能缺少原因、约束或上下文。让 Agent 先搜索,再按路径和行号读取必要范围,可以显著降低误用风险。
组装阶段要去重、截断、标注来源和新鲜度。Claude Code 的做法是异步预取相关记忆,在主流程合适时机再消费结果;它还会限制被选中的记忆数量,避免上下文污染。OpenClaw 则把记忆作为工具结果动态进入对话历史,使模型能追溯“这条信息从哪里来”。
工程上,记忆注入的目标不是最大化召回,而是最大化有用信息密度。一个错误或过时记忆进入上下文,可能比没有记忆更糟。
7. 压缩、截断与成本控制
Agent Memory 与上下文压缩高度耦合。上下文窗口有限,记忆系统不能无限注入。
常见控制手段包括:
- 索引入口截断:例如对 MEMORY.md 设置行数和字节上限,避免索引本身变成噪音。
- 分层加载:先加载摘要或索引,只在需要时读取详情。
- 异步预取:把检索延迟隐藏在主模型调用和工具执行过程中。
- 去重过滤:已经被工具读取过的记忆不再重复注入。
- 预压缩刷新:压缩前保存关键事实,压缩后用摘要替代长历史。
- 时间衰减和重要性评分:降低旧信息进入上下文的概率。
OpenViking 的分层上下文思路可以借鉴:用一句话摘要做粗召回,用概览做规划和重排,最后按需读取完整内容。这个模式能把“全量可用”和“低 token 成本”统一起来。
8. 安全与治理:记忆系统也是数据系统
记忆系统会保存用户偏好、项目背景、工具结果和可能敏感的信息,因此必须按数据系统治理。
路径安全是本地文件方案的底线。系统需要拒绝相对路径、路径遍历、非法字符、异常 home 展开和危险目录配置,避免 Agent 被诱导写出记忆目录。
后台提取 Agent 应只拥有记忆目录写权限;不同项目、不同用户、不同 Agent 的记忆要隔离;团队记忆和个人记忆要明确边界。
敏感信息保护不能依赖模型自觉。上传团队记忆或服务化记忆前应做 secret scanning,避免 token、密钥和凭证进入共享空间。对于企业系统,还要考虑访问审计、删除权、备份、加密和合规要求。
此外,超过一定时间未更新的记忆,应当标注“可能过时”,提示模型在关键场景下重新验证。尤其是项目状态、服务配置、人员分工这类易变信息,不应被长期记忆无条件支配。
9. Claude Code、OpenClaw、Mem0 的架构取舍
| 维度 | Claude Code | OpenClaw | Mem0 |
|---|---|---|---|
| 存储 | 本地 Markdown 文件树 | Markdown 源文件 + SQLite 索引 | 向量库、图数据库、KV 和服务化后端 |
| 检索 | LLM 选择相关记忆文件,文件读取为主 | 向量 + BM25 混合检索,再精确读取 | 记忆抽取、更新、检索、rerank 流水线 |
| 写入 | 主 Agent 写入 + 后台提取 Agent | 主动写入、压缩前刷新、会话归档 | Extract-Update 两阶段,自动维护记忆库 |
| 整理 | Auto-Dream 合并和清理文件 | Dreaming 评分晋升长期记忆 | 平台化更新、去重、图增强 |
| 透明度 | 高 | 很高 | 中等,取决于平台观测能力 |
| 适合场景 | 编码 Agent、个人/项目记忆 | 本地可控、可审计、低运维 Agent | 企业级、服务化、多用户长期记忆 |
Claude Code 倾向以模型能力降低工程复杂度,只要 LLM 能准确判断和读写文件,就不需要重型索引。OpenClaw 则在透明文件和高效检索之间做了平衡。Mem0 更像可集成的企业记忆层,把复杂的抽取、图增强和更新逻辑封装成服务。
10. 评估指标
记忆系统至少要覆盖在线和离线两类指标。
在线指标关注用户体验和成本:
- 延迟:记忆检索、读取、注入对端到端响应的影响,尤其关注 P95。
- Token 开销:每次注入记忆新增多少上下文 token。
- 查询成本:embedding、rerank、LLM 整理和存储带来的综合成本。
- 相关性反馈:用户是否认可被召回的记忆,Agent 是否减少重复澄清。
- 错误记忆率:回答中是否引用了过时、错误或不属于当前用户的记忆。
离线指标关注检索质量和系统健康:
- Precision:召回内容中真正相关的比例。
- Recall:应该召回的记忆中被找到的比例。
- 存储增长率:记忆库是否无控制膨胀。
- 冲突处理成功率:新旧事实冲突时是否正确更新。
- 整理有效性:dreaming 后长期记忆是否更精炼、更常被正确召回。
评估时要警惕只看 Recall。对 Agent Memory 来说,Precision 通常更重要,因为低质量记忆会直接污染模型输入。
11. 小结
Agent Memory 的工程本质,是在 LLM 外部建设一个长期状态管理系统。它既要像知识库一样可检索,又要像数据库一样可治理,还要像协作笔记一样可审计。Claude Code、OpenClaw 和 Mem0 代表了从本地文件到轻量索引再到企业服务化的三种取舍。选择哪种方案,取决于团队更看重透明度、检索能力、运维成本还是企业治理。