Claude Code 不自动压缩上下文?阈值设置与长任务管理实践
用第三方模型跑 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。
可行的思路是把"理解"这一步的产物持久化,让后续会话直接读取而不是重新推导:
- 先用内置初始化命令生成项目说明。多数工具都有
/init一类的命令,产出如CLAUDE.md的项目级说明,作为默认加载的基线。 - 拆分职责,建立多个记忆文件。例如
memory.md存长期有效的架构约定与坑,plan.md存当前目标与拆解,task.md存进行中的进度。粒度越清晰,读取时越省 token。 - 通过自定义工具暴露读写入口。用 MCP 之类的方式提供
get_memory、update_memory、get_workspace_info等能力,让模型在动手前先查、完成后回写,而不是每次从零探索。 - 在会话开头明确指令。例如"先读 memory.md 和 plan.md,信息不足再探索代码",把它固定成习惯。
- 任务结束时强制更新。不更新的话,文件很快过期,反而误导后续会话。
这套做法的效果取决于模型是否愿意主动读文件。实测中有些模型会优先尝试读取工作区与记忆文件,缺失时才去探索;也有模型需要你在提示词里反复强调。建议先用一两个真实任务验证,再决定投入多少精力维护这些文件。
一份可执行的检查清单
- 确认当前版本是否支持相关的自动压缩环境变量(查
/help或官方文档) - 查清所用第三方模型的真实上下文窗口,据此设置
CLAUDE_CODE_AUTO_COMPACT_WINDOW - 设置
CLAUDE_AUTOCOMPACT_PCT_OVERRIDE,从 80 开始试 - 跑一段长对话,确认在预期位置触发压缩
- 观察压缩前后的缓存命中与费用变化,判断是否划算
- 把不相关的任务拆到不同会话,不要靠压缩硬扛
- 建立
CLAUDE.md/memory.md/plan.md等文件,减少重复扫描 - 升级前在独立环境验证兼容性,不要在生产配置上直接跳版本
小结
Claude Code 的自动压缩并不是没有,而是默认参数假设了一个较大的上下文窗口,用在第三方模型上容易错位。把窗口大小和触发百分比这两个参数显式设好,问题基本能解决大半。至于要不要重度依赖压缩,取决于任务形态:短任务开新会话更干净,长任务则压缩加外部记忆文件更稳妥。真正需要避免的,是把一堆不相关的工作堆进同一个上下文,然后指望压缩来收拾。
环境变量属于易变细节,实际使用前请以官方最新文档和你当前版本的行为为准。