LLM APIフォールバックルーティング:本番障害対応プレイブック
LLM API のフォールバックルーティングは、最初の実障害に遭遇するまでは簡単に聞こえます。エラーを捕捉し、モデルを切り替えて、もう一度試すだけです。本番環境では、そのルールが 1 つのプロバイダ障害を、重複したツール呼び出し、壊れた JSON、混在したストリーミング出力、暴走するリトライ トラフィック、あるいは技術的には成功しているものの製品契約を満たさなくなったレスポンスへと変えてしまうことがあります。
より安全な設計では、フォールバックをバックアップモデル名の一覧ではなく、境界付きステートマシンとして扱います。各リクエストは、次の少数の判断を通過します。
- 障害は再試行可能か?
- このリクエストを繰り返しても安全か?
- 次の試行は同じターゲットを使うべきか、別のターゲットを使うべきか?
- フォールバックは必要な契約を維持できるか?
- このリクエストはすでに出力または副作用を発生させたか?
- エンドツーエンドのレイテンシと試行予算は使い切られていないか?
このプレイブックでは、これらの問いを、マルチプロバイダの LLM アプリケーション向けのエラーマトリクス、ルーティング ポリシー、TypeScript コントローラ、テスト計画、ロールアウト チェックリストへと落とし込みます。
信頼性の高い LLM API フォールバックルーティングを支える 4 つのアクション
すべてのエラーを同じリトライループに入れてはいけません。本番用ルーターには、4 つの異なるアクションが必要です。
| アクション | 適用する条件 | 典型例 |
|---|---|---|
| 同じターゲットを再試行する | 障害が一時的に見え、現在のデプロイがリクエスト期限内に回復する可能性がある場合 | ヘッダー前の接続リセット、局所的なタイムアウト、短時間のレート制限待機 |
| 同等のターゲットへフェイルオーバーする | プロバイダ、リージョン、デプロイ、またはアカウントの健全性が悪いが、同じモデル契約が別の場所で利用可能な場合 | リージョン障害、デプロイクオータの枯渇、連続する 5xx 応答 |
| 別のモデルにフォールバックする | 評価済みの代替モデルが、アプリケーションの最低限の能力と出力契約を維持できる場合 | プライマリモデルが利用不可で、テスト済みのセカンダリモデルが同じツールとスキーマをサポートしている |
| 停止してエラーを表面化する | リクエストを繰り返しても解決せず、副作用を生む可能性がある、または契約を維持できない場合 | 認証不正、形式不正のリクエスト、未サポートのパラメータ、ポリシーブロック、部分的なストリーム |
フェイルオーバーとフォールバックの違いは重要です。フェイルオーバーは論理的なモデル契約を維持したまま、インフラを変更します。フォールバックはモデルまたは機能階層を変更します。通常、より低リスクなのはフェイルオーバーです。
エイリアス、ヘルススコアリング、課金、可観測性を含む広いリクエストパス設計が必要な場合は、まず AI API ゲートウェイ アーキテクチャガイド を参照してください。この記事は、ターゲットが選択された後に実行されるコントローラに焦点を当てています。
リトライコードを書く前に、エラーからアクションへのマトリクスを作成する
プロバイダの SDK は異なる例外クラスやレスポンス本文を公開しますが、ルーターはそれらを小さな内部分類体系に正規化すべきです。
| 正規化された障害 | 同じ対象を再試行? | 同等のフェイルオーバー? | クロスモデルのフォールバック? | 備考 |
|---|---|---|---|---|
| リクエスト受理前の接続失敗 | はい、1回 | はい | 場合による | 1つのエンドツーエンドのデッドライン内に収める |
| レスポンスヘッダー前のタイムアウト | 場合による | はい | 場合による | 再送して安全なリクエストのみ繰り返す |
429 レート制限 |
上限付き遅延の後 | はい | 場合による | 可能であればサーバーの指示に従う。リトライストームを起こさない |
プロバイダーの5xxまたは過負荷 |
多くても1回 | はい | 場合による | 定義した失敗しきい値を超えたらサーキットを開く |
| 認証または権限エラー | いいえ | いいえ | いいえ | 認証情報またはポリシーを修正する。モデル切り替えでは解決しない |
| 不正なリクエストまたは未対応パラメータ | いいえ | いいえ | いいえ | クライアント契約を修正する |
| コンテキスト長の超過 | 盲目的な再試行はしない | いいえ | 明示的な適応がある場合のみ | 切り詰め、要約、またはより大きなコンテキストのルートによりリクエストが変わる |
| 安全性またはポリシーによる拒否 | 盲目的な再試行はしない | いいえ | 通常はいいえ | ポリシー判断を回避するためにプロバイダーを切り替えるのは、信頼性戦略ではない |
| 出力スキーマの検証失敗 | 修復できれば場合による | いいえ | 評価済みの場合のみ | スキーマ修復とトランスポートの再試行は分けて扱う |
| 最初のトークン前にストリームが失敗 | 場合による | はい | 場合による | まだユーザーに見える出力は存在しない |
| 出力開始後にストリームが失敗 | 自動切り替えなし | いいえ | 自動切り替えなし | 2つのモデル応答をつなぎ合わせない |
| ツール呼び出しがすでに実行済みの可能性がある | 盲目的な再試行はしない | いいえ | 盲目的な再試行はしない | 冪等性キーまたはツールレベルの重複排除を必須にする |
公式のプロバイダー文書は、なぜ正規化が必要かを裏付けています。Anthropic は、レート制限、API、過負荷の各エラーを区別して文書化しており、ストリーミング要求は初回の成功応答の後でも失敗しうると述べています。OpenAI も同様に、無効なリクエスト、レート制限、サーバー側の失敗を分けています。アプリケーションは、プロバイダー固有のシグナルをビジネスロジック全体にプロバイダー名を埋め込むのではなく、安定した内部判断に変換するべきです。
リクエスト全体に対して 1 つのリトライ予算を適用する
再試行は、HTTP クライアント、プロバイダー SDK、ゲートウェイ、バックグラウンドジョブ、アプリケーションサービスなど、複数の場所で同時に存在しがちです。各レイヤーが 3 回ずつ試行すると、1 回のユーザー操作が、チームの意図をはるかに超える数の上流呼び出しに増幅される可能性があります。
より安全なパターンは次のとおりです。
- LLM の再試行とフォールバックを管理する 1 つのレイヤー を選ぶ。
- ユーザー要求またはジョブに対して 1 つのエンドツーエンドの期限を設定する。
- 上流への最大試行回数を設定する。
- フォールバック先のために期限の一部を確保する。
- 一時的な障害に対しては、ジッター付きの指数バックオフを使用する。
- 残り時間が、もう 1 回の意味のある試行を支えられない場合は停止する。
AWS のタイムアウト、再試行、バックオフ、ジッターに関するガイダンスでは、再試行がどのように過負荷を増幅しうるかが説明され、即時の繰り返しではなく、上限付きの動作が推奨されています。同じ原則はモデル API にも当てはまり、負荷の高いプロバイダーほど同期的な再試行トラフィックを吸収しにくくなります。
実用的なインタラクティブ予算は、ハードコードされたスリープではなくポリシーとして表現するとよいでしょう。
type RetryBudget = {
deadlineMs: number;
maxAttempts: number;
maxSameTargetAttempts: number;
reserveForFallbackMs: number;
};
具体的な値は製品によって異なります。チャット UI、コーディングエージェント、バッチ評価、非同期の動画ワークフローで、同じ予算を共有すべきではありません。
既知の障害先へのルーティングを停止するためにサーキットブレーカーを使う
サーキットブレーカーは、新しいリクエストが毎回同じ障害を再発見するのを防ぎます。
標準的な状態は次のとおりです。
- Closed: ルーターが失敗とレイテンシを計測しながら、リクエストは通常どおり流れる。
- Open: 直近の挙動がしきい値を超えたため、そのターゲットは一時的に不適格になる。
- Half-open: 少数のプローブリクエストで、そのターゲットが回復したかどうかをテストする。
Azure のサーキットブレーカーパターンでは、この Closed/Open/Half-open のライフサイクルが説明されています。LLM ルーティングでは、ブレーカーのキーは障害箇所を切り分けられるほど具体的である必要があります。役立つ次元には、プロバイダー、モデル、リージョン、デプロイメント、アカウント、機能などがあります。テキスト補完デプロイメントは正常でも、ツール呼び出しルートやリージョンエンドポイントが失敗している場合があります。
すべてのクライアントエラーでサーキットを開かないようにしてください。認証無効、リクエスト形式不正、コンテキストオーバーフロー、ポリシー拒否は、通常はプロバイダーの健全性よりもリクエスト内容を示しています。ブレーカーは、接続失敗、タイムアウト、過負荷、サーバーエラーなどの一時的なインフラシグナルに主に反応すべきです。
モデル間で機能契約を維持する
フォールバックモデルは、OpenAI 互換のリクエストを受け付けるというだけでは安全ではありません。各ルートエイリアスに対して最小契約を定義してください。
route: support-agent-v3
requires:
modalities: [text]
streaming: true
tools: true
parallel_tool_calls: false
structured_output: json_schema
context_window_min: 64000
max_output_tokens_min: 4000
quality_gates:
task_success_rate_min: 0.94
schema_valid_rate_min: 0.995
policy:
same_model_failover_first: true
cross_model_fallback_allowed: true
ターゲットをフォールバックセットに追加する前に、少なくとも次をテストしてください。
- サポートされるリクエストパラメータ
- ツール定義とツール呼び出しの動作
- 構造化出力の妥当性
- ストリーミングイベントの形状
- コンテキストと出力の上限
- アプリケーションに適した安全性の動作
- コスト制御で使用されるトークン計測フィールド
- 代表的なプロンプトでのレイテンシーと品質
この契約ファーストのアプローチは、モダリティをまたぐワークフローでは特に重要です。マルチモーダルエージェントルーティングガイドでは、テキスト、画像、音声、動画のルートに対する追加チェックを解説しています。
A TypeScript fallback controller
以下の例は、あえてプロバイダーに依存しない形にしています。ルーティング層が見る前に、上流のアダプターがエラーとレスポンスを正規化していることを前提としています。
type FailureKind =
| "connect"
| "timeout"
| "rate_limit"
| "overloaded"
| "server_error"
| "invalid_request"
| "auth"
| "policy"
| "context_overflow"
| "partial_stream"
| "unknown";
type Target = {
id: string;
contractId: string;
healthy: boolean;
circuit: "closed" | "open" | "half_open";
};
type RequestState = {
attempt: number;
sameTargetAttempts: number;
deadlineAt: number;
outputStarted: boolean;
sideEffectsPossible: boolean;
};
function canReplay(state: RequestState): boolean {
return !state.outputStarted && !state.sideEffectsPossible;
}
function isTransient(kind: FailureKind): boolean {
return [
"connect",
"timeout",
"rate_limit",
"overloaded",
"server_error",
].includes(kind);
}
function chooseNextAction(
kind: FailureKind,
state: RequestState,
current: Target,
equivalent: Target | undefined,
fallback: Target | undefined,
) {
if (!canReplay(state) || kind === "partial_stream") return { type: "stop" };
if (!isTransient(kind)) return { type: "stop" };
if (state.attempt >= 3 || Date.now() >= state.deadlineAt) {
return { type: "stop" };
}
if (
state.sameTargetAttempts < 1 &&
current.circuit === "closed" &&
current.healthy
) {
return { type: "retry", target: current };
}
if (equivalent?.healthy && equivalent.circuit !== "open") {
return { type: "failover", target: equivalent };
}
if (
fallback?.healthy &&
fallback.circuit !== "open" &&
fallback.contractId === current.contractId
) {
return { type: "fallback", target: fallback };
}
return { type: "stop" };
}
本番コードには、ジッター付き遅延、キャンセルの伝播、リクエストID、サーキットブレーカーの更新、テレメトリー、アダプター固有のエラー解析も必要です。重要なのは、別のターゲットを選ぶ前に、再実行の安全性と契約の互換性をチェックすることです。
Treat streaming fallback as a separate protocol
ストリーミングには明確な境界があります。コンテンツがクライアントに届いた時点で、ゲートウェイはその試行がなかったふりはできません。
上流が最初のイベントを転送する前に失敗した場合でも、再試行やフォールバックはまだ透過的に扱える可能性があります。最初のトークン、tool delta、画像イベント、または音声チャンクが配信された後に自動モデル切り替えを行うと、互換性のない2つのレスポンスを混在させるリスクがあります。
次のいずれかの明示的な戦略を使用してください:
- ストリームを明確に失敗させる。 リクエストID付きの安定したエラーイベントを返し、クライアントに再試行を促します。
- 解放前にバッファする。 短い構造化レスポンスでは、下流へ送信する前に完全な結果を検証します。これは初回トークンまでの時間を犠牲にします。
- アプリケーションレベルの再開を実装する。 以前のレスポンスが中断されたことを明示するコンテキストで新しいターンを開始します。同じバイトストリームの継続ではなく、新しいモデル生成として扱います。
2つのモデルの出力を黙って連結しないでください。
ツール呼び出しの信頼性とモデル呼び出しの信頼性を分離する
LLMリクエストは再実行可能でも、選択されたツールはそうでない場合があります。支払い、メール、デプロイ、データベース書き込み、チケット作成は、アプリケーションが結果を記録する前にモデル接続が失敗しても成功し得ます。
書き込み系ツールは次の方法で保護してください:
- プロバイダーの試行ではなく、ユーザー操作から派生した冪等性キー
- 永続的なツール実行レコード
- ツール境界での重複排除
planned、started、succeeded、unknownの明確な区別- 影響の大きい不確実な副作用に対する人手レビュー
副作用の可能性があり、その結果が不明な場合は、自動フォールバックを停止してください。まずツール状態を照合します。
フォールバックをプロダクトの成果として監視する
プロバイダーのエラー率が低いことは、フォールバックが機能している証拠にはなりません。ルーティング全体の結果を追跡してください。
| Metric | What it reveals |
|---|---|
| Primary-target success rate | ベースラインとなるプロバイダーまたはデプロイの健全性 |
| Retry recovery rate | 同一ターゲットへの再試行が有用かどうか |
| Equivalent failover recovery rate | 冗長なデプロイまたはリージョンの価値 |
| Cross-model fallback recovery rate | 代替モデルセットの価値 |
| Contract rejection rate | 候補ターゲットが適格性チェックに失敗する頻度 |
| Post-fallback schema validity | 「成功」したレスポンスが引き続き利用可能かどうか |
| Post-fallback task success | ユーザーが意図した作業を最後まで完了できるかどうか |
| Added fallback latency | ユーザーが支払う信頼性コスト |
| Fallback cost delta | 回復パスによる請求への影響 |
| Circuit open duration and probe success | ブレーカーのしきい値と回復タイミングが妥当かどうか |
各試行についてルート理由を記録してください: 選択されたターゲット、正規化されたエラー、再試行遅延、サーキット状態、フォールバック理由、リクエストの残り期限、最終結果。製品のデータポリシーで明示的に許可されていない限り、機密性のあるプロンプトや出力のログは避けてください。
自動フォールバックを有効にする前に失敗経路をテストする
ステージング環境で障害注入を実行し、その後、本番でポリシーをカナリアリリースしてください。
トランスポートおよびプロバイダーテスト
- 応答ヘッダーの前に接続を切断する。
- リトライの指示がある場合とない場合の、繰り返しレート制限を返す。
- 過負荷とサーバーエラーをシミュレートする。
- リクエストのデッドラインがほぼ使い切られるまで、プライマリを遅延させる。
- 対象のサーキットを開き、トラフィックが利用可能なルートに移動することを確認する。
- 対象を回復させ、ハーフオープンのプローブがトラフィックを早すぎる段階で全面復帰させないことを確認する。
Contract tests
- フォールバックアダプターから必須ツールを削除する。
- 無効な構造化出力を返す。
- ストリーミングイベントの形状を変更する。
- コンテキストまたは出力の制限を超える。
- 固定の評価セットでフォールバック品質を比較する。
Replay-safety tests
- 最初のストリーミングイベントの前後で失敗させる。
- 書き込み側ツールが開始された後に失敗させる。
- 同じ冪等性キーを繰り返す。
- フォールバック試行が保留中の間にクライアントリクエストをキャンセルする。
このテストは、ルーターが期待どおりのアクションを選び、その理由を記録した場合にのみ合格します。
Flatkeyの位置づけ
Flatkeyは、サポート対象モデル向けに1つのAPIキーとOpenAI互換のベースURLを提供し、利用状況と請求を一元管理します。これにより、マルチモデルアクセスとルーティングのための安定した統合境界が生まれます。
アプリケーションチームは、このプレイブックで説明したルート契約も引き続き所有する必要があります。つまり、どのエラーが再試行可能か、どのターゲットが同等か、クロスモデルフォールバックを許可するか、ツールをどのように重複排除するか、回復した応答が満たすべき品質しきい値は何か、です。
最短の統合手順には、Flatkey integration starter を使用してください。既存のクライアントを移行する場合は、OpenAI-compatible API gateway checklist にベースURL、パラメータ、ストリーミング、エラー形状の検証がまとめられています。
本番展開チェックリスト
- プロバイダーのエラーを安定した内部分類体系に正規化する。
- 再試行、同等のフェイルオーバー、クロスモデルフォールバック、停止アクションを定義する。
- 再試行予算の所有者を1つのコンポーネントに割り当てる。
- 単一のエンドツーエンドのデッドラインと最大試行回数を強制する。
- 一時的な失敗に対してジッター付き指数バックオフを追加する。
- サーキットブレーカーは、最小限で有用な障害ドメイン単位でキー付けする。
- 各ルートエイリアスに対してバージョン管理された機能契約を定義する。
- 部分出力が開始された後の自動切り替えをブロックする。
- 書き込み側ツールに対する冪等性と再調整を追加する。
- ルート理由と最終的なタスク結果を記録する。
- トランスポート、過負荷、契約、ストリーミング、サイドエフェクトの失敗を注入する。
- クロスモデルフォールバックを有効にする前に、同等のフェイルオーバーをカナリアリリースする。
- 各ターゲットとフォールバックポリシーにキルスイッチを追加する。
FAQ
LLM APIのフォールバックルーティングとは何ですか?
LLM APIのフォールバックルーティングは、優先ルートがリクエストを完了できない場合に、別の利用可能なモデルまたはプロバイダーを選択する信頼性ポリシーです。安全なフォールバックでは、切り替え前にリプレイ安全性、機能互換性、サーキットの健全性、レイテンシ予算、出力状態を確認します。
LLMのリトライとフォールバックの違いは何ですか?
リトライは同じターゲットに対してリクエストを繰り返します。フェイルオーバーは、論理的なモデル契約を維持しながら同等のインフラに移行します。クロスモデルのフォールバックはモデルを変更するため、より強力な互換性テストと品質テストが必要になります。
LLM API は 429 や 5xx エラーごとに必ずリトライすべきですか?
いいえ。リトライは、エンドツーエンドのデッドライン、試行回数の上限、バックオフポリシー、サーキット状態、再実行安全性チェックによって制限されるべきです。対象が不健全な場合は、繰り返し呼び出すよりも同等のフェイルオーバーのほうが適していることがあります。
LLM ルーターはストリーム中にモデルを切り替えられますか?
出力がクライアントに届いた後に、透過的に切り替えることはできません。安全なデフォルトは、ストリームを明確に失敗させるか、新しいアプリケーションレベルのターンを開始することです。異なるモデルの部分出力を連結すると、レスポンス契約が壊れる可能性があります。
クロスモデルのフォールバックはいつ無効化すべきですか?
代替モデルが、必要なツール、構造化出力、コンテキスト上限、安全性の挙動、品質基準、または副作用の保証を維持できない場合は無効化してください。また、部分出力後やツール実行の確実性がない場合の自動再実行も無効化してください。
LLM リクエストは何回フォールバックを試すべきですか?
普遍的な回数はありません。製品のレイテンシ予算とテスト結果に合う、最小の上限付き試行回数を使用してください。ルーターは、残りのデッドラインで次の有用な試行を支えられなくなった時点で停止すべきです。
信頼できるフォールバックは「すべてを試す」ことではありません。次のアクションを明確にし、互換性があり、再実行安全で、観測可能で、停止しやすくすることです。



