博客 • 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 的差別。

返回博客