技術実験

Decision APIでデプロイの再試行を判断できる? 失敗ログ10件で検証

ローカルで10件の失敗を再現し、同じ設定で再試行した

デプロイに失敗して、最後のログに timed out と出たら、もう一度押せば直るのでしょうか。ローカルで初回のログが完全に同じ2件を作ってやり直したところ、片方だけ成功しました。

デプロイの失敗画面で次の行動を案内できるか試すため、初回の記録を OpenAI の Decisions API に渡しました。APIは同じログの2件を、どちらも「情報不足」と判定しました。一方、タイムアウトの直後に同じ接続先が HTTP 200 を返した記録があるケースでは、「再試行」を選びました。

ケースA・Bに共通する初回ログ
GET /artifact: TimeoutError: timed out
error: deployment step failed (TimeoutError: timed out)
ケースAの再試行HTTP 200 が返り、処理が通った
ケースBの再試行再びタイムアウトし、処理が失敗した
図1 初回の記録が同じ2件でも、同じ設定でやり直した結果は異なった。

同じタイムアウトのあと、確認リクエストで応答が戻ったケースの初回ログは次のとおりです。上のログに、同じ接続先が HTTP 200 を返した2行目が加わっています。

GET /artifact: TimeoutError: timed out
follow-up probe of the same artifact endpoint: HTTP 200
error: deployment step failed (TimeoutError: timed out)

失敗を作り、初回の記録だけで案内を選ぶ

手元のPCで、デプロイ時のビルド、起動、起動後の応答確認を模した小さなプログラムを動かしました。模擬HTTPサーバーがリクエストごとに返す応答をあらかじめ決め、同じ設定でやり直すと通るケースと失敗するケースを作りました。ログは、実際のHTTP応答やPythonが返した例外を、実験プログラムが記録したものです。本番のデプロイログや実際のサービスは使っていません。

合計10件で初回を失敗させ、同じ設定で1回ずつ再試行しました。HTTPリクエストのタイムアウトは200ミリ秒、初回の記録を取り終えてから再試行までの待ち時間は50ミリ秒です。復旧を確認するケースでは、初回失敗後に同じURLへ確認用のリクエストを1回送っています。

判定に渡す情報初回のログ、失敗した工程、確認リクエストの結果があればその記録
案内を判定渡された記録から3択を選ぶ
再試行の結果と照合同じ設定で1回実行した結果を、判定の評価に使う
図2 判定と照合の関係。実験では再試行の記録を先に採取し、APIには初回の記録だけを渡した。

案内の基準は先に決めました。復旧など、一時的な失敗と判断できる記録があれば「再試行」、具体的な設定不備が見えれば「設定を確認」、一時的な失敗か設定の問題かを見分けられなければ「情報不足」です。この基準を選択肢の説明としてAPIにも渡しました。

Decisions APIには失敗した工程と初回のログを渡し、gpt-6-luna の choice で3択から1つ選ばせました。再試行のログと結果はAPIに渡していません。1件につき1回、合計10回呼び出しました。 OpenAI Decisions APIの選択肢の仕様

API費用の概算は10回で約0.00026米ドルです。使用量の記録では、キャッシュされていない入力が合計2,603トークンでした。gpt-6-luna の Decisions API では、キャッシュされていない入力の基本単価が100万トークン当たり0.10米ドルです(2026年11月5日時点)。今回の使用量に当てはめると、2,603 ÷ 1,000,000 × 0.10 = 0.0002603 米ドルです。出力は課金対象外です。失敗の再現と再試行はローカルで行ったため、今回の検証にPaaSのデプロイ料金はかかっていません。 OpenAIのDecisions API料金

差が出たのは、最終行だけでは分からない2件

比較対象は、最終行にタイムアウト、接続切断、HTTP 503、HTTP 429があれば「再試行」、HTTP 404や設定不備の語があれば「設定を確認」とするルールです。先に決めた案内と一致した件数は次のとおりです。

期待した案内Decisions API最終行のルール
再試行4/4件4/4件
設定を確認4/4件4/4件
情報不足2/2件0/2件
合計10/10件8/10件
表1 初回の記録から選んだ案内と、事前に決めた案内が一致した件数。

「再試行」の4件は、依存先がHTTP 503、HTTP 429、接続切断、タイムアウトのいずれかで失敗し、その後の確認リクエストでHTTP 200を返したケースです。4件とも、同じ設定でやり直すと処理が通りました。「設定を確認」の4件は、依存ファイルの取得先が見つからない、必須の環境変数がない、起動確認のURLが違う、設定ファイルが壊れている、というケースで、再試行も4件とも失敗しました。

残る2件は、最初の記録だけでは区別がつかないように作りました。最終行のルールは両方に再試行を勧め、片方は再試行しても失敗しました。APIは両方を「情報不足」としました。この2件では、後から再試行が成功したかよりも、案内する時点で再試行を勧める根拠があったかを評価しています。

この差は初回ログ全体と失敗した工程を見たAPIと最終行だけのルールの比較です。同じ情報を読むルールとの比較や、実際のデプロイでの判定精度は今後の検証になります。

実験で採取した全10件のログ

掲載したログは、この模擬実験で採取したものです。パスと設定名は実験用で、実サービスのホスト名、認証情報、ユーザー情報は含まれていません。

各ケースに、失敗した工程、Decisions APIが選んだ案内、初回と再試行のログを載せています。確認リクエストを送ったケースでは、その結果が初回ログに含まれます。

1. 依存先が一時的に HTTP 503 を返した

失敗した工程はビルド。Decisions APIの案内は「再試行」。

初回ログ

GET /artifact: HTTP 503
follow-up probe of the same artifact endpoint: HTTP 200
error: deployment step failed (HTTP 503)

再試行ログ(成功)

GET /artifact: HTTP 200
deployment step passed

2. 依存ファイルが見つからなかった

失敗した工程はビルド。Decisions APIの案内は「設定を確認」。

初回ログ

GET /artifact/not-in-lock: HTTP 404
the locked dependency artifact path returned not found
error: deployment step failed (HTTP 404)

再試行ログ(失敗)

GET /artifact/not-in-lock: HTTP 404
the locked dependency artifact path returned not found
error: deployment step failed (HTTP 404)

3. タイムアウト後に再試行が成功した(ケースA)

失敗した工程はビルド。Decisions APIの案内は「情報不足」。

初回ログ

GET /artifact: TimeoutError: timed out
error: deployment step failed (TimeoutError: timed out)

再試行ログ(成功)

GET /artifact: HTTP 200
deployment step passed

4. 起動に必要な環境変数がなかった

失敗した工程は起動。Decisions APIの案内は「設定を確認」。

初回ログ

required runtime setting is missing: 'PORT'
error: startup validation failed

再試行ログ(失敗)

required runtime setting is missing: 'PORT'
error: startup validation failed

5. 依存先との接続が途中で切れた

失敗した工程はビルド。Decisions APIの案内は「再試行」。

初回ログ

GET /artifact: RemoteDisconnected
follow-up probe of the same artifact endpoint: HTTP 200
error: deployment step failed (RemoteDisconnected)

再試行ログ(成功)

GET /artifact: HTTP 200
deployment step passed

6. 起動確認のパスが違っていた

失敗した工程は起動確認。Decisions APIの案内は「設定を確認」。

初回ログ

GET /ready: HTTP 404
configured readiness path is /ready. App route /health: HTTP 200
error: deployment step failed (HTTP 404)

再試行ログ(失敗)

GET /ready: HTTP 404
configured readiness path is /ready. App route /health: HTTP 200
error: deployment step failed (HTTP 404)

7. 依存先が一時的に HTTP 429 を返した

失敗した工程はビルド。Decisions APIの案内は「再試行」。

初回ログ

GET /artifact: HTTP 429
follow-up probe of the same artifact endpoint: HTTP 200
error: deployment step failed (HTTP 429)

再試行ログ(成功)

GET /artifact: HTTP 200
deployment step passed

8. 設定ファイルを読み取れなかった

失敗した工程はビルド。Decisions APIの案内は「設定を確認」。

初回ログ

could not parse build-settings.json: Expecting value: line 1 column 16 (char 15)
error: build configuration is invalid

再試行ログ(失敗)

could not parse build-settings.json: Expecting value: line 1 column 16 (char 15)
error: build configuration is invalid

9. タイムアウト後も再試行が失敗した(ケースB)

失敗した工程はビルド。Decisions APIの案内は「情報不足」。

初回ログ

GET /artifact: TimeoutError: timed out
error: deployment step failed (TimeoutError: timed out)

再試行ログ(失敗)

GET /artifact: TimeoutError: timed out
error: deployment step failed (TimeoutError: timed out)

10. タイムアウトの直後に復旧を確認できた

失敗した工程はビルド。Decisions APIの案内は「再試行」。

初回ログ

GET /artifact: TimeoutError: timed out
follow-up probe of the same artifact endpoint: HTTP 200
error: deployment step failed (TimeoutError: timed out)

再試行ログ(成功)

GET /artifact: HTTP 200
deployment step passed

再試行の前に、失敗した工程と接続先を確認する

たとえばビルド中に依存ファイルを取れなかったなら、同じファイルのURLがいま応答するかを確認できます。起動確認で失敗しているなら、アプリが提供するパスと、設定した確認先が合っているかを見ます。タイムアウトしか分からないときは、失敗した工程や接続先が分かるログを探します。

失敗画面にこの判断を取り入れるなら、選んだ案内の横に、ログで確認できた事実を示す設計が考えられます。たとえば「依存ファイルの取得に失敗しましたが、直後の確認では応答しています」と出せば、利用者は再試行を勧める理由を確かめられます。今回のAPI判定で取得したのは選択肢です。画面に表示する事実はログから組み立てる想定です。

KamuiDashは、GitHubからWebアプリをデプロイできるPaaSです。 KamuiDash