バッチAPIに回す処理、回さない処理:OpenAIとClaudeの非同期処理の選び方
AIを使いこなすClaudeで執筆し、GPTで自動校閲・修正しています。

結論から言うと、バッチAPIに回すのは「結果が数時間〜翌日に届いても困らず、1件ずつ独立していて、失敗した分だけ再投入できる処理」です。逆に、ユーザーが画面の前で待つ処理や、前の出力が次の入力になる処理は通常APIに残します。 理由は、どちらのバッチも「安いが、いつ終わるかは保証されない」仕組みだからです。2026年10月28日時点で公式ドキュメントを確認した範囲では、次の点が共通しています。 • 同期APIに比べて料金が50%安い(OpenAI Batch APIガイド、Claudeのバッチ処理ガイド) • OpenAIは完了時間を24時間以内と案内しています。Claudeも作成から24時間で期限切れとなり、大半は1時間以内に終わりますが、早く終わる時間は保証ではありません • 結果は入力順に並ぶとは限らず、custom_idで突き合わせる 割引の対象モデルや条件は更新されうるため、導入前に各社の料金ページで自分のモデルを確認してください。ClaudeのバッチはZero Data Retention(ZDR)の対象外と案内されているため、データ要件も確認してください(Claudeのバッチ処理ガイド)。
判断の軸は「待てるか」より「期限を決められるか」
「即時性が不要」だけでは判断が曖昧です。次の3つの質問に全部「はい」なら、バッチ候補です。
- 結果を使う時刻の24時間以上前に投入できるか
- 1件の結果が他の件の入力に依存しないか
- 一部が失敗しても、その件だけやり直せば業務が成立するか
1つ目が特に見落とされます。24時間枠は「最長で24時間かかりうる」という意味なので、「夜22時に投げて朝8時に使う」設計は、運が悪いと間に合いません。朝に必須の処理は、締切の手前(たとえば朝6時)に未完了分を通常APIで処理し直す逃げ道をセットにします。
処理の種類別の振り分け表
以下は公式仕様をもとにした編集上の振り分け案です。自社の締切と件数に合わせて調整してください。
- 過去の問い合わせ数千件の分類・タグ付け、振り分け:バッチ、理由・条件:件ごとに独立。急がない
- 商品説明文・要約の一括生成(翌営業日利用)、振り分け:バッチ、理由・条件:締切まで24時間以上の余裕を取る
- プロンプト変更時の評価セット実行、振り分け:バッチ、理由・条件:結果は翌日でよく、件数が多い
- 全文書の埋め込み(embedding)再生成、振り分け:OpenAIのバッチ、理由・条件:OpenAIのバッチは/v1/embeddingsに対応
- 朝一番に使うレポートの下書き、振り分け:バッチ+通常APIの保険、理由・条件:未完了分を締切前に通常APIへ切り替える
- チャット応答、入力中の補助、振り分け:通常API、理由・条件:ユーザーが待つ
- ツール呼び出しを繰り返すエージェント、振り分け:通常API、理由・条件:往復ごとに前の結果が必要で、各往復で待ちが発生しうる
- 管理画面のボタンで即結果を見たい処理、振り分け:通常API、理由・条件:完了時刻を約束できない
- バッチで失敗した少数の再処理、振り分け:件数次第、理由・条件:数件なら通常API、数百件なら再バッチ
OpenAIのバッチは、Responses、Chat Completions、Embeddings、Completions、Moderations、画像生成・編集の各エンドポイントに対応し、1つのバッチファイルで使えるモデルは1つです。1バッチの上限は50,000リクエスト・200MBです(OpenAI Batch APIガイド)。Claudeはバッチあたり最大100,000リクエストまたは256MBのいずれかに達するまでで、結果は作成から29日間取得できます(Claudeのバッチ処理ガイド)。
2社の入力と結果回収の違い
どちらも「投入→待機→回収→突き合わせ」の流れは同じですが、入口と出口の形が違います。
- 入力、OpenAI:JSONLファイルをアップロードしてバッチを作成、Claude:リクエスト配列をそのまま渡して作成
- 1行/1件の中身、OpenAI:custom_id、method、url、body、Claude:custom_id、params(Messages APIのパラメータ)
- 状態、OpenAI:validating、in_progress、finalizing、completed、failed、expired、cancelling、cancelled、Claude:in_progress、canceling、ended
- 結果の取得先、OpenAI:完了後にoutput_file_id(成功分)とerror_file_id(失敗分)、Claude:results_url(JSONL)
- 件ごとの結果種別、OpenAI:出力ファイル/エラーファイルで分かれる、Claude:succeeded、errored、canceled、expired
Claudeのcustom_idは英数字・ハイフン・アンダースコアで1〜64文字、バッチ内で一意という制約があります。両社で使い回せるよう、最初から次の形式にしておくと楽です。
ticket-10234-v3 (業務ID-プロンプト版)プロンプトの版を入れておくと、再投入や比較のときにどの設定の結果か判別できます。
入力行の形は次のとおりです(説明用の例で、実際には動かしていません。<モデル名>は自分の環境のものに置き換えます)。
{"custom_id":"ticket-10234-v3","method":"POST","url":"/v1/responses","body":{"model":"<モデル名>","input":"次の問い合わせを3分類のいずれかに分類: ..."}}{"custom_id":"ticket-10234-v3","params":{"model":"<モデル名>","max_tokens":200,"messages":[{"role":"user","content":"次の問い合わせを3分類のいずれかに分類: ..."}]}}結果回収の流れ(夜間処理の例)
夜間バッチを運用に載せるときの手順です。
- 投入前:入力をDBに「未処理」で保存し、custom_idを割り当てる。バッチ作成の応答に含まれるバッチIDを必ず保存する
- 投入:夜間(例:22:00)に作成。同時に「この時刻までに終わらなければ保険に切り替える」締切時刻も記録する
- 確認:定期ジョブで状態を取得する。Claudeの取得エンドポイントは何度呼んでも結果が変わらない(冪等な)ポーリング用で、endedになるとresults_urlが入る。OpenAIはcompletedになったら出力ファイルを取得する
- 保存:完了を検知したら、結果ファイルをすぐ自社ストレージに保存する。OpenAIの出力ファイルには保持期限があり、Claudeにも結果が取得できなくなる(アーカイブされる)仕組みがあります
- 突き合わせ:行の順序を信用せず、custom_idでDBと結合する
- 仕分け:成功は反映。失敗・期限切れ・キャンセルは「再処理待ち」に戻す
- 保険:締切時刻を過ぎても未完了なら、残りを通常APIで処理するか、翌日の枠に回す
期限切れの扱いも確認しておきます。OpenAIでは、期限に間に合わずexpiredになったバッチでも、完了済みのリクエストの結果は取得でき、未実行分はbatch_expiredエラーとして記録されます。Claudeもexpiredが件単位の結果種別にあるので、「バッチ全体の成否」ではなく「件単位の結果」で判定する作りにしておくと、両社の件単位の結果形式の違いを吸収しやすくなります。結果取得後は保存先の権限・保持方針も確認してください。
回さない方がよい落とし穴
- バッチ内の失敗を見ずに全件成功扱いにする:状態が完了でも、全件成功とは限りません。件数の内訳(成功・失敗・期限切れ)を毎回ログに残します
- プロンプトの試行錯誤をバッチでやる:1回の確認に最大24時間かかりえます。調整は少数件を通常APIで回し、固まってからバッチへ移します
- キャンセルを即時停止と考える:OpenAIではキャンセル要求後、処理中のバッチがキャンセルされるまでcancelling状態が続き、最大10分かかることがあります。完了済みのリクエストは課金・結果の対象になりうるため、途中結果の扱いを決めておきます(OpenAI Batch APIガイド)
- 機密データをそのまま投入する:バッチでも送るデータの扱いは通常APIと同様に検討が必要です。保持や学習利用の条件は、契約や各社のデータ保持に関する公式説明で別途確認してください。テストには架空データを使います
実装前のチェックリスト
- 結果を使う時刻から逆算して、投入の締切時刻を決めたか
- 1件ずつ独立した処理に分解できているか
- custom_idの規則と、再投入のルール(何回まで、どの条件で)を決めたか
- 結果ファイルを完了検知後すぐ保存する処理があるか
- 締切を過ぎた分の保険(通常APIまたは翌日回し)があるか
なお、Claudeのバッチのサイズ上限(MB)や結果の保持日数は、今回の確認範囲では特定できていません。実装前にClaudeのバッチ処理ガイドで確認してください。

