生活分享
模型路由與級聯:便宜先試、貴的兜底
多模型級聯(cascade)讓便宜的輕量模型先答,模型自己評估的信心不夠、逾時或呼叫失敗才升級到更貴的模型,藉此把大多數請求的成本壓低,同時對少數困難的請求保留品質。這篇說明規則路由怎麼依長度、語言與任務類型決定起點,信心怎麼觸發升級,逾時、重試與 fallback 三者有什麼不同,以及每次請求的成本上限怎麼擋住最壞情況;範例是一段純 Python 程式,OpenRouter 與 LiteLLM 內建的路由功能只做對照。
閱讀時間約 8 分鐘

本篇目錄
一個工作流要串好幾個模型時,多數請求其實不需要動用最貴的那一顆:把便宜、快的輕量模型放在前面讓它先答,只有當它自己評估信心不夠,或呼叫逾時、出錯,才把同一個問題交給更貴、更強的模型,這種做法叫級聯(cascade),目的是把多數簡單請求的成本壓在輕量模型的價位,同時保留少數困難請求的答題品質。
這篇會講規則路由怎麼依長度、語言與任務類型決定第一個要打的模型,模型怎麼替自己的答案評信心,信心不夠時怎麼升級,呼叫逾時或出錯時怎麼跟「信心不夠」分開處理成 fallback,以及每次請求另外設一個成本上限。範例要跑起來需要 Python 3.11 以上、安裝官方的 anthropic 套件、並把 API 金鑰放進環境變數 ANTHROPIC_API_KEY;OpenRouter 與 LiteLLM 本身內建的路由功能不是這篇的重點,只用一段和一張對照表列出它們官方文件怎麼稱呼同樣的概念。
規則路由:用長度、語言與任務類型決定起點
級聯的第一步不是丟給模型判斷,而是用幾個簡單、幾乎不花錢的規則先決定要打哪一顆模型。常見的規則有三種:輸入的長度(字數短的閒聊或翻查用詞,多半輕量模型就能處理,長文摘要或整篇改寫通常要換到中階以上)、輸入用的語言或混用的程度(單一語言的短句一般較容易,中英夾雜或包含大量專有名詞的輸入本身就比較吃模型能力)、以及任務類型的關鍵字(提到「程式」「合約」「法律」這類字眼,或要求輸出結構化欄位,代表這題本來就不簡單)。這些規則只決定起點,不是最終答案;規則怎麼切、門檻放在哪裡要看自己的流量調整,本站沒有實測。
規則路由的重點是快、不用另外呼叫模型去判斷難度,因為判斷難度本身如果也要打一次 API,那還不如直接用輕量模型作答,讓下一步的信心評估去處理「答得好不好」。這篇只借用「先便宜、有需要再升級」這個方向,不重講路由本身以外的取捨。
讓模型自己說有多確定:自評信心與升級
規則決定起點之後,實際要不要繼續往上升級,這篇用最簡單的做法:請模型在回答之後自己多輸出一行信心分數,例如「CONFIDENCE: 0.4」,分數愈接近 1 代表模型自己愈確定答案正確。呼叫端用一個簡單的規則運算式(regular expression)抓出這一行,跟一個門檻比較,低於門檻就把同一個問題交給下一階更強的模型再答一次,直到信心夠高、打到最頂層,或碰到後面會提到的成本上限為止。
自評信心不是校準過的機率,這篇把它當成一個粗略、幾乎不用額外成本的訊號,用來決定要不要多花一次呼叫;這一點下面的提醒會再講清楚。
逾時、重試與 fallback:呼叫失敗時怎麼處理
信心不夠是「這顆模型答完了,但不太確定」,逾時、出錯或被限流則是另一回事:這顆模型這次根本沒有正常回應。這篇把兩者分開處理。逾時(timeout)是幫每次呼叫設一個等待上限,超過就不再乾等;重試(retry)是同一顆模型因為網路或暫時性的錯誤,用同樣的問題再打一次;fallback 則是重試也不行之後,直接換成下一階的模型,不再糾結原本那一顆。
Anthropic 官方的 Python 套件文件寫,用戶端預設逾時是十分鐘,可以用 timeout 這個選項調整,接受一個秒數,或更細緻的物件;連線錯誤、408、409、429 與 500 以上的伺服器內部錯誤,預設都會自動重試兩次,重試次數用 max_retries 這個選項調整,逾時的請求同樣預設重試兩次,而逾時時套件丟出的是 APITimeoutError。這篇的範例只靠這兩個選項處理「同一顆模型該不該再試一次」,fallback(換到下一階模型)則是自己在級聯迴圈裡寫的邏輯:捕捉到逾時或錯誤,就把索引往上移一階,而不是留在原地一直重試;整個級聯另外再設一個最大嘗試次數,計的是實際打出去的呼叫次數,升級與 fallback 各算一次,同一顆模型的重試由套件在一次呼叫內部處理、不算進這個計數。範例直接把這個上限設成階數:迴圈每失敗或升級一次就往上一階,每一階最多只打一次,所以在這個範例裡寫成比階數大的數字永遠不會生效。三個上限疊在一起,請求才不會卡住不放。
純 Python 的級聯:規則路由、信心升級與成本上限
下面兩段程式把前面三節的邏輯串起來:規則路由決定第一階要打哪顆模型,模型自評信心決定要不要升級,逾時或出錯則直接跳去下一階,整個過程另外設一個成本上限。程式用 Python 3.11 以上與 Anthropic 官方的 anthropic 套件(pip install anthropic),API 金鑰從環境變數 ANTHROPIC_API_KEY 讀,不寫死在程式裡。範例把同一家供應商的三個模型當成級聯的三個階,由輕到重是 claude-haiku-4-5-20251001、claude-sonnet-5 與 claude-opus-5;同一家供應商為什麼會分成這樣的層級,「同一家為什麼有好幾個模型:旗艦、中階、輕量怎麼選」那篇已經講過,這裡直接借用這個分層當級聯的階梯;依 Anthropic 的模型頁,由輕到重的輸入與輸出單價各差到五倍,也是先用輕量模型划算的原因。
每次呼叫前,級聯依序檢查下面四件事:
- 目前是不是已經到最大嘗試次數
- 累積花費是不是已經到這次請求的成本上限
- 這一階模型有沒有在時限內正常回應
- 回應裡的信心分數有沒有到門檻
"""route_and_call.py -- rule-based starting tier, one timed call with a self-rated confidence."""
import re
TIERS = [
{"model": "claude-haiku-4-5-20251001", "in_price": 1.0, "out_price": 5.0},
{"model": "claude-sonnet-5", "in_price": 2.0, "out_price": 10.0},
{"model": "claude-opus-5", "in_price": 5.0, "out_price": 25.0},
] # USD per MTok, read on the official models overview page (see sources)
CONFIDENCE_RE = re.compile(r"CONFIDENCE:\s*([01](?:\.\d+)?)")
HARD_TASK_WORDS = ("程式", "合約", "法律", "重構", "逐字稿")
def choose_start_tier(prompt: str) -> int:
"""Length, script and task-type rules pick the first rung; they do not answer the question."""
cjk_count = sum("一" <= ch <= "鿿" for ch in prompt)
looks_hard = any(word in prompt for word in HARD_TASK_WORDS)
if looks_hard or len(prompt) > 400 or cjk_count > 200:
return 1 # start at Sonnet; skip Haiku for long or specialised requests
return 0 # short, plain-language requests start at Haiku
def call_tier(client, tier: dict, prompt: str, timeout: float) -> dict:
"""One timed call. Asks the model to end its own answer with a confidence line."""
ask = prompt + "\n\n最後另起一行,格式 CONFIDENCE: 0 到 1 的小數,越確定答案正確越接近 1。"
message = client.with_options(timeout=timeout).messages.create(
model=tier["model"],
max_tokens=1024,
messages=[{"role": "user", "content": ask}],
)
text = "".join(block.text for block in message.content if block.type == "text")
match = CONFIDENCE_RE.search(text)
confidence = float(match.group(1)) if match else 0.0
cost = (
message.usage.input_tokens * tier["in_price"]
+ message.usage.output_tokens * tier["out_price"]
) / 1_000_000
return {"text": text, "confidence": confidence, "cost": cost, "model": tier["model"]}
第一段程式定義三個階的模型與價格、規則路由的起點判斷,以及打一次某一階模型、抓出信心分數與這次呼叫花費的函式;範例把「語言」這條規則簡化成數中文字數,要分辨中英夾雜得另外寫。第二段程式是實際的級聯迴圈:每次呼叫前先看上面四件事,逾時或出錯就升級成 fallback,信心不夠門檻就升級成正常的下一階,兩種升級走的是同一個索引往上移的動作,差別只在觸發的原因。
"""cascade.py -- escalate on low confidence, fall back on error, both capped."""
import os
from anthropic import Anthropic, APIConnectionError, APIStatusError, APITimeoutError
from route_and_call import TIERS, call_tier, choose_start_tier
CONFIDENCE_THRESHOLD = 0.6
MAX_ATTEMPTS = len(TIERS) # one call per tier; SDK retries happen inside one call
PER_CALL_TIMEOUT = 20.0 # seconds
COST_CAP_USD = 0.05 # this cascade's own limit for one end-user request
def run_cascade(prompt: str) -> dict:
client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"], max_retries=2)
tier_index = choose_start_tier(prompt)
spent = 0.0
calls = 0
best = {"text": "", "confidence": -1.0, "cost": 0.0, "model": None}
for _ in range(MAX_ATTEMPTS):
if spent >= COST_CAP_USD:
break # checked before the call, so this round never spends anything
tier = TIERS[tier_index]
calls += 1
try:
result = call_tier(client, tier, prompt, PER_CALL_TIMEOUT)
except (APITimeoutError, APIConnectionError, APIStatusError):
if tier_index >= len(TIERS) - 1:
break # already on the strongest tier, nothing left to fall back to
tier_index += 1 # fallback: this tier failed outright, not just unsure
continue
spent += result["cost"]
if result["confidence"] > best["confidence"]:
best = result
if result["confidence"] >= CONFIDENCE_THRESHOLD or tier_index >= len(TIERS) - 1:
break
tier_index += 1 # escalate: this tier answered but is not confident enough
best["attempts"] = calls # calls really made, not loop rounds
best["spent_usd"] = round(spent, 6)
return best
if __name__ == "__main__":
outcome = run_cascade("幫我用三句話說明報稅的基本流程")
print(outcome) # 示意:實際文字與信心依當次呼叫而定
每次請求的成本上限,與 OpenRouter/LiteLLM 內建路由的對照
沒有成本上限時,最壞情況是每個請求都真的把三個層級都打過一輪:先問輕量模型,信心不夠再問中階,還是不夠再問旗艦,一個請求付出三顆模型的錢。這篇在級聯外面另外加一個以美元計的成本上限,累積花費碰到上限就不再升級,直接把目前最好的答案回傳,即使那時候的信心還沒到門檻。這個上限只防最壞情況,不是估算平均成本的方法;怎麼幫成本、品質與延遲三個量抓出可比較的估算表,是本系列《成本、品質、延遲:多模型流程怎麼取捨》那篇的主題,這篇不重複,只借用「先便宜、有需要再升級」這個方向。
OpenRouter 與 LiteLLM 這兩個工具自己也各有一套路由邏輯,這篇不重講怎麼用它們串接不同供應商——那是本系列《統一 API 層:OpenRouter 與 LiteLLM 換模型不改程式》那篇的主題——這裡只照官方文件列出兩邊怎麼稱呼跟這篇同樣的概念,方便對照。
OpenRouter 把這類功能叫 Auto Router,模型設成 openrouter/auto 之後,OpenRouter 的文件寫,會用一個輕量的分類器把提示詞分成大約三十種任務類型,再依 OpenRouter 社群過去七天在同類任務上的花費占比挑模型,另外可以用 cost_tier 這個設定選價格帶,由便宜到最強是 low、medium、high、xhigh、max 五個值,文件註明那是一條帶不是上限,比該帶便宜的模型一樣會被排除;同一份文件也寫,分類或排名萬一暫時不可用,路由會退回一組預設模型,不會直接讓請求失敗。LiteLLM 的 Router 則是在自己設定的多個節點之間分流,挑節點的方式在 Router 類別上用 routing_strategy 這個參數指定,文件把這一頁上的策略列成 simple-shuffle、least-busy、usage-based-routing-v2、latency-based-routing 與 cost-based-routing 五個值,並建議正式環境用預設的 simple-shuffle;另外還有 allowed_fails 與 cooldown_time 可以把常失敗的節點暫時移出名單,重試次數與間隔則是 num_retries 與 retry_after,文件並註明 num_retries 是 LiteLLM 自己的重試迴圈,跟供應商套件的 max_retries 不是同一個設定。
| 項目 | 這篇的純 Python 級聯 | OpenRouter | LiteLLM |
|---|---|---|---|
| 路由依據 | 規則(長度、語言、任務關鍵字)決定起點,模型自評信心決定要不要往上升 | Auto Router 依過去七天社群花費占比,把提示詞分成約三十種任務類型後選模型;cost_tier 可另外選價格帶 | 在自己設定的多個節點之間分流,Router 類別的 routing_strategy 參數指定策略,文件列出 simple-shuffle(預設)、least-busy、usage-based-routing-v2、latency-based-routing 與 cost-based-routing 五個值 |
| 升級或容錯 | 信心低於門檻,或呼叫逾時、出錯,就換下一階模型 | Auto Router 分類或排名不可用時退回一組預設模型;一般模型呼叫也能用 models 陣列依序 fallback | allowed_fails 與 cooldown_time 把常失敗的節點暫時移出名單,再靠 fallback 換模型 |
| 逾時與重試 | 呼叫另設 timeout,重試次數交給官方套件的 max_retries 處理 | 這篇讀到的 Auto Router 與 Model Fallbacks 兩頁沒有列出獨立的逾時或重試參數,失敗時走的是上一列的 fallback | num_retries 控制重試次數,retry_after 設最短等待間隔 |
| 成本控制 | 累積花費碰到本文設的每請求上限就停止再升級 | cost_tier 只選價格帶,不是金額上限;文件寫,要限制一次請求的花費得用 provider.max_price,它依價格篩掉端點 | rpm、tpm 是各節點每分鐘的用量上限,用來挑節點或濾掉超限的節點,不是每次請求的金額上限 |
常見問題
級聯一定要從最便宜的模型開始嗎?
不一定。規則路由會先看輸入的長度、語言與任務類型,遇到明顯困難的任務,例如提到「程式」「合約」這類關鍵字,或輸入本身很長,可以直接跳過輕量模型、從中階開始,不用每次都從最便宜的那一顆試起。
模型自己說信心很高,代表答案一定對嗎?
不代表。模型自己回報的信心分數只是它自己的猜測,不是統計上校準過的機率,可能講得很肯定但答案其實是錯的。這篇把信心分數當成要不要多打一次、換更強模型的粗略訊號,真正要確認答案內容,還是要靠獨立的規則或架構驗證。
升級(escalate)跟 fallback 有什麼不同?
升級是這一階模型正常回應了,但信心分數沒到門檻,所以換下一階再問一次;fallback 是這一階模型呼叫逾時或出錯,根本沒有正常回應,所以直接換下一階,不會在原地一直重試。兩者最後都是把問題交給更強的模型,但觸發的原因不一樣。
為什麼還要另外設每次請求的成本上限?
因為級聯最壞的情況是一個請求把輕量、中階、旗艦三個層級都打過一輪,等於付了三顆模型的錢。這篇在信心門檻與最大嘗試次數之外,另外用一個以美元計的成本上限擋住這種最壞情況:累積花費碰到上限就不再升級,直接回傳目前最好的答案。
OpenRouter 的 Auto Router 或 LiteLLM 的 Router 可以取代這篇的做法嗎?
可以是另一種選擇。OpenRouter 的 Auto Router 是平台端寫好的路由,依 OpenRouter 社群整體的花費挑模型;LiteLLM 的 Router 則是跑在自己程式裡的套件,在自己設定的多個節點之間分流。兩邊依據的訊號跟能調的參數都跟這篇不完全一樣,這篇只照官方文件列出兩邊怎麼稱呼相關概念做對照,不是教學主體;要不要換成它們,看團隊想不想自己控制升級與成本的判斷邏輯。
範例裡的 timeout、max_retries 與成本上限這些數字要怎麼設?
這篇範例裡的信心門檻、逾時秒數與成本上限都只是示意,用來示範這幾個機制怎麼串在一起,不是建議值;最大嘗試次數則是直接設成階數,不是另外挑的數字;實際要設多少,需要依請求的長度、模型的正常回應時間與能接受的花費調整,量測成本、品質與延遲的方法在本系列另一篇會講。
多模型 AI 工作流教學:從拆任務到串接不同模型多模型 AI 工作流教學:從拆任務到串接不同模型這個系列教的是怎麼把一件工作拆開、交給合適的模型,再把結果接回同一條流程:判斷該不該拆、拆給誰,換供應商不改程式,設計便宜先試的路由與級聯,讓模型之間用結構化輸出交接資料,再到代理式工具怎麼分工、同一套工具怎麼給多個客戶端共用、Claude Code 與 Codex 怎麼搭本機模型,以及上線後怎麼追蹤與防護。一般使用者可以從判斷該不該拆的觀念讀起,已經會寫 Python 的人能直接進到換供應商、寫路由與交接資料的幾篇。閱讀全文
成本、品質、延遲:多模型流程怎麼取捨成本、品質、延遲:多模型流程怎麼取捨多模型流程的成本、品質與延遲要分開量:成本是官方每百萬 token 單價乘上呼叫次數與 token 數,品質要靠自己建的評測集分數而不是各家公布的跑分,延遲要看 p50 與 p95 兩個百分位數而不是平均值。這篇說明串行與並行架構怎麼影響這三個量,快取與批次該放進流程的哪一步,並用 2026 年 9 月當日的官方定價,換算單一旗艦、級聯與並行互審三種流程處理同一個假設請求的估算成本,附上每一步的假設,方便換成自己的用量重算。閱讀全文
同主題延伸閱讀
生活分享
Claude Code、Codex 搭本機模型:兩種接法怎麼選
Claude Code 與 Codex 搭配本機模型有兩種接法:代理照常連雲端、把大量雜務交給腳本或 MCP 工具去問本機模型,或是把代理的模型整個換成本機模型。這篇用資料能不能出門、上下文開得夠不夠長、工作的類型三個問題幫你選,並對照 Ollama、LM Studio、Anthropic 與 OpenAI 的官方文件,分清楚本機權重、Ollama 的 cloud 標籤與供應商端點是三種不同的東西。
引用本文的文章
最新旅遊情報攻略

情報
2026 韓國楓葉預測:雪嶽山 10 月 20 日、首爾近郊 10 月底、內藏山與漢拏山 11 月上旬
韓國山林廳 2026 年 9 月 22 日公布的楓紅高峰預測:雪嶽山 10 月 20 日,春川、國立樹木園到首爾植物園落在 10 月 28 日到 11 月 2 日,內藏山 11 月 4 日、漢拏山 11 月 6 日,整體比最近 5 年晚約 0.8 天。整理各地楓樹與銀杏的預測日、首爾出發怎麼排,以及出發前去哪裡看即時楓況。2026 年 10 月查證。
- 季節活動
- 自然
- 觀景

攻略胡志明市
胡志明市到頭頓一日遊:白藤碼頭搭高速船、船票與班次,下船就是胡梅纜車與耶穌基督像
人在胡志明市挪一天去頭頓看海:市中心的白藤高速船碼頭搭船,航程 120 分鐘到頭頓的胡梅碼頭,平日成人 320,000 越南盾、週末 350,000,回程末班平日 15:00。下船就是胡梅纜車站,同一條路上有白宮,小山頂上是耶穌基督像。平日一天只有兩班船,整天要從末班船倒推著排。
- 交通
- 行程範例
- 海灘

攻略沖繩
沖繩不開車攻略:單軌只到浦添,美麗海水族館要坐兩個多小時的巴士,回那霸的最後一班直達車 17:22 就開走
不租車的沖繩怎麼移動:那霸市區靠沖繩都市單軌電車(ゆいレール),那霸機場站到終點てだこ浦西 19 站、17 公里、37 分鐘,一日券 1,000 日圓;美麗海水族館有那霸機場直達的高速巴士,單程 2,000 日圓起、官方時刻表上 2 小時上下,下車後還要走 10 分鐘;古宇利島要在今帰仁村役場轉車,當天來回光坐車就六個半小時;回程的最後一班直達車 17:22 就從記念公園前開走(2026 年 9 月查證)。
- 交通
- 行程範例
- 預算
資料來源
- Auto Router · 查證日期:
- Model Fallbacks · 查證日期:
- Router - Load Balancing · 查證日期:
- Models overview · 查證日期:
- Get started with Claude · 查證日期:
- Python SDK · 查證日期:
- Create a Message · 查證日期: