Coding agent 多模型路由值得嗎?提示快取成本解析
Coding agent 每次切換模型都可能失去 prompt cache。本文用 20 至 60 次 API 呼叫與前綴重複計費,說明何時路由划算、何時固定模型更省。
多模型路由對 coding agent 的影響
多模型路由會將每個請求傳送給能夠處理該請求的最低成本模型。這種方式用於聊天流量時通常效果良好。但用於 coding agent 時,節省的費用通常會低於額外成本,因為 agent 的費用主要來自每個模型各自快取的 prompt 前綴,而切換模型會使該快取失效。
本文主張的規則如下:為了維持可用性,可在不同 provider 之間路由;只有在工作邊界才為了降低成本而切換不同 tier;凡是涉及 agent 工作流程的情境,每個 session 應固定使用一個模型。以下說明理由。
以下一次定義 4 個術語。router 會為每個請求選擇模型。gateway 是請求經過的 proxy,可能同時負責路由,也可能不負責。prompt cache 是 provider 儲存 prompt 已處理前綴的機制,因此後續請求若重複使用該前綴,輸入費用只按原價的一小部分計算。KV cache(key value cache)則是在自行執行的伺服器內實作相同概念。
為什麼聊天流量能順利路由,而 agent 流量不行
聊天請求只有一個回合。請求送達後會經過分類、傳送至模型,再傳回結果。下一個請求不會沿用前一個請求的內容。路由器可以將這個問題傳送至小型模型,再將下一個問題傳送至大型模型;兩個請求彼此不知道對方曾經發生。幾乎所有路由基準測試測量的都是這類工作負載,而優良的路由器確實能處理得很好。
agent 回合並不是單一請求。像「修正失敗的測試」這類指令,可能會轉換成 20 到 60 個 API 呼叫。每次呼叫都會重新傳送完整對話:system prompt、每個工具定義、agent 讀取過的每個檔案,以及它看過的每個命令輸出。內容只會持續增加。到了第 30 次呼叫,重複的前綴可能達到數萬個 token,但每次呼叫真正新增的內容只有幾百個 token。
這種結構會改變「昂貴」一詞的意義。在聊天中,成本大致是模型價格乘以請求數。在 agent 迴圈中,成本來自前綴,而且每次呼叫都會重新計費。本文其餘內容都建立在這個事實上。
提示快取是以模型為單位,agent 位於提示快取中
Anthropic 將快取讀取定價為基礎輸入價格的 0.1 倍,5 分鐘快取寫入定價為 1.25 倍。以下是截至 August 2026 公布的牌價。
The data behind this chart
[
{
"label": "Opus 5",
"uncached_input_usd": "5.00",
"cache_read_usd": "0.50"
},
{
"label": "Sonnet 5",
"uncached_input_usd": "2.00",
"cache_read_usd": "0.20"
},
{
"label": "Haiku 4.5",
"uncached_input_usd": "1.00",
"cache_read_usd": "0.10"
}
]請跨列比較第二組數列與第一組數列,而不是逐欄向下比較。Opus 5 的快取讀取費用為每百萬 tokens 0.50 美元。未使用快取的 Haiku 4.5 輸入費用,也就是清單中最便宜的模型,為 1.00 美元。因此,在最昂貴的模型上重新讀取熱快取中的提示前綴,每個輸入 token 的費用反而低於在最便宜模型上冷讀取相同前綴的費用。
單是這項比較,就足以推翻大多數路由計畫。路由器將工作「向下」移到較低層級時,比較的是牌價。但 agent 在工作階段中途,不是按照目前使用模型的牌價付費,而是按照快取讀取價格付費;這個價格已低於較便宜模型的未使用快取輸入費率。
快取索引是根據提示前綴的雜湊值建立,並且以模型為單位。向不同模型發出的請求會與一個從未看過該請求的儲存區進行雜湊比對,因此找不到快取,必須支付完整價格。快取本身也是階層式的:先是 tools,再來是 system,最後是 messages。任何層級的變更都會使該層級及其後的所有內容失效,也就是說,編輯一項 tool 定義,會捨棄位於其後的 system prompt 快取。會在執行階段註冊 tools 的 agent,即使完全未接觸路由器,也會遇到這種情況。
實際進行一次工作階段中途切換的代價
假設工作階段具有 40,000 個 token 的穩定前綴。代理程式讀取數個檔案後,這是常見的大小。以下根據上方的牌價,計算單一回合的前綴成本。
The data behind this chart
[
{
"label": "Opus 5, cache warm",
"prefix_cost_usd": "0.020"
},
{
"label": "Sonnet 5, turn after switch",
"prefix_cost_usd": "0.100"
},
{
"label": "Opus 5, cache re-warmed",
"prefix_cost_usd": "0.250"
}
]維持使用 Opus 5 並命中暖快取時,該回合的前綴成本為 0.020 美元。切換至 Sonnet 5 後的第一個回合成本為 0.100 美元,因為 Sonnet 沒有這個前綴的快取項目,必須建立一份。切回 Opus 5 時成本為 0.250 美元,因為原本的項目在工作階段離開期間已過期。
因此,這次往返切換支付了 2 次快取寫入成本,換來避免 2 次快取讀取。相對地,切換讓其中 1 個回合能以 Sonnet 的輸出價格,而不是 Opus 的輸出價格產生內容。詳細計算完整列出整段往返過程:節省金額只有不到 1 美分,而快取懲罰成本達到數十美分。懲罰成本大於節省金額超過 1 個數量級;前者會隨前綴長度增加,後者則不會。
這些數字的計算方式
這裡的所有數字,都是以第一張圖表中的公開牌價進行算術計算。這是成本模型,不是效能基準測試,計算過程沒有送出任何請求。修改前綴大小後,比例也會隨之改變。
前綴:40,000 個 token,在整個回合中維持不變。
Opus 5, warm read 40,000 x $0.50 / 1e6 = $0.020
Sonnet 5, cache write 40,000 x $2.50 / 1e6 = $0.100 (1.25 x $2 base)
Opus 5, cache write 40,000 x $6.25 / 1e6 = $0.250 (1.25 x $5 base)往返切換成本:$0.100 + $0.250 = $0.350。被取代的 2 個 Opus 暖快取回合:$0.040。這次繞路增加的成本:$0.310。
以 1 個回合產生 800 個輸出 token 計算,節省金額是 Opus 5 每百萬個 token $25 與 Sonnet 5 每百萬個 token $10 之間的輸出價格差:
800 x ($25 - $10) / 1e6 = $0.012花費 $0.310 只節省 $0.012,成本約為收益的 25 倍。節省金額會隨輸出 token 數量增加,而輸出 token 每回合通常較少且大致固定。懲罰成本則會隨前綴大小增加,而前綴會在整個工作階段中持續成長。工作階段越長,情況只會越差,不會改善。
不同供應商的工具呼叫格式並不相同
代理程式是工具呼叫迴圈,因此工具呼叫格式的重要性遠高於聊天情境。Anthropic 的 Messages API 會回傳 tool_use 內容區塊,並要求回傳 tool_result 區塊。OpenAI 相容 API 會回傳 tool_calls 陣列,其中 function.arguments 是 JSON 編碼的字串,而不是巢狀物件。閘道會在兩者之間進行轉換,一般呼叫通常能順利完成。
問題會出現在邊界情況。平行工具呼叫是指模型在一次回應中發出多個呼叫;不同服務對這類呼叫的表示方式不同,支援程度也不一致。嚴格 schema 驗證是個別供應商提供的功能,因此模型在某個端點能保證參數符合 schema,在另一個端點通常只能做到參數大致有效。代理程式會將這項差異視為包含剖析錯誤的工具結果,接著再花一個回合嘗試修正。這些修正回合會按照完整 prefix 價格計費,因此格式不符不只會出現在對話記錄中,也會反映在帳單上。
自架端點需要明確完成這項設定。vLLM 的 OpenAI 相容伺服器需要 --enable-auto-tool-choice,以及與模型系列相符的 --tool-call-parser(hermes、mistral、llama3_json 等),另外還需要能處理工具角色訊息的 chat template。vLLM 文件明確說明這條路徑的限制:使用 tool_choice="auto" 且未設定嚴格 schema 限制時,vLLM 會從原始文字擷取工具呼叫,因此參數偶爾可能格式錯誤,或不符合函式的參數 schema。為模型選錯 parser 是設定錯誤,表現為代理程式無法呼叫工具。在將網路流量轉送至該端點前,了解這點很重要。這裡的Ollama 與 vLLM 自行提供模型服務的差異也很重要,因為兩者對工具呼叫的支援方式不同。
中途 fallback 會在沒有錯誤的情況下改變行為
Fallback routing 是最容易被誤啟用的功能。Gateway 設定會在第一個模型回傳 rate limit 或 5xx 時,改用另一個模型重試,並讓失敗的模型進入數秒的 cooldown。對聊天流量而言,這是正確行為。但在長時間 agent task 中,這表示 task 的後半段改由你未選擇的模型執行。
系統不會回報這項變更。Task 不會失敗,agent 不會發出警告,exit status 也會是 success。你得到的是一個由某個模型撰寫計畫、再由另一個模型進行編輯的 task;執行到一半時,語氣與操作習慣會改變。唯一可靠的訊號是 gateway request log 或 response metadata 中的 model 欄位。因此,如果你確實使用 fallback,應記錄每個 request 的該欄位,並在結果異常時查看。若不知道結果由哪個模型產生,除錯行為所花的時間可能比 fallback 節省的時間更多。
相同的問題也會出現在 context compression。許多 agent 會呼叫小型模型,摘要過長的歷史內容。如果該呼叫使用不同的模型或不同的 system prompt,就會寫入自己的 cache entry,而不會更新主要 session 的 cache。因此,下一個完整 turn 仍須付出 cold prefix 的成本。壓縮節省了 token,卻使 cache 失效。
路由開銷確實存在,但延遲不是主要問題
路由器確實會為每個請求增加處理工作,因此應準確評估其影響。DigitalOcean 報告指出,其 Arch-Router 模型在自有評估中,約以 51 milliseconds 判定路由意圖,路由準確率為 93.17%。這些數據來自其測量方式與基準測試,不是我們的數據,也不是普遍適用的結果。若直接採用這些數據,結論仍令人放心:40 次 agent 呼叫增加的時間約為 2 seconds,而整個工作通常會執行數分鐘。
在這裡,讓路由變得昂貴的不是這 2 seconds。真正造成影響的是使用完整模型呼叫進行分類的路由器,因為每個請求都會新增一次推論,而且和其他請求一樣需要計費並排隊。上述快取計算才是兩者共同的基礎,但那根本不是額外開銷,而是路由原本要最佳化的對象所需付出的成本。
在自行管理的伺服器上,同樣的規則仍然適用,但調整空間更小。prompt cache 在本機的對應機制是 KV cache 中的 prefix caching,而 KV cache 會佔用 GPU 記憶體。在一個 GPU 上託管 2 個模型,會將這些記憶體分配給兩者,因此每個模型可用的 KV cache 都更小,prefix 也會更早被移除。如此一來,在 2 個本機模型之間進行路由,可能同時降低兩者的快取命中率。如果你正在估算硬體需求,與其先考慮路由器,不如先參考 coding agent 在 VPS 上實際需要的記憶體與 CPU。
決策規則
- 跨 provider 路由以維持可用性。 如果替代方案是請求失敗,任何成本都值得付出。將 fallback 固定到使用相同 tool call 格式的 model,讓 agent 的迴圈持續運作,並記錄每次呼叫由哪個 model 提供服務。
- 僅在工作邊界跨 tier 路由以控制成本。 在 session 開始前,只做一次決策:rename 使用 Haiku,refactor 使用 Opus。若在該 session 的第 30 個 turn 才做這項決策,則是不好的做法。
- 任何 agentic 工作每個 session 固定使用一個 model。 session 的價值在於 warm cache。切換 model 等同於清除該 cache,因為實際上就是如此。
- 可自由路由 subagent。 subagent 以全新的小型 context 啟動,不會損失 warm cache,因此可使用最適合其工作的 model。這是 agent 內部唯一幾乎不需付出路由成本的情境。
若要實作這套方式,交由 gateway 處理即可:使用 model aliases 和明確的 fallback lists。以下是最精簡的 LiteLLM proxy 設定。
model_list:
- model_name: agent-primary
litellm_params:
model: anthropic/claude-opus-5
api_key: os.environ/ANTHROPIC_API_KEY
- model_name: agent-standby
litellm_params:
model: anthropic/claude-sonnet-5
api_key: os.environ/ANTHROPIC_API_KEY
router_settings:
fallbacks: [{"agent-primary": ["agent-standby"]}]
num_retries: 2
cooldown_time: 30讓 agent 指向 agent-primary 後,在該 model 無法連線前,agent 會持續使用同一個 model。兩個項目位於同一個 provider,因此 fallback 啟用時,tool call 格式不會改變。此時仍會接受 tier 變更,但只有在替代方案是請求失敗時,這項取捨才值得。這就是不附帶成本路由的可用性路由,也是大多數 coding agent 需要的組合。完整建置方式包含 keys 與 budgets,請參閱在自己的 VPS 上執行自架 LiteLLM gateway;本文刻意不重複說明。
一個精心選擇的模型勝過任何路由器
路由是用來處理請求難度差異的方案。編碼代理程式的難度差異沒有看起來那麼大,因為每次呼叫中最昂貴的部分都是相同的前綴,與請求內容無關。當前綴占主要成本後,廉價層與高價層之間的差異會逐漸縮小至輸出價格的差異,而輸出通常只占代理程式 token 的一小部分。
因此,合理的預設做法是選定一個模型,啟用快取,並設定足夠長的 TTL(存留時間),涵蓋你停下來閱讀 diff 的間隔。Anthropic 提供 1 小時的快取寫入,價格是基本輸入價格的 2 倍;使用 2 次讀取後通常即可回本。這往往比任何路由器都更有效。請參考 Opus、Sonnet 與 Haiku 的直接比較,有意識地選擇模型層級。如果費用仍是問題,請依照 在 VPS 上控制 AI 代理程式成本 的做法,透過設定預算與縮小內容範圍來降低費用,而不是在工作階段中途切換模型。
當請求彼此獨立且內容簡短,或子代理程式一開始就使用全新的內容環境時,才適合進行路由。若是一個長工作階段持續處理同一項工作,則應固定使用同一個模型。大多數編碼代理程式的工作都屬於後者,因此能替聊天產品省錢的路由器,在這裡反而會悄悄增加成本。如果你尚未決定使用哪個代理程式,Claude Code、Cursor、Codex 與 Copilot 的比較 說明了各工具如何處理模型選擇,其中有些工具會替你做出這項決定。
FAQ
在工作階段中途切換模型,真的會遺失 prompt cache 嗎?
會。Prompt cache 會根據 prompt 前綴的雜湊值建立索引,並依模型分開儲存。因此,傳送至其他模型的請求會對照一個從未見過該前綴的儲存區,找不到任何項目,必須支付完整的未快取輸入費用;若已啟用快取,還會另外支付寫入快取的費用。切回原模型也無法取回原本的項目,因為預設的 five minute 存留時間通常已經到期。請檢查回應 usage object 中的 cache_read_input_tokens 與 cache_creation_input_tokens 欄位:長時間工作階段若讀取到的 cached tokens 為 0,就是這項問題的徵兆。
對 agent 而言,改用較便宜的模型是否真的能降低成本?
只有在沒有 warm cache 可供捨棄時才會。Anthropic 的 cache read 費用是 base input 的 0.1 倍,因此在 Opus 5 上進行 warm read,費用低於 Haiku 4.5 的未快取輸入費率。工作階段已有大型快取前綴後,原本使用的模型在輸入成本上通常已是較便宜的選項。內容新且規模小時,路由至其他模型才可能降低成本,例如工作開始時,或只攜帶必要內容的 subagent。
為什麼我的 agent 在工作進行到一半時行為改變?
請確認是否觸發了 gateway fallback。主要模型發生 rate limit 或 5xx 時,gateway 會在 standby model 上重試,並讓主要模型進入 cooldown 幾秒,因此工作後續內容會改由其他模型執行。這不會產生錯誤或警告,工作仍會回報成功。gateway request log 或回應 metadata 中的 model 欄位是唯一可靠的紀錄;只要使用 fallback,就應逐一記錄每個請求的該欄位。
Tool call 在每個 provider 上的運作方式都相同嗎?
不完全相同。Anthropic 的 Messages API 使用 tool_use 與 tool_result content block;OpenAI-compatible API 使用 tool_calls array,其中的 function.arguments 是以 JSON 編碼的字串。Gateway 能妥善轉換常見情況,但 parallel tool call 與 strict schema enforcement 會依 provider 而異。在 self-hosted vLLM 上,必須設定 --enable-auto-tool-choice,並指定符合模型系列的 --tool-call-parser。vLLM 文件指出,若沒有 strict schema constraint,server 會從 raw text 擷取 tool call,因此 arguments 偶爾可能格式不正確。
Coding session 的 cache TTL 應設定多久?
連續工作時使用預設的 five minute 存留時間;若使用者會在每次操作之間查看 diff,則使用 one hour 選項。Anthropic 對 five minute write 的計費是 base input 的 1.25 倍,對 one hour write 的計費是 2 倍,而 read 的計費是 0.1 倍。Five minute write 只要一次 read 就能回本,one hour write 則需要兩次。因此,只要預期稍後會回來繼續工作,較長的存留時間通常比每次為 cold prefix 付費更省。