OpenAI の Batch API を使うと、複数のリクエストをまとめて送信し、非同期に処理できます。料金は同期 API よりも 50% 安く、レート制限も同期 API とは別枠で、上限は大幅に高く設定されています。処理は 24 時間以内に完了するため、即時の応答が不要なジョブに適しています。詳しい仕様は API リファレンスでも確認できます。
概要
OpenAI Platform では、用途によっては同期リクエストが必要です。一方、すぐに応答を受け取る必要がない場合や、レート制限のために大量のクエリを短時間で実行できない場合もあります。バッチ処理は、たとえば次のような用途に役立ちます。
- 評価の実行
- 大規模なデータセットの分類
- リポジトリ内のコンテンツの埋め込みベクトル生成
Batch API のエンドポイントを使えば、複数のリクエストを 1 つのファイルにまとめ、バッチ処理ジョブを開始できます。リクエストの実行中はバッチのステータスを確認でき、完了後は結果をまとめて取得できます。
標準のエンドポイントを直接使う場合と比べて、Batch API には次の利点があります。
- コストの削減:同期 API よりも料金が 50% 安くなります。
- 高いレート制限:同期 API よりも大幅に高い上限が適用されます。
- 短い処理時間:各バッチは 24 時間以内に完了し、多くの場合はさらに短時間で完了します。
利用手順
1. バッチファイルの準備
まず .jsonl ファイルを用意し、API に送信するリクエストの詳細を 1 行に 1 件ずつ記述します。現在利用できるエンドポイントは次のとおりです。
/v1/responses(Responses API)/v1/chat/completions(Chat Completions API)/v1/embeddings(Embeddings API)/v1/completions(Completions API)/v1/moderations(モデレーションガイド)/v1/images/generations(Images API)/v1/images/edits(Images API)
入力ファイルの各行の body フィールドには、対象のエンドポイントに直接リクエストを送る場合と同じパラメータを指定します。各リクエストには一意の custom_id 値が必要です。この値を使って、処理の完了後に対応する結果を参照できます。以下は 2 件のリクエストを含む入力ファイルの例です。1 つの入力ファイルで指定できるモデルは 1 つだけです。
/v1/moderations を使う場合は、すべてのリクエストの本文に input フィールドを含めてください。Batch API では、omni-moderation-latest を使って、プレーンテキストのほか、テキストや画像を含むコンテンツ配列を入力できます。同期モデレーションエンドポイントと同様に、バッチワーカーは stream=true を指定したリクエストを拒否します。
{"custom_id": "request-1", "method": "POST", "url": "/v1/responses", "body": {"model": "gpt-6-luna", "input": "Reply with the word blue.", "reasoning": {"effort": "none"}, "max_output_tokens": 64}}
{"custom_id": "request-2", "method": "POST", "url": "/v1/responses", "body": {"model": "gpt-6-luna", "input": "Reply with the word green.", "reasoning": {"effort": "none"}, "max_output_tokens": 64}}
モデレーションの入力例
テキストのみのリクエスト例です。
{
"custom_id": "moderation-text-1",
"method": "POST",
"url": "/v1/moderations",
"body": {
"model": "omni-moderation-latest",
"input": "This is a harmless test sentence."
}
}
テキストと画像を入力するリクエスト例です。
{
"custom_id": "moderation-mm-1",
"method": "POST",
"url": "/v1/moderations",
"body": {
"model": "omni-moderation-latest",
"input": [
{
"type": "text",
"text": "Describe this image"
},
{
"type": "image_url",
"image_url": {
"url": "https://api.nga.gov/iiif/a2e6da57-3cd1-4235-b20e-95dcaefed6c8/full/!800,800/0/default.jpg"
}
}
]
}
}
特にマルチモーダルなモデレーションリクエストでは、base64 形式のデータを埋め込む代わりに、image_url でリモートの画像を参照することをおすすめします。これにより、.jsonl ファイルのサイズをバッチのアップロード上限である 200 MB より十分小さく抑えられます。
2. バッチ入力ファイルのアップロード
Fine-tuning API と同様に、バッチの開始時に入力ファイルを参照できるよう、事前にアップロードする必要があります。.jsonl ファイルは Files API を使ってアップロードします。
import fs from "fs";
import OpenAI from "openai";
const openai = new OpenAI();
const file = await openai.files.create({
file: fs.createReadStream("fixtures/batchinput.jsonl"),
purpose: "batch",
});
console.log(file);3. バッチの作成
入力ファイルのアップロードが完了したら、その File オブジェクトの ID を使ってバッチを作成できます。ここでは、ファイル ID を file-abc123 とします。現在、完了までの制限時間に指定できる値は 24h のみです。任意の metadata パラメータを使って、独自のメタデータを追加することもできます。
import OpenAI from "openai";
const openai = new OpenAI();
const batch = await openai.batches.create({
input_file_id: "file-abc123",
endpoint: "/v1/responses",
completion_window: "24h",
});
console.log(batch);このリクエストは、バッチのメタデータを含む Batch オブジェクトを返します。
{
"id": "batch_abc123",
"object": "batch",
"endpoint": "/v1/responses",
"errors": null,
"input_file_id": "file-abc123",
"completion_window": "24h",
"status": "validating",
"output_file_id": null,
"error_file_id": null,
"created_at": 1714508499,
"in_progress_at": null,
"expires_at": 1714536634,
"completed_at": null,
"failed_at": null,
"expired_at": null,
"request_counts": {
"total": 0,
"completed": 0,
"failed": 0
},
"metadata": null
}
4. バッチのステータス確認
バッチのステータスはいつでも確認できます。このリクエストも Batch オブジェクトを返します。
import OpenAI from "openai";
const openai = new OpenAI();
const batch = await openai.batches.retrieve("batch_abc123");
console.log(batch);Batch オブジェクトのステータスは次のいずれかです。
| ステータス | 説明 |
|---|---|
validating |
バッチを開始する前に、入力ファイルを検証しています。 |
failed |
入力ファイルの検証に失敗しました。 |
in_progress |
入力ファイルの検証に成功し、バッチを実行しています。 |
finalizing |
バッチの実行が完了し、結果を準備しています。 |
completed |
バッチが完了し、結果を取得できます。 |
expired |
バッチが 24 時間以内に完了しませんでした。 |
cancelling |
バッチのキャンセル処理中です(最大 10 分かかります)。 |
cancelled |
バッチはキャンセルされました。 |
5. 結果の取得
バッチが完了したら、Files API に Batch オブジェクトの output_file_id フィールドの値を指定して、出力をダウンロードできます。ダウンロードした内容をローカルファイルに保存します。この例では batch_output.jsonl に保存します。
import OpenAI from "openai";
const openai = new OpenAI();
const fileResponse = await openai.files.content("file-xyz123");
const fileContents = await fileResponse.text();
console.log(fileContents);出力の .jsonl ファイルには、入力ファイルのうち処理に成功したリクエストごとに、応答が 1 行ずつ記録されます。失敗したリクエストのエラー情報はエラーファイルに記録されます。このファイルはバッチの error_file_id で参照できます。
出力の行順は、入力の行順と一致しない場合があります。結果を処理する際は、行順に頼らず、出力ファイルの各行に含まれる custom_id フィールドを使って、入力のリクエストと出力の結果を対応付けてください。
次の出力例では、リクエストと結果の ID の対応関係と生成されたテキストを示すため、一部の項目を省略しています。各メッセージの output_text の内容は、response.body.output から読み取ってください。
{"id": "batch_req_2", "custom_id": "request-2", "response": {"status_code": 200, "request_id": "req_2", "body": {"id": "resp_2", "object": "response", "status": "completed", "output": [{"type": "message", "role": "assistant", "content": [{"type": "output_text", "text": "green"}]}]}}, "error": null}
{"id": "batch_req_1", "custom_id": "request-1", "response": {"status_code": 200, "request_id": "req_1", "body": {"id": "resp_1", "object": "response", "status": "completed", "output": [{"type": "message", "role": "assistant", "content": [{"type": "output_text", "text": "blue"}]}]}}, "error": null}
出力ファイルは、バッチの完了から 30 日後に自動的に削除されます。
6. バッチのキャンセル
必要に応じて、実行中のバッチをキャンセルできます。バッチのステータスは cancelling に変わり、処理中のリクエストが完了するまでその状態が続きます(最大 10 分)。その後、ステータスは cancelled に変わります。
import OpenAI from "openai";
const openai = new OpenAI();
const batch = await openai.batches.cancel("batch_abc123");
console.log(batch);7. すべてのバッチの一覧取得
作成したバッチの一覧はいつでも取得できます。バッチが多い場合は、limit パラメータと after パラメータを使って結果をページ単位で取得できます。
import OpenAI from "openai";
const openai = new OpenAI();
const list = await openai.batches.list();
for await (const batch of list) {
console.log(batch);
}対応モデル
ほとんどのモデルが Batch API に対応しています。利用するモデルの対応状況はモデルリファレンスで確認してください。GPT-6 Sol と Luna は、Standard、Flex、Batch の各処理方式で EU のデータレジデンシーに対応しています。詳しくはデータレジデンシーの対象モデルと機能をご覧ください。
GPT Image 2.5 では、gpt-image-2.5-flare と gpt-image-2.5-sunburst で画像生成と編集をバッチ処理できます。両モデルの 2026-09-08 スナップショットも対応しています。/v1/images/generations または /v1/images/edits を使用してください。バッチ処理の料金は画像生成の料金をご覧ください。
レート制限
Batch API のレート制限は、既存のモデル別レート制限とは別枠です。Batch API には次の 3 種類のレート制限があります。
- バッチごとの上限:1 つのバッチに含められるリクエストは最大 50,000 件で、バッチ入力ファイルのサイズは最大 200 MB です。また、
/v1/embeddingsのバッチでは、埋め込みの入力数にも上限があり、バッチ内の全リクエストの合計で最大 50,000 件です。 - モデルごとのキュー内のプロンプトトークン数:バッチ処理のキューに入れられるプロンプトトークン数には、モデルごとに上限があります。各モデルの上限はプラットフォームの設定ページで確認できます。
- バッチ作成のレート制限:1 時間あたり最大 2,000 件のバッチを作成できます。さらに多くのリクエストを送信するには、バッチあたりのリクエスト数を増やしてください。
現在、Batch API には出力トークン数の上限はありません。Batch API には専用のレート制限が設けられているため、Batch API を使用しても、標準のモデル別レート制限のトークン枠は消費されません。そのため、API に送信できるリクエスト数と処理できるトークン数を手軽に増やせます。
バッチの期限切れ
期限内に完了しなかったバッチのステータスは expired に変わります。そのバッチ内の未完了のリクエストはキャンセルされますが、完了したリクエストの応答はバッチの出力ファイルから取得できます。完了したリクエストで消費されたトークンには料金がかかります。
期限切れになったリクエストは、次のメッセージとともにエラーファイルに記録されます。custom_id を使って、期限切れになったリクエストのデータを取得できます。
{"id": "batch_req_123", "custom_id": "request-3", "response": null, "error": {"code": "batch_expired", "message": "This request could not be executed before the completion window expired."}}
{"id": "batch_req_123", "custom_id": "request-7", "response": null, "error": {"code": "batch_expired", "message": "This request could not be executed before the completion window expired."}}