博客 • Claude Code
Claude Code 终端里超过 20 万 token 的会话闲置约 54 分钟后,怎样用设置 JSON 关掉自动压缩?
Claude Code 2.1.299 的更新说明写得很具体:终端里超过 20 万 token 的会话,闲置大约 54 分钟后,会在一小时提示缓存到期前被压缩,这样下一条消息不必把整段历史再算一遍。压缩会用摘要换掉消息历史。要阻止这次替换,改的是 settings.json,不是再发一条提示。
Messages API 里 compaction 块要落哪些字段,写在那篇 API 文。会话、权限和 JSON 工作流写在Claude Code 工作流那篇。本篇只写终端闲置压缩:它何时换掉历史,以及 settings.json 里哪两个字段能把它关掉或抬高门槛。
- 对象是终端会话,而且当时走的是一小时提示缓存。
- 门槛是大约 20 万 token,闲置大约 54 分钟。CLAUDE_CODE_IDLE_COMPACT_MIN_TOKENS 只改这个 token 下限。
- 要留下原文,idleCompaction 写成布尔值 false。写成字符串 false,形状就不对。
- 关掉之后,一小时缓存仍会到期。下一条消息可能把整段历史再算一遍。你换来的是历史不被摘要替换。
直接结论:终端、一小时缓存、大约 20 万 token、闲置大约 54 分钟,历史会被摘要换掉。settings.json 里 idleCompaction 用布尔值 false 才能关掉。
它在什么条件下才会换掉历史?
2.1.299 的更新说明把范围限定在终端:超过 20 万 token 的会话,闲置大约 54 分钟,会在一小时提示缓存到期前压缩。同一条说明给出关掉的方法,以及改 token 下限的环境变量,并写明这两项需要 2.1.290 或更高。2.1.302 又在 /config 里加了一行 Idle compaction,压缩之后的提示也会告诉你怎么关掉。原文在Claude Code 更新说明。
提示缓存文档把同一件事说成:终端会话正处在一小时 TTL 上,并且长时间闲置时,Claude Code 可以在缓存到期前不久压缩它。订阅套餐内的主会话默认用一小时。用量额度、API key 或云厂商上的主会话默认是五分钟。文档里的闲置压缩,写的是一小时那一条。关掉的设置名是 idleCompaction,值为 false,版本同样是 2.1.290 或更高。文档在提示缓存文档。
settings.json 里要写哪两个字段?
一个字段决定开还是关,一个字段只改 token 下限。env 里的值是字符串,因为 Claude Code 的环境变量在设置文件里就是字符串。200000 写成数字,形状就不对。
{
"idleCompaction": false,
"env": {
"CLAUDE_CODE_IDLE_COMPACT_MIN_TOKENS": "200000"
}
}
只想少压缩、不想关掉时,把字符串里的数字调高。更新说明说这个变量改的是 20 万 token 的下限,没有说它会改那大约 54 分钟。2.1.302 之后也可以在 /config 里开关,不必手改文件。手改时仍要是布尔值,不是字符串。
这份 JSON 用什么 Schema 卡住形状?
用 JSON Schema 卡住类型。idleCompaction 必须是布尔值。env 里的门槛必须是字符串。Schema 不证明你该不该关掉。true 的形状仍然合法。要留下历史,应用规则才把 true 退回 false。
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"required": ["idleCompaction"],
"properties": {
"idleCompaction": { "type": "boolean" },
"env": {
"type": "object",
"properties": {
"CLAUDE_CODE_IDLE_COMPACT_MIN_TOKENS": { "type": "string" }
},
"required": ["CLAUDE_CODE_IDLE_COMPACT_MIN_TOKENS"]
}
}
}
| 看到的设置 | Schema | 要留下历史时 |
|---|---|---|
| idleCompaction 写成字符串 false | 失败。这里要布尔值。 | 先改成布尔值,再决定开还是关。 |
| 门槛写成数字 200000 | 失败。env 的值是字符串。 | 改成字符串 200000,或删掉这一项用默认门槛。 |
| idleCompaction 为 true,形状正确 | 通过。true 是布尔值。 | 要留下历史就改成 false。true 表示闲置压缩仍会换掉历史。 |
压缩之后,什么还在,什么已经被换掉?
文档写的是:压缩用摘要换掉消息历史,会话层的缓存前缀因此不再相同。系统提示那一层会继续用,除非这次恢复带着一份本来就会变的系统提示。项目上下文从磁盘重读。CLAUDE.md 和记忆从会话开始后没有改过,这一层才能命中缓存。这不是 Messages API 那篇里的 compaction 块。
| 这一层 | 压缩之后 |
|---|---|
| 消息历史 | 被摘要换掉。下一条请求的会话前缀和压缩前不同。 |
| 系统提示 | 通常继续用原来那一层。恢复时如果带着本来就会变的系统提示,第一次压缩会改用当前提示,这一层重建一次。 |
| CLAUDE.md 和记忆 | 从磁盘重读。会话开始后没有改过,才能命中缓存。会话中途改过的 CLAUDE.md,要等压缩、清空或重启才进入会话。 |
| 更早调用过的工具 | 2.1.304 把更早调用过的工具名字加进转录视图里的压缩摘要,快捷键是 Ctrl+O。更新说明写的是名字,不是整份参数 JSON。参数要自己另存。 |
/recap 不是同一次替换。它把摘要追加成命令输出,消息历史还在,缓存前缀也还在。/rewind 是截回更早的一轮,不是写成摘要。闲置压缩才会用摘要换掉历史。
这和 Messages API 的压缩文有什么差别?
| API 那篇 | 本篇 | |
|---|---|---|
| 发生在哪 | Messages API 的会话恢复 | Claude Code 终端,一小时缓存上的闲置 |
| 要校验的 JSON | compaction 块里必须原样留下的字段 | settings.json 里的 idleCompaction 和 token 下限 |
| 怎样不停 | 不靠把闲置开关写成 false | idleCompaction 写成布尔值 false,或在 /config 里关掉 |
在 JSONNote 里怎样核对这份设置?
- 1选对操作
打开 JSON Schema。操作选「用 Schema 校验」。第一栏贴设置,第二栏贴上面的 Schema。idleCompaction 只能是布尔值。门槛如果写了,只能是字符串。
- 2撞四条坏数据
idleCompaction 写成字符串 false,或删掉 idleCompaction,或把门槛写成数字 200000,或留下 env 却删掉里面的门槛。这四条都会失败。上面那份 false 的设置会通过。通过只说明形状对。
- 3对比 false 和 true
打开 JSON 对比 Diff。第一栏贴 idleCompaction 为 false 的设置。第二栏只把 idleCompaction 改成 true。门槛字符串可以相同。两份都能通过 Schema。挡住自动替换历史的是 false,不是这次形状检查。
常见问题
这和手动 /compact 是同一次吗?
不是。/compact 是你在任务间隙自己跑的。闲置压缩是终端在大约 54 分钟没有新消息、会话又超过大约 20 万 token、并且正处在一小时缓存上时,自己换成摘要。两者都会换掉历史。只有闲置这一次由 settings.json 的 idleCompaction 关掉。
API key 会话也会在 54 分钟后压缩吗?
文档把闲置压缩写在一小时 TTL 的终端会话上。用量额度、API key 或云厂商上的主会话,默认 TTL 是五分钟,不是一小时。更新说明里的大约 54 分钟,是赶在一小时缓存到期之前。五分钟那一档,不要套用这 54 分钟。
关掉之后,下一句话还会很慢吗?
会。更新说明给这个功能的理由,就是避免下一条消息把整段历史再算一遍。关掉只是不让摘要换掉历史。缓存到期之后,下一条消息仍可能把未压缩的历史重新处理。你换来的是原文还在。
和 9 月那篇 Conversation Compaction 是同一篇吗?
不是。那篇写 Messages API 在压缩前后要原样落盘的字段,用来恢复 session。本篇写 Claude Code 终端在闲置后换掉历史,以及 settings.json 里怎样关掉。两篇都叫压缩,落盘的 JSON 不是同一份。
工具参数会留在压缩摘要里吗?
2.1.304 写明的是:转录视图里的压缩摘要会带上更早调用过的工具名字,快捷键是 Ctrl+O。它没有说整份参数 JSON 会留在摘要里。参数还要的话,在压缩前自己另存一份,再用 Schema 校验那一份。
总结
终端里超过大约 20 万 token 的会话,在一小时缓存上闲置大约 54 分钟后,历史会被摘要换掉。CLAUDE.md 从磁盘重读。工具名字可以从 2.1.304 起出现在转录摘要里,参数 JSON 要自己另存。
直接结论:要留下历史就把 idleCompaction 写成布尔值 false;门槛若要改,写成字符串;关掉不会阻止缓存到期;/recap 和 /rewind 都不是这次闲置替换。
下一步:用 Schema 卡住 idleCompaction 的布尔值和门槛字符串,再用 Diff 看出 false 和 true 的差别。