Architecture Journal
Agent 成本,不只看模型單價:從 Context Architecture 談快取、壓縮與記憶
重點摘要
最近大家在談 agent cost,常見的討論方式是比較不同模型的價格表:
- input token 單價
- output token 單價
- context window
但對真正跑起來的 agent 系統來說,成本通常不只是 model pricing 問題。
更常見的問題其實是:
你是不是在每一輪 request,都重新支付同一份 context 的成本?
如果答案是 yes,那你要處理的就不只是「換便宜模型」,而是 context architecture。
Google ADK 提供了一個很好的切分方式,把這個問題拆成三層:
- Context caching:重用相同前綴
- Context compaction:壓縮持續膨脹的 session
- Session / State / Memory:管理短期與長期上下文
這三者常常都被叫做「快取」,但它們其實在解完全不同的問題。
而把這三層設計成一套可觀測、可優化、可演進的系統,本來就是 harness engineering 的工作範圍之一。
Problem
最近 agent 成本會變成熱門話題,不難理解。
不管是 coding agent、research agent、customer support agent,還是內部 automation agent,這些系統都在做同一件事:
- 把更多工具接進來
- 把更多上下文塞進 prompt
- 把更多步驟拆成多輪 interaction
於是每個 request 的組成都變得越來越重。
一個現代 agent request 很可能同時包含:
- system prompt
- tool definitions / schema
- policies / guardrails
- repo 或文件摘要
- session history
- memory retrieval 結果
- 最新 user 任務
- 最新 tool result
很多團隊到這個階段,才第一次明確意識到:
agent 很貴,不一定是因為模型太貴, 而是因為同一份昂貴的 context 被反覆重送。
真正的浪費,常常發生在 Prefill
談 LLM 成本時,大家很容易把注意力放在 output token。
但在 agent 系統裡,很多時候真正被低估的是 prefill 成本。
所謂 prefill,簡單講就是模型在開始生成前,先把整段輸入讀進去並建立中間表示的過程。
如果你的 agent 每次都把這些東西重送一次:
- 一大段 system instruction
- 一堆 tools schema
- 相同的 repo policy
- 相同的 reference docs
- 幾乎沒變的 conversation prefix
那你其實是在反覆支付同一段前綴的計算成本。
這也是為什麼 prompt caching / prefix caching 這幾年會成為主流能力。
它不是附加小優化,而是在處理 agent 架構中最常見的一種浪費:
重複處理相同前綴。
ADK Context Caching 在解什麼問題
Google ADK 的 Context caching 很適合作為理解這件事的起點。
它的出發點非常直接:
當 agent 反覆使用長指令或大型資料集時,每次 request 都重送這些內容會慢、會浪費 token,也會增加成本。
在 ADK 中,context caching 是在 app / agent configuration 層提供的能力,透過 ContextCacheConfig 來控制行為。文件中提到的主要參數包括:
min_tokens:小於這個 token 門檻就不啟用 cachettl_seconds:cache 存活多久cache_intervals:同一份 cached content 最多重用幾次後刷新
它適用的場景很明確:
- 大量且穩定的 system instructions
- 反覆分析同一批大型文件
- 多次 query 同一份 codebase / repo context
- 多輪 agent interaction 中幾乎不變的 prompt prefix
從工程觀點看,ADK context caching 的重點不是 API 本身,而是它在提醒你一件事:
有些 context 應該被視為 reusable prefix,而不是每次重新拼裝的 request body。
這對 coding agent 特別重要。
因為 coding agent 的 prompt 常常正好符合這個模式:
- 前綴非常重
- 前綴變化很慢
- 真正高頻變動的是後綴
例如:
- coding rules
- repo conventions
- allowed tools
- approval policies
- review rubrics
- project architecture summary
這些資訊如果每一輪都重新付費一次,成本與 latency 很容易失控。
Cache 不是萬靈丹,它只解決「可重用前綴」
這裡有一個很重要的邊界。
Context caching 很有用,但它只在某一類問題上特別有效:
相同前綴會被反覆使用。
如果你的 prompt 結構很亂,導致本來應該穩定的部分常常被改動,那 cache 命中率就會很差。
例如:
- system prompt 版本頻繁變動
- tool schema 順序不穩定
- 每次 request 都把動態資料插進前綴中段
- retrieval 結果的位置或排序不穩定
這時候你不是沒有 cache feature。
你是沒有 cache discipline。
這也是為什麼 OpenAI 的 Prompt Caching、Anthropic 的 Prompt Caching、以及 Gemini API 的 Caching 都一直強調同一件事:
- 把 static content 放前面
- 把 dynamic content 放後面
- 讓前綴儘可能保持完全一致
換句話說,cache 能不能發揮效益,並不是只靠 provider 提供 feature。
還取決於你是否把 prompt 結構設計成「可快取」。
ADK Context Compaction 解的是另一個問題
很多人在第一次看到 ADK 的 Context compaction 時,直覺會把它當成另一種 cache。
但嚴格說,它不是。
ADK context compaction 的目標是:
當 session event history 持續變長時,用摘要來控制 context 膨脹。
這是一個完全不同的問題。
如果 context caching 解的是:
- 重複送出同樣前綴
那 context compaction 解的就是:
- 單一 session 隨時間推進,不可避免地越來越胖
ADK 文件裡的做法,本質上是 sliding window 式的 event compaction。 當 session 事件累積到某個門檻後,就對較舊的事件做摘要,保留較新的原始事件與摘要結果。
這裡的 trade-off 很明顯:
- 好處是 context 可以維持在比較受控的大小
- 代價是細節可能被摘要損失
所以 compaction 的本質不是 reuse,而是 lossy compression。
這點很重要,因為它代表你的優化目標也不一樣。
你評估 caching 時通常關心:
- cache hit rate
- cached token ratio
- latency 改善
- input cost 降低
但你評估 compaction 時更應該關心:
- 摘要是否丟失關鍵資訊
- 長任務成功率有沒有下降
- agent 在多輪互動後是否還能維持正確 state
一句話總結:
Caching 是重用同樣內容,Compaction 是用摘要換空間。
這兩個能力常常要一起用,但不能混成同一件事。
Session、State、Memory 也不是 Cache
ADK 在 Sessions 與 Memory 的設計上,也把概念切得很清楚。
可以這樣理解:
Session:單次會話的事件流State:該 session 內部的短期狀態Memory:跨 session 的長期可搜尋知識
很多實務系統會把這些東西通通叫「記憶」或「快取」,但它們其實在系統行為上完全不同。
Session / State
這一層比較像是當前會話的工作上下文。
它負責的是:
- 目前聊到哪
- 已經做過哪些工具呼叫
- 現在有哪些暫時狀態需要保留
這不是 cache。
因為它不是為了重用相同前綴,也不是為了降低 prefill 成本設計的。
Memory
Memory 更接近 searchable recall。
它的核心問題是:
agent 要怎麼從過去對話或外部知識中,把對現在有用的資訊找回來?
這也不是 cache。
因為 memory 通常是 selective retrieval:
- 你查什麼,拿回來的內容就不同
- 它不是固定前綴
- 它甚至可能讓 prompt 結構更動態
所以如果把 memory 誤當成 cache,你會很容易得到錯的成本預估。
memory 可能提升 recall 與回答品質, 但它不一定會降低 request 成本; 有時甚至會增加 token 消耗。
因此更精準的說法是:
- cache 解決 reuse
- compaction 解決 growth
- memory 解決 recall
這三者都有機會影響成本,但機制完全不同。
從 Provider 與 Infra 角度看,大家其實都在收斂到同一件事
如果把視角從 ADK 拉高,你會發現主流 provider 與推論 infra 都在往類似方向收斂。
Gemini API
Gemini API 的 Caching 分成 implicit caching 與 explicit caching。
- implicit caching:自動啟用,命中時可能帶來成本與延遲改善
- explicit caching:顯式建立 cached content,可控制 TTL,成本模型更可預期
這其實對應兩種工程哲學:
- 平台盡量自動幫你省
- 或你自己把 reusable prefix 當成一級資源來管理
OpenAI
OpenAI 的 Prompt Caching 本質也很清楚:
- exact prefix match 才有機會命中
- static content 應該放在 prompt 開頭
- dynamic content 應該放在後面
這說明了一件事:
prompt caching 不是魔法,它依賴 prompt 結構紀律。
Anthropic
Anthropic 的 Prompt Caching 文件,對 breakpoint、lookback window、automatic caching、explicit caching 都講得非常細。
對工程師來說,這份文件的價值不只在功能介紹,而是在提醒你:
- cache 命中是可以被設計的
- cache miss 也常常是結構問題,不只是運氣問題
Amazon Bedrock
Bedrock 的 Prompt Caching 進一步把這件事帶到平台治理層。
它談的是 cache checkpoints、TTL、不同模型限制,以及在平台 API 中如何管理這些能力。
這表示 prompt caching 已經不只是模型小技巧,而是正式進入 production architecture。
vLLM
從 infra 層看,vLLM 的 Automatic Prefix Caching 更直接點出本質:
prefix caching 是在重用已經計算過的 KV cache blocks,避免重複 prompt computation。
這個視角很好,因為它讓我們知道:
- 應用層看到的是 prompt caching
- infra 層看到的是 prefix reuse / KV reuse
不同抽象層的說法不同,但在解的其實是同一種浪費。
真正要設計的,不只是 Cache Feature,而是 Context Architecture
到這裡可以得到一個更完整的架構視角。
如果你在做 agent,context 不應該被視為一整塊沒有結構的 prompt blob。
它至少可以被拆成下面三類:
flowchart TD
A[Stable Prefix] --> B[Context Caching]
C[Growing Session History] --> D[Context Compaction]
E[Long-Term Knowledge] --> F[Memory / Retrieval]
B --> G[Runtime Context]
D --> G
F --> G
1. Stable Prefix
這類內容變化很慢,最適合拿去做 caching:
- system prompt
- policies
- tool definitions
- coding rules
- architecture guide
- common examples
2. Growing Session History
這類內容會隨互動膨脹,適合用 compaction 控制:
- 多輪對話
- 多步驟 tool traces
- 中間推理軌跡的摘要表示
3. Searchable Long-Term Knowledge
這類內容不應該每次硬塞進 prompt,而應該以 retrieval / memory 方式按需載入:
- 過去 session 的重要知識
- 使用者偏好
- 長期文件庫
- 跨任務知識
當你這樣切分後,很多所謂的 agent 成本問題就會開始變得可處理。
因為你終於可以問對問題:
- 哪些內容值得 cache?
- 哪些內容應該被 summary?
- 哪些內容應該被 retrieve?
- 哪些內容根本不該進 prompt?
這就是 Harness Engineering 的一部分
從 agent 系統設計角度看,這一整塊工作本來就是 harness engineering 的一環。
如果把 agent 想成一個持續演進的系統,那很多真正影響成本與穩定性的東西,其實不在單一 feature 裡,而在它的執行 harness 裡。
這個 harness 可能包含:
- prompt 組裝邏輯
- tool schema 管理
- cacheable prefix 設計
- retrieval 注入策略
- compaction 觸發規則
- session / memory 邊界
- eval cases
- latency 與 token metrics
這些事情很難被單純歸類成:
- application code
- infra code
- model tuning
它更像是一層讓 agent 可被量測、可被回歸測試、可被持續優化的執行框架。
也就是說:
harness engineer 的工作,不只是把 agent 跑起來, 而是把 agent 的 prompt、tools、memory、cache、eval 與 observability 串成一個可優化閉環。
從這個角度看,context caching 就不是「一個可以順手打開的設定」。
它是 harness design 的一部分。
給 Coding Agent 團隊的實作建議
對使用 coding agent 的工程團隊來說,下面幾個設計原則最值得優先處理。
1. 先把 Prompt 結構切乾淨
把內容分成:
- 穩定前綴
- 會成長的 session 部分
- 每次不同的動態輸入
如果這三者混在一起,你很難把 cache 做好。
2. Static Content 前置,Dynamic Content 後置
這幾乎是所有 provider 都反覆強調的原則。
把下列內容盡可能放前面:
- system rules
- coding style
- review criteria
- tool definitions
- stable repo guidance
把下列內容放後面:
- 當前任務
- 最新 diff
- 最新 tool result
- 即時 retrieval snippets
3. 不要把 Compaction 當成免費午餐
Compaction 可以控制 session 成本,但它可能損失細節。
所以你需要 eval:
- 長任務成功率
- 多輪一致性
- 關鍵資訊保留率
4. 不要把 Memory 當成「塞得比較聰明的 Prompt」
Memory 要做的是按需找回,不是把更多內容永遠附加在 request 前面。
如果 retrieval 沒設計好,memory 只會讓 prompt 更貴、更亂。
5. 量測的不是總 Token,而是結構化指標
至少應該觀測:
- cache hit rate
- cached tokens ratio
- TTFT / latency
- per-run total token cost
- compaction frequency
- retrieval hit quality
如果沒有這些指標,你就很難知道到底是:
- cache 沒命中
- compaction 太 aggressive
- retrieval 注入太多垃圾
- 還是 prompt prefix 根本不穩定
6. Side-agent 與 Background Agent 要特別注意 TTL
有些 agent 工作流不是連續高速互動,而是:
- 先開一個 side-agent
- 跑很久
- 幾分鐘後才有下一輪
這種情況下,TTL 設定會直接影響 cache 還有沒有價值。
所以你的快取策略,必須和 workflow 節奏一起設計。
一個實用的心智模型
如果要把整篇濃縮成一個簡單模型,我會這樣拆:
| 問題 | 適合機制 | 核心目的 |
|---|---|---|
| 相同前綴反覆出現 | Context caching | 降低重複 prefill 成本 |
| 單一 session 不斷膨脹 | Context compaction | 控制 context 成長 |
| 需要跨 session 找回資訊 | Memory / retrieval | 提升 recall 能力 |
這三個問題常常同時存在。
真正成熟的 agent 系統,不會只選其中一個,而是會把三者組合起來。
結論
最近大家在談 agent cost,表面上像是在談模型價格。
但對工程團隊來說,更值得關心的其實是這個問題:
你的 agent,是否把 context 當成一種需要被架構化管理的資源?
ADK 的價值,在於它把幾種常被混淆的能力分開了:
- caching
- compaction
- sessions / state
- memory
這種切分方式,有助於用更清楚的架構視角理解 agent 成本與上下文管理。
而當你開始把這些東西放進同一個可觀測、可評估、可回歸優化的執行系統裡,這件事就已經不只是 prompt engineering。
它更像是 harness engineering。
在 agent 時代,成本優化不再只是 procurement 問題。
它是 prompt、runtime、memory、cache 與 eval 的共同設計問題。