AIエージェントの障害回復パターン:リトライ、タイムアウト、バックオフ、サーキットブレーカー

AIエージェントの障害回復のためのリトライ、タイムアウト、バックオフ、およびサーキットブレーカーのパターン。モックに対して429および500エラーを強制的に発生させ、エージェントがバックオフし、決して二重送信しないことを証明する方法。

Ashley Innocent

Ashley Innocent

21 7月 2026

AIエージェントの障害回復パターン:リトライ、タイムアウト、バックオフ、サーキットブレーカー

Apidog エンタープライズ

オンプレミスデプロイ

SSO & RBAC

SOC 2 準拠

Apidog Enterpriseを見る

エージェントがAPIを呼び出します。APIは429を返します。エージェントはすぐに再試行し、再び429を受け取り、再度再試行します。こうして、実行が停止するか、料金が高騰するまで、スロットリングされたサービスに負荷をかけ続けるループが発生します。誰も意図的にそのループを作成したわけではありません。これは「エラーを処理する」という素朴なバージョンの結果として生じ、Anthropic SDKのディスカッションボードで開発者から最もよく尋ねられる質問の1つです。

エラーリカバリは、エージェント構築において、クリーンなデモと、誰かを呼び出すような問題を引き起こすものとを分ける部分です。モデルが問題なのではありません。問題は、ツール呼び出しが遅い、スロットリングされる、または壊れた場合に、あなたのコードがどう反応するかです。リカバリが適切であれば、不安定な依存関係はユーザーが気づかない短い一時停止で済みます。間違っていれば、1つの500エラーがインシデントに発展します。このガイドでは、ほとんどの負荷を担う4つのパターン、すなわちバックオフを伴う再試行、タイムアウト、サーキットブレーカー、および冪等性キーについて説明します。そして、ユーザーが欠陥を見つける前に、モックに対してそれらをテストする方法を示します。エージェントがどのように失敗するかというより広い視野については、AIエージェントが本番環境でなぜ壊れるのかから始めてください。

ボタン

正常なAPIに対してリカバリをテストすることはできません

ここに落とし穴があります。開発環境では依存関係は問題なく動作します。あなたはエージェントを作成し、呼び出しは成功し、デモはクリーンで、そしてリリースします。正常なAPIは処理すべきエラーを返さないため、リカバリコードは一度も実行されません。バックオフロジックが初めて実行されるのは本番環境で、実際の障害発生時、実際のユーザーが見守る中なのです。再試行ループのタイプミスを発見するのにこれほど最悪な場所はありません。

したがって、ルールはシンプルです。リカバリをテストするには、意図的に障害を発生させます。エージェントが呼び出すAPIのモックを立ち上げ、429、500、タイムアウト、または不正な形式のボディを返すようにプログラムし、エージェントをそれに向け、その動作を監視します。障害は、午前3時にあなたを呼び起こすものではなく、テストであなたがトリガーするものになります。Apidogはそのモックを立ち上げ、レスポンスをスクリプト化し、最終的なテストセクションで実行します。

指数バックオフとジッターによる再試行

再試行は最初の防衛線であり、素朴なバージョンには落とし穴があります。エラーを捕捉し、すぐに再度呼び出す。一時的な障害に対しては機能しますが、負荷がかかっているサービスに対しては、すべての失敗したクライアントが同時に再試行するため、殺到によりサービスが停止したままになり、事態を悪化させます。

2つの修正が組み合わされます。指数バックオフは試行間隔を広げます。1秒、次に2秒、次に4秒、次に8秒と、上限まで倍増させます。これにより、サービスは即座の再試行の壁に直面する代わりに回復する余裕を得ます。ジッターは各待機時間にランダムなオフセットを追加し、同じ瞬間に失敗した多数のクライアントがすべて同時に再試行するのを防ぎます。これがないと、バックオフでも同期された再試行の波が生じます。

2つのことを制限します。試行間の待機時間が数分にならないように遅延を、そして永続的な失敗が永遠に再試行するのではなく諦めるように試行回数を制限します。3回から5回の試行でほとんどの一時的なエラーはカバーされます。それ以上は、通常成功しないものを再試行していることになります。Anthropic SDKは、独自の呼び出しに対してこの処理の一部を行います。接続エラーや特定のステータスコードを指数バックオフで再試行し、max-retriesオプションで上限を設定できます。ただし、エージェントのツールがアクセスする他のAPIはカバーしないため、それらは自分でラップする必要があります。再試行を介してお金を扱うチームはこれを早期に学び、私たちの高リスクAPIの再試行ロジックの分析では、不注意な再試行がどれほどの損害を与えるかを示しています。

すべての呼び出しにタイムアウトを設定する

再試行はリクエストが失敗した場合にのみ役立ちます。より厄介なケースは、応答が返ってこないリクエストです。依存関係が接続を受け入れた後、ハングアップしてしまいます。タイムアウトがないと、ツール呼び出しがブロックされ、1つのデッドソケットのために実行全体が停止します。エラーもリカバリもなく、壁時計の時間とトークン予算を無駄に消費する、立ち往生したエージェントだけが残されます。

すべての外部呼び出しにはタイムアウトが必要です。接続確立のための接続タイムアウトと、応答待機のための読み取りタイムアウトを設定し、さらにエージェント実行全体に総予算を設定して、遅いが合法的な呼び出しの連鎖がユーザーの忍耐力を超えないようにします。タイムアウトが発生した場合は、他の再試行可能なエラーと同様に扱います。バックオフして、設定された上限まで再度試行します。

数値は推測ではなく、実際のレイテンシから選びます。各タイムアウトは、依存関係のp99を超え、余裕を持たせて設定します。厳しすぎると、成功するはずだった呼び出しを中断してしまいます。緩すぎると、ハングアップした依存関係がエージェントを使い物にならないほど長時間拘束してしまいます。ストリーミング応答には独自の予算を与えてください。長い完了は正当に遅く、短い固定タイムアウトでは途中で中断されてしまうためです。

依存関係がダウンしている場合にサーキットブレーカーを作動させる

バックオフは一時的にビジーなサービスを処理します。完全に停止しているサービスには不適切なツールです。依存関係が1分間失敗し続けている場合、次のリクエストもほぼ確実に失敗します。それを再試行すると、すでに壊れているものにさらに負荷がかかり、ユーザーは予測できたはずの失敗を待つことになります。

サーキットブレーカーは、3つの状態によってこれを解決します。クローズ状態は正常で、リクエストは流れ、ブレーカーは失敗をカウントします。失敗がしきい値を超えると、オープン状態に移行します。これは、リクエストの送信を停止し、クールダウン期間中は迅速に失敗を返します。これにより、停止したサービスへのすべての呼び出しでタイムアウト料金を支払うことを避けられます。クールダウン期間後、ハーフオープン状態になり、単一のプローブを通過させます。プローブが成功すれば、ブレーカーはクローズ状態に戻り、トラフィックが再開されます。失敗すれば、再びオープン状態になり待機します。

エージェントにとって、ブレーカーは「決済APIがダウンしている」という状況を、トークン予算と時間を浪費する40回の遅いタイムアウトではなく、エージェントが推論できる1回の高速でクリーンな失敗に変えます。これはグローバルではなく依存関係ごとに配線することで、検索APIがダウンしても、エージェントが健全な請求APIを使用できないようにする事態を防ぎます。

冪等性キーで再試行を安全にする

これまでのすべてのパターンは、再試行が安全であると仮定しています。しかし、多くの場合そうではありません。エージェントがPOST /chargeを送信し、サーバーがそれを処理した後、応答が途中でタイムアウトしたとします。エージェントは成功を見ていないため再試行し、その結果、顧客は二重に課金されます。再試行はあなたの要求通りに動作しましたが、設計がバグだったのです。

冪等性キーがこのギャップを埋めます。クライアントは論理的なアクションごとに一意のキーを生成し、通常はIdempotency-Keyヘッダーとしてリクエストと共に送信します。サーバーは最初の受信時にそのキーを記録し、同じキーを再度検出した場合は、作業を二重に行う代わりに最初の結果を返します。これにより、再試行は構造上安全になります。同じキーを持つ2回目のPOST /chargeは、最初の課金結果を返すノーオペレーションとなります。

キーは同じアクションの再試行全体で安定している必要があり、異なるアクション間では変更する必要があります。リクエストを構築する際に一度生成し、再試行ループ内では生成しないでください。そうしないと、すべての試行が新しいキーを受け取り、重複排除が機能しません。状態を作成または変更する(課金、注文、メール送信、記録など)すべてのツール呼び出しにはキーが必要です。冪等性キーに関する私たちのガイドでは、生成とサーバーサイドでの処理について詳しく説明しています。

レート制限とRateLimitErrorループを乗り切る

レート制限は、その指示があるため、独自の処理が必要です。レート制限超過の応答は通常、待機すべき正確な時間(秒数または日付)を示すRetry-Afterヘッダーを伴う429として届きます。これを尊重してください。サーバーが30秒待てと言っているのに2秒で再試行すると、再度429を受け取り、SDKのディスカッションボードを埋め尽くすRateLimitErrorループを構築してしまいます。制限を捕捉し、早すぎる再試行を行い、より厳しく制限され、実行が停止するまで繰り返すのです。別のSDKスレッドでは、開発者がここで直面する同じ壁について説明しています。

解決策は、サーバーにペースを決定させることです。429を受け取った場合、Retry-Afterを読み取り、再試行する前に少なくともその時間だけ待機します。ヘッダーがない場合は、ジッター付きの指数バックオフにフォールバックします。試行回数を制限し、持続的な制限が無限の待機ではなく、クリーンな失敗で終わるようにします。Anthropic SDKは独自の呼び出しに対してRetry-Afterを既に尊重しています。すべき作業は、エージェントがアクセスする他のレート制限されたAPIにも同じルールを適用することです。

予防的な側面もあります。プロバイダーが1分あたりのリクエスト数を設定している場合、トークンバケットで自身の呼び出しを測定し、スロットリングされて上限に達するのではなく、上限内で維持するようにします。リカバリは発生した制限を処理しますが、ペース調整は制限に達するのを防ぎます。

リカバリパスをテストする方法

さあ、これらをまとめましょう。上記のパターンは、それらが実行されるという証明があって初めて価値があり、その証明とは、健全なAPIが与えないような障害を強制的に発生させるテストです。その形はすべてのシナリオで再利用されます。

  1. 依存関係をモックする。エージェントのツールが呼び出すAPIのモックを立ち上げ、すべてのステータスコード、ヘッダー、ボディ、遅延を制御できるようにし、テスト中に実際の課金やメールが送信されないようにします。
  2. シーケンスをプログラムする。モックをスクリプト化し、次の一連の呼び出しに順番に回答するようにします。まずRetry-After: 2を伴う429、次に500、そして有効なボディを持つ200です。1つのエンドポイント、3つのスクリプト化された応答で、1回の実行で完全なリカバリフローをテストします。
  3. モックにエージェントを駆動させる。エージェントのツールを実際のサービスではなくモックのURLに向け、シナリオを最初から最後まで実行します。
  4. 動作をアサートする。重要な点を確認します。エージェントが429の後に再試行する前に少なくとも2秒待機したか、500の後に再試行したか、3回目の呼び出しで成功したか、そして試行回数上限を超えなかったかを確認します。

この1つのシナリオで、バックオフとRetry-Afterが1回のパスで証明されます。次に、諦めるパスのための2番目のシナリオを追加します。モックが毎回失敗するようにスクリプト化し、エージェントが上限で停止し、ループする代わりにクリーンなエラーを返すことをアサートします。サーキットブレーカーのために3番目のシナリオを追加します。十分な回数連続して呼び出しを失敗させ、エージェントがトリップして、すべての試行でタイムアウトを支払う代わりに、迅速に失敗することをアサートします。

冪等性のチェックは人々が見落としがちですが、費用を節約するために非常に重要です。モックを変異する呼び出しを受け入れるようにスクリプト化し、応答を破棄してエージェントが失敗したと認識するようにし、その後再試行を受け入れます。次に、リクエストの形式をアサートします。両方のリクエストが同じIdempotency-Keyを保持していたか、そしてモックが2つの論理的なアクションではなく1つの論理的なアクションとして認識したかを確認します。再試行時に新しいキーが生成された場合や重複する呼び出しがあった場合、それは顧客が発見する前にあなたが二重送信を発見したことを意味します。APIを呼び出すエージェントのテストに関するより広範な方法では、エンドツーエンドのハーネスをセットアップします。

エラーリカバリチェックリスト

エージェントが本番環境に移行する前に、このリストを確認してください。

これら7つすべてをクリアすれば、エージェントは偶然ではなく意図的に回復します。

Apidogが適している点(と適していない点)

ツールの役割を正直に理解しましょう。Apidogはエージェントフレームワークでも、モデルホストでも、ランタイムでもありません。エージェントを構築したり、実行したり、オーケストレーションしたりすることはなく、モデルの出力を評価することもありません。Apidogが担当するのは、エージェントが呼び出すAPIレイヤーであり、まさにリカバリの成否が決まる場所です。

これにより、Apidogには3つの役割があります。1つ目は、エージェントがアクセスする依存関係をモックし、ライブサービスではなく制御可能な代替物を提供すること。2つ目は、実際のAPIがコマンドで生成しないような失敗応答(Retry-After付きの429、500、タイムアウト、不正な形式のボディ)をプログラムし、リカバリの練習ができるようにすること。3つ目は、モックが受け取るリクエストを検証すること(冪等性キーが存在し安定しているか、正しい形式か、期待される呼び出し回数かなど)。これにより、二重送信やヘッダーの欠落が顧客の問題ではなくテストで失敗するようになります。これが正直な役割です。Apidogは、エージェントが乗り越えなければならない失敗をモックし、エージェントが何を返すかをチェックします。

よくある質問

Anthropic SDKが再試行を処理してくれませんか? 独自の呼び出しについては、はい。SDKは特定のエラーを指数バックオフで再試行し、Retry-Afterを尊重します。max-retriesオプションで上限を設定できます。しかし、エージェントのツールが呼び出す他のAPIは対象外です。それらには、あなたが同じパターンを適用する必要があります。

いつ冪等性キーが必要ですか? 状態を作成または変更するすべての呼び出し、例えば課金、注文、送信メッセージ、新規記録などです。読み取り専用の呼び出しは、キーなしで安全に再試行できます。各アクションにつき1回キーを生成し、再試行全体で安定性を保つようにします。

今週、1つの障害をリハーサルする

4つのパターンすべてを一度に構築する必要はありません。最も損害が大きいと思われるもの、通常はレート制限ループや非冪等な再試行を選び、モックに対してリハーサルを行います。429をプログラムし、応答を破棄し、エージェントが何を送信するかを監視してください。二重課金を恐れていた箇所で、クリーンなバックオフと単一の冪等性キーを初めて見たとき、あなたは青信号のデモよりも確かな理由でエージェントを信頼するでしょう。

Apidogをダウンロードして、障害をモックし、シーケンスをスクリプト化し、APIが反発したときにエージェントがどのように動作するかをアサートしてください。

ボタン

ApidogでAPIデザイン中心のアプローチを取る

APIの開発と利用をよりシンプルなことにする方法を発見できる