
1. 这个实验到底在折腾什么先把这个标题拆开看。上下文压缩指的是 AI 编码代理在长会话里因为上下文窗口塞满了系统自动把前面的对话历史做摘要、截断或者向量化归档腾出空间继续跑。AI 编码代理就是那种能自己读代码、改文件、跑命令、看报错的自动化编程助手比如 Codex 这类 CLI 工具。long_mem和engram是两种记忆机制的代称一个偏向长期记忆存储一个偏向记忆痕迹的激活与召回。整个实验的核心问题是当上下文被压缩之后代理还能不能接得上之前的工作状态会不会出现失忆导致重复劳动或者逻辑断裂。这个实验跑了 10 天积累了 430 条公开记录。记录的内容大概率包括每次压缩前后的对话轮次、代理的行为变化、任务完成率、错误率、以及人工干预的次数。为什么要做这个因为实际用 Codex 这类工具写代码的人都知道一个稍微复杂点的重构任务动辄几十轮对话上下文窗口根本不够用。系统一压缩代理就可能忘了前面定的命名规范、忘了已经改过哪些文件、甚至忘了用户明确说过的约束条件。这不是小问题这是直接决定代理能不能干长活的关键。适合谁看如果你只是用 AI 补全几行代码那这个实验跟你关系不大。但如果你在用 Codex CLI 做项目级开发或者你在自己搭 AI 编码代理的工作流那这 430 条记录里的坑和结论值得你花时间琢磨。我接下来会从实验设计、核心机制、实操细节、问题排查几个角度把这个实验的逻辑和发现拆开讲同时补充一些我在类似场景下的经验。2. 实验设计与核心思路拆解2.1 为什么选 10 天和 430 条记录这个量级10 天不是一个随便拍的数字。AI 编码代理的上下文压缩问题在短会话里几乎看不出来。你跑个三五轮窗口还没满压缩根本没触发。只有把时间拉长到一周以上让代理经历多次压缩、多次任务切换、多次跨文件修改才能真正暴露接不上的问题。430 条公开记录平均每天 43 条这个密度说明实验者不是偶尔跑一下而是把代理当成了日常开发的主力工具在用。从统计角度看430 条记录足够覆盖几种典型场景单文件小修改、多文件重构、新功能开发、bug 修复、依赖升级。每种场景对上下文连续性的要求不一样。比如单文件小修改压缩了也无所谓代理重新读一下文件就行。但多文件重构代理必须记住我已经改了 A 文件的接口接下来要改 B 文件的调用这种跨文件的逻辑链一旦断了代理就会做出自相矛盾的修改。注意如果你自己想复现这个实验不要只跑一种任务类型。任务类型的多样性比记录条数更重要。我见过有人跑了 1000 条记录但全是单文件修改结论完全没有参考价值。2.2 long_mem 和 engram 两种记忆机制的分工这个实验里提到的 long_mem 和 engram我理解是两种不同层次的记忆方案。long_mem 更像是外挂的长期存储把压缩掉的历史对话、代码变更记录、用户偏好等存到一个可以检索的地方比如向量数据库或者结构化的 JSON 文件。当代理需要回忆用户之前说过要用 snake_case时就去 long_mem 里查。engram 则更偏向记忆痕迹的概念它不存储完整的历史而是存储一种激活模式。打个比方long_mem 像你的笔记本engram 像你的肌肉记忆。笔记本可以翻但翻得慢肌肉记忆不用翻但只能记住高频、重复的东西。在编码代理的场景里engram 可能表现为代理对某些常见的代码模式、项目结构、命名习惯形成了直觉不需要每次都去查 long_mem 就能做出合理决策。为什么要两种一起用因为单靠 long_mem每次压缩后都要重新检索延迟高而且检索结果可能不准确。单靠 engram遇到全新的、低频的约束条件就抓瞎。两者结合高频的走 engram低频的走 long_mem才能在压缩后既快又准地接上。2.3 压缩策略的选择摘要、截断还是向量化实验里肯定涉及了不同的压缩策略。常见的做法有三种第一种是摘要式压缩让模型把前面的对话总结成一段话第二种是截断式压缩直接丢掉最早的几轮对话第三种是向量化归档把历史对话转成向量存起来需要时再检索。摘要式压缩的问题是摘要本身会丢失细节。比如前面讨论了 10 个文件的修改方案摘要可能只写讨论了文件修改方案代理看了等于没看。截断式压缩更粗暴直接导致代理失忆。向量化归档看起来最优雅但检索的准确率是个大问题尤其是代码这种高度结构化的内容向量检索经常找不准。我推测实验者的做法是混合策略近期对话保留原文中期对话做结构化摘要保留文件路径、函数名、关键约束远期对话做向量化归档。这样在压缩触发时代理至少能拿到结构化的摘要知道之前改过哪些文件、定了什么规范而不是一片空白。3. 核心细节解析与实操要点3.1 压缩触发时机的判断逻辑上下文压缩不是等到窗口 100% 满了才触发那样就来不及了。通常会在窗口使用率达到 70% 到 80% 时开始准备压缩。实验里的 430 条记录应该能看出压缩触发时机对代理表现的影响。触发太早压缩频繁代理一直在回忆效率低触发太晚压缩时信息已经挤爆了摘要质量差。实操中你可以通过配置项来控制这个阈值。比如在 Codex 的配置里找到上下文管理的相关参数把触发阈值设在 0.75 左右。这个值不是固定的如果你的任务对上下文连续性要求极高比如大型重构可以调到 0.85让代理尽量多保留原文。但代价是压缩时的信息密度更大摘要可能更粗糙。提示压缩触发阈值和任务类型要匹配。我自己的经验是写新功能可以设低一点0.7因为新功能的上下文依赖相对少改老代码要设高一点0.85因为老代码的约束条件多丢一条就可能改错。3.2 压缩后代理接不上的三种典型表现从 430 条记录里我推测接不上主要有三种表现。第一种是重复劳动代理忘了已经改过的文件又重新改一遍甚至改回原来的样子。第二种是逻辑断裂代理忘了前面定的接口规范新写的代码和旧代码风格不一致导致编译错误或者运行时问题。第三种是约束遗忘用户明确说过不要动配置文件代理压缩后忘了直接把配置文件改了。这三种表现的严重程度递增。重复劳动浪费 token 和时间但还能救逻辑断裂会导致代码质量下降需要人工 review约束遗忘最危险可能直接破坏项目配置导致构建失败。针对这三种表现实验里应该记录了对应的缓解措施。比如针对重复劳动可以在压缩摘要里强制包含已修改文件列表针对逻辑断裂可以在摘要里保留接口定义和命名规范针对约束遗忘可以把用户约束单独存到 long_mem 里每次压缩后强制检索一次。3.3 engram 机制在代码场景下的具体落地engram 在代码场景下怎么落地我理解它可能表现为一种项目级记忆。代理在多次会话中逐渐学习到这个项目的代码风格、目录结构、常用工具函数。当上下文压缩后代理不需要重新读所有文件就能凭 engram 做出符合项目习惯的决策。举个例子项目里有一个工具函数叫formatDate放在utils/date.js里。代理第一次用的时候需要读文件才知道。但用了几天之后engram 里就记住了这个项目处理日期用 formatDate。压缩后代理直接调用formatDate不需要再去读 utils 目录。这就是 engram 的价值把高频、稳定的项目知识固化下来减少对上下文的依赖。但 engram 也有风险。如果项目重构了formatDate被移到了别的地方engram 还记着旧路径代理就会调用失败。所以 engram 需要定期刷新或者和 long_mem 配合当 long_mem 里检测到文件移动时同步更新 engram。4. 实操过程与核心环节实现4.1 实验环境的搭建与配置要复现这个实验你需要一套能跑 AI 编码代理的环境。核心组件包括一个支持长会话的 CLI 工具比如 Codex CLI一个可配置的上下文管理模块以及一个用于存储 long_mem 的持久化层可以是本地文件也可以是轻量数据库。配置上重点调整几个参数。第一是上下文窗口大小这个取决于你用的模型但你可以通过配置限制代理实际使用的窗口比例。第二是压缩策略选择混合策略近期保留原文中期做结构化摘要远期向量化。第三是 long_mem 的存储路径和检索方式建议用本地 JSON 文件起步简单可控等实验跑通了再考虑向量数据库。注意不要一上来就上向量数据库。我见过太多人卡在向量检索的调优上结果实验根本没跑起来。先用 JSON 文件把流程跑通验证了 long_mem 和 engram 的配合逻辑再考虑升级存储。4.2 记录采集的字段设计与实操430 条记录每条记录应该包含哪些字段从实验目的出发至少要有时间戳、任务类型、压缩触发时的窗口使用率、压缩策略、压缩前后的对话轮次、代理在压缩后的行为变化是否重复劳动、是否逻辑断裂、是否约束遗忘、人工干预次数、任务最终是否完成。采集这些字段的方式可以靠代理本身的日志也可以靠人工标注。我建议两者结合代理日志自动记录时间戳、窗口使用率、压缩策略这些客观数据人工标注行为变化和干预次数这些主观判断。标注的时候最好用统一的标签体系比如重复劳动、逻辑断裂、约束遗忘、正常接续方便后续统计。实操中我建议每跑完一个任务就立刻标注不要攒着。攒着的话回忆会失真标注质量下降。430 条记录如果每天标注 43 条每条花 2 分钟一天也就一个半小时完全可以接受。4.3 压缩摘要的生成模板与参数计算压缩摘要的质量直接决定代理能不能接上。实验里应该有一套摘要生成模板。我推测模板包含这几个部分任务目标、已完成步骤、待完成步骤、关键约束、已修改文件列表、接口定义和命名规范。生成摘要时要让模型按照这个模板来写而不是自由发挥。自由发挥的摘要经常漏掉关键信息。参数上摘要的长度要控制。太短了信息不够太长了又占窗口。我的经验是摘要长度控制在原对话的 10% 到 15% 比较合适。比如原对话 10000 token摘要控制在 1000 到 1500 token。计算方式很简单先统计原对话的 token 数然后按比例设定摘要的 max_tokens。如果摘要生成时超了就让模型压缩如果不够就让它补充细节。这个比例不是固定的任务越复杂摘要比例可以越高但一般不超过 20%。4.4 压缩后接续效果的验证方法怎么验证代理压缩后有没有接上最直接的方法是设计一组接续测试。比如在压缩前让代理修改一个文件的接口压缩后让代理修改另一个文件的调用。如果代理能正确修改调用说明它记住了接口变更如果改错了说明没接上。另一种方法是约束测试。在压缩前明确告诉代理不要修改 config 目录下的任何文件。压缩后给一个需要修改 config 的任务看代理会不会违反约束。如果违反了说明约束遗忘。这两种测试可以定期跑比如每天跑一次记录结果。430 条记录里应该有一部分就是这种测试记录。验证方法要标准化不然结果没法对比。5. 常见问题与排查技巧实录5.1 压缩后代理反复读同一个文件这是最常见的问题。代理压缩后忘了自己已经读过某个文件又去读一遍。浪费 token 不说还可能因为读到的内容和之前理解的不一致导致逻辑混乱。排查思路先看压缩摘要里有没有已读文件列表。如果没有那就是摘要模板的问题需要加上这个字段。如果有但代理还是反复读那就是 engram 没起作用代理没有形成这个文件我读过的记忆。这时候要检查 engram 的更新逻辑看看是不是压缩后没有触发 engram 刷新。解决方法在摘要模板里强制包含已读文件列表并且在压缩后主动触发一次 engram 更新把已读文件的信息固化进去。另外可以在代理的 prompt 里加一句压缩后优先检查已读文件列表避免重复读取。5.2 压缩摘要丢失关键约束条件用户说过的约束条件比如用 TypeScript 严格模式、不要引入新的依赖在压缩后经常丢失。这是因为摘要生成时模型倾向于总结做了什么而不是不能做什么。排查思路检查摘要模板里有没有关键约束这一项。如果没有加上。如果有但约束还是丢了那就是摘要生成时的 prompt 不够强调。可以在 prompt 里明确写必须保留所有用户明确提出的约束条件包括禁止事项。解决方法把用户约束单独存到 long_mem 里并且在每次压缩后强制检索一次。检索结果直接注入到压缩后的上下文里不依赖摘要生成。这样即使摘要漏了long_mem 也能兜底。5.3 engram 与 long_mem 的冲突处理engram 和 long_mem 有时候会冲突。比如 engram 记着日期处理用 formatDate但 long_mem 里记录了一次重构formatDate 已经被废弃了。这时候代理该听谁的排查思路看冲突发生的频率。如果偶尔发生可能是 engram 刷新不及时如果频繁发生那就是两者的优先级没定义清楚。解决方法定义明确的优先级规则。一般来说long_mem 里的显式记录优先于 engram 的隐式记忆。因为 long_mem 是用户或系统明确写入的engram 是代理自己总结的前者更可靠。在代理的决策逻辑里先查 long_mem如果 long_mem 有明确记录就用 long_mem 的如果没有再用 engram 的。5.4 常见问题速查表问题表现可能原因排查方法解决措施反复读同一文件摘要缺已读列表engram 未刷新检查摘要模板和 engram 更新日志补全摘要字段压缩后触发 engram 更新约束条件丢失摘要模板缺约束项prompt 强调不足检查摘要内容和生成 prompt约束单独存 long_mem压缩后强制检索engram 与 long_mem 冲突优先级未定义engram 刷新滞后统计冲突频率检查两者记录定义 long_mem 优先规则定期刷新 engram压缩后逻辑断裂摘要丢失接口定义和命名规范检查摘要是否包含接口和规范摘要模板强制包含接口定义和命名规范压缩触发过晚阈值设置过高查看压缩触发时的窗口使用率调低阈值到 0.75 到 0.85 之间提示这张表里的解决措施不是一次全上。先解决最频繁的问题观察效果再逐步加其他措施。一次性全上出了问题不好定位是哪个措施导致的。6. 我自己的实操心得与后续扩展跑这种实验最大的体会是压缩策略不是越复杂越好而是越稳定越好。我一开始尝试了很复杂的向量化归档结果检索准确率不稳定代理有时候能接上有时候接不上反而比简单的摘要式压缩更差。后来退回到结构化摘要 long_mem 兜底的方案虽然看起来朴素但胜在稳定代理的表现可预测。另一个心得是engram 的刷新频率要控制好。刷新太频繁engram 一直在变代理没有稳定的记忆刷新太少engram 过时了代理用旧知识做决策。我的经验是每天刷新一次或者在检测到项目结构发生重大变化时立即刷新。这个实验后续还可以这样扩展把 430 条记录按任务类型分组分别统计每种任务类型下压缩后的接续成功率找出哪种任务最怕压缩。然后针对最怕压缩的任务类型设计专门的压缩策略。比如多文件重构可以强制在压缩摘要里保留完整的文件依赖图单文件修改可以简化摘要只保留文件路径和修改点。最后分享一个小技巧在代理的 prompt 里加一句如果你不确定之前是否改过某个文件先查 long_mem 的已修改文件列表不要直接动手改。这句话能显著减少重复劳动我实测下来重复修改的次数少了大概三成。