Claude

Claude Code 不自动压缩上下文?阈值设置与长任务管理实践

编辑部阅读约 6 分钟

用第三方模型跑 Claude Code 时,常感觉上下文不会像 Codex 那样自动压缩。原因多半不是功能缺失,而是触发阈值与模型窗口不匹配。本文整理两个关键环境变量的用法、压缩与开新会话的取舍,以及用文件沉淀项目记忆、减少重复扫描代码的做法。

当用第三方模型(比如智谱的 GLM 系列)驱动 Claude Code 时,很容易产生一个疑问:为什么它不像 Codex 那样,聊到一定长度就自动把前文压缩掉?尤其是在固定使用某个旧版本、担心升级后不兼容的情况下,这种"它到底会不会自己处理上下文"的不确定感会更明显。

先说结论:自动压缩这个能力本身是有的,问题通常出在"什么时候触发"。它的触发逻辑依赖上下文窗口大小和占用百分比,而第三方模型的窗口往往比官方模型小得多,默认参数就容易错位——要么迟迟不触发,要么一触发就已经接近超限。下面把触发机制、参数配置、以及"压缩到底该不该依赖"的争议分开说清楚。

自动压缩为什么"看起来"没生效

常见的原因大致有三类:

  • 阈值到得太晚。自动压缩一般是在上下文占用达到某个较高比例时才启动。官方大窗口模型按这个比例算,触发点非常靠后,用户在小窗口模型上照搬同样的参数,就会觉得"怎么一直不压缩"。
  • 窗口大小没被正确识别。走兼容接口的第三方模型,客户端未必知道它真实的上下文长度,可能按一个偏大的默认值估算,导致百分比计算失真。
  • 版本行为差异。较旧的版本对某些环境变量的支持可能不完整,或者默认值不同。这就是为什么"同一个模型、别人能压缩、你不能"的情况经常出现。

另外要区分两个概念:自动压缩(达到阈值自动执行)和手动压缩(主动输入 /compact 之类的命令)。后者任何时候都能用,前者才需要调参。

用两个环境变量把触发点调到合适位置

社区里被反复提到的两个变量,作用正好互补:

环境变量 作用 示例值
CLAUDE_CODE_AUTO_COMPACT_WINDOW 覆盖/声明上下文窗口大小,让百分比基于这个值计算 250000
CLAUDE_AUTOCOMPACT_PCT_OVERRIDE 直接指定触发压缩的占用百分比 80

配置方式很直接,写进 shell 配置或启动脚本即可:

export CLAUDE_CODE_AUTO_COMPACT_WINDOW=250000
export CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=80

临时验证可以先在单次终端会话里 export,再启动工具,确认行为符合预期后再固化到 ~/.zshrc、~/.bashrc 或项目的 .env 里。

几个实操建议:

  • 窗口值不要虚报。设得比模型真实窗口还大,压缩会在真正超限之后才想启动,反而更糟。宁可保守一点。
  • 百分比留出余量。压缩本身、工具调用输出、以及后续对话都要占空间,80% 左右是比较常见的起点,再根据实际表现上下微调。
  • 先用小任务验证。跑一段可控的长对话,观察是否在预期位置触发,再投入正式工作。
  • 善用状态查看。多数版本能通过状态栏或 /context 一类的命令看到当前占用,结合它判断参数是否生效。

需要提醒的是,这类环境变量的名称和语义会随版本演进,不同第三方模型的适配层也可能有自己的处理方式。上面给出的写法来自实际使用经验,请以你所用版本的官方说明和 --help、/help 输出为准,升级前后各验证一次。

压缩值得依赖吗:两种做法各有适用场景

关于自动压缩的价值,实践者的看法分歧很大。

一种观点认为它极其有用,尤其是"一个目标跑很久"的长时程任务,上下文必然会撑满,不压缩根本走不下去。另一种观点认为收益有限:压缩会重置 KV Cache,缓存命中率下降,费用反而上升;而且压缩是有损的,早期细节被摘要掉之后,模型容易在后面对不上号,产生莫名其妙的错误。

两种说法都对,只是对应的任务形态不同:

场景 更合适的做法 原因
任务短、可切分、彼此不相关 一个会话只做一件事,做完就新开 上下文干净,缓存命中高,没有压缩损失
长时程任务、目标需要持续推进 打开自动压缩,配合外部记忆文件 单会话无法承载全程上下文
一个会话里混着多个不相关任务 拆开 无论怎么压缩都会互相干扰

一个容易被忽略的点是:把不相关的任务塞进同一个上下文,压缩只会把混乱一起压缩进去。这种情况下优化参数没用,该做的是拆会话。

如果长任务必须连续运行,本地机器的休眠、断网、终端断开都会让会话中断,重连后上下文衔接很麻烦。这类情况下,把 Claude Code 放在一台长期在线的远程 Mac 上跑(例如整机托管在新加坡机房、按月租用、远程连接使用)是可选方案之一,网络环境相对稳定,适合需要长时间在线的场景;本地条件够用则不必多此一举。

减少重复扫描:把分析结果沉淀成文件

讨论中另一个高频痛点是:让 AI 给已有代码加功能,不同工具、甚至同一工具的不同会话,都会把代码库重新扫一遍。代码越大,越费时间也越费 token。

可行的思路是把"理解"这一步的产物持久化,让后续会话直接读取而不是重新推导:

  1. 先用内置初始化命令生成项目说明。多数工具都有 /init 一类的命令,产出如 CLAUDE.md 的项目级说明,作为默认加载的基线。
  2. 拆分职责,建立多个记忆文件。例如 memory.md 存长期有效的架构约定与坑,plan.md 存当前目标与拆解,task.md 存进行中的进度。粒度越清晰,读取时越省 token。
  3. 通过自定义工具暴露读写入口。用 MCP 之类的方式提供 get_memory、update_memory、get_workspace_info 等能力,让模型在动手前先查、完成后回写,而不是每次从零探索。
  4. 在会话开头明确指令。例如"先读 memory.md 和 plan.md,信息不足再探索代码",把它固定成习惯。
  5. 任务结束时强制更新。不更新的话,文件很快过期,反而误导后续会话。

这套做法的效果取决于模型是否愿意主动读文件。实测中有些模型会优先尝试读取工作区与记忆文件,缺失时才去探索;也有模型需要你在提示词里反复强调。建议先用一两个真实任务验证,再决定投入多少精力维护这些文件。

一份可执行的检查清单

  • 确认当前版本是否支持相关的自动压缩环境变量(查 /help 或官方文档)
  • 查清所用第三方模型的真实上下文窗口,据此设置 CLAUDE_CODE_AUTO_COMPACT_WINDOW
  • 设置 CLAUDE_AUTOCOMPACT_PCT_OVERRIDE,从 80 开始试
  • 跑一段长对话,确认在预期位置触发压缩
  • 观察压缩前后的缓存命中与费用变化,判断是否划算
  • 把不相关的任务拆到不同会话,不要靠压缩硬扛
  • 建立 CLAUDE.md / memory.md / plan.md 等文件,减少重复扫描
  • 升级前在独立环境验证兼容性,不要在生产配置上直接跳版本

小结

Claude Code 的自动压缩并不是没有,而是默认参数假设了一个较大的上下文窗口,用在第三方模型上容易错位。把窗口大小和触发百分比这两个参数显式设好,问题基本能解决大半。至于要不要重度依赖压缩,取决于任务形态:短任务开新会话更干净,长任务则压缩加外部记忆文件更稳妥。真正需要避免的,是把一堆不相关的工作堆进同一个上下文,然后指望压缩来收拾。

环境变量属于易变细节,实际使用前请以官方最新文档和你当前版本的行为为准。

Claude Code长任务环境变量上下文压缩KV Cache