昨天最後留了一個問題:歷史 token 的 K、V 算一次就不變,那共用開頭的請求,能不能共用計算?今天把這件事講完,因為 cache 是 L1 裡投資報酬率最高的一層,而它的天花板也正好暴露 prompt 層的邊界。
先看問題長什麼樣。一個每天處理五萬次請求的 LLM 系統,prompt 已經精簡到不能再短,帳單還是壓不下來。問題多半出在系統一直讓模型想同一件事:一萬個使用者問「怎麼重設密碼」,模型就完整思考一萬次,即使答案一模一樣。
Prompt Cache 的機制就是昨天的 KV Cache 延伸:兩個請求共用同一段前綴,這段前綴的 K、V 只算一次。API 商(OpenAI、Anthropic)把這件事做成計費優惠,快取命中的 input token 常常只收一折。
它最適合的形狀是「固定的長前綴 + 變動的短輸入」:長 system prompt、工具的 schema 定義、輸出格式說明,這些每次呼叫都一樣的東西,放在 prompt 的最前面,讓每次呼叫只付變動部分的全價。
這裡有一個跟昨天的機制直接相關的細節:cache 是按前綴匹配的。你在 system prompt 的開頭放了一個當下時間戳,後面的一切就永遠 miss。想吃到 cache,固定的放前面,變動的放後面,這個排列跟 Day 2(Prompt 為什麼有效)講的「指令放前面」剛好同向,機制上互相加成。
真實系統把這件事當工程紀律在管,HermesAgent(Nous Research 的開源 agent)做得特別徹底。它的記憶系統會把記憶內容注入 system prompt,這就撞上一個兩難:agent 在對話中會不斷寫入新記憶,如果每輪都用最新記憶重組 system prompt,前綴每輪都變,cache 永遠 miss。
它的解法叫 frozen snapshot:session 開始時把記憶拍一張快照注入 system prompt,之後整個 session 不管記憶怎麼更新,system prompt 都用這張舊快照,新寫入的記憶下個 session 才生效。連每輪要動態注入的檢索結果,都刻意塞進 user message、避開 system prompt,原始碼註解寫得很直白:「system prompt modifications break the prompt cache」。
這套紀律值多少錢?以 2000 token 的 system prompt 跑 20 輪對話估算,每輪重組 system prompt 的話 input token 全額付費;frozen snapshot 讓後 19 輪全部走快取價,整體 input 費用降到大約四分之一。在 production 裡,「前綴穩定性」是一條有金額的約束,甚至值得為它犧牲「記憶即時生效」這個功能。
Prompt Cache 的命中條件是字串相同。這在真實流量面前很脆弱:
它解決的是語法層的重複,解決不了語意層的重複。而真實產品裡大量的重複是語意的:客服場景八成的問題集中在二十種類型,每種有十幾種問法。
Semantic Cache 用 embedding 判斷新請求跟快取裡的問題像不像。embedding 是把一段文字壓成一串數字向量,意思越接近的兩段文字,向量距離越近。流程是:新請求進來先算 embedding,跟快取做相似度搜尋,超過門檻直接回快取的答案,沒超過才真的呼叫 LLM,然後把結果存進去。
它的成本結構很划算:算一次 embedding 的錢大約是一次生成呼叫的百分之一以下,只要偶爾命中一次就回本。兩層疊起來用,先查字串(快、零風險),再查語意(命中率高),最後才是 LLM。設計得好的系統可以攔掉一半以上的呼叫。想看實作的話,開源的 GPTCache 就是一套完整的 semantic cache:embedding、向量搜尋、相似度評估、淘汰策略都模組化了,讀它的架構比讀十篇教學文更快搞懂這件事的全貌。
但 Semantic Cache 是有風險的 cache,工程都在門檻設計上:
Prompt Cache 和 Semantic Cache 的差別,是「字一樣」和「意思一樣」的差別。前者是純機制,零風險;後者開始需要工程判斷:多像才算像、放多久、什麼不能放。越往上省,省的東西越抽象,需要的設計也越多,這個規律在後面的層會一直重複。
到目前為止,我們都在處理模型的輸入端。明天換到輸出端:模型吐出來的是給人讀的散文,但你的系統管線要的是能進 if/else 的資料。讓 LLM 的輸出變成可靠的結構,是把它接進真實系統的第一道門檻。