执子念

Coding Agent 的长期上下文治理:为什么 MEMORY.md 应该是一份索引

长期使用 Coding Agent 后,团队很容易形成一种直觉:把项目历史持续写进记忆,下一次任务就能少解释一些。

这个做法在早期确实有效。架构边界、代码规范和验收口径被保存后,新会话可以快速进入状态。随着项目增加,主记忆却会逐渐混入发布记录、临时报错、版本快照和命令输出。某一天,Agent 记住了很多事情,却更难判断哪一件仍然有效。

我最近清理了一套 Codex 记忆:MEMORY.md 从 1,875 行、201,111 字节缩到 150 行、8,698 字节,降幅 95.7%;摘要从 99 行缩到 60 行;整个目录从约 2.0 MB 降到 976 KB。

长期记忆清理前后的尺寸变化

对话和历史证据没有删除。62 份任务回放摘要继续保留,只是退出了默认加载路径。

这次实践的核心不是文件压缩,而是重新定义长期上下文的职责。

上下文不是一块连续的文本

在真实工程任务里,Agent 至少要协调五类来源:系统与应用规则、工作区说明、跨会话记忆、当前线程,以及磁盘或线上环境中的事实。

Coding Agent 的五层上下文

它们的更新频率和权威性并不相同。

系统安全边界相对稳定;工作区规则随仓库演进;当前线程不断增长;提交号、部署状态和运行日志随时变化。把这些信息合并进同一个 Markdown 文件,会隐藏两个关键属性:事实的有效期,以及出现冲突时谁更权威。

这也是很多“模型降智”体感的来源。模型可能没有变,但输入里同时存在旧包管理器、新锁文件和一次临时绕行方案。三条记录都以肯定语气出现,Agent 需要自己还原时间线。它可能选择错误,也可能为了避免错误而反复确认。

因此,长期上下文治理首先是信息架构问题,不是文本压缩问题。

MEMORY.md 最适合扮演控制面

主记忆不应保存所有项目数据,更适合保存决策所需的控制信息:

  • 稳定的用户偏好与验收定义;

  • 架构、隐私、许可和安全边界;

  • 工作区之间的信任关系;

  • 当前事实应到哪里核验;

  • 信息冲突时采用什么优先级。

换句话说,MEMORY.md 应该告诉 Agent “如何找到可靠事实”,而不是把所有事实都复制一份。

这个区别类似索引与数据页。索引的价值来自小、稳定、可定位;如果把整张表塞进索引,不仅查询成本上升,更新一致性也会恶化。

我最终把内容分成三层:

层级典型内容读取方式
活跃索引偏好、硬边界、决策规则、工作区入口新任务默认读取
日常日志当天进展、临时判断、待跟进事项按日期查阅
证据层命令输出、故障过程、发布回读、历史快照按任务或标识精确检索

凭据、私钥和客户私有内容不属于任何记忆层。它们应该留在专用秘密管理或受控数据系统中。

动态事实应该保存核验规则,而不是快照

最容易污染长期记忆的内容,是“写入时完全正确”的动态事实:

  • 当前版本号或提交号;

  • 某个部署地址和线上状态;

  • 某次测试通过;

  • 一次性故障的原因;

  • 某天的依赖选择。

这些句子看起来比普通日志更有价值,所以更容易长期保留。问题是它们的半衰期很短,且通常有更权威的数据源。

比起记录“当前生产是版本 X”,长期记忆更适合记录“涉及生产结论时,先读取部署指针并回读公开端点”。比起记录“项目使用 npm”,更适合记录“包管理器以仓库当前锁文件和最近的工作区规则为准”。

保存验证方法而不是动态结果,可以显著降低旧快照压过新事实的概率。

长线程压缩解决不了错误的源材料

上下文过长时,compaction 很有价值。OpenAI 针对长上下文和工具密集任务建议在里程碑后压缩,并在长任务中重新锚定目标。压缩可以减少后续 Token,却不能把含糊的源材料自动变成正确知识。

如果压缩前同时存在三个冲突版本,摘要可能只保留其中一个,却丢掉它为什么被选择的证据。此时文本更短了,错误反而更难追溯。

顺序应该是先治理源材料,再做压缩:删除重复指令,移走已过期事实,明确权威来源,最后把当前里程碑压成可继续工作的状态。

OpenAI 的模型指南也给出类似方向:减少重复提示和无关工具,并对真实工作负载做评测。官方内部 Coding Agent 的方向性结果显示,精简系统提示可以同时改善评测得分和 Token 使用。它不能证明任何一份本地记忆的具体收益,但说明了上下文治理值得进入工程指标。

一次可审计的瘦身流程

这次清理没有从删除开始,而是从盘点开始:

MEM_DIR="$HOME/.codex/memories"

wc -l -c "$MEM_DIR/MEMORY.md" "$MEM_DIR/memory_summary.md"
du -sh "$MEM_DIR"
find "$MEM_DIR" -maxdepth 3 -type f -print

盘点发现除主文件外,还有 289,360 字节的阶段性原始聚合、39 份已处理更新单、一份重复归档和 3 个 .DS_Store。逐项确认后清理。62 份回放摘要共约 335 KB,因具有独立证据价值而保留。

随后先备份主文件与摘要,再重写活跃索引。新的硬预算是:主记忆不超过 150 行或 15 KiB,摘要不超过 60 行或 4 KiB。预算不是普遍标准,只是迫使每条新增内容说明其默认加载价值。

自动脚本中途遇到了 macOS awk 正则兼容问题,暂存区还存在 Markdown 空白错误。因此结果没有以脚本返回值为准,而是用下面三项回读:

git status --short
git diff --cached --stat
git diff --cached --check

最终提交包含 41 个文件变化,新增 208 行、删除 6,447 行;仓库压缩后只剩一个约 402 KiB 的 pack,工作区干净。

这里值得保留的不是某条具体命令,而是验收结构:任何自动化阶段都必须能回读实际状态,删除操作必须可恢复,外部事实必须回到权威来源验证。

衡量治理效果需要固定任务集

文件大小下降不等于 Agent 一定更聪明。要确认治理收益,需要在相同模型和仓库状态下,用固定任务对比:

  • 发出要求到首次有效行动的时间;

  • 输入、输出 Token;

  • 过期事实误引次数;

  • 冲突导致的重复确认;

  • 最终验收成功率。

新任务与旧长线程应分开。前者主要反映默认记忆层,后者还包含已经加载的历史、工具输出和压缩状态。冷缓存与热缓存也不应直接比较。

本次清理能确认的,是默认主记忆减少 95.7%,长期约束仍然保留,历史证据仍可按需检索。它不能单独证明所有工作负载固定提速多少。

结语

Coding Agent 的长期记忆最终会遇到和生产数据一样的问题:职责膨胀、重复副本、陈旧快照、权威来源不清,以及缺乏生命周期。

解决方法不是定期清空,也不是无限追加。更可靠的结构是让活跃记忆成为一份小而稳定的索引,让按日日志承载时间线,让证据层保留可追溯细节,再用固定任务持续评测。

“记住一切”听起来很强大。工程上更有用的能力,是知道哪些信息仍然可靠,其他信息应该去哪里核验。

参考资料

posted on 2026-08-25 21:09  执子念  阅读(15)  评论(0)    收藏  举报

导航