AI API Fallback 策略:建立供應商故障矩陣

依 Failure Class、回應階段、冪等性與 Attempt Budget,決定何時重試、同契約回退、停止或核對副作用。

AI API 的 Retry、Route Fallback 與 Model Substitution 是三種不同動作。Retry 在同一契約下重做一次嘗試;Route Fallback 把相同模型與協定送往另一條合格路徑;Model Substitution 則改變模型,可能連帶改變品質、價格、延遲、工具行為、Context Limit 與輸出格式。

可靠的策略不應在事故發生後才臨時決定。它必須預先回答:這是什麼類型的失敗、回應是否已交付、完整業務操作能否安全重播,以及使用者 Deadline 內還容得下幾次嘗試。

分清 Retry、Fallback 與 Model Substitution

在設定、日誌與 Runbook 中使用不同名稱。

動作 改變內容 合適用途 主要風險
Same-route Retry 時間與 Attempt Number 從同一路徑的短暫故障恢復 持續向不健康依賴增加負載
Same-contract Fallback Upstream Channel、Account 或有序 Group 某一路徑失敗時維持原模型與協定 名義相同的路徑其實不相容
Model Substitution Model ID 或命名 Model Policy 經產品核准的品質、成本或可用性取捨 靜默改變行為與計費

不要把三者都寫成「重試」。營運人員必須知道請求是原路重播、換了供應商路徑,還是由另一個模型回答。模型替換也必須是明確的產品契約,不應成為隱藏的救援捷徑。

部分 Gateway 支援有序 Provider 或 Model Step。例如 Cloudflare 的 Fallback 文件會揭示最後成功的步驟。值得採用的不是某家供應商的固定順序,而是「路徑一旦改變,就保留 Attempt-level Evidence」的設計原則。

重播前通過四道 Gate

Status Code 本身不是 Retry Policy。每次重播前都要判斷:

  1. Failure Class:失敗是暫時性、永久性、由呼叫端造成,還是完成狀態不明?
  2. Response Phase:發生在 Header 前、有效輸出前,還是輸出已交付後?
  3. Idempotency:完整應用操作能否重做而不產生重複副作用?
  4. Attempt Budget:剩餘 Wall-clock Time 是否足夠,且還有未使用的 Attempt?

Google Cloud 的 Retry Strategy對一般 API 也強調兩個基礎判斷:回應是否代表重試可能有效,以及操作是否具備 Idempotency。4084295xx、Socket Timeout 與 Disconnect 常屬暫時性故障,但非冪等操作仍需要更嚴格條件。

對 AI Workflow 而言,冪等邊界不只在模型 HTTP Request。重播 Prompt 可能再次提出寄信、退款、部署或資料庫寫入。即使推論本身唯讀,Tool Execution 仍需要穩定的 Idempotency Key 與持久化結果。

從 Failure Matrix 建立策略

以下矩陣是偏保守的應用層策略。Gateway 可能在應用收到終態前,已完成內部 Same-contract Channel Failover,因此兩層必須協調,不能重複放大嘗試次數。

失敗或階段 Same-route Retry Same-contract Fallback 停止或調查 原因
Client Validation Error、Unsupported Field、Malformed Request 修正請求 重播相同錯誤契約不會成功
Gateway Authentication、Authorization、Quota 或 Policy Denial 修正帳戶或政策 不能用另一條 Provider Route 繞過 Gateway 決策
輸出前的 Upstream Credential 或 Account Failure 不重試失敗路徑 有已驗證的合格 Channel 時可以 隔離並調查失敗 Channel 可以在不改使用者契約下移除不健康憑證
輸出前 Network Failure 或 408 冪等時最多一次有界嘗試 可以 到 Deadline 即停止 故障可能短暫,但 Disconnect 後完成狀態可能不明
輸出前 429 延後重試並遵守 Retry-After 其他同契約路徑有容量時可以 Budget 用盡即停止 立即連續重試會放大限流
輸出前 500502503504 有界 Backoff 可以 路徑反覆失敗時調查 通常短暫,但不代表所有路徑都安全
下游輸出前收到 Schema-invalid 或 Malformed Provider Response 通常否 僅限已驗證相同 Schema 的路徑 隔離或調查相容性 重複呼叫不相容實作通常無效
Model Refusal 或符合安全政策的 Completion 回傳模型結果 合法拒絕不是基礎設施故障
Caller Cancellation 或 Downstream 499 立即停止 呼叫端已不需要結果,繼續只會浪費容量與成本
可見內容或 Tool Arguments 已送達後的 Partial Stream 不透明重播 不透明回退 標記 Partial,由應用決定 第二條 Stream 可能重複或矛盾
Tool Side Effect 完成狀態不明 核對前否 核對前否 查詢 Idempotency Record 或下游系統 再次推論可能重複提出同一副作用

這個矩陣刻意納入 Response Phase。輸出前收到 503,與已渲染 400 個 Text Token 後連線中斷,不是同一種故障。

把 Stream 開始視為 Commit Boundary

在下游輸出開始前,Gateway 通常能捨棄失敗 Attempt,改走另一條合格路徑,而不讓呼叫端看到兩份答案。第一個有意義的 Byte 一旦到達呼叫端,透明重播就不再安全。

重新啟動 Stream 可能:

  • 重複答案開頭;
  • 產生不同續寫;
  • 以新的 Call ID 發出重複 Function Call;
  • 在沒有清楚邊界下增加 Usage 與 Cost;
  • 讓 Client 無法判斷 Event 屬於哪次嘗試。

輸出後 Stream 中斷時,應以原 Request Identity 回傳明確的 Partial 或 Transport Error。應用可以提供顯式「再試一次」、從安全 Checkpoint 繼續,或捨棄部分結果;不應把新模型 Stream 拼接到舊 Stream,假裝沒有發生故障。

Function Calling 的安全邊界更嚴格:任何重試可能重新建立 Tool Call 前,先持久化已接受的 Tool Call Identity 與 Side-effect Result。Function Calling 比較進一步說明 Call ID 與應用冪等性的配合方式。

同時限制 Attempt 與 Wall-clock Time

Exponential Backoff 讓嘗試分散在時間上,Jitter 則避免大量 Client 在共同故障後同步重試。

delay_cap = min(max_delay, base_delay * 2^retry_index)
sleep_for = random_between(0, delay_cap)

有效的 Retry-After 若沒有超過使用者 Deadline,應優先遵守。但 Backoff 並不等於獲得重試許可;Failure 與 Idempotency Gate 仍須先通過。

策略需要 Total Budget,而不只是 Retry Count:

  • 單一 User Action 的最大 Attempt;
  • 包含 Queue 與 Backoff 的最大 Elapsed Time;
  • 選擇 Fallback Group 前後各自的 Attempt 上限;
  • 產生有用答案至少需要保留的時間;
  • Caller Cancellation 向所有 Active Attempt 的傳播。

若互動請求 Deadline 為 15 秒,安排三次各 10 秒的 Attempt 並不是可執行策略。Batch Workload 可以使用較長 Budget,但仍需 Terminal Deadline 與 Durable Job Identity。

避免跨層 Retry Amplification

假設 SDK 做一次請求加兩次重試,共三次 Client Attempt;Gateway 對每次 Client Attempt 做 Primary 加兩條 Channel Fallback,共三次 Gateway Attempt;Upstream Proxy 又各重試一次,共兩次 Provider Call:

3 client attempts × 3 gateway attempts × 2 upstream attempts = 18 provider calls

一個使用者動作因此變成 18 次 Provider Call。事故期間,這會同時增加 Queue、Rate Limit、成本與恢復時間。

應明確分配 Retry Ownership:

  • Gateway 負責立即的 Same-contract Channel Failover;
  • Application 決定完整 User Action 是否可以重播;
  • Gateway 已重試時,SDK Automatic Retry 應停用或嚴格限制;
  • Async Job 使用單一 Durable Job ID 與 Attempt Ledger;
  • Caller Cancel 後,任何一層都不得啟動新 Attempt。

同時記錄「本層 Attempt Number」與穩定的 End-to-end Request ID,否則每層看起來只重試兩三次,整體放大卻無法察覺。

驗證 Fallback 是否真的維持契約

相同公開模型名稱不代表兩條 Route 行為一致。把 Channel 加入 Same-contract Fallback Set 前,至少驗證:

契約範圍 所需證據
Model Identity Requested Model 可用,且沒有 Silent Mapping
Endpoint 設定的 Responses 或 Chat Completions Request 能被接受
Streaming Event Type、Termination、Usage 與 Cancellation 都能處理
Structured Output 必要 JSON Schema 子集與 Strict Behavior 可運作
Function Calling Tool Definition、Call ID、Argument Streaming 與 Result 能 Round-trip
Limits Context、Output、Rate 與 Concurrency Limit 符合 Workload
Errors Status 與 Error Body 可分類且不洩露 Secret
Usage and Cost Token、Cache Field、Service Tier 與 Price Policy 已釐清
Safety and Region Policy、Data Path 與 Residency 要求仍符合

只要候選 Route 未通過任何必要範圍,它就不是該 Workload 的透明 Fallback。它仍可能在另一套顯式產品政策下使用。

換成不同模型永遠是產品決策。必須定義允許的 Model、Quality Floor、Price Ceiling、Tool Contract 與 User-visible Disclosure,不能只因某條 Route 報錯就靜默換成較弱或較便宜的模型。

正確理解 Modelflare 的 Fallback Semantics

Modelflare 會為 API Client 指定的模型搜尋合格路徑。一般 API Key 有一個 Primary Group,也可以配置有序 Fallback Group;Smart API Key 則依 Routing Strategy 評估帳戶可用 Group。兩種機制都不應靜默把 Requested Model 換成另一個模型。

Group-level RPM Admission 發生在計費與 Upstream Request 前。選定 Group 已滿時,可以評估有序 Fallback Group 或 Smart Routing Candidate;若沒有合格 Group,請求回傳 429

在 Group 內,Channel Priority 定義 Account Failover 順序。Upstream Error 後,失敗 Channel 會被排除,選擇器繼續尋找其餘合格 Channel。現行 Channel Failover 不依賴 RetryTimesAutomaticRetryStatusCodes;成功、路徑耗盡、Caller Cancel,或 Downstream Response 已開始而無法透明重播時即停止。

這些是內部 Same-model Path Decision,並不代表 Client 可以再加一個無限 Retry Loop。Group 與 Channel 設計可參考 Reliable AI API RoutingAI API Error Troubleshooting則可協助區分 Gateway Policy Error 與 Upstream Failure。

為每次 Attempt 保留可重建證據

最終 200 不代表第一條 Route 成功;Final Channel ID 也無法描述前面的失敗。至少保留:

  • 穩定 Request ID 與呼叫端可見 Correlation ID;
  • Attempt Sequence 與選中的 Group/Channel Reference;
  • 各 Attempt 使用的 Model 與 Endpoint Contract;
  • Failure Status、Error Class 與 Stream Phase;
  • Downstream Output 是否已開始;
  • Timing Milestone 與 Cancellation State;
  • 可取得時的 Input、Output 與 Cached-token Usage;
  • Completed 或 Billable Attempt 的 Cost Attribution;
  • Success、Exhausted、Cancelled、Partial 或 Policy Stop 等 Terminal Reason。

不要只為診斷 Fallback 就保留 API Key、Raw Prompt、Raw Response 或 Provider Credential。一般情況使用去識別 Error Class 與 Timing Metadata 即足夠;只有在明確啟用 Failure Investigation 時,才使用受限且短期的 Request Archive。

在 Production 前演練政策

以真實 Protocol Boundary 與安全、可重現輸入進行 Staging Exercise:

  1. 在 Header 前讓 Primary Channel 不可用,確認下一條合格 Same-model Path;
  2. 回傳 Rate Limit,確認 Attempt 上限與 Retry-After 行為;
  3. 取消 Caller,證明不會啟動後續 Attempt;
  4. 在輸出後中斷 Stream,證明沒有透明重播;
  5. 送出 Invalid Request,證明 Fallback 不會掩蓋錯誤;
  6. 重複 Tool Workflow,證明只記錄一次 Side Effect;
  7. 耗盡所有 Route,確認只有一個清楚 Terminal Error;
  8. 檢查 Attempt Ledger,核對 Usage 與 Cost。

先在小流量 Workload 上推出,分開監控 Attempt Count、Success-after-fallback 與 Raw Success Rate,並保留快速移除不健康 Route 的能力。目標不是讓 Fallback 次數最大化,而是在不改變原模型契約的前提下,於有限 Deadline 內安全恢復,且每次嘗試都有證據。