博客 • 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 分钟,历史会被摘要换掉。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,门槛仍写着默认的 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。

设置的形状。idleCompaction 为 true 时,这套类型仍然通过。
{
  "$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 终端,一小时缓存上的闲置
要校验的 JSONcompaction 块里必须原样留下的字段settings.json 里的 idleCompaction 和 token 下限
怎样不停不靠把闲置开关写成 falseidleCompaction 写成布尔值 false,或在 /config 里关掉

在 JSONNote 里怎样核对这份设置?

  1. 1
    选对操作

    打开 JSON Schema。操作选「用 Schema 校验」。第一栏贴设置,第二栏贴上面的 Schema。idleCompaction 只能是布尔值。门槛如果写了,只能是字符串。

  2. 2
    撞四条坏数据

    idleCompaction 写成字符串 false,或删掉 idleCompaction,或把门槛写成数字 200000,或留下 env 却删掉里面的门槛。这四条都会失败。上面那份 false 的设置会通过。通过只说明形状对。

  3. 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 的差别。

返回博客