welclaiAI·TREND·DIGEST
チュートリアル

エラーとタイムアウトを優雅に処理する

モデル呼び出しは失敗し、止まり、レート制限を受けます。AI機能を信頼できる状態に保つリトライ、タイムアウト、フォールバック、フェイルセーフの実践ガイドです。

tutorials2026-04-21 12:49 KST·編集長·7

デモはすべてがうまくいくことを前提とします。プロダクトは物事が失敗することを前提とし、それでも有用であり続けます。ネットワーク越しに言語モデルを呼び出すとき、あなたはリモートサービスのあらゆる失敗モード——タイムアウト、レート制限、一時的なエラー、遅い応答——を受け継ぎ、さらに必要だった形に一致しない出力など、モデル特有のいくつかが加わります。脆い機能と信頼できる機能の違いは、ほぼ完全に、うまくいかない経路をどう扱うかにあります。このガイドでは、計画しておくべき失敗と、それぞれを優雅に処理する方法を順に見ていきます。

計画している失敗を知る

モデル呼び出しは、いくつかの見分けのつく形で失敗します。うまく処理するには、まずそれらを区別することから始まります。一時的なエラーは一過性のしゃっくり——短いネットワークの瞬断や、単にもう一度試せば成功するサーバー側のエラーです。レート制限は、リクエストを送るのが速すぎるので遅くしろとプロバイダーが告げているものです。タイムアウトは、応答が待てる時間より長くかかったときに起き、モデルでは生成時間が出力の長さによって変わるため頻繁に起こります。無効入力エラーは、リクエスト自体が不正で、変えずに再試行しても同じように失敗することを意味します。そして内容レベルの失敗があります。呼び出しは成功したのに、出力が間違っている、空である、または要求した形式になっていない。

これらのカテゴリが重要なのは、正しい対応がそれぞれ異なるからです。一時的なエラーの再試行は正しく、不正なリクエストの再試行は無意味です。レート制限で後退するのは助けになり、強く叩き続ければ悪化します。処理コードを書く前に、目の前のエラーを分類しましょう。分類が治療法を決めるからです。

一時的なものは再試行し、礼儀正しく後退する

一時的なエラーとレート制限には、再試行が答えです——ただし、どう再試行するかが重要です。即座に繰り返し再試行するとかえって悪化することがあり、特にレート制限では、即時再試行の洪水がスロットリングを続けさせるだけです。標準的で行儀のよいアプローチは、ジッター付き指数バックオフです。最初の再試行の前に短い時間待ち、その後の試行ごとに待ち時間をおよそ倍にし、多くのクライアントが足並みをそろえて再試行しないよう小さなランダムなずれを加えます。

delay = base
for attempt in range(max_attempts):
    try:
        return call_model(request)
    except Transient or RateLimited:
        wait(delay + random_jitter())
        delay = delay * 2
raise GiveUp

試行回数と最大遅延に上限を設け、失敗する呼び出しが永遠に再試行しないようにします。そして再試行で直せるエラーだけを再試行します——一時的な失敗とレート制限の失敗には再試行を巻き、不正リクエストのエラーは速やかに失敗させましょう。成功しえないリクエストを再試行するのは、時間とお金の無駄だからです。

必ずタイムアウトを設定する

タイムアウトのないモデル呼び出しは罠です。生成時間はばらつき、ときに通常よりはるかに長くリクエストが止まります。タイムアウトがなければ、たった1つの遅い呼び出しがリクエストハンドラを占有し、コネクションプールを枯渇させ、ほんの少数の呼び出ししか不調でないのに全面的な障害に見えるカスケードへと連鎖します。すべてのモデル呼び出しに明示的なタイムアウトを必ず設定し、周囲の文脈が実際にどれだけ待てるかに合わせて選びましょう。

タイムアウトは意図的に選びます。人間が待つインタラクティブな機能は、辛抱できるバックグラウンドのバッチジョブよりも厳しい上限を必要とします。呼び出しがタイムアウトを超えたら、一時的な失敗として扱います。キャンセルし、再試行するかフォールバックします。要点は、際限のない呼び出しに決めさせるのではなく、どれだけ待つかをあなたが決めることです。ストリーミングもここで役立ちます——応答をストリームすれば、最初のトークンまでの時間が呼び出しが生きている早期のシグナルになり、その最初のチャンクに別の、より厳しいタイムアウトを適用できます。

再試行が尽きたときのためのフォールバックを持つ

再試行は一時的なトラブルへの耐性を買ってくれますが、ときにトラブルは一時的ではありません——プロバイダーが持続的な障害を起こしている、またはあらゆる試行がタイムアウトする。こうした場合、モデルが単に利用できないときに機能が何をするかを、あらかじめ決めておきましょう。間違った答えは、未処理の例外が壊れた画面となって浮かび上がることです。

フォールバックは、タスクに応じていくつかの種類があります。利用できる可能性が高い、より小さなまたは代替のモデルにフォールバックするかもしれません。合うものがあれば、キャッシュされた、または既定の応答を返すかもしれません。非AIの経路——単純なルール、手動の選択肢、ユーザーの入力を保持して何も失われない「後でもう一度お試しください」のメッセージ——へと優雅に劣化させるかもしれません。正しいフォールバックは機能次第ですが、すべてのAI機能は1つ持つべきです。ローンチ前に答えるべき問いはこうです。モデルがまったく応答できないとき、ユーザーには何が見えるのか? 「エラーページ」は、重要なものについては受け入れられる答えではありません。

呼び出しだけでなく出力を検証する

呼び出しの成功は、結果の成功ではありません。モデルは空の、的外れの、または——最もよく痛い目を見る——コードが期待する構造になっていないテキストを返しうります。JSONを求めたのに、有効だと決めつけて応答を解析すれば、不正な出力はネットワークエラーと同じくらい確実にコードをクラッシュさせます。モデルの出力を信頼できない入力として扱い、頼る前に検証しましょう。

呼び出しの後、出力が要件を満たすか確認します。解析できるか、必須フィールドがあるか、期待される範囲内か。検証が失敗したとき、選択肢があります。何が悪かったかを指摘する明確な指示を添えて、呼び出しを再試行できます。軽微な問題には寛容な修復を試みられます。あるいはフォールバックできます。してはいけないのは、整っていると決めつけるコードに、検証していないモデル出力を直接渡すことです。モデルは確率的なコンポーネントです。防御的な検証こそが、確率的なコンポーネントの上に安全に構築する方法です。

失敗を見えるように、観測可能にする

決して見ない失敗は直せません。エラーを、理解できるだけの文脈とともにログに残しましょう——失敗の種類、それを引き起こした入力、何回の再試行を要したか、フォールバックが発動したか。タイムアウト、レート制限、検証失敗の率を見ていれば、ユーザーが不満を言う前に何かが劣化しつつあると分かります。タイムアウトの急増はプロバイダーの問題かもしれません。検証失敗の絶え間ない流れは、プロンプトがずれたか入力が変わったことを意味するかもしれません。

エラーは正直に、しかし穏やかにユーザーに見せます。何かがうまくいかなかったが入力は安全だという明確で落ち着いたメッセージは、暗号めいたスタックトレースや無言の空の応答に勝ります。内部では、ユーザーには静かでも、監視では失敗が大きく鳴るようにします。この組み合わせ——ユーザーには優雅、あなたには見える——こそが、不満を通じて弱点を発見するのではなく、機能を長く信頼できる状態に保つものです。

まとめ

信頼性はうまくいかない経路の上に築かれます。直面している失敗を分類しましょう——一時的、レート制限、タイムアウト、不正、不良出力——それぞれ異なる対応を要するからです。再試行できるものはジッター付き指数バックオフで再試行し、それ以外は速やかに失敗させ、すべての呼び出しに明示的なタイムアウトを置いて、1つの遅いリクエストがシステムを止められないようにします。モデルが利用できないとき何が起きるかをあらかじめ決め、すべての機能に本物のフォールバックを与えます。頼る前に出力を信頼できない入力として検証し、失敗を監視で見えるように保ちます。これらをうまく処理すれば、モデルが協力してくれない日でも、あなたの機能は有用であり続けます。

#reliability#errors#timeouts#resilience