ARTICLE · 1112791
AI 换个会话就忘事?DeepSeek 和 Codex 的记忆怎么做
聊天记录还在,新会话也可能用不上。 程序得把相关内容找出来,重新放进这次模型请求。漏在这一步,之前讨论得再仔细也白搭。
我想弄清一条项目规则怎样被保存,又怎样影响下一次任务。准备做 Agent 开发,这条数据流比记住几个“长期记忆”的术语更有用。
01一条报表规则,存在哪里
之前我在报表模块里定下规则:导出时间按 Asia/Shanghai 展示。此前考虑过直接保留 UTC,后来放弃了;普通运行日志仍用 UTC。
那段讨论会留下好几种材料。按下一次任务会怎样使用它们,拆成下面这张表。
旧聊天可能同时包含两套方案。直接搜到“UTC”,就拿去改代码,反而会把已经定好的规则改回去。读取历史时得保留方案的状态。

AI 机制示意:外部记录可以很长,本轮使用的视图只包含选定内容,并保留来源关系。
把现行设计文档作为报表的业务依据。记忆里出现相关经验,适合帮助定位文件;实际修改前,仍要打开当前文件看一遍。
02DeepSeek Harness:从日志重建会话
DeepSeek Harness 建立了一份追加式事件日志。用户输入、模型输出和工具结果按顺序记录,每个事件带着序号和对应数据。这个做法叫事件溯源:根据发生过的事件,重建会话状态。
日志可以回答“当时发生了什么”。例如,模型曾说测试通过,工具随后返回测试失败,这两条都应该留下。
核心会话服务管理事件的含义,持久化插件负责落盘。官方文件后端按会话保存 JSONL,默认使用 Zstandard 压缩。更换存储后端时,可以继续沿用上层会话逻辑。
LLM 看的是 Surface
日志会不断增长。DeepSeek Harness 从事件中推导一份模型可见的消息序列,叫 Surface。
Surface 支持追加消息,也支持用新消息替换其中一段内容。上下文压缩可以借这个操作,把旧讨论换成摘要;替换操作不决定摘要该怎样生成。
报表模块的摘要只留下“报表导出使用 Asia/Shanghai,普通日志保留 UTC”,本轮就可以不用再读完整争论。被放弃的方案仍留在事件日志中。
替换形成的新节点带有 sourceEventSeqs,记录它依据哪些源事件。摘要不能给 LLM 解释当初为什么这么选时,还有回查入口。
写缓存前,日志先落盘
恢复会话时,从头处理全部事件会增加重复计算。Harness 用 Projection 表示由事件推导出的会话状态,再用 Projection Cache 保存结果。
缓存记录处理进度。恢复时加载这份状态,从后面的事件继续计算,不必重放整个会话。
源码在写缓存前调用会话的 flush,先保证相应日志持久化。进程崩溃后,缓存落后于日志,可以补算缺的一段。缓存领先于日志,就可能引用磁盘上根本没有的事件。

架构图:事件日志派生出 Surface 和会话状态;外部 Memory MCP 是扩展入口。图中的全文会话搜索需按配置启用。
跨会话查询可以把历史提供给新任务,默认组合中的全文搜索没有开启。查询返回哪些材料,仍取决于工具调用与配置。
跨很多次任务归纳偏好、合并经验这些工作,可以交给外部 Memory MCP。Harness 负责连接服务,把记忆工具提供给 Agent;实际服务承担存储、检索和更新规则。默认组合没有装入这些第三方记忆服务。
准备沿着这套架构开发,外部服务怎样划分用户与项目范围,需要继续检查服务自己的实现。接上一个工具接口,还没有说明它会把什么知识共享给谁。
03Codex:经验在后台经过两次加工
Codex 在会话记录上方加了一套记忆生产流程。当前任务的 Agent 使用整理后的材料,后台任务负责从过去会话中加工经验。
这里分析的源码提交,memories 总开关默认关闭;下面的流程以相关生成与读取配置启用为条件。桌面应用采用什么配置,要单独核对。
后台入口在符合条件的根会话启动时运行。它筛选历史会话,避开当前会话,并检查空闲时间等条件。刚说完的一条新规则,可能还没有进入候选范围。

AI 机制:逐会话提炼先形成候选内容,跨记录整理再生成后续任务使用的记忆。
Phase 1 挑出单个会话里值得留下的内容
Phase 1 把保存的会话历史交给模型,按专门的提示词提炼。输出包含候选知识 raw_memory、会话摘要 rollout_summary,以及用于组织摘要文件的名字。
raw_memory 这个名字容易让人读岔:它已经经过模型加工。要核对原话和工具结果,得沿来源回到原始会话记录。
提炼提示词优先寻找未来任务能复用的信息。用户反复纠正的要求、经过验证的排错办法,都可能被选中。一次临时查询没留下有用经验,可以返回空结果。
报表例子里,值得留下的是特定模块的时区约定及其依据。把它写成“用户在中国,所以所有导出都用上海时间”,就添了原材料没有支持的原因,还扩大了适用范围。
这一步的选择由模型完成。程序可以解析字段、控制输入预算并处理敏感内容,归纳是否准确仍要回查材料。
SQLite 保存会话级提炼结果,也保存后台任务状态。提炼结果带着源会话的更新时间 source_updated_at。同一段历史会话后来又继续了,系统可以据此判断旧结果是否需要重新提炼。
我喜欢这个字段的用途:它让“这份经验依据哪一版记录”有了检查位置。只记生成时间,无法知道生成后原会话又发生过什么。
Phase 2 整理共享的记忆文件
多份 Phase 1 结果进入 Phase 2,由内部整理 Agent 结合已有记忆重新组织。重复内容可以合并,后续更正可以改掉旧认识,可复用的操作流程也可以整理成 Skill。
memory_summary.md | |
MEMORY.md | |
rollout_summaries/ | |
skills/ | |
raw_memories.md |

Codex目录截图,可以看见记忆产物的文件布局;不展示数据库内容或后台提炼过程。
Markdown 产物可以直接打开阅读。SQLite 用来管理结构化记录与任务状态,需要数据库工具读取。
各会话的 Phase 1 可以并行处理,Phase 2 却要修改同一套文件。源码为对应记忆版本的整理任务设置全局租约,执行者取得限时的写入资格,并在处理期间续租。
租约还记录所有权。一个执行者停顿太久,旧租约到期,其他执行者可能接手。旧执行者恢复后,必须重新确认自己仍持有资格,才能完成后续基线更新。
Phase 2 在工作目录里维护内部 Git 基线。同步本次候选输入后,它检查文件变化;没有变化且已有产物有效时,可以跳过模型整理。有变化时,把差异写成文件,供整理 Agent 阅读。
这里的 Git 用于比较这一轮输入和产物的变化。源码里的“重置基线”是在更新下次比较的起点。
整理完成后,程序检查产物结构,确认租约所有权,记录实际消费的源版本。SQLite 与 Markdown 目录跨着两个存储边界,源码通过这些步骤和重试协调更新,没有把整个目录放进一个数据库事务。

Codex架构图。左上方是原始会话来源,SQLite 保存提炼结果和任务状态;用户更正经 note 文件进入整理阶段。
04新会话先收到一份小导航
Codex 的读取入口会读取 memory_summary.md,与读取规则一起组装成上下文片段。文件缺失或内容为空时,这个入口不提供记忆片段;摘要太长时,按预算截断。
模型从导航中判断任务是否涉及已有经验,再按需查 MEMORY.md、相关会话摘要或 Skill。详细材料经过读取,才进入本轮工作上下文。

Codex源码,展示导入项及两版模板定义;摘要文件读取与预算截断位于未展示的下方函数。
这条本地读取路径使用关键词文本检索,没有内置向量数据库。语义整理已经发生在前面的模型提炼与汇总里,读取端可以依靠项目名、路径、报错和任务词去找对应材料。
我看重的是导航写得够不够具体。摘要里只有“做过报表”,新任务要求改导出时间时,模型未必会继续检索。写明“报表导出、Asia/Shanghai、当前设计入口”,才给了它足够明确的查找线索。
摘要承担着后续检索的入口职责。它的内容被漏写或截掉,可能使已有经验没有机会被读到。检查一次漏召回,需要看到本轮实际注入的摘要,以及后续搜索用了什么词。
05记忆写错了,怎样影响后面的任务
Phase 1 把“报表模块用上海时区”写成了“项目所有导出用上海时区”。这条候选被 Phase 2 收进手册后,未来改普通日志的任务就可能读到它。
作用范围应跟着知识一起保存。Codex V1 的本地记忆目录采用用户级入口,项目路径帮助定位内容,并没有把每个项目做成严格隔离的记忆库。
源码提供了显式 note 入口。用户明确要求记住、忘记或更新某项内容后,Agent 可以留下修正说明;专用工具是否可用还受配置控制。
例如,我可以要求它更新这项记忆:报表导出用 Asia/Shanghai,普通运行日志保留 UTC,核对依据是该项目的现行设计文件。
本地后端会新建一份 Markdown note,放在 extensions/ad_hoc/notes/,供后续 Phase 2 消费。它没有当场改完所有记忆产物。
更正与下一次读取之间可能有时间差。立即另开会话时,后台整理尚未完成,仍可能得到旧内容。验收需要查看整理后的记录,并检查新会话实际读到了什么。
note 的整理规则把内容作为记忆修正数据,禁止据此执行其他动作。某条更正里夹着“顺便删除项目目录”,不属于这次记忆更新的执行授权。
从记忆手册里移除一条旧认识,也没有证明保存的原始会话已被删除。涉及清除历史数据时,需要检查原记录自己的保存与删除机制。
06用一个新会话检查接手
我给这条报表规则设的验收问题是:
在修改报表导出前,找到当前生效的时间约定,指出依据文件的位置。说明这条约定是否适用于普通运行日志。
这次检查要求它真的打开依据。只复述一句“报表用上海时间”,还看不出它读了当前设计,还是碰巧从旧摘要里找到了同一句话。
答错以后,可以沿本文的数据流定位故障。例如,候选记忆已经扩大了范围,就回查提炼时使用的源记录;记忆里保留了正确规则,本轮却搜不到,就检查注入的导航和实际检索词。
同一个项目目录,只共享磁盘上的文件。 新会话接手时,具体读到了哪份资料,仍要从读取记录里确认。