メインコンテンツへスキップ

LLM API は再試行かフォールバックか:切り替える前の5項目

一時障害で、安全に再送でき、復旧予算内なら同じ経路を再試行します。代替経路は同じ業務テストに合格した場合だけ使います。

LaoZhang AI Team公開9 分で読めます
目次
LLM API の障害が所有者、コミット状態、復旧予算、代替経路の等価性、経路の健全性という5項目を通り、再試行、フォールバック、キュー、縮退、停止に分岐する図。

LLM API の失敗に対して、同じ経路を再試行できるのは「一時的な障害」「安全な再送」「復旧予算内」の三条件がそろうときです。代替モデルへ切り替えられるのは、そのモデルが同じ業務の出力スキーマ、ツール、安全性、データ、費用、遅延、品質テストを事前に通過しているときだけです。それ以外はキュー、限定機能への縮退、または安全側での停止を選びます。

まず30秒で確認する5項目

確認合格条件不合格時
障害の所有者ネットワーク/プロバイダーの短期障害リクエスト、認証、ポリシー、予算を修正
コミット状態visible output も side effect もない状態照合または停止
復旧予算attempts、time、cost、quality に余裕queue または縮退
代替経路の等価性同じ fixture に合格済み自動切替しない
経路の健全性限定的なヘルスプローブが有効で試行を追跡できるサーキットを開く

フォールバックは「別モデルでもう一度」という意味ではありません。model/provider を変えると、context、tool calling、structured output、安全フィルター、データ保持、価格、応答品質が変わり得ます。

429 を見ても、すぐ backoff しない

OpenAI の現行エラーコードガイドでは、429 は request rate と quota/spend exhaustion に分かれます。前者は送信速度を落とす対象ですが、後者は予算所有者が解決する問題です。同じ payload を待って送り直しても、残高は増えません。

実運用では次のように正規化します。

  • 公式のエラー詳細が一時障害と示す 5xx/過負荷:上限付きバックオフとジッター。HTTP コードだけでは判断しない。
  • レート上限の 429:retry-after や限流ヘッダーを読み、同時実行数を下げる。
  • 429 quota/budget:同期 retry を止める。許可された job だけ queue。
  • リクエストの検証で返る400エラー:形式の誤りやコンテキスト超過なら、リクエストを修正する。
  • 401/403:credential、permission、route owner を修正。
  • safety/policy:別の緩いモデルで回避しない。
  • partial stream/tool uncertainty:再送前に実状態を照合する。

SDK の内部動作も数えます。Anthropic の現行API errorsでは、公式 SDK は transient connection、rate limit、5xx をデフォルトで2回再試行し、retry-after を尊重します。Gemini のトラブルシューティングも自動 retry を記載しています。アプリ側の回数だけを見てはいけません。

「タイムアウトした」は未実行の証明ではない

再送可否は、失敗回数よりコミット境界で決まります。

  1. provider が受理する前:replay しやすい。
  2. 受理後、結果未取得:結果は unknown。
  3. 最初の token を表示後:別モデルの出力を透明に足せない。
  4. tool、DB、webhook、メールなどを開始後:side effect が完了した可能性がある。

外部動作にはアプリ側で発行する operation ID または idempotency key を付け、requested / started / committed / acknowledged を保存します。状態が不明なら実状態を問い合わせて照合します。別モデルを呼ぶことは照合ではありません。

ストリーミングの製品仕様も先に決めます。最初の可視イベント前なら状態を初期化して承認済み経路を使えます。表示後は中断を明示し、利用者が再実行するか、正式な再開プロトコルを使います。

復旧予算を一枚にする

総試行数 =
  初回
  + SDK 内部
  + gateway
  + application retry
  + fallback
  + queue redelivery

回数だけでなく、総経過時間、追加 token/費用、許容品質低下を上限化します。対話 UI と夜間 batch で同じ値を使う理由はありません。

AWS の timeouts, retries, backoff with jitter は、多層 retry が負荷を乗算し、overload の回復を遅らせると説明します。判断点は一か所に集約し、SDK/gateway は実際の試行回数を上位へ返す必要があります。

yaml
workflow: faq-extraction
max_total_attempts: 3
max_elapsed_ms: 7000
max_extra_cost_usd: 0.015
safe_replay_until: output_persisted
fallback: approved-json-backup
queue_allowed: true
fail_closed_on: [auth, policy, unknown_commit]

値はサンプルです。SLO と fault injection の結果から決めます。

代替モデルの受け入れ試験

同じ fixture で次の8項目を合格させます。

  1. input:context、画像/ファイル、system instruction、言語。
  2. output:JSON Schema、required field、refusal、truncation。
  3. tools:argument schema、parallel call、tool result、idempotency。
  4. safety:禁止内容、high-impact stop、人手への escalation。
  5. data:region、retention、tenant、扱えるデータ分類。
  6. operations:p95/p99 latency、stream、request ID、status。
  7. economics:価格単位、cache、quota owner、最大費用。
  8. quality:workflow 固有の eval と合格閾値。

classification 用の fallback が、顧客向け説明にも使えるとは限りません。生成モデルが合格しない場合は、cache、決定論的 rule、または明確な「後で再試行」を使います。

分岐をコードに閉じ込める

ts
type Action = "retry" | "fallback" | "queue" | "degrade" | "fail_closed";

function decide(p: {
  owner: "transient" | "rate" | "quota" | "request" | "auth" | "policy" | "unknown";
  commitState: "none" | "committed" | "unknown";
  attemptsLeft: number;
  elapsedMsLeft: number;
  costLeft: number;
  retryAfterMs: number;
  retryExpectedMs: number;
  retryExpectedCost: number;
  fallbackExpectedMs: number;
  fallbackExpectedCost: number;
  primaryRoute: "healthy" | "degraded" | "open";
  fallbackRoute: "healthy" | "unhealthy";
  fallbackApproved: boolean;
  queueAllowed: boolean;
  degradeApproved: boolean;
}): Action {
  if (["request", "auth", "policy"].includes(p.owner)) return "fail_closed";
  if (p.commitState !== "none") return "fail_closed";
  if (p.owner === "unknown") return p.queueAllowed ? "queue" : "fail_closed";

  const canRetry =
    p.attemptsLeft > 0 &&
    p.elapsedMsLeft >= p.retryAfterMs + p.retryExpectedMs &&
    p.costLeft >= p.retryExpectedCost;
  const canFallback =
    p.attemptsLeft > 0 &&
    p.elapsedMsLeft >= p.fallbackExpectedMs &&
    p.costLeft >= p.fallbackExpectedCost;

  if (canRetry && ["transient", "rate"].includes(p.owner) && p.primaryRoute !== "open") {
    return "retry";
  }
  if (
    canFallback &&
    ["transient", "rate", "quota"].includes(p.owner) &&
    p.fallbackApproved &&
    p.fallbackRoute === "healthy"
  ) return "fallback";
  if (p.queueAllowed) return "queue";
  return p.degradeApproved ? "degrade" : "fail_closed";
}

retryAfterMs は主経路の再試行だけに使います。代替経路は固有の予測時間・費用で判定し、fallbackApproved には独立した quota 確認も含めます。そのため主経路の長い retry-after が、残り SLO 内で完了できる健全な代替経路を妨げません。committed または unknown は、自動分岐の外で状態照合するか、検証済みの再開・冪等性プロトコルを使います。次の送信前に試行レコードを保存し、要求経路、選択経路、プロバイダーの request ID、エラー分類、待機時間、トークン、費用、コミット状態、切替理由を残します。500 でも入力コンテキストが長すぎる場合など、リクエスト側の原因があり得るため、エラー詳細を見ずに一時障害へ分類しません。

障害注入で合格を確認する

staging で rate 429、quota 429、stream 前 503、token 表示後の切断、tool commit 後 timeout、fallback schema 欠落、open circuit を再現します。さらに、主経路の retry-after が残り SLO より長くても、承認済みの健全な代替経路が固有の時間・費用予算内に収まるケースでは、期待 action を queue ではなく fallback にします。各ケースは期待する action が一つでなければなりません。

メトリクスは primary success、retry recovery、fallback recovery、degraded、fail closed を分離します。最終 HTTP 200 だけでは、壊れた primary route を隠します。

今あるのが具体的な provider の 429 なら、先に OpenAI API rate limit、Claude API rate limit、Gemini API rate limit で owner を特定してください。

承認済みモデルを一つの互換 endpoint で試す場合は、staging で最新の LaoZhang AI API ドキュメントと照合できます。ただし統一 endpoint は等価性、復旧予算、ログ、stop rule を自動で保証しません。

注記:laozhang.ai は当ブログ運営チームの自社サービスです。その料金は中立的な比較ではなく、自社の提示価格です。

完了条件は、すべての障害が説明可能な一つの action に進み、全レイヤーが一つの予算を共有し、代替経路が同じ業務契約を通過し、最終成功が途中の失敗を消さないことです。

参考資料4

本文で参照している外部ページを、登場順に並べています。最終更新日:2026年7月27日。

  1. 1.エラーコードガイドdevelopers.openai.com/api/docs/guides/error-codes
  2. 2.API errorsplatform.claude.com/docs/en/api/errors
  3. 3.トラブルシューティングai.google.dev/gemini-api/docs/troubleshooting
  4. 4.timeouts, retries, backoff with jitteraws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter
さらに読む: API ガイド
LLM APIの保存先を分け、契約と実際の呼び出し条件を稟議資料に照合する概念図
API ガイド

LLM APIのデータ保持とZDR:稟議で使える確認手順

保存目的、期限、削除方法が業務の条件に合えば、通常保持のLLM APIも選べます。ZDRが必要な場合は、契約名だけでなく組織・モデル・機能・中継先・自社ログまで照合して承認範囲を決めます。

30 分
OpenAI APIの接続エラーで、同じプロセスの原因とHTTP応答を分け、結果不明の送信を照合する図
API ガイド

OpenAI API 接続エラー: APIConnectionError はまず経路から切り分ける

APIConnectionErrorが出たら、失敗したプロセスで接続先、例外の原因、HTTP応答の有無を確認します。原因に合うCA・プロキシ・通信許可を直し、同じ条件の小さい要求から復旧を確かめます。リクエストIDがなくても、未処理や未課金とは断定できません。

27 分