gateway 的未辨識模型 ID,Claude Code 猜 200K 還是 1M:DISABLE_1M_CONTEXT、AUTO_COMPACT_WINDOW、MAX_CONTEXT_TOKENS 怎麼選
Claude Code 後面接的如果不是 Anthropic API,而是公司架的 LLM gateway,模型 ID 叫 my-gateway-opus(這是官方文件拿來舉例的名字,不是我手上真有這個環境),它不認得這個名字。不認得,就得猜這個模型的 context window 有多大。
猜多少,決定它什麼時候開始壓縮。猜得比後端真實上限大,後端會先拒絕請求,session 卡在那裡。猜得比較小,頂多是壓縮得早一點。兩種猜錯的代價差很多。
那它到底猜多少?我讀了兩份官方說法,答案對不上。
兩份官方說法對不上
changelog 的 2.1.323 區塊有兩條,我照原文貼:
1 | - Changed the context window assumed for a model ID that Claude Code doesn't recognize from 200K to 1M; use `/autocompact` to compact earlier, or `CLAUDE_CODE_DISABLE_1M_CONTEXT=1` to keep 200K |
第二條的後果寫得很直白:視窗比較小的別家模型,一旦滿了,每一回合都可能失敗,直到你 /clear。
我今天抓的 model-config 文件頁「Correct the window for a gateway or custom model ID」那一節是這樣寫的:
1 | Either of these warnings means Claude Code doesn't recognize your session's model ID, so it can't tell the model's context window and assumes 200K tokens: |
errors 頁列的警告文字也是 Model "<model>" isn't recognized · context assumed to be 200k tokens。
所以一邊說 2.1.323 起假設改成 1M,另一邊的文件還在說 200K。changelog 沒寫為什麼改,文件也沒寫。我不替官方裁決哪個才是現況:本機 claude --version 輸出是 2.1.323 (Claude Code),但我沒有未辨識的模型 ID 可以拿來看實際行為。文件頁大概只是還沒跟上,這是我的推測,沒有證據。
這篇只讀了文件和 changelog,沒有 gateway 環境可實測。實際跑過的只有 claude --version 和 claude --help(確認有 --autocompact <auto|tokens> 這個選項),沒有設過任何一個下面提到的環境變數,也沒見過下面的警告文字真的印出來。
落到你身上就是:升到 2.1.323 之前,先確認自己用的模型 ID 有沒有被辨識。changelog 自己寫的後果是「滿了每回合都可能失敗」,這比多壓縮幾次嚴重得多。
三個變數管三件不同的事
文件把這三個變數各放在不同的段落,沒有一張對照表。我把它們放在一起想:
CLAUDE_CODE_DISABLE_1M_CONTEXT=1 管的是「Claude Code 相信模型有多大」。它會把 [1m] 變體從模型選單拿掉,並且把預設跑 1M 視窗的模型壓在 200K。文件特別講了一句:就算你把 auto-compact window 設到 200K 以上,這個壓制也不會解除,因為 Claude Code 會把 auto-compact window 限制在模型的視窗以內。壓縮關掉的話,session 會在 200K 邊界停下來,丟出 context-limit 錯誤,不會壓縮。
CLAUDE_CODE_AUTO_COMPACT_WINDOW 管的是「滿到哪裡開始壓縮」,範圍從 100000 到 1000000 個 token。同一件事有四個入口:
1 | /autocompact 500k # 目前這個模型,存在 user settings 的 modelSettings |
文件說,除非 Claude Code 忽略這個值,環境變數的優先序高過指令、旗標和 autoCompactWindow。文件也給了預設值:視窗原生 1M 的模型,預設大約在 967K 個 token 時壓縮。這個數字我只在文件看到,沒驗證過。
CLAUDE_CODE_MAX_CONTEXT_TOKENS 管的是「未辨識 ID 的視窗假設」,文件拿 CLAUDE_CODE_MAX_CONTEXT_TOKENS=400000 當例子,給後端視窗既不是 200K、也不是 1M 的情況。
聽起來分工很乾淨。問題出在第三個。
MAX_CONTEXT_TOKENS 看你的 ID 長什麼樣,三種結果
這一節是我讀文件時最意外的。你以為設了數字就生效,文件按 ID 的長相分三種,結果不一樣。
Claude Code 解析不出你的 ID,而且 ID 裡沒有 [1m]:變數直接生效,主動壓縮照著你宣告的視窗進行。這是你期待的那條路。
ID 裡有 [1m](大小寫不拘):Claude Code 直接假設 1M,變數自己不生效。文件說要同時設 CLAUDE_CODE_DISABLE_1M_CONTEXT=1,才能一邊更正視窗、一邊保留主動壓縮。
ID 解析成它認得的模型,或是不帶後綴的 claude- 開頭名字:變數只有在你同時設了 DISABLE_COMPACT 時才生效,而 DISABLE_COMPACT 會關掉所有壓縮。文件舉的「會被解析成已知模型」的例子有 anthropic/claude-opus-4-8、us.anthropic.claude-…-v1:0,還有帶日期的 claude-sonnet-4-5@20250929。
第三種是最容易踩的:你的 gateway 別名如果把真正的 Claude 型號名嵌在裡面,Claude Code 會把它當成已知模型,你設的數字被放著不理。更糟的是,要讓它生效得關掉全部壓縮,等於為了改一個數字,把安全網整個拆掉。
這種別名該走另一條路。文件的做法是用 modelOverrides(例如 "claude-opus-4-8": "my-gateway-opus")或 modelPicker 的 behavesAs,讓 gateway 別名對應到一個已知模型。這兩個欄位的細節我沒讀 settings-reference,不敢多寫。
還有一個我只能照文件轉述的警告。設了 DISABLE_1M_CONTEXT,但 200K 的上限沒有被執行時,文件列的警告文字是:
1 | CLAUDE_CODE_DISABLE_1M_CONTEXT is set, but the 200K limit isn't enforced for <model>, so this session can grow past it. To enforce it, set CLAUDE_CODE_AUTO_COMPACT_WINDOW=200000 (or the autoCompactWindow setting). |
文件說觸發條件包括:未辨識 ID 又設了 CLAUDE_CODE_DISABLE_UNKNOWN_MODEL_WINDOW_ENFORCEMENT=1,或用 CLAUDE_CODE_MAX_CONTEXT_TOKENS 把假設視窗調過 200K。CLAUDE_CODE_DISABLE_UNKNOWN_MODEL_WINDOW_ENFORCEMENT 是第四個旋鈕,文件說它的作用是不辨識模型 ID 時略過主動壓縮,需要 v2.1.223 以上。changelog 的 2.1.223 區塊另有一條:auto-compact 改成讓未辨識 ID 的 session 留在假設的視窗內,不再放任它長過頭,要回到之前的行為就設這個變數。
我會選哪一個
如果後端是一個真的在 200K 就拒絕請求的 gateway,我會在啟動 Claude Code 的環境裡設 CLAUDE_CODE_AUTO_COMPACT_WINDOW=200000,不會只靠 DISABLE_1M_CONTEXT。
理由有兩個,都是從文件來的。第一,model-config 針對 gateway 寫了一句:Claude Code 偵測不到 gateway 或後端伺服器強制的較低上限;如果你的 gateway 拒絕超過 200K 的請求,就設 CLAUDE_CODE_AUTO_COMPACT_WINDOW=200000,讓每個模型的 session 都在這個邊界壓縮。文件把「後端拒絕 200K 以上」這個情境直接配給它。第二,上面那個警告本身就說:DISABLE_1M_CONTEXT 設了,200K 也不一定被執行,它要你補一個 CLAUDE_CODE_AUTO_COMPACT_WINDOW=200000。壓縮邊界是實際保護你的東西,視窗假設只是它的輸入。
這跟 changelog 的寫法有點出入。changelog 第二條只提 DISABLE_1M_CONTEXT=1,第一條則把它和 /autocompact 並列。我偏向壓縮視窗那一邊,是因為它更直接地對應「後端拒絕」這個後果,不是因為我試過兩個比較。
會讓我改主意的條件有兩個。一是我真的接上自己的 gateway,只設 DISABLE_1M_CONTEXT=1,session 確實在 200K 前壓縮、也沒有出現上面那條警告,那單變數就夠,我就改用它。二是 model-config 頁改成跟 changelog 一致,兩邊說法統一之後,我會重讀一次整個段落。
單位的坑
文件另外提醒了一個單位的差別,值得單獨記:沒有後綴的數字,環境變數會把它當成那麼多個 token,所以 CLAUDE_CODE_AUTO_COMPACT_WINDOW=200 是 200 個 token,但 /autocompact 200 是 200,000。指令和旗標接受的視窗大小是 100K 到 1M,一個 100 到 1000 之間的裸數字代表千為單位。
200k 這種後綴寫法,文件說需要 v2.1.304 以上。changelog 另有一條較早的修正:CLAUDE_CODE_AUTO_COMPACT_WINDOW=200k 曾經靜默設成 100K 的視窗,現在變數接受 k 和 M 後綴,值超出範圍或被忽略時會警告。那一條屬於哪個版本,我沒有對標題查,不寫版本號。
在腳本裡我會一律寫完整數字 200000,不碰後綴也不碰千為單位的簡寫。
什麼情況下這套反而是壞選擇
上面的選擇建立在「後端上限剛好是 200K」。如果你的後端視窗是 400K,那 AUTO_COMPACT_WINDOW=200000 只是白白浪費一半的空間,這時候該走 CLAUDE_CODE_MAX_CONTEXT_TOKENS=400000,而且要先確認你的 ID 屬於上面三種情況裡的第一種。如果你只是想早點壓縮,視窗本身沒問題,那 /autocompact 500k 就夠了,用不到環境變數。
如果你的別名其實就是某個已知模型換了名字,什麼都不用猜視窗,直接用 modelOverrides 把它對上去。
至於升版:model 本身比 Claude Code 新的話,文件的第一個建議是 claude update,這比任何變數都便宜。
一句話的選擇:後端會在 200K 拒絕你,就在啟動環境裡設 CLAUDE_CODE_AUTO_COMPACT_WINDOW=200000;其他情況,先確認 ID 有沒有被辨識,再決定要不要動這三個變數。
前面寫過 autoCompactWindow 的門檻與壓縮鉤子,那篇談壓縮丟掉什麼、鉤子怎麼接,這篇談的是 Claude Code 猜的視窗和後端真實視窗不一致的時候,哪個變數該動。

















