Memory 不是更长的 History:Agent 长期记忆的真实边界

11 阅读1分钟

cover

「给 Agent 加记忆」最常见的做法,是把更多旧会话塞回下一次请求的 History 里。codex 没有这么做。它的 Memory 从 rollout(完整会话回放)取材,却不参与 ContextManager 的 replay——先做单 thread 提取,再做全局文件合并。长期记忆和会话历史是两条不同的所有权链。

五段式管线:从 rollout 到 usage 回写

固定版本里,记忆的完整链是:eligible rollout JSONL → Phase 1 提取 + redaction → memories SQLite → Phase 2 选择(usage + recency)→ 机械同步 raw_memories.md 与 rollout_summaries → 受限 consolidation agent 更新 memory_summary.md 与 MEMORY.md → progressive-disclosure 语料 → developer prompt + 按需读取 → 模型返回结构化 citation → core 把被引用的 rollout id 写回 usage metadata。

关键在最后一步:模型要在最终回答里返回结构化 citation,core 才会给对应的 Phase 1 行记一次 usage。也就是说,「被引用」才「被记数」——记忆的使用是可审计的,不是模糊的「大概用到了」。

flow

至少五个 owner,没有单一的 Memory store

这条回路里至少有五个 owner,不能缩写成一个「Memory store」:

表示保存什么主要 owner不能据此推出什么
rollout JSONL原 thread 的 durable replay itemsrollout / thread store不是整理后的长期知识,也不会被 consolidation 改写
ContextManager History当前 live session 的模型工作集core Session不会因为 Memory 生成而自动变长
memories SQLiteStage 1 输出、选择标记、usage、job lease/retry/watermarkMemoryStore不是直接拼进 prompt 的最终语料
Phase 2 bridge 文件raw_memories.md 与 rollout_summaries/*.mdstorage.rs 的机械同步不是 consolidation agent 自由改写的输出
curated memory 文件memory_summary.md、MEMORY.md 与可选 skills受限 consolidation agent不会自动进入 live History
ExtensionData本 thread 是否注入 Memory、是否暴露 dedicated tools、memory root 在哪MemoriesExtension不是跨进程 durable corpus

rollout 是「发生过什么」的完整记录;History 是「这一次模型看到什么」的工作集;memories DB 是「被提取出来待选择」的中间产物;bridge 文件是「机械同步的暂存」;curated 文件才是「整理后的长期知识」。每一层都不能替代另一层。

MemoryTool 默认关闭:记忆是一种 gate

rust-v0.144.6 把 Feature::MemoryTool 放在 experimental 区,default_enabled = false。这不是文案上的保守说法,而是启动 pipeline、read-path extension 和专用工具共同依赖的 gate。没有显式启用 feature,后面的流水线不会自动出现。

入口还有四个硬拒绝:ephemeral session、feature 关闭、non-root agent、没有 state DB。记忆不是「有就注入」,而是「显式开启 + 条件满足才启动」。

注入边界:不是只有新 thread 才收到记忆

read path 开启且 memory_summary.md 存在并非空时,启动中的 thread 或配置刷新后重新生成 context 的 thread 都可能收到摘要和检索规则。read crate 显式拥有 injection、citation 解析和 read telemetry,不依赖 write pipeline——读和写是两条独立的路径。

拆完这章,我的感受是:「Agent 记忆」这个词掩盖了太多结构。真正重要的是区分四件事:什么是完整历史(rollout)、什么是工作集(History)、什么是待选中间产物(memories DB)、什么是整理后的知识(curated 文件)。把四者混成一个「记忆」,就会在「为什么上下文没变长」「为什么记忆没生效」「为什么 usage 不对」这三个问题上反复踩坑。codex 的选择是让每一层都有自己的 owner、自己的 gate、自己的审计痕迹。

源码依据:codex-rs rust-v0.144.6 Memory 模块(Phase 1/Phase 2、memories SQLite、read-path extension、citation/usage 回写),commit 5d1fbf26c43abc65a203928b2e31561cb039e06d。