エラーからの復旧
復旧層はモデル呼び出しの失敗を分類してから、待機、入力圧縮、出力予算変更、互換の代替モデルを選びます。原因を変えずに再試行すれば、同じ失敗を繰り返し得ます。
ソファを運ぶとき、ドアが一時的に引っ掛かる場合と、ソファが幅を超える場合では対処が違います。建物が違えば行き先を直します。再試行も、一時障害、要求変更、停止して修正する問題を区別します。
復旧の仕組み
教材は、時間を変える、要求を変える、自動試行を止めるという 3 種を使います。
待機で対処するもの
本例の 529 overloaded は一時的なサービス負荷で、実際の 429 rate_limit も多くはそうです。待った後なら同じ要求でも状態が変わり得ます。実際の 429 は利用枠など、待機だけで解消しない制限もあるため、本文とサーバーの指示を確認します。
要求を作り直すもの
400 context_length_exceeded は、このモデルの入力と予約出力が窓に収まらないことを表します。待機では短くなりません。古い記録を要約し、必要な末尾を保って再計算します。
成功応答の stop_reason: max_tokens は出力予算到達です。本例は未完了として max_tokens を増やします。実際にはタスクの完成も確認し、モデルの出力上限と入出力合計の制限を守ります。
529 が続くと、許可済みで互換の代替モデルへ切り替える方針を取れます。元の選択が誤りだった、永久に復旧しないという証明ではありません。ツールと要求形式の互換性も必要です。
停止して修正するもの
本例の 400 invalid_request_error は無効なツール JSON Schema。待機、圧縮、無条件の切り替えでは直らないので、1 回目で止めて報告します。要求を修正すれば再試行でき、自動再試行を止めることと修復不能は別です。
分類に使う証拠
classify(response) は複数層を見ます。HTTP の 429、529、400、エラー本文の判別子、そして成功応答の停止理由です。本例の Anthropic 形式では error.type に rate_limit_error、overloaded_error、invalid_request_error が入り、打ち切りは stop_reason: "max_tokens" に出ます。API ごとのフィールドは同じとは限りません。
業務上の成功は harness が判定します。 HTTP 200 でも回答が途中かもしれません。例外だけを捕まえると見落とします。
エラー復旧のステップ
初期設定は長すぎる要求を分類して修復する 8 ステップです。
- 要求を組む。
primary、入力 203,800 token、max_tokens = 4,096、34 メッセージ、窓は 200,000。 - 試行 1。 203,800-token の入力を送ります。
- 拒否。
400 context_length_exceeded。203,800 + 4,096 = 207,896 > 200,000で、入力だけでも超えています。生成、タイムアウト、過負荷は起きていません。同じ要求は同じ制限に違反します。 - 分類。
context_too_long。待機でなく要求変更が必要です。 - 圧縮。 古い 28 メッセージ、172,300 token を 1,450-token 要約へ置換。最近 6 件、18,900 token は原文保持。system とツール定義 12,600 はこの方針で不変です。新要求は 32,950 token、7 メッセージで約 84% 減ります。タスクと末尾は残しても、要約は有損です。
- 試行 2。 モデルと
max_tokensは同じで、入力内容とメッセージ数が変わります。 - 成功。
32,950 + 4,096 = 37,046で窓内です。 - 台帳。 2 試行、待機 0.0 秒、提出入力合計 236,750 token。提出量であり請求額ではありません。決定的な超過は先に要求を修正します。
blind は毎回 203,800 を送り、失敗後に 1、2、4、8、16 秒待ちます。5 試行、31 秒のバックオフ、1,019,000 token 提出、回答なし。最後の失敗後にも 16 秒待つのは、この単純ループが意図的に持つ欠点です。
無条件再試行の費用差
一時的な過負荷なら、両方とも 1 秒待って試行 2 で成功し、合計 49,200 token を提出します。分類はこのケースの結果を変えません。差は時間で直らない失敗に現れます。
窓超過では blind の提出量が約 4.3 倍で、31 秒待っても失敗します。無効要求では classify は 1 回、0 秒で終わり、blind は 5 回、31 秒です。試行と提出量は 5 分の 1 ですが、実速度や価格が正確に 5 倍改善するとは言えません。
要約も無料ではありません。172,300-token を読んで要約する追加モデル処理を台帳は省いています。その入力を足すと約 409,000 token となり、blind の提出量との比は約 2.5 倍です。これも価格ではありません。拒否要求の課金、キャッシュ、要約出力、モデル別料金で変わります。実予算には修復呼び出しも含めます。
一時的な 529 と継続的な 529 は最初の応答では同じです。本例は 1 秒、2 秒待ち、試行 3 も失敗したら代替へ切り替え、4 回目で成功します。予算は切り替え時点を決めるもので、元モデルが復旧しない証明ではありません。実際の障害頻度も測っていません。
境界条件
- 圧縮不足。 保持する末尾が窓を超えていれば、要約 1 回では収まりません。保持範囲の縮小、分割、明確な失敗が必要で、同じ修復を無限に繰り返しません。
- 代替も停止中。 切り替えは成功保証ではなく、総予算と終了条件が必要です。
- 副作用の重複。 前の試行が課金や送信を済ませたなら、再試行は重複し得ます。受信側が冪等性キーを実装している場合は同じキーを使い、そうでなければ重複除去や照合復旧を設計します。無視されるキーだけでは防げません。
- 再び出力上限。 倍増にも出力上限と総窓があります。上限では仕事を小さくするか分割します。
- jitter なし。 全クライアントが 1、2、4、8、16 秒で同時に起き、再び集中し得ます。実際はランダム化とサーバーの推奨待機を使います。
よくある間違い
- 失敗を 1 条件にまとめる。 except と sleep だけでは、時間と無関係なエラーにも待機します。詳細を読みます。
- 決定的問題の修正後にも無意味に待つ。 圧縮後の 4 秒はそれ以上何も直しません。別の流量制限があれば、その独立した条件は守ります。
- 最終失敗後に sleep。 blind の最後の 16 秒は次の試行につながらず、待機だけを増やします。
- 例外だけ捕捉。 HTTP 200 にも未完了があるので、停止理由と必要な完成条件を見ます。
- 全 400 を同じにする。 無効 schema は schema 修正が必要ですが、同じ 400 の窓超過は圧縮して再試行できます。状態コードだけでは決められません。
- 代替で障害を隠す。 毎回切り替えると主系の異常を見失います。理由、回数、結果をログへ残します。
モデルの簡略化
要求サイズ、圧縮率、失敗順は固定で、決定的な harness が計算します。モデル呼び出しも録画もありません。秒数は例の方針で、本番の既定値ではありません。
修復費用はゼロ扱いです。要約の入出力 token と遅延、代替のコールドスタートを含めません。比率にはこの範囲が付き、提出 token は請求 token と同じではありません。
本番は jitter、retry-after、切れたストリームの復旧、対応する冪等性、サーキットブレーカー、エラー別予算、クライアントのトークンバケット制限も使います。分類と修復の考え方は再利用できますが、数値は教材の計算例です。
続けて学ぶ
同じ手法につながるレッスンや、次の概念への入口です。
鍵マークのあるレッスンの操作には有料アクセスが必要です。解説はすべて無料で読めます。
誤りや気になる点を見つけましたか? フィードバックを送る。