资讯详情

第四章:我是如何扒开 Claude Code 记忆与上下文压缩机制的

📅 2026/10/4 9:50:30 | 华诺云谱 👁 阅读
第四章:我是如何扒开 Claude Code 记忆与上下文压缩机制的
1. 长会话为什么会“失忆”从一次 400 报错说起如果你用 Claude Code 跑过稍微大一点的重构任务大概率见过这个报错400 Token Limit Exceeded。前一秒它还在帮你改src/services/compact/里的逻辑后一秒你贴了一段日志它直接翻脸不认人连刚才改过哪个文件都答不上来。这不是模型变笨了而是上下文窗口被塞满了。Claude Code 面对的是一个很现实的矛盾代码库动辄几万行排查一个 Bug 可能聊半小时但 API 的上下文窗口是有限的而且越长越贵。它必须做两件事——保留关键信息同时不撑爆 Token 预算。这套机制拆开看主要落在三个地方src/services/compact/负责压缩src/memdir/负责记忆分层src/tools/AgentTool/负责分身试错。我实测下来理解这三块之后你对“长会话里信息怎么被保留、裁剪、回填”会有一个非常具体的画面。这篇就按可跟做的顺序来先讲压缩触发点怎么观察再讲记忆文件怎么落地然后给出可复制的配置片段最后把常见报错一个个对照排查。适合已经在用 Claude Code 做长期编码、或者想自己搭 Agent 记忆层的人。核心检索词先摆出来Claude Code 上下文压缩、记忆机制、AgentTool、git worktree。这几个词贯穿全文你可以在每一节里找到对应的操作动作。2. 压缩链路拆解stripImages 与 PTL 逃生舱怎么触发2.1 压缩前先“瘦身”图片和文档被替换成占位符Claude Code 在发起压缩总结之前会先做一次大瘦身。原因很直接把几兆的截图重新发给模型只为了让它生成一句“用户发了一张报错截图”是极度浪费钱的。源码里stripImagesFromMessages这个函数干的就是这件事——扫描消息内容把image和document类型的块替换成纯文本占位符[image]、[document]。你可以这样理解压缩不是一上来就总结而是先把“体积大但信息密度低”的部分砍掉再对剩下的文本做摘要。这个顺序很关键因为如果先总结再剥离总结请求本身可能就已经超载了。2.2 连压缩请求都超载truncateHeadForPTLRetry 逃生舱这是我在源码里看到最硬核的设计之一。设想一个场景用户一次性塞入太多巨大文件导致连“发起压缩总结”这个请求本身都超过了 API 的最大 Token 限制。按普通逻辑系统直接死锁崩溃。源码里专门写了truncateHeadForPTLRetry作为最后的逃生舱。它的逻辑分两种如果 API 明确返回了超出的 Token 数量tokenGap就精准计算要丢弃几轮对话累加估算直到覆盖这个 gap如果连超出多少都不知道就默认抛弃最老的 20% 历史记录dropCount Math.max(1, Math.floor(groups.length * 0.2))。官方注释写得很直白这是最后的逃生舱丢弃最老的上下文虽然有损但能防止对话彻底卡死。真金白银买来的经验——宁可丢老信息也不能让整个会话挂掉。2.3 怎么观察压缩触发点想亲眼看到压缩发生可以构造一个多轮长上下文任务。我的做法是先让 Claude Code 读一个中等大小的模块然后连续追问十几轮细节每轮都让它引用之前改过的文件。当对话历史累积到一定程度你会观察到它开始“概括”前面的内容而不是逐字引用。验证动作在会话里让它列出“到目前为止我们改过哪些文件”。如果它列出的条目比实际少或者把早期改动合并成一句模糊描述说明压缩已经触发。这时候你可以对比压缩前后的回答差异记录哪些信息被保留了、哪些被裁剪了。注意压缩是有损的。关键决策、文件路径、报错原文这类信息最好在对话早期就写进记忆文件而不是指望压缩帮你留住。3. 记忆分层落地MEMORY.md 索引 详情文件的可复制配置3.1 没有向量数据库只有文件系统加一段 Prompt外界一直猜 Claude Code 连了向量数据库管理长期记忆。翻开src/memdir/memdir.ts会发现它极其务实地用了本地文件系统外加一段教科书级的 System Prompt。核心是“两步走法则”Step 1把详细记忆写进独立的.md文件比如user_role.md、feedback_testing.md带name、description、type的 frontmatterStep 2在MEMORY.md里加一行指针每个条目一行控制在约 150 字符以内。MEMORY.md是索引不是记忆本身。它会被无条件塞进每一次对话上下文所以必须严防死守。源码里做了强制截断MAX_ENTRYPOINT_LINES 200MAX_ENTRYPOINT_BYTES 25_000。一旦超标直接从末尾一刀切并附上大写警告 WARNING: MEMORY.md is ... Only part of it was loaded.。模型下次读到这句警告自己就会去精简索引。3.2 可复制的 settings 片段如果你在 Claude Code 里配置记忆目录可以参考下面这个结构。路径按你项目实际位置调整字段名保持一致{ memory: { enabled: true, entrypoint: MEMORY.md, directory: .claude/memory, maxEntrypointLines: 200, maxEntrypointBytes: 25000, autoCompact: true } }对应的目录长这样.claude/memory/ ├── MEMORY.md # 索引每行一条150 字符 ├── user_role.md # 详情文件 └── feedback_testing.md # 详情文件MEMORY.md内容示例# 全局记忆索引 - [用户角色](./user_role.md): 后端工程师主用 TypeScript 和 Go - [测试反馈](./feedback_testing.md): 集成测试必须跑真实数据库不用 mock3.3 三件套对齐Base URL Key Model ID如果你是通过兼容接口接入 Claude Code配置里必须写全三件套缺一个都会在请求阶段报错# 示例配置字段名按你的客户端要求调整 base_url https://taotoken.net/api api_key 你的 API Key model claude-sonnet-4-20250514Base URL 用https://taotoken.net/api不要加多余路径。Key 在控制台的 API Keys 页面生成。Model ID 按你实际要用的模型填别照抄示例里的名字。这三项对齐之后记忆文件和压缩机制才有稳定的请求通道。4. 验证请求与成功结果构造多轮长上下文任务4.1 构造任务打开 Claude Code进入一个真实项目。第一步让它读一个模块并总结请阅读 src/services/compact/ 下的文件列出每个文件的职责写进 .claude/memory/compact_module.md第二步连续追问每轮都要求它引用之前的内容基于刚才的总结compact.ts 里处理图片剥离的函数叫什么它把 image 块替换成了什么第三步累积到十几轮后触发压缩再问到目前为止我们讨论过哪些文件分别改了什么4.2 成功结果长什么样如果配置正确你会看到早期写入MEMORY.md的条目在压缩后依然被引用因为索引文件每次都会加载而对话历史里的细节可能被概括。验证点是——它能否准确说出compact_module.md这个文件的存在以及里面记录的函数名。请求层面成功的标志是返回200响应里choices字段有正常内容。如果走的是流式你会看到 token 逐步返回没有中断。4.3 记录可复现的排查步骤每次验证都记下三样东西触发压缩的轮数、被保留的信息、被裁剪的信息。我试过在同一个项目里跑两遍第一遍不写记忆文件第二遍先写MEMORY.md再聊。结果很明显第二遍在压缩后仍能准确回答早期决策第一遍则开始含糊。这个对比就是你判断记忆机制是否生效的最直接证据。5. 常见报错对照排查401、local proxy failed、reading choices、OAuth5.1 401 Unauthorized最常见的原因是 Key 没配对或者 Base URL 写错。检查顺序先确认api_key字段填的是控制台生成的 Key没有多余空格再确认base_url是https://taotoken.net/api没有拼错路径。如果 Key 刚生成等几秒再试避免缓存。5.2 local proxy failed这个报错通常出现在本地网络配置层面。先确认你的请求地址是直连的 API 地址不要经过额外的本地转发层。检查配置文件里有没有残留的代理字段删掉后重启客户端。如果用的是环境变量确认HTTP_PROXY、HTTPS_PROXY没有被设置成无效值。5.3 reading choices 相关报错这类报错说明请求发出去了但响应结构不符合预期。常见原因是 Model ID 填错或者接口返回了错误对象而不是正常的choices数组。排查动作把 Model ID 换成确认可用的值重新发一次最小请求。如果还报错检查请求体里有没有多余的字段导致服务端拒绝。5.4 OAuth 相关报错如果你用的是需要 OAuth 的客户端报错通常和 token 过期有关。重新走一遍授权流程确认回调地址和客户端配置一致。OAuth 和 API Key 是两套体系别混用——用 API Key 的场景就不要再配 OAuth。5.5 三件套检查清单出现任何请求类报错先过一遍这个清单检查项正确值常见错误Base URLhttps://taotoken.net/api多了/v1或结尾斜杠API Key控制台生成复制时带了空格Model ID实际可用模型照抄示例名6. 把记忆层接进你的工作流压缩和记忆这两块跑通之后下一步是让 AgentTool 和 git worktree 发挥作用。当你要做破坏性实验时让子代理在独立的 worktree 里跑主分支不受影响。配置里isolation: worktree这个字段就是干这个的底层会自动调git worktree add创建平行目录。如果你想把记忆能力接到自己的工具链里可以从 API Keys 页面拿到 Key再对照接入文档把 Base URL 和 Model ID 填好。验证模型是否通直接用模型对话发一条最小请求最快。长期跑编码任务、需要 Agent 持续记忆的场景Coding Plan 更合适省得每次手动配。最后留一个实用技巧每次开新会话前先让 Claude Code 读一遍MEMORY.md把索引加载进来。这一步花不了几秒但能让它在长会话里少失忆好几次。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑