我才發現所謂的模型降智,大多是上下文管理沒做好甩的鍋

深入研究 Claude Code 上下文管理機制後,我才發現所謂的模型降智,大多是上下文管理沒做好甩的鍋

Part 1: 一個上下文管理失效導致的故障案例

共享數據庫管理工具Basedash的創始人Daniil Okhlopkov 跑了一個7x24小時不間斷的 Claude Code agent,專門處理服務器運維。

這個 agent 有明確的訪問控制規則——哪些請求該響應,哪些該拒絕。它在前三個小時表現完美。

然後,200 分鐘後,安全規則消失了。

"My always-on agent forgot critical rules after 200 minutes of continuous operation."

>

"我的常駐 agent 在連續運行 200 分鐘後忘記了關鍵規則。"

Agent 開始響應本應阻止的請求。沒有報錯,沒有警告彈窗,日誌裏一切正常。只是在某個你看不到的時刻,它"忘記"了那些寫在會話開頭的重要指令。

這種症狀有名字:上下文腐化(Context Rot)。

上下文腐化是 AI agent 性能隨上下文窗口逐漸填滿而發生的漸進式退化——沒有警告,沒有錯誤,只是悄然退化。

一般情況下,如果發生下面四種場景,代表出現了上下文腐化

  • 生成與早期工作矛盾的代碼

  • 重複詢問已經解釋過的項目結構

  • 丟失架構決策和命名約定

  • 破壞性變更忽略已建立的模式。

上下文腐化的根本原因是上下文窗口裏的信息被壓縮或丟棄了。

Okhlopkov 的事故里,罪魁禍首是自動壓縮(auto-compaction),壓縮後丟掉了會話指令。

Claude Code 會在上下文快滿的時候自動觸發壓縮,把對話歷史壓縮成摘要,騰出空間繼續工作。Anthropic 沒有公佈過精確的觸發百分比,社區實測估測在 80-95% 之間(Part 3 會展開分析)。

壓縮會保留當前任務和最近的錯誤信息,但可能會丟掉會話指令、架構決策、風格規則。

Okhlopkov後來把安全規則移到了 CLAUDE.local.md 裏,因爲 CLAUDE.md 是系統提示的一部分,不存在於對話歷史中,壓縮動不了它。

問題解決了,但我們能從這個事故學到一些教訓:那就是必須深刻了解上下文窗口管理機制。

Part 2: 你的 200K 到底被誰喫了

上一節說上下文窗口裝滿了就會丟東西。那到底誰在佔你的空間?

Claude Sonnet 的上下文窗口是 200K token。弄清楚這 200K 被誰佔了,才能做好上下文管理。直接上一份實測數據:

組件 | Token 數 | 佔比

系統提示(System Prompt) | ~19,000 | ~9.5%

CLAUDE.md(項目配置) | ~4,000 | ~2.0%

MCP 工具描述(Tools) | ~26,500 | ~13.3%

對話歷史(Conversation) | ~100,000+ | ~50%+

壓縮工作區(Compaction Buffer) | ~44,000 | ~22%

來源:Damian Galarza 的 Claude Code Token Breakdown 實測(個人技術博客,2025 年底數據,不同版本可能有差異)

從上面表格我們可以看到,一次Claude Code的對話,發送給LLM的內容主要包括以下部分:

  1. 系統提示詞。這是 Claude Code 自身的指令集——告訴模型怎麼讀文件、怎麼執行命令、怎麼格式化輸出。我們控制不了這部分,也減不掉。

  2. CLAUDE.md。這塊我們可以控制,Galarza 的項目配置大約 4K token,佔 2%。但這取決於你往裏面塞了多少東西。有些人把架構文檔、編碼規範、工作流模板全堆進 CLAUDE.md,它能膨脹到 10K 以上。

  3. MCP 工具。 每個 MCP server 的描述都會被注入系統提示。Galarza 的項目加載了幾個 MCP server,工具描述加起來 26.5K token——比 CLAUDE.md 多了六倍。很多人根本不知道 MCP server 的工具定義在佔用上下文。

Claude Code 提供了一個不太爲人知的配置項來緩解這個問題:ENABLE_TOOL_SEARCH: true。開啓後,MCP 工具從常駐加載變成按需檢索——只有你真正調用某個工具時,它的定義才被加載進上下文。對於裝了五六個 MCP server 的項目,這個配置能直接砍掉上萬 token 的固定開銷。代價是額外的延遲——第一次調用某個工具時需要先檢索再加載。但跟你省下的上下文空間相比,這個代價可以忽略。

  1. 壓縮後的摘要。上面的例子約 44K token(約 22%)的空間。

Part 3: 壓縮機制詳解

清楚了誰在喫你的上下文空間,也知道了消耗速度。接下來看壓縮本身——它保留了什麼,丟掉了什麼,又在什麼時候觸發。

壓縮是怎麼工作的

壓縮的觸發條件:當上下文使用率接近上限時自動啓動。具體是多少?Anthropic 沒有公佈過精確數字。 官方文檔只說 "when you approach context limits",沒有百分比。下面從官方 changelog 和社區實測兩個維度推導一個合理區間。

壓縮過程本身是一次獨立的模型調用。

Claude Code 把你的完整對話歷史——幾百條來回、代碼片段、錯誤日誌——打包發給一個單獨的 API 請求,讓它生成一份關鍵事實摘要。

這份摘要隨後替換掉完整的對話歷史,壓縮產出的摘要可能比原始上下文短 60-80%。

也就是說,一次壓縮可能會丟掉三分之二到五分之四的對話內容,本質是有損壓縮。

那什麼東西會被保留,什麼東西會被壓縮呢?

Okhlopkov 在事後對自己的 agent 做了一次分析——逐條對照壓縮前後的上下文,看哪些信息還在、哪些消失了。這是目前公開可查的最詳細的壓縮行爲實測。

可靠保留的信息:當前正在執行的任務、最近修改過的文件名、最近遇到的錯誤和解決方案、項目的總體架構描述。

經常丟失的信息:會話開頭設定的指令和約束、中間的決策過程(爲什麼選方案 A 而不是方案 B)、50 條消息以前的代碼片段、代碼風格規則。

這個保留/丟失的模式有明確的邏輯:壓縮模型優先保留"現在正在發生什麼",犧牲"過去爲什麼這樣做"。它保證 agent 能繼續當前任務,但不保證它還記得爲什麼要做這個任務。

壓縮後的 agent 能繼續寫代碼,但你 40 分鐘前跟它討論的"不要用全局變量"這個約定,它多半已經忘了。

有的信息會保留,有的信息會丟失。但有一樣東西壓縮動不了:CLAUDE.md。

CLAUDE.md 不在對話歷史裏,它是系統提示詞的一部分,每次調用模型時都會完整注入,不會被壓縮、不會被截斷、不會因爲對話太長而丟失。

具體來說,Claude Code 給了三層的 CLAUDE.md 配置,每層解決不同的問題。

第一層:全局配置 ~/.claude/CLAUDE.md。對所有項目生效。放個人偏好和通用規則——編碼風格、註釋語言偏好、安全紅線。Okhlopkov 的建議是:這裏只放"不管做什麼項目都不該變"的東西。

第二層:項目配置 ./CLAUDE.md。對當前項目生效,跟着倉庫走。放項目架構、依賴關係、測試命令、目錄結構說明。團隊協作時可以提交到 git,所有人共享同一份上下文。

第三層:本地配置 ./CLAUDE.local.md。這一層的關鍵特性:它在壓縮中存活。

Okhlopkov 在他的 24/7 agent 事故後做了一個關鍵操作——把安全規則從對話歷史搬進了 CLAUDE.local.md。他的實測結論:

"CLAUDE.md loads as part of the system prompt, exists outside conversation history, and is the only place that's guaranteed to survive any compression."

>

"CLAUDE.md 作爲系統提示詞的一部分加載,存在於對話歷史之外,是唯一保證在任何壓縮後都能存活的地方。"

—— Daniil Okhlopkov(Claude Code Compaction Explained)

自動壓縮的觸發條件

Anthropic 從來沒有正式公佈過何時自動壓縮的確切百分比。 官方文檔一直用的是模棱兩可的說法 "when you approach context limits"。但是 Claude Code 的 changelog 和社區的實測結合起來,可以推導出一個大致的範圍。

證據一:官方 changelog。

版本 | 日期 | 變更

v1.0.51 | 2025-07-11 | 把自動壓縮**警告閾值**從 60% 提高到 80%

v2.1.41 | ~2026-02 | 修復 auto-compact 在大 output token 模型上觸發過早

v2.1.85 | 2026-03-26 | 修復 token 估算對 thinking/tool_use blocks 的過度計算,防止過早壓縮

v2.1.116 | 2026-04-20 | 修復 Opus 4.7 會話顯示膨脹的 /context 百分比導致過早壓縮

v1.0.51 將告警閾值從60%提高到了80%,注意是告警閾值,說明觸發閾值至少比80%高。

證據二:社區實測。

Okhlopkov 根據他的 7*24 agent 給他報告的數據得出大概是 95%。

Robert Matsuoka 在跑了一個獨立的監控工具( Claude MPM )之後,發現了一個bug:Claude Code 自報只剩 10% 上下文時,Matsuoka 的獨立監控顯示顯示實際上只有64% 已經使用。

Matsuoka 基於這一現象提出假設:Anthropic 在默默調低壓縮閾值,真實的自動觸發點可能在 64-75%。

這個bug Claude Code官方在v2.1.85(2026-03-26)修復了 "...token estimation overcounting for thinking and tool_use blocks"。

v2.1.116 進一步修復了 Opus 4.7 顯示的上下文百分比膨脹。

綜合以上線索,實際觸發點大概率在 80-95% 之間。

四個信號,判斷壓縮是否發生

判斷壓縮是否剛發生過,看四個信號。

第一,終端出現 [context compacted] 指示器。這是最直接的信號。

第二,成本突然跳升。壓縮是一次獨立的 API 調用,會消耗額外的 token。你在 /cost 裏看到的突然跳升,多半是壓縮觸發了。

第三,上下文計數器重置。壓縮前你可能看到使用量 180K/200K,壓縮後變成 60K/200K——因爲 10 萬 token 的對話被替換成了 2-4 萬 token 的摘要。

第四,也是最隱蔽的信號:agent 開始重新問你已經討論過的問題。比如你 30 分鐘前告訴過它用 TypeScript 而不是 JavaScript,它又問了一遍"這個項目用什麼語言"。這是信息丟失的直接症狀。

四個信號裏,前三個是客觀數據,第四個是主觀體感。如果你發現 agent 的行爲突然變"笨"了,先檢查前三個信號。

到目前爲止,我們聊的都是壓縮發生之後的事:它怎麼觸發、保留了什麼、丟掉了什麼、怎麼感知到它發生了。這些全部是事後補救。

Part 4: 實戰指南,如何進行上下文管理,5 個決策點與案例實操

現在我們知道自動壓縮會丟失上下文信息,爲了更好的完成任務,我們有時候需要手動進行上下文管理。

在做任何操作之前,先學會看儀表盤。

/cost 和 /context:先學會看儀表盤

/cost 告訴你這輪會話花了多少錢。/context 告訴你當前上下文用了多少——系統提示詞佔了多少、對話歷史佔了多少、工具輸出佔了多少、還剩多少空間。

使用節奏:每 20-30 分鐘查一次 /cost,開始新任務前查一次 /context。突然的變化是信號——/cost 突然跳升可能是壓縮觸發了,/context 顯示使用量驟降同樣是壓縮的痕跡。養成習慣後你會對 token 消耗建立直覺——什麼時候該 compact、什麼時候該 clear,不需要每次都查數字。

看完儀表盤,你知道了當前上下文的狀態。接下來根據狀態做決策,有五個選擇:

  1. **`/compact`** — 手動壓縮對話歷史,保留摘要。適合任務還要繼續,但上下文已經太長。

  2. **`/clear`** — 清空上下文,開新會話。適合切換到完全不相關的新任務。

  3. **`/rewind`** — 回退到指定步驟,抹掉之後的交互。適合走錯方向、能指出"從哪一步開始出問題"的場景。

  4. **sub-agent** — 給子任務開獨立的 200K 窗口。適合重活但中間產物不需要留在主上下文。

  5. **繼續** — 不做任何操作,接着聊。適合簡單追問、小修改。

按使用頻率從高到低逐個拆解。

/compact:在 60% 時動手,別等 95%

/compact 把你的對話歷史壓縮成一份摘要,騰出空間,執行後你不會丟失當前會話,可以接着聊。

這是五個操作裏使用頻率最高的一個,也是社區公認投入產出比最高的單一動作。社區裏有人把它叫做"單一最高影響力習慣改變"(single highest-impact habit change)。

在 60% 動手而不是等到 95%,原因很簡單:到了 70-80%,模型已經明顯喫力了。你會發現 Claude Code 開始重複自己、忽略之前的約束、對簡單問題給出冗長但不準確的回答。等到 95% 才壓縮,等於在模型最差的狀態下讓它做最重要的總結——產出質量可想而知。

手動 compact 的觸發時機有兩個經驗法則。第一,開始一個大任務之前。比如你要啓動一個跨文件重構,先 compact 一下,給新任務騰出乾淨的上下文空間。第二,任務方向切換時。你剛修完一個 bug,現在要寫新功能——compact 掉調試過程的細節,只保留關鍵結論。

還有一個進階技巧:自定義壓縮提示詞(compactPrompt)。默認的壓縮提示詞是通用的,不會優先保留你關心的東西。你可以在 ~/.claude/settings.json 里加一段自定義指令,告訴 Claude Code 壓縮時優先保留什麼。Okhlopkov 在他的 24/7 agent 上就是這麼做的——他發現自定義提示詞比默認的"有明顯改善"。

// ~/.claude/settings.json
{
"compactPrompt": "保留所有安全規則和訪問控制約束。保留項目架構決策。保留最近10條錯誤和解決方案。優先丟棄已完成的工具輸出和搜索結果。"
}

/clear:清空當前會話

/clear 清空當前會話的全部上下文,給你一個乾淨的起點。舊會話不會消失——Claude Code 把它們保存在本地,隨時可以通過/resume找回。執行後你就進入了一個全新的 200K 窗口,什麼歷史都沒有。

這個操作的心理門檻比實際難度高很多。大部分人不願意清空一個聊了 40 分鐘的會話——感覺像是"浪費了"之前的上下文。但事實是:一個已經被錯誤方向污染的上下文,比空白上下文更糟糕。模型會沿着錯誤的慣性繼續走偏。

Anthropic 官方給了一個具體的觸發條件:同一問題連續 2 次糾正失敗後,/clear。如果同樣的錯誤犯了兩遍,這時候不是模型理解力的問題,是上下文裏的錯誤信號太強了,糾正指令淹沒在噪音裏。

/clear 之後的新會話是空白的,你需要把關鍵上下文帶過去。用兩三句話寫一個交接摘要(handoff brief):當前任務是什麼、已經嘗試了什麼、卡在哪裏、下一步要做什麼。這個摘要就是新會話的種子。

這個摘要也可以讓模型幫你生成。/clear 之前,給 Claude Code 一句指令:

請用 2-3 句話總結當前會話:1) 任務目標 2) 已嘗試的方案 3) 卡點 4) 下一步。我要用這個摘要開新會話。

本質上就是用模型壓縮模型自己的上下文。/compact 是同會話內的自動壓縮,handoff brief 是跨會話的有損遷移。兩者的關鍵區別在於:compact 保留的是"模型認爲重要的東西",handoff brief 保留的是"你知道重要的東西"——你在迴路中做了最後一道篩選,信息密度更高,因爲你比模型更清楚哪些是信號、哪些是噪音。

你可能想讓這個交接摘要自動生成——比如在 /clear 執行前自動觸發一次摘要。

目前做不到。/clear 是 Claude Code 的內置 CLI 命令,不是工具調用(tool use)。Claude Code 的 Hooks 機制只能攔截工具級別的事件——工具調用前(PreToolUse)、工具調用後(PostToolUse)、agent 停止響應時(Notification)、agent 完成任務後(Stop)。/clear、/compact、/rewind 這些斜槓命令繞過了 hooks,沒有鉤子點可以掛載。

還有一個 prompt 優化技巧:開新會話時,第一句話就把約束說清楚。不要等對話進行到第三輪才補充"對了,這個項目用 pnpm 不用 npm"。把所有關鍵約束寫在第一句話裏,讓它們成爲上下文裏最早、最不容易被壓縮丟掉的信息。

/rewind:回退到正確的岔路口

/rewind 把對話回退到你指定的某一步,抹掉之後的所有交互。相當於 Git 的 git reset——回到過去,從那個點重新開始。

Anthropic 內部有人稱 /rewind 是"最重要的單一習慣"。這個評價的依據是:大部分上下文污染源於一個錯誤決策,之後每一步都在錯誤的基礎上疊加。你讓 Claude Code 走了一條錯誤的架構路線,它基於這個錯誤路線又做了三步推導——這時候 /compact 沒用,因爲錯誤推導還在;/clear 太重,因爲前半段對話是好的。/rewind 剛好對症:回退到做決策之前那個點,選另一條路。

判斷 /rewind 比 /clear 更合適的標準:你能不能指出"從哪一步開始出問題了"。如果你能明確地說"第 12 輪讓它改數據庫 schema 的方向就錯了"——/rewind 回到第 11 輪。如果你說不出具體哪一步出了問題,只是感覺整體質量在下降——/compact 或 /clear 更合適。

這個命令可能是最被低估的一個,因爲這個命令剛剛拯救了這篇文章。我花了一下午將這篇文章修改到了這裏,然後被AI回滾了。

所有的修改全部丟失了,還好我記得/rewind命令,嘗試之後驚喜的發現他可以直接回滾掉代碼,做到了git沒有做到的事情。

現在我對/rewind有一個更加深刻的理解了,它其實相當於給你每次提問的文件做了一個快照,你可以隨時回撤到任意的對話,回到會話開始前的狀態。

Sub-agent(子代理):給子任務開獨立的 200K 窗口

壓縮是對話太長之後的補救措施,治標。Sub-agent 是從架構層面預防對話變長,治本。

原理是給每個子任務開一個全新的 200K 上下文窗口,讓它在這個獨立空間裏工作,完成後只把結果摘要返回給主 agent。

看下五種典型用法:

代碼審查:讓 sub-agent 讀完整 PR 的 diff,輸出審查意見。主 agent 只看到審查結果,不消耗 token 在讀代碼上。適合 PR 超過 500 行的場景。

文件分析:讓 sub-agent 遍歷某個目錄、分析架構、輸出摘要。比如"分析 src/ 目錄下所有文件的依賴關係"。主 agent 只拿到一份架構圖。

搜索調研:讓 sub-agent 跑多輪搜索、整理結果、輸出結構化摘要。搜索過程會產生幾萬 token 的工具輸出——這些全部在子窗口裏,主窗口只看到最終結論。

分治執行:把一個大任務拆成 3-5 個獨立子任務,每個交給一個 sub-agent。比如"重構認證模塊"拆成"重寫登錄邏輯""更新中間件""補測試用例"三個子任務。Claude Code 支持在單條消息裏同時發起多個 sub-agent 並行執行,所以分治既能省時間,也能省主窗口的上下文。

Builder-Validator:一個 sub-agent 寫代碼,另一個 sub-agent 審查代碼。兩個獨立的上下文窗口意味着審查者不會受到寫代碼時的上下文偏見影響。社區裏有人報告這種模式比在同一個窗口裏"寫完再檢查"效果好很多。

Sub-agent 的限制也要清楚:無過程可見性(你只能看到最終結果)、每次需要顯式傳遞所有信息(子窗口不繼承主窗口的上下文)。這意味着它更適合"發射後不管"的任務——你把要求說清楚,讓 sub-agent 自己跑完,拿結果回來。不過 Claude Code 支持在一條消息裏同時啓動多個 sub-agent 並行執行,對於獨立子任務可以大幅節省等待時間。

五種操作什麼場景用哪個,下面這張速查卡做了對照。

速查卡

信號 | 操作 | 什麼時候用

完全不相關的新任務 | `/clear` | 每次切換大方向

發現走錯方向,能指出"從哪步錯" | `/rewind` | 錯誤決策可定位時

上下文 >60%,當前任務還要繼續 | `/compact` | 大任務前、方向切換時

重活但中間產物不需要留在主窗口 | sub-agent | 文件分析、搜索、代碼審查

簡單追問、小修改 | continue | 快速確認,上下文消耗小

更多遊戲資訊請關註:電玩幫遊戲資訊專區

電玩幫圖文攻略 www.vgover.com