モデルフォールバックは1つの振る舞いではありません。安全制約の異なる、いくつかの復旧判断の集合です。
本番環境でのモデルフォールバック戦略は、次の3つのワークフローを分けて考えるべきです。
- 再試行または同等のフェイルオーバー:リクエストを再実行してもまだ安全な場合。
- クロスモデルフォールバック:別のモデルが同じ能力と品質契約を満たせる場合。
- 停止、整合、またはエスカレーション:出力がすでにユーザーに届いている、またはツールの副作用が発生した可能性がある場合。
この切り分けが重要なのは、最も速い復旧手段が、必ずしも最も安全とは限らないからです。失敗した分類リクエストを再送するのは、通常は低リスクです。一方で、ストリーミング回答の途中や、不確実な支払いツール呼び出しの後で、黙って別のモデルに切り替えるのはそうではありません。
このプレイブックでは、フォールバック方針を、チームが実装し、テストし、観測できる3つの運用ワークフローに落とし込みます。
1つの表で見るモデルフォールバックの判断
プロバイダー名ではなく、まずリクエストの状態から始めます。
| Request state | Preferred workflow | Typical action | Do not do |
|---|---|---|---|
| No response bytes, transient transport error | Workflow 1 | Bounded retry, then equivalent endpoint failover | Retry without a deadline or budget |
| No response bytes, rate limit or overload | Workflow 1 | Honor retry guidance, apply jitter, then move to equivalent capacity | Create a synchronized retry storm |
| Primary target unavailable, compatible model exists | Workflow 2 | Check the fallback contract, then route to the approved alternate | Assume every model supports the same tools, schema, or context |
| Structured response fails validation | Workflow 2 | Repair once or try an approved model that meets the schema contract | Treat HTTP 200 as task success |
| Partial stream already delivered | Workflow 3 | Stop, mark partial, offer an explicit restart | Splice a second model into the same answer invisibly |
| Write-side tool may have executed | Workflow 3 | Reconcile tool state using an idempotency record | Replay the entire model-and-tool workflow automatically |
| Safety or policy classification is uncertain | Workflow 3 | Escalate or fail closed according to product policy | Lower the safety bar to preserve availability |
基本ルールはシンプルです。再試行は対象を維持し、同等のフェイルオーバーはモデル契約を維持し、クロスモデルフォールバックは契約リスクを変える。各ステップには、より厳格な適格性チェックが必要です。
サーキットブレーカー、エラー正規化、プロバイダー非依存のコントローラーについてさらに詳しくは、LLM API fallback routing playbookをご覧ください。
ワークフローの前に:1つのフォールバック・エンベロープを定義する
すべてのリクエストは、上限付きのエンベロープを持ってルーティング層に入るべきです。このエンベロープは、リクエストを停止する前にどれだけの復旧を許可するかをシステムに伝えます。
type FallbackEnvelope = {
requestId: string;
deadlineMs: number;
maxAttempts: number;
maxAddedLatencyMs: number;
maxCostUsd?: number;
allowEquivalentFailover: boolean;
allowCrossModelFallback: boolean;
allowAfterPartialOutput: false;
sideEffectMode: "none" | "read_only" | "write_possible";
requiredCapabilities: string[];
requiredSchemaVersion?: string;
};
これらの値は、グローバルなデフォルトではなく製品のワークフローから取得すべきです。バックグラウンドの要約ジョブは、対話型のコーディングアシスタントよりも多くのレイテンシーを許容できます。ツールを使わないチャット応答は、コードをデプロイしたりメールを送信したりできるエージェントとは異なる回復挙動を許容できます。
このエンベロープは、ネストされた再試行も防ぎます。SDK、アプリケーション、ゲートウェイ、プロバイダーアダプターがそれぞれ独立して再試行すると、小さな障害が大きな試行バーストに増幅されることがあります。総試行予算を管理するレイヤーを1つ選び、下位レイヤーには既に消費した分を報告させるようにします。
ワークフロー1: リトライ、その後に同等フェイルオーバー
このワークフローは、オペレーションが再実行可能で、システムが部分出力を公開していない、または side effect の状態が不確定になっていない場合に使います。
同等ターゲットとは、重要な契約を維持する別の経路です。つまり、同じモデルの動作クラス、必要な機能、スキーマ期待値、安全設定、互換性のあるコンテキスト制限を満たします。異なるリージョン、デプロイメント、プロバイダーエンドポイント、または容量プールである場合があります。
ステップ1: 障害を正規化する
プロバイダー固有のレスポンスを、少数の内部分類にマッピングします:
transport_transientrate_limitedprovider_overloadedprovider_server_errorauthentication_or_permissioninvalid_requestdeadline_exhaustedcontract_failurepartial_outputside_effect_uncertain
通常、最初の4つだけが自動再実行の対象になります。認証、権限、無効なリクエストのエラーは、別のエンドポイントでもリクエストを修復できる可能性が低いため停止すべきです。契約違反はワークフロー2に属します。部分出力と不確かな side effect はワークフロー3に属します。
ステップ2: 残りの予算を計算する
各試行の前に、次を確認します:
remaining time > estimated next-attempt latency + response safety margin
remaining attempts > 0
remaining added latency > 0
remaining cost budget > estimated attempt cost, when a cost ceiling exists
必要な予算が1つでも尽きている場合は、もう1つプロバイダーを試すのではなく終了します。
ステップ3: バックオフとジッターを使って再試行する
利用可能であれば、プロバイダーの再試行ガイダンスを使用します。そうでなければ、ジッター付きの指数バックオフを適用し、遅延をリクエストの期限内に収めます。
function retryDelayMs(attempt: number, retryAfterMs?: number): number {
if (retryAfterMs !== undefined) return retryAfterMs;
const base = Math.min(250 * 2 ** attempt, 4_000);
const jitter = Math.random() * base * 0.3;
return Math.round(base + jitter);
}
ジッターが重要なのは、多数の同時クライアントが同じスケジュールで再試行し、過負荷状態を長引かせる可能性があるためです。あなたのLLMレート制限ガイドでは、RPM、TPM、キュー、同時実行数、再試行バジェットがどのように相互作用するかを定義すべきです。
ステップ4: 同等のキャパシティへ移行する
同じターゲットの健全性が引き続き回復しない場合は、以下を確認したうえでのみ同等のエンドポイントへルーティングします。
- サーキットが閉じているか、プローブ用に半開状態であること。
- ターゲットが必要な入力モードと出力モードをサポートしていること。
- ターゲットがコンテキスト制限内でリクエストを受け付けられること。
- ターゲットが期待される安全性およびデータ処理設定を使用していること。
- 試行が依然として期限とコストの範囲内に収まること。
同等のフェイルオーバーは、応答契約の維持を目的とするため、通常はモデルの変更よりもリスクが低くなります。
ステップ5: 回復理由を記録する
以下のようなルート結果を返します。
{
"workflow": "retry_equivalent_failover",
"primary_attempts": 2,
"equivalent_failover_attempts": 1,
"recovered": true,
"recovery_reason": "provider_overloaded",
"added_latency_ms": 684
}
製品がその透明性を約束していない限り、内部のプロバイダー詳細をエンドユーザーに公開しないでください。ただし、トレースや運用ログには保持してください。
ワークフロー2: 制御されたクロスモデル・フォールバック
クロスモデル・フォールバックは、代替モデルがそのタスク向けに事前承認されている場合にのみ適切です。テキストを返すモデルであるだけでは不十分で、ワークフロー契約を満たしている必要があります。
ステップ1: 能力契約を作成する
各ルートクラスについて、譲れない要件を定義します。
{
"route_class": "support_ticket_triage_v3",
"required": {
"input": ["text"],
"output": ["json_schema"],
"tools": [],
"minimum_context_tokens": 24000,
"schema": "triage-result-v3",
"languages": ["en", "es", "de"],
"safety_profile": "customer-support-standard"
},
"fallback_models": [
"approved-model-b",
"approved-model-c"
]
}
ツールを使用するルートでは、ツール選択の挙動、並列ツール対応、引数スキーマの処理、そしてモデルが「呼び出さない」条件にどれだけ確実に従うかを含めます。構造化出力については、各試行後に実際の応答をスキーマと照合して検証してください。
ステップ2: 転送成功とタスク成功を分けて考える
HTTPの成功応答であっても、製品ワークフローとしては失敗している場合があります。少なくとも3層を評価してください。
- 転送成功: プロバイダーが完全な応答を返した。
- 契約成功: 応答がパースされ、スキーマに一致し、サポートされるツールを正しく使用した。
- タスク成功: 出力が実際にユーザーの作業を許容可能な品質で完了した。
この区別は、フォールバック候補を比較する際に不可欠です。応答率は高くても、スキーマやツールの失敗が多いモデルは信頼できるフォールバックではありません。
ステップ3: 承認済み候補をポリシーで順位付けする
本番ルーターは、あるモデルが普遍的に最適だと装うことなく、運用シグナルを使って対象候補をスコアリングできます。
type Candidate = {
id: string;
capabilitiesPass: boolean;
circuitOpen: boolean;
estimatedLatencyMs: number;
estimatedCostUsd: number;
recentContractSuccess: number;
recentTaskSuccess: number;
};
function eligible(candidate: Candidate, envelope: FallbackEnvelope): boolean {
return (
candidate.capabilitiesPass &&
!candidate.circuitOpen &&
candidate.estimatedLatencyMs <= envelope.maxAddedLatencyMs &&
(envelope.maxCostUsd === undefined ||
candidate.estimatedCostUsd <= envelope.maxCostUsd)
);
}
あらゆるタスクに対して、静的な「主系、バックアップ、バックアップ」のリストは避けてください。コード生成に最適なフォールバックセットは、抽出、翻訳、画像認識、またはツール実行に最適なセットとは異なる場合があります。
Step 4: validate the fallback output
まずは決定的なチェックを適用します。
- JSON またはスキーマの検証
- 必須フィールドのチェック
- ツール引数の検証
- 引用または URL 形式のチェック
- 長さと言語の制約
- 禁止出力パターン
その後、ワークフロー固有の品質チェックを追加します。これらは軽量ルール、タスク評価器、サンプリングした人手レビュー、または検証済みのジャッジモデルにできます。品質ゲートに失敗した場合は、そのフォールバックを復旧済みとして扱わないでください。
Step 5: canary policy changes
新しいフォールバックモデルを拡大する前に、次を実施します。
- オフライン評価セットを再実行する。
- ポリシーで許可される場合は、シャドートラフィックを流す。
- 候補を、適格な失敗のうち少数の割合で有効化する。
- 契約成功率、タスク成功率、レイテンシ、コストを比較する。
- 復旧価値が回帰リスクを上回る場合にのみ拡大する。
これらの測定値は、各試行につき 1 つの route と 1 つの span を記録する LLM API observability スキーマで追跡してください。
Workflow 3: stop, reconcile, or escalate
一部の失敗では、別のモデル呼び出しを行うべきではありません。正しいフォールバックは、制御された停止です。
Case 1: partial streaming output
応答トークンがユーザーに届いた後に、モデルを黙って切り替えると、矛盾、重複コンテンツ、壊れたコードブロック、あるいは突然の文体変化を招くことがあります。また、最終応答の帰属やデバッグも難しくなります。
代わりに、次のような明示的な結果のいずれかを使ってください。
- 復旧可能なエラーでストリームを終了し、「再試行」アクションを提示する。
- 冒頭から回答を再開する提案をする。
- アプリケーションに再開プロトコルが設計されており、新しいモデルが受け入れ済みの接頭辞を正確に受け取る場合のみ継続する。
デフォルトは allowAfterPartialOutput: false にするべきです。
Case 2: uncertain tool side effects
モデルが支払い、メール、デプロイ、チケット、またはデータベース書き込みのツールを選択したとします。オーケストレーターが結果を記録する前に接続が失敗していても、ツール自体は成功している可能性があります。ワークフロー全体を再実行すると、副作用が重複する恐れがあります。
書き込み側のツールは次の方法で保護してください。
- ユーザー操作に基づく冪等性キーであり、プロバイダーの試行に基づくものではない。
planned、started、succeeded、failed、およびunknownの状態を持つ永続的な実行レコード。- ツール境界での重複排除。
- リプレイの前に照合クエリを実行すること。
- 不確実性が残る影響の大きい操作に対する人間によるレビュー。
type ToolExecution = {
operationId: string;
toolName: string;
state: "planned" | "started" | "succeeded" | "failed" | "unknown";
externalReference?: string;
};
function nextAction(execution: ToolExecution): "continue" | "reconcile" | "stop" {
if (execution.state === "succeeded") return "continue";
if (execution.state === "failed") return "stop";
return "reconcile";
}
プロバイダーの認証情報とツールの認証情報は分離してください。安全な API キー管理ガイドでは、周辺のシークレット管理とアクセス制御のモデルを扱っています。
ケース 3: 安全性、権限、またはポリシーの不確実性
可用性が安全性や認可の判断を弱めてはなりません。フォールバック候補が必要なポリシー制御をサポートしていない場合、そのルートは対象外です。システムが操作が許可されているかどうかを判定できない場合は、製品のリスクモデルに従ってフェイルクローズするか、エスカレーションしてください。
ケース 4: いずれの候補も契約を満たさない
アプリケーションが処理できる型付きの失敗を返します。
{
"status": "unavailable",
"reason": "no_eligible_fallback",
"retryable": true,
"retry_after_ms": 30000,
"request_id": "req_123"
}
明確な劣化応答は、スキーマに違反し、誤ったツールを使用し、または誤った副作用を引き起こす、成功したように見える応答よりも優れています。
3つのワークフローを1つの状態機械にまとめる
オーケストレーション層は、遷移を明示的にするべきです。
START
-> PRIMARY_ATTEMPT
-> SUCCESS: validate and return
-> TRANSIENT + replayable: WORKFLOW_1
-> CONTRACT_FAILURE + approved alternate: WORKFLOW_2
-> PARTIAL_OUTPUT or SIDE_EFFECT_UNCERTAIN: WORKFLOW_3
WORKFLOW_1
-> retry inside budget
-> equivalent failover inside budget
-> if compatible alternate allowed: WORKFLOW_2
-> otherwise: STOP
WORKFLOW_2
-> capability check
-> alternate attempt
-> contract and task validation
-> return only on validated success
-> otherwise: STOP
WORKFLOW_3
-> mark partial or uncertain state
-> reconcile external side effects when possible
-> offer explicit restart or human escalation
-> never silently replay unsafe work
これもまた、マルチモデルゲートウェイにとって適切な境界です。OpenAI互換エンドポイントの背後にモデルアクセスを集約すると、統合の重複を減らせますが、アプリケーション側では依然としてワークフローの意図、つまり期限、副作用モード、必要なツール、スキーマバージョン、そしてモデル横断のフォールバックを許可するかどうかを指定する必要があります。Flatkeyは、モデルプロバイダーをまたいで1つのキーと1つの統合面を求めるチーム向けに、統一APIアクセス層を提供しますが、最も安全なルーティングポリシーは依然として明示的なアプリケーション契約から始まります。
モデルフォールバック戦略の展開チェックリスト
ポリシー
- [ ] すべてのルートクラスにフォールバック用エンベロープがある。
- [ ] リトライ可能なエラーがプロバイダー間で正規化されている。
- [ ] 総リトライ予算の責任者が1人に定まっている。
- [ ] 等価なエンドポイントと代替モデルが区別されている。
- [ ] モデル横断の候補にバージョン管理された機能契約がある。
- [ ] 部分出力により、デフォルトでは透過的フォールバックが無効になる。
- [ ] 書き込み系ツールは永続的な冪等性レコードを使用する。
検証
- [ ] 伝送、契約、タスクの成功を別々に測定する。
- [ ] 構造化出力はフォールバック後に検証する。
- [ ] ツール引数とツール選択の挙動をモデルごとにテストする。
- [ ] フォールバック評価セットは実際のルートクラスを表している。
- [ ] 新しい候補はオフライン評価と本番カナリアを通過する。
運用
- [ ] 各試行にルート理由、対象、レイテンシ、結果を記録する。
- [ ] ダッシュボードは、プライマリ、リトライ、等価フェイルオーバー、モデル横断復旧を個別に表示する。
- [ ] アラートには期限切れと、利用可能なフォールバックなし率を含める。
- [ ] サーキットブレーカーは制御された半開プローブを使用する。
- [ ] インシデントレビューには、ユーザーから見える品質と重複副作用リスクを含める。
フォールバックが役立っていることを示す指標
プロバイダーのエラー率だけを最適化しないでください。ユーザーの成果を追跡してください。
| 指標 | 答える問い |
|---|---|
| リトライ回復率 | 同一対象へのリトライは、そのレイテンシに見合う価値があるか。 |
| 等価フェイルオーバー回復率 | 冗長キャパシティは安全にサービスを復旧できるか。 |
| モデル横断の契約成功率 | 代替応答は必要なインターフェースを満たしているか。 |
| モデル横断のタスク成功率 | ユーザーは意図した作業を引き続き完了できるか。 |
| 追加フォールバックレイテンシ | 復旧によってどれだけ遅延が増えるか。 |
| フォールバックコスト差分 | 復旧パスのコストはいくらか。 |
| 部分ストリーム失敗率 | システムはどのくらいの頻度で回復不能な表示状態に達するか。 |
| 副作用の再整合率 | 継続前に外部状態の確認が必要になるのはどのくらいの頻度か。 |
| 重複副作用インシデント | 再実行保護は失敗したか。 |
| 利用可能なフォールバックなし率 | ルート契約が厳しすぎるのか、それともキャパシティが不足しているのか。 |
これらの指標はルートクラスごとに分けて確認してください。集計された回復率だけでは、抽出ではフォールバックがうまく機能していても、コード生成やツール使用では不十分であることを隠してしまう可能性があります。
よくある質問
モデルフォールバック戦略とは何ですか?
モデルフォールバック戦略とは、AIリクエストについて、同じ対象に再試行するか、同等のキャパシティにフェイルオーバーするか、承認済みの代替モデルに切り替えるか、あるいは再実行が安全でないため停止するかを決定するためのポリシーです。
retry と fallback の違いは何ですか?
retry は同じ対象またはデプロイメントに対してリクエストを再送します。equivalent failover は、同じモデル契約を維持することを意図したキャパシティへリクエストを移します。cross-model fallback はモデルを変更するため、能力と品質の検証が必要になります。
すべての 429 エラーで別のモデルに切り替えるべきですか?
いいえ。まず制限の種類を分類し、再試行の指針に従い、残りの期限を確認したうえで、上限付きの再試行またはキューを使います。承認済みの代替キャパシティがある場合はモデルの切り替えが有効なこともありますが、出力品質、ツールの挙動、コストが変わる可能性もあります。
ストリーミング応答は回答途中でフォールバックできますか?
通常、トークンがユーザーに届いた後に透過的に切り替えるのは避けるほうが安全です。アプリケーションにテスト済みの再開プロトコルがない限り、ストリームを停止し、明示的な再開を案内します。
ルートに持たせるフォールバックモデルはいくつ必要ですか?
意味のある復旧を提供できる、承認済みの最小セットを使います。候補が増えるほど、評価、監視、インシデント対応の作業が増えます。長くても未検証のリストはレジリエンスではありません。
フォールバックロジックはどこに置くべきですか?
プロバイダーの正規化、ルーティング、試行予算、可観測性は、ゲートウェイまたはオーケストレーション層で一元化します。副作用リスク、スキーマ要件、安全ポリシー、品質しきい値といったワークフロー固有の意図は、アプリケーション側に近い場所に置きます。
ワークフローのリスクに基づいてフォールバックを設計する
最良のモデルフォールバック戦略は、「次のモデルを試す」ことではありません。上限付きの意思決定システムです。
- ワークフロー 1 は、再試行と同等のキャパシティで再実行可能なリクエストを復旧します。
- ワークフロー 2 は、能力と品質のチェックを行った後にのみモデルを切り替えます。
- ワークフロー 3 は、出力や副作用によって復旧が安全でない場合、自動再実行を停止します。
この設計により、契約違反を隠したりユーザー操作を重複させたりすることなく、可用性を向上できます。チームがモデルプロバイダー間でのアクセスを標準化しているなら、Flatkey の統合 OpenAI 互換 API レイヤーを統合面として使い、そのうえでこれらのワークフロー固有のエンベロープを本番ルートごとに付加してください。



