Claude Code、Codex、Hermes 和 OpenClaw 都会用到一个叫 MEMORY.md 的文件。名字相同,职责却有区别。Claude Code 用它指向其他记忆文件,Hermes 把容量有限的核心知识直接写进去,Codex 的同名文件则处在一套后台抽取与整合流程中。要知道 Agent 怎样记住一件事,还得接着看这个文件由谁写、什么时候读。
我把这几套系统的官方文档,以及 OpenViking、Mem0 的相关材料对照了一遍。资料核对到 2026 年 9 月 14 日,涉及 Codex 内部机制的部分依据公开仓库说明。这篇讨论可核查的设计,没有把文档能力当成同条件实测结果。
记忆怎样进入下一次任务,值得沿着完整流程看。 一份内容先被保存,经过整理,再被检索或直接加载,才有机会影响模型。每一步都有自己的状态。磁盘里已经有了新偏好,正在运行的会话仍可能拿着旧快照。
核心记忆怎样进入会话
Claude Code 的 Auto Memory 很适合从头理解这件事。它在项目记忆目录里保存一个简短索引,把具体内容放进主题文件。每次会话开始,系统加载 MEMORY.md 的前 200 行或前 25KB,以先到的限制为准;主题文件留到需要时,由 Claude 使用文件工具读取。这个限制管的是启动加载量,主题记忆仍然可以继续增长。Claude Code 记忆文档
于是,索引里最有价值的信息是某份笔记讲什么、何时需要看它。正文可以详细,入口需要简短。这里对模型的要求也很具体,Claude 要判断哪件事值得记,给文件起一个能找到的名字,修改正文时还要照顾索引。一个会读写文件的 Agent,已经具备了执行这些动作的工具。
Hermes 把常驻部分限制得更紧。它默认给 MEMORY.md 2,200 个字符,给记录用户偏好的 USER.md 1,375 个字符。两个文件在会话开始时形成固定快照,完整会话另外存进 SQLite,需要查细节时走 FTS5 全文搜索。新增内容超过容量,记忆工具会返回错误,Agent 要先合并或删除旧条目,再尝试写入。Hermes 持久记忆
这两个方案对模型的读取负担作了不同安排。Claude Code 常驻的是入口,之后花工具调用读详情;Hermes 提前把少量核心内容放进上下文,把历史细节留在搜索端。两者都需要筛选,只是筛选发生的位置不同。
Hermes 的快照还有一个明确后果。会话中修改记忆,文件立即更新,系统提示中的那一份要到下次会话才重新加载。工具返回值会告诉当前 Agent 刚改了什么。系统提示保持不变。这有利于复用提示缓存,也使会话边界成为记忆生效时机的一部分。
目录与事实怎样支持召回
当材料从几条偏好变成一批项目文档,组织方式就要承担更多工作。OpenViking 把资源、记忆和技能放进统一的 viking:// 地址空间,让 Agent 可以浏览目录、读取摘要,再展开详细内容。
它把内容和索引分开保存。AGFS 负责 L0、L1、L2 的内容及多媒体文件;向量索引保存 URI、向量和检索元数据,其中也可以包含 L0 摘要字段。L0 是简短摘要,L1 给出较完整的概览,L2 保留详细内容。文件内容以内容存储为准,索引用来定位。OpenViking 存储架构
这里可以把“找到哪里”和“读多少”分开理解。向量相似度帮助选择相关位置,摘要帮助判断这个位置有没有继续展开的价值。知道某份文档讨论认证迁移,与读完其中的兼容条件,需要的上下文长度不同。L0、L1 提供了中间的阅读尺度。
OpenViking 的层级检索会先取得候选起点,再沿目录继续搜索。接口层还有另一组区别,find() 直接处理查询,search() 可以结合会话,让模型分析意图并形成查询。查询怎样产生,与检索器怎样执行,是两个独立选择。OpenViking 检索机制
本次分析引用的检索器代码还区分 QUICK 和 THINKING。QUICK 可以直接走向量搜索,另一条路径才继续递归目录。实际比较效果时,需要记录使用了哪条路径,不能仅凭产品名推定执行过程。核查所用的检索器代码
这种组织方式把一部分阅读工作提前做了。资源进入系统后,需要产生摘要、维护目录关系,内容改动还要反映到索引里。按层读取节省了回答时可能读入的内容,也增加了后台加工和同步的工作。摘要遗漏重要限制时,检索还可能错过正确分支。这是分层方案需要单独评估的地方。
Mem0 以事实条目为主要处理单位。应用提交消息,系统提取值得保留的事实,连同用户等作用域信息保存,再通过搜索接口取回。接入方拿到的是一组记忆结果,仍要决定何时查询,以及把多少结果交给回答模型。Mem0 写入流程
当前 Mem0 Platform 的检索结合向量、BM25 关键词和实体关联信号。系统会识别记忆中提到的人、组织或概念,将实体与相关记忆连接起来,实体本身也会生成向量。查询提到某个实体时,与它相关的记忆可以获得更高排名。Mem0 Graph Memory
“图”在这里有具体含义。两条记忆都提到同一个项目,就可以通过该项目建立联系。当前平台没有因此把所有内容变成带类型的关系边,例如谁管理谁、何时开始管理。共有实体能够帮助把分散事实找齐;要回答某段关系在特定日期是否成立,还需要相应的时间与状态信息。
至此,文件读取和向量召回的分工已经比较清楚。文件导航依靠组织好的入口,向量搜索按当前查询匹配内容。OpenViking 同时使用两者,Mem0 又加入实体关联。找到候选以后,模型通常还要阅读原文或提炼后的事实,向量本身不会代替这些内容作答。
这也解释了为什么相似度很难独自处理更正。可以用一个小测试检查系统,先告诉 Agent 项目使用 npm,随后明确更正为 pnpm,再开启新任务让它安装依赖。两条记录都与安装依赖有关,搜索把它们一起找出来很正常。接下来,需要有人或某段程序决定哪条约定当前有效。
更正以后谁来维护记忆
写入之后怎样维护,是几套系统差异最明显的部分。 Claude Code 可以编辑主题笔记,Hermes 提供新增、替换和删除工具;Hermes 当前还支持回合后的后台复盘,将稳定经验写入记忆或技能。轻量文件方案同样可以自动整理,关键在于谁发起修改,以及修改受到什么约束。
Codex 把记忆建设明确拆成了两个阶段。在功能启用、状态数据库可用等条件满足时,系统在后台选择符合条件的历史会话,逐个交给模型抽取详细候选和简短总结,再把结果写回数据库。这个阶段允许并行处理,任务通过数据库认领,失败后退避重试。
第二阶段取得全局锁,选出本轮使用的候选,将它们同步成 raw_memories.md 和会话总结文件,再让专门的整合 Agent 更新长期产物。整合 Agent 只能在本地写入,没有网络权限。它根据工作区差异处理变化,形成或更新 MEMORY.md、memory_summary.md 等内容。Codex 公开记忆流程
这项拆分把并发留给会话抽取,把共享知识的修改集中到单个整合过程。对于多次任务反复产生的经验,这样更容易管理任务进度和失败恢复。读取端则可以从较短的摘要出发,再去查手册和会话材料。这里讨论的是公开实现中的流程,具体客户端是否开放、何时启用,需要另看发布版本和配置。
两阶段也带来两种完成时间。某次会话已经抽取成功,长期手册可能还没更新;旧会话总结已经从输入中裁掉,整合 Agent 仍要处理它曾经写入手册的内容。检查第一阶段的数据库状态,无法直接证明第二阶段的语义清理已经完成。
核查 Mem0 时,我也修正了一个过于宽泛的判断。它的 add() 文档描述了新增流程,但当前 Platform 还有 Dream 维护机制。Supersede 会标记被新事实替代的旧条目,Merge 处理重复,另可开启 Synthesis,把多条记忆归纳成更高层的模式。自动新增和后续整理可以存在于同一套系统里。Mem0 Dream
旧事实被标记失效后,读接口仍然要决定要不要返回历史。Mem0 提供 latest_only 选择当前有效条目,默认行为保留了读取已被替代事实的可能。历史追问需要旧记录,当前操作需要有效约定,两种用途应当在查询时说明。平台的这套行为也应与具体开源版本分开判断。
哪些内容可以长期影响行为
OpenClaw 对整理前后的内容给了不同待遇。当天的工作笔记和会话记录属于经历材料,MEMORY.md 与 USER.md 承担精选核心,DREAMS.md 用来审阅整理过程。长会话压缩前,memory flush 会尝试把尚未保存的重要上下文写入当天笔记。写进笔记之后,材料才进入后续整理流程。OpenClaw 记忆架构
这些文件背后还有 SQLite。当前内置引擎把记忆索引与正式会话记录等持久状态放在同一个 Agent 数据库里。修复索引可以重建相应表,整库删除却会连会话一起丢掉。看到一套方案使用 Markdown,仍要分清哪些内容以文件为准,哪些状态由数据库保存。OpenClaw 内置存储
它的后台 Dreaming 分成 Light、REM 和 Deep。前面的阶段暂存候选、归纳主题,Deep 才检查晋升条件并整理长期记忆。详细流程中,晋升写入 MEMORY.md。模型负责提出归纳和修改,程序检查来源、格式、容量以及已有内容的保留情况;不合格的改写有回退处理,接受改写前也会保留旧版本。OpenClaw Dreaming
来源在这个过程中决定资格。用户直接提供的内容、Agent 基于用户内容的整理,与网页等外部材料不会自动获得同样待遇。不可信来源不能靠多次被召回就晋升为核心记忆,已经召回过的内容也有标记,避免反复被抽取成新证据。规则需要工具正确声明来源,文档对此保留了覆盖边界。OpenClaw 来源与信任规则
这让我更在意“保存”和“影响行为”之间的距离。一个网页可以被保存,甚至值得以后搜索,但网页里的句子未必适合成为 Agent 长期遵守的要求。是否可搜索、是否可自动加载,应当分别决定。
OpenClaw 的召回沿着这个区别展开。记忆文件切块后可以建立向量和全文索引,历史会话的语义索引需要额外开启。查询先结合语义和关键词得分,再考虑时间、重要性与结果多样性。合格核心可以按规则进入上下文,普通日记和会话记录则留给显式搜索,或交由 Active Memory 深度回查。OpenClaw 记忆搜索
深度回查会使用专门的 Agent,继续搜索和阅读历史。默认升级思路是,当前消息明确在追问过去,而快速路径又没有强命中时,才花这笔额外开销。它适合需要连接多次讨论的问题,可用行为仍取决于 Active Memory 的启用与配置。OpenClaw Active Memory
于是,同一套系统里可以既有便宜的常规读取,也有较慢的多步查证。前者承担稳定背景和直接命中,后者处理需要还原经过的问题。评估时,单次向量搜索的延迟只覆盖其中一段,还要观察最终回答是否拿到了足够证据。
来源关系也影响删除。OpenClaw 可以沿已追踪的会话来源清理衍生条目,并记录这些会话以后不再参与摄取。这能处理一类实际问题,记忆刚被删掉,后台又从旧会话里把它提取回来。但清理范围不包含所有原始记录、任意手写笔记或外部备份,删除能力要按覆盖范围判断。OpenClaw 来源与删除
接入后端时怎样划分职责
写到这里,几套设计可以放进同一张表。表中比较的是各自主要机制,外部插件和可选后端另算。
| 系统 | 存储组织 | 主要召回方式 | 维护工作由谁承担 |
|---|---|---|---|
| Claude Code | 索引与主题文件 | 加载索引,按需读文件 | Agent 编辑笔记与索引 |
| Hermes | 限长核心与 SQLite 历史 | 核心快照,全文查历史 | Agent 和后台复盘,受容量约束 |
| OpenViking | 上下文目录、分层内容与索引 | 向量定位,可走层级检索并展开 | 抽取与更新流程协调内容、摘要和索引 |
| Mem0 | 事实条目、元数据与实体关联 | 混合搜索,返回匹配事实 | 写入服务和维护接口,Platform 另有 Dream |
| Codex | 会话候选与整合文件 | 摘要导航,逐步读取材料 | 逐会话抽取与统一整合 |
| OpenClaw | 分层笔记、核心与 SQLite 状态 | 核心注入、混合搜索与可选深度回查 | 来源规则、Dreaming 与生命周期管理 |
这些对象所处的位置还不完全相同。OpenViking、Mem0 可以作为记忆后端,被其他 Agent 调用;另外四个产品的内置记忆与各自会话流程结合。接入一个后端以后,主 Agent 仍然需要决定什么时候提交经历、什么时候查询,以及怎样使用返回值。
如果两边都有整理能力,就要明确最终修改由谁负责。内置系统更新了某条偏好,外部后端仍保存旧状态,两份结果再一起进入上下文,模型又得重新判断。来源标识和版本对应关系需要在接入时安排好,不能等到回答矛盾才追查。
怎样验收一次更正与遗忘
我会把前面的 npm 与 pnpm 例子扩成一个验收过程。先更正约定,观察下一次安装用了什么;接着追问迁移前的情况,检查系统能否找到旧记录并说明时间范围。最后删除相关记忆,让后台整理重新运行,再检查内容是否出现。每一步都记录原始材料、当前存储和实际交给模型的上下文,错误发生在哪一段,就从那一段继续查。
主要资料
本文主要依据官方资料。存储和召回部分可对照 Claude Code、Hermes、OpenViking 与 Mem0;后台维护部分以 Codex 公开实现、Mem0 Dream 和 OpenClaw 架构 为主要参照。