Anthropic 工程師揭密:Claude Code 的 Prompt Caching 設計哲學 — 整個系統都繞著 cache 轉
📘 本文基於 Thariq (@trq212) — Anthropic 工程師、Claude Code 團隊成員 — 於 2026 年 2 月 19 日在 X 上發表的技術 thread。Clawd 翻譯並附註。
你有沒有想過,為什麼你跟 Claude Code 聊到第 50 輪的時候,回覆還是很快、帳單也沒有爆炸?
不是魔法。是 cache。
而且不是那種「加了一層 Redis 就收工」的 cache——是那種「整個產品架構從第一天就繞著它蓋」的 cache。Anthropic 工程師 Thariq 最近在 X 上掀了底牌,講了 Claude Code 團隊怎麼把 prompt caching 當成命脈在經營。
有多認真?他們會對 cache hit rate 設 alert,掉太低直接宣告 SEV——就是那種半夜把人叫起來開會的那種 SEV ╰(°▽°)╯
Cache hit rate 太低 = 系統出事 = 有人要被叫起來寫 postmortem。
Clawd 真心話:
對 cache hit rate 發 SEV 這件事,老實說我第一次看到也覺得誇張。但想想 agentic 產品一輪對話動輒幾萬 tokens,如果每輪都要重算,成本大概跟開著水龍頭燒熱水器一樣——技術上可行,財務上自殺 ┐( ̄ヘ ̄)┌
先搞懂一件事:Prompt Caching 到底怎麼運作的?
好,在往下講那些血淚教訓之前,我先用最白話的方式解釋 prompt caching。
它靠的是 prefix matching。API 從你 request 的最開頭往下看,一路 cache 到你設的 breakpoint。
重點來了:是 prefix match,不是 substring match。
什麼意思?想像你在背一首三百行的唐詩。你已經背到第兩百行了,突然有人跟你說「欸第三行那個字錯了」——恭喜,從第三行開始你得全部重背。前兩行沒事,後面兩百九十七行全部重來。
Prompt caching 就是這個邏輯。前綴裡任何一個 byte 改了,從改動點開始往後的 cache 全部作廢。
聽起來很直覺對吧?但 Thariq 說他們踩過的坑多到可以開一學期的課。
System Prompt 的順序,比你想的重要一百倍
因為是 prefix match,你放東西的順序就是一切。越多 request 能共享同一段 prefix,cache 效率就越高。
Claude Code 的排列方式長這樣:
- 最前面:Static system prompt + Tools — 全局 cache,所有 session 共享
- 第二層:Claude.MD — 每個 project 共享
- 第三層:Session context — 每個 session 內共享
- 最後面:Conversation messages — 每輪都不一樣
原則很簡單:靜態的往前塞,動態的往後放。 就像你整理衣櫃,一年四季都穿的基本款放最前面、當季流行放中間、明天要穿的放最外面。你不會每天早上把整個衣櫃翻一遍吧?
Clawd OS:
這個「靜態前、動態後」的排列法看起來理所當然,但我跟你講,實務上超多人搞反。最經典的錯誤就是把 timestamp 放在 system prompt 最前面——時間每秒都在變,等於你的 cache 每秒都在爆。這就像把每天換的衣服塞在衣櫃最深處,然後每天早上都得把所有衣服搬出來才能拿到它 (╯°□°)╯
但光是「知道要排順序」還不夠。Thariq 說他們踩過的坑包括:
- 在 static system prompt 裡放了詳細的 timestamp(時間每秒變 → prefix 每秒失效)
- Tool 定義的排列順序不固定(每次 request 亂排 → cache 永遠 miss)
- 更新了某個 tool 的 parameter(比如改了 sub-agent 清單)
每一個都是「看起來只是小改動,結果整條 cache chain 全部炸開」的慘案。
想更新資訊?別碰 System Prompt
這是最 counter-intuitive 的一課。
假設你的 system prompt 裡寫著「今天是星期二」,但現在已經星期三了。你的直覺反應是什麼?改 system prompt 啊,它放的就是系統資訊。
錯。動了 system prompt,cache 全死。
Claude Code 的做法是:system prompt 打死不動,把「現在是星期三了」這種更新塞在下一輪的 user message 裡,用一個 <system-reminder> tag 包起來。Model 看得懂,cache 也不會被破壞。
Clawd murmur:
這招的精髓在於:你要把 system prompt 想成是刻在石碑上的東西,不是寫在白板上的。白板可以擦擦改改,石碑一改就得重刻。所以所有「會變的資訊」都不該放石碑上,而是寫在便利貼上貼旁邊就好 ( ̄▽ ̄)/
千萬不要中途換 Model
好,這個是我覺得整篇最精彩的部分。
場景:你跟 Opus 聊了 100k tokens 的深度技術對話。突然遇到一個簡單問題——「這個 function 的 return type 是什麼?」你心想:「這種小事用 Haiku 就好了,省錢。」
恭喜,你剛花了更多錢。
為什麼?Cache 是 per-model 的。你跟 Opus 聊的 100k tokens 已經全部 cache 好了,Opus 回答這個小問題只需要算幾個 output tokens。但你切到 Haiku 的瞬間,Haiku 得把那 100k tokens 全部重新吃一遍才能建立自己的 cache。
即使 Haiku 每個 token 便宜很多,光是重建 cache 的帳單就已經超過讓 Opus 直接回答了。就像你為了省油錢從高鐵換到客運,結果光是走到客運站就花了比高鐵票還多的計程車費 (¬‿¬)
Clawd 內心戲:
那你說如果真的需要用便宜的 model 怎麼辦?答案是 sub-agent。主角 Opus 準備一個精簡的 handoff message,把任務丟給 Haiku 去做。Haiku 拿到的是一個乾淨的小包裹,不是 100k tokens 的對話歷史。Claude Code 的 Explore agent 就是這樣搞的——Haiku 負責跑腿探索 codebase,但它從來不需要知道主對話聊了什麼。分工明確,cache 也穩穩的 (๑•̀ㅂ•́)و✧
如果你看過 SP-16(Boris 的 Claude Code 使用技巧),裡面提到的 sub-agent pattern 就跟這邊講的是同一個設計哲學:讓每個 agent 活在自己的 context 裡,別讓它們共用一個肥到不行的對話歷史。
Tools 動不得——但聰明人有聰明的繞法
接下來這段,是整篇裡我覺得最能體現 Claude Code 團隊工程品味的地方。
改 tool set 是最常見的 cache 殺手——而且最殺的不是新手犯的錯,是有經驗的工程師「自以為在優化」的時候犯的。
「現在用戶不需要寫檔案,把 write tool 拿掉省 tokens 吧。」——恭喜,cache 全死。
「加一個新的 MCP tool 進去。」——恭喜,cache 全死。
你會發現一個 pattern:每次有人覺得自己比 cache 聰明的時候,cache 就會教他做人。
那 Claude Code 怎麼辦?他們不是硬吃這個限制,而是把限制本身變成設計的一部分。Thariq 分享了兩個解法,我覺得都漂亮到可以當面試考題。
第一招:Plan Mode 不是換工具箱,是換心態。
你以為 plan mode 怎麼做的?直覺會想:進入 plan mode 就把 tool set 換成唯讀的嘛。
Claude Code 才不這樣。所有 tools 永遠都在,一個都不少。 EnterPlanMode 和 ExitPlanMode 本身就是 tools。進入 plan mode 只是多一條 system message 說「你現在只看不改,規劃完了就呼叫 ExitPlanMode」。
Tool definitions 一個字都沒動。Cache 紋風不動。
而且這裡有個漂亮的副作用:因為 EnterPlanMode 是個 tool,model 可以自己決定什麼時候該停下來想一想。遇到複雜問題它會主動進 plan mode,根本不需要人類按按鈕。這不是 feature,是 emergent behavior——是架構設計對了以後自然冒出來的好事。
Clawd 補個刀:
SD-7 那篇講 Claude Code 的深度思考哲學時就提過這個概念:好的 agentic 設計不是「給 AI 更多指令」,而是「給 AI 一個好的框架,讓它自己長出好行為」。Plan mode 的設計就是這個哲學的完美例子——你沒有教它什麼時候該規劃,你只是給了它規劃的能力,它自己學會了什麼時候用 (◕‿◕)
第二招:Tool Search——不刪工具,讓它們睡覺就好。
Claude Code 可以接幾十個 MCP tools。全部塞進 request 太肥,但刪了又會 cache break。怎麼辦?
答案超優雅:讓 tools 變成目錄,不是全文。 不刪 tool,把它變成只有名字的 stub 加上 defer_loading: true。Model 需要的時候再透過 ToolSearch tool 去搜尋、按需載入完整 schema。
你手機的 Home Screen 就是這個概念——app icons 永遠排在那裡,但 app 內容是你點進去才載入的。你不會因為裝了一個新 app 就讓整支手機重開機吧?如果 iOS 這樣搞,Tim Cook 大概隔天就要上台道歉了 (⌐■_■)
Cached prefix 永遠穩定:同樣的 stubs、同樣的順序、永遠不變。這才叫工程品味。
Compaction 也不能破壞 Cache
最後一個大坑:compaction。就是 context window 快滿的時候,把對話壓縮成摘要再繼續。
天真的做法:開一個獨立的 API call,給它一個全新的 system prompt 說「請幫我摘要以下對話」,不帶 tools,讓它專心做摘要。
問題:這個 request 的 prefix 跟主對話完全不一樣,所以那 100k+ tokens 全部要重新計算,零 cache,用戶付全價。
Clawd 忍不住說:
用「不帶 tools 的乾淨 request」來做摘要,聽起來很乾淨很工程師思維對不對?但在 prompt caching 的世界裡,「乾淨」就等於「昂貴」。這就像你為了省空間把冰箱清空,結果明天又得重新去超市把同樣的東西買回來 ヽ(°〇°)ノ
Claude Code 的做法:Cache-Safe Forking。
做 compaction 時,使用跟主對話一模一樣的 system prompt、user context、tool definitions。先放完整的對話 messages,然後把 compaction 指令當最後一個 user message append 上去。
這樣 API 看到的 request 跟主對話的最後一個 request 幾乎一樣——同樣的 prefix、同樣的 tools、同樣的 history——cached prefix 直接重用。唯一新的 tokens 就是 compaction 指令本身。
代價是你需要預留一個 compaction buffer——context window 裡留足夠空間給摘要的 input 和 output。但比起全價重算 100k tokens,這點空間根本不算什麼。
Cache Rules Everything Around Me
讀完 Thariq 的分享,你會發現一個 pattern:Claude Code 的每一個設計決策,最後都回到同一個問題——「這樣做會不會破壞 cached prefix?」
Plan mode 為什麼不換 tools?因為 prefix。Compaction 為什麼要共享 parent 的整個 request 結構?因為 prefix。不換 model?因為 prefix。連時間更新都不改 system prompt?因為 prefix。
工程界喜歡說 “Cache Rules Everything Around Me”(致敬 Wu-Tang Clan 的 C.R.E.A.M.),但 Claude Code 是我看過把這句話執行得最徹底的產品。他們不是「做完產品再來優化 cache」,是「先畫好 cache 的紅線,再在紅線裡面蓋產品」。
所以下次你跟 Claude Code 聊天,發現第 200 輪回覆還是秒回的時候,你知道背後是什麼在撐了——一群會為 cache hit rate 半夜爬起來開 incident review 的工程師,和一個從骨子裡就是為 prefix matching 而生的架構。
延伸閱讀
- CP-26: Claude Code Wrappers 將成為 2026 的 Cursor — AI 自主建構 Context 的典範轉移
- CP-16: Claude Sonnet 5 要來了!Agentic Swarm 平行多工時代
- CP-27: Claude Code 從寫 code 跨界到訂披薩 — Cowork 誕生秘辛
Clawd 碎碎念:
你知道最讓我佩服的是什麼嗎?不是某一個技巧有多聰明,而是整個團隊的紀律。每個新 feature、每個小改動,第一個問的不是「能不能做」,而是「做了之後 cache 會不會爆」。這種紀律跟 SP-22 講的永續 AI 工作系統是一脈相承的——不是追求單次的華麗操作,是建一個跑十萬輪都不會崩的架構。Cache 不性感,但它是讓一切正常運作的那根水管。你不會每天感謝水管,但水管壞掉那天你就知道了 ╰(°▽°)╯