OpenAI Batch API

2026-11-09 13:38 更新

Batch API将请求异步成组处理,来源说明相对同步API费用降低50%、使用独立且更高的限额池,并有24小时完成窗口,适合无需立即回应的作业。接口见Batch参考。

概览

评测、大型数据分类、内容库嵌入等任务不一定需要同步响应,或受同步速率限制约束。Batch流程是收集请求文件、启动作业、查询状态、完成后取回结果。相比标准同步端点,它有50%价格折扣、独立容量空间,通常可在24小时内完成;未完成部分按后文过期流程处理。

开始使用

1. 准备批处理文件

使用.jsonl,每行一条请求。目前支持/v1/responses、/v1/chat/completions、/v1/embeddings、/v1/completions、/v1/moderations、/v1/images/generations和/v1/images/edits。行内body参数与目标端点相同,每条请求必须有唯一custom_id用于关联结果;一个输入文件只能请求单个模型。

Moderations每条body必须有input,使用omni-moderation-latest支持纯文本及含文本/图像的内容数组;不接受stream:true。

来源示例 1(jsonl):

JSONL每个非空行是独立JSON对象,不能把多行整体当成单个JSON文档;保留custom_id以关联批处理输入和结果。

{"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}}

审核输入示例

纯文本:

来源示例 2(jsonl):

来源围栏标为JSONL,但本块是格式化展示的单个JSON对象。实际JSONL文件需每条记录占一行;按custom_id关联请求。

{
  "custom_id": "moderation-text-1",
  "method": "POST",
  "url": "/v1/moderations",
  "body": {
    "model": "omni-moderation-latest",
    "input": "This is a harmless test sentence."
  }
}

文本与图像:

来源示例 3(jsonl):

来源围栏标为JSONL,但本块是格式化展示的单个JSON对象。实际JSONL文件需每条记录占一行;按custom_id关联请求。

{
  "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"
        }
      }
    ]
  }
}

多模态审核应尽量用image_url引用远程素材,避免大段Base64使JSONL接近200MB上传上限。

2. 上传批处理输入文件

与模型优化流程类似,先用Files API上传JSONL,再引用文件ID。

来源示例 4(javascript):

// [中文] 以purpose=batch上传JSONL文件,供后续批处理引用;文件必须预先准备。
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);

来源示例 5(python):

## [中文] 以purpose=batch上传JSONL文件,供后续批处理引用;文件必须预先准备。
from openai import OpenAI

client = OpenAI()

batch_input_file = client.files.create(
    file=open("batchinput.jsonl", "rb"), purpose="batch"
)

print(batch_input_file)

来源示例 6(go):

// [中文] 以purpose=batch上传JSONL文件,供后续批处理引用;文件必须预先准备。
package main

import (
    "context"
    "fmt"
    "os"

    "github.com/openai/openai-go/v3"
)

func main() {
    client := openai.NewClient()
    file, err := os.Open("batchinput.jsonl")
    if err != nil {
        panic(err)
    }
    defer file.Close()

    uploaded, err := client.Files.New(context.Background(), openai.FileNewParams{
        File:    file,
        Purpose: openai.FilePurposeBatch,
    })
    if err != nil {
        panic(err)
    }
    fmt.Println(uploaded.ID)
}

来源示例 7(java):

// [中文] 以purpose=batch上传JSONL文件,供后续批处理引用;文件必须预先准备。
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.files.FileCreateParams;
import com.openai.models.files.FilePurpose;
import java.nio.file.Path;

var file =
    client
        .files()
        .create(
            FileCreateParams.builder()
                .file(Path.of(System.getenv("OPENAI_EXAMPLE_FILE_PATH")))
                .purpose(FilePurpose.BATCH)
                .build());

System.out.println(file.id());

来源示例 8(ruby):

## [中文] 以purpose=batch上传JSONL文件,供后续批处理引用;文件必须预先准备。
require "openai"
require "pathname"

client = OpenAI::Client.new
file = Pathname("batchinput.jsonl")
uploaded = client.files.create(file: file, purpose: :batch)
puts(uploaded.id)

来源示例 9(bash):

## [中文] 以purpose=batch上传JSONL文件,供后续批处理引用;文件必须预先准备。
curl https://api.openai.com/v1/files \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -F purpose="batch" \
  -F file="@batchinput.jsonl"

来源示例 10(bash):

## [中文] 以purpose=batch上传JSONL文件,供后续批处理引用;文件必须预先准备。
openai files create \
  --file batchinput.jsonl \
  --purpose batch

3. 创建批处理

上传成功后用输入文件ID创建Batch,来源示例ID为file-abc123。completion_window目前只能设24h,可选metadata保存自定义元数据。

来源示例 11(javascript):

// [中文] 用上传文件ID创建Batch,completion_window为24h,endpoint与文件中请求一致。
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);

来源示例 12(python):

## [中文] 用上传文件ID创建Batch,completion_window为24h,endpoint与文件中请求一致。
batch = client.batches.create(
    input_file_id=batch_input_file.id,
    endpoint="/v1/responses",
    completion_window="24h",
    metadata={"description": "nightly eval job"},
)
print(batch)

来源示例 13(go):

// [中文] 用上传文件ID创建Batch,completion_window为24h,endpoint与文件中请求一致。
package main

import (
    "context"
    "fmt"

    "github.com/openai/openai-go/v3"
)

func main() {
    client := openai.NewClient()
    batch, err := client.Batches.New(context.Background(), openai.BatchNewParams{
        InputFileID:      "file-abc123",
        Endpoint:         openai.BatchNewParamsEndpointV1Responses,
        CompletionWindow: openai.BatchNewParamsCompletionWindow24h,
    })
    if err != nil {
        panic(err)
    }
    fmt.Println(batch.ID)
}

来源示例 14(java):

// [中文] 用上传文件ID创建Batch,completion_window为24h,endpoint与文件中请求一致。
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.batches.BatchCreateParams;

String fileId = "file-abc123";

var batch =
    client
        .batches()
        .create(
            BatchCreateParams.builder()
                .inputFileId(fileId)
                .endpoint(BatchCreateParams.Endpoint.V1_RESPONSES)
                .completionWindow(BatchCreateParams.CompletionWindow._24H)
                .build());

System.out.println(batch.id());

来源示例 15(ruby):

## [中文] 用上传文件ID创建Batch,completion_window为24h,endpoint与文件中请求一致。
require "openai"

client = OpenAI::Client.new
batch = client.batches.create(input_file_id: "file-abc123", endpoint: "/v1/responses", completion_window: "24h")
puts(batch.id)

来源示例 16(bash):

## [中文] 用上传文件ID创建Batch,completion_window为24h,endpoint与文件中请求一致。
curl https://api.openai.com/v1/batches \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input_file_id": "file-abc123",
    "endpoint": "/v1/responses",
    "completion_window": "24h"
  }'

来源示例 17(bash):

## [中文] 用上传文件ID创建Batch,completion_window为24h,endpoint与文件中请求一致。
openai batches create \
  --input-file-id file-abc123 \
  --endpoint /v1/responses \
  --completion-window 24h

返回Batch对象:

来源示例 18(json):

Batch对象展示状态、输入及结果/错误文件ID等元数据;按状态和各请求结果分别判断完成情况。

{
  "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对象:

来源示例 19(javascript):

// [中文] 按Batch ID获取当前状态,不将已结束一概当成全部请求成功。
import OpenAI from "openai";
const openai = new OpenAI();

const batch = await openai.batches.retrieve("batch_abc123");
console.log(batch);

来源示例 20(python):

## [中文] 按Batch ID获取当前状态,不将已结束一概当成全部请求成功。
batch = client.batches.retrieve(batch.id)
print(batch)

来源示例 21(go):

// [中文] 按Batch ID获取当前状态,不将已结束一概当成全部请求成功。
package main

import (
    "context"
    "fmt"

    "github.com/openai/openai-go/v3"
)

func main() {
    client := openai.NewClient()
    batch, err := client.Batches.Get(context.Background(), "batch_abc123")
    if err != nil {
        panic(err)
    }
    fmt.Println(batch.Status)
}

来源示例 22(java):

// [中文] 按Batch ID获取当前状态,不将已结束一概当成全部请求成功。
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;

String batchId = "batch_abc123";

var batch = client.batches().retrieve(batchId);

System.out.println(batch.status());

来源示例 23(ruby):

## [中文] 按Batch ID获取当前状态,不将已结束一概当成全部请求成功。
require "openai"

client = OpenAI::Client.new
batch = client.batches.retrieve("batch_abc123")
puts(batch.status)

来源示例 24(bash):

## [中文] 按Batch ID获取当前状态,不将已结束一概当成全部请求成功。
curl https://api.openai.com/v1/batches/batch_abc123 \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json"

来源示例 25(bash):

## [中文] 按Batch ID获取当前状态,不将已结束一概当成全部请求成功。
openai batches retrieve \
  --batch-id batch_abc123

状态 含义
validating 启动前验证输入文件。
failed 输入验证失败。
in_progress 验证通过,正在执行。
finalizing 执行完成,正在准备结果。
completed 结果已准备好。
expired 未在24小时窗口内完成。
cancelling 正在取消,最多可能需10分钟。
cancelled 已取消。

5. 获取结果

完成后根据output_file_id调用Files API,将内容写入本地batch_output.jsonl:

来源示例 26(javascript):

// [中文] 按output_file_id下载结果;按custom_id关联输入输出,不依赖行顺序。
import OpenAI from "openai";
const openai = new OpenAI();

const fileResponse = await openai.files.content("file-xyz123");
const fileContents = await fileResponse.text();

console.log(fileContents);

来源示例 27(python):

## [中文] 按output_file_id下载结果;按custom_id关联输入输出,不依赖行顺序。
## Replace the illustrative IDs and URLs below with your own resource values.

from openai import OpenAI

output_file_id = "file_123"
client = OpenAI()

file_response = client.files.content(output_file_id)
print(file_response.text)

来源示例 28(go):

// [中文] 按output_file_id下载结果;按custom_id关联输入输出,不依赖行顺序。
package main

import (
    "context"
    "fmt"
    "io"

    "github.com/openai/openai-go/v3"
)

func main() {
    client := openai.NewClient()
    response, err := client.Files.Content(context.Background(), "file-xyz123")
    if err != nil {
        panic(err)
    }
    defer response.Body.Close()
    contents, err := io.ReadAll(response.Body)
    if err != nil {
        panic(err)
    }
    fmt.Println(string(contents))
}

来源示例 29(java):

// [中文] 按output_file_id下载结果;按custom_id关联输入输出,不依赖行顺序。
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.core.http.HttpResponse;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;

String fileId = "file-xyz123";

try (HttpResponse content = client.files().content(fileId)) {
  Files.copy(
      content.body(), Path.of("batch_output.jsonl"), StandardCopyOption.REPLACE_EXISTING);
}

来源示例 30(ruby):

## [中文] 按output_file_id下载结果;按custom_id关联输入输出,不依赖行顺序。
require "openai"

client = OpenAI::Client.new
content = client.files.content("file-xyz123")
puts(content.read)

来源示例 31(bash):

## [中文] 按output_file_id下载结果;按custom_id关联输入输出,不依赖行顺序。
curl https://api.openai.com/v1/files/file-xyz123/content \
  -H "Authorization: Bearer $OPENAI_API_KEY" > batch_output.jsonl

来源示例 32(bash):

## [中文] 按output_file_id下载结果;按custom_id关联输入输出,不依赖行顺序。
openai files content \
  --file-id file-xyz123 \
  --output batch_output.jsonl

成功的输入请求各有一条输出行;失败请求写入error_file_id对应的错误文件。输出顺序不保证与输入相同,应按custom_id关联,不能按行号配对。

以下输出仅展示请求 ID 对应关系及生成文本。请在 response.body.output 中读取各消息的 output_text 内容。

来源示例 33(jsonl):

JSONL每个非空行是独立JSON对象,不能把多行整体当成单个JSON文档;保留custom_id以关联批处理输入和结果。

{"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。

来源示例 34(javascript):

// [中文] 取消Batch后先进入cancelling,等待进行中请求结束。
import OpenAI from "openai";
const openai = new OpenAI();

const batch = await openai.batches.cancel("batch_abc123");
console.log(batch);

来源示例 35(python):

## [中文] 取消Batch后先进入cancelling,等待进行中请求结束。
## Replace the illustrative IDs and URLs below with your own resource values.

from openai import OpenAI

batch_id = "batch_123"
client = OpenAI()

client.batches.cancel(batch_id)

来源示例 36(go):

// [中文] 取消Batch后先进入cancelling,等待进行中请求结束。
package main

import (
    "context"
    "fmt"

    "github.com/openai/openai-go/v3"
)

func main() {
    client := openai.NewClient()
    batch, err := client.Batches.Cancel(context.Background(), "batch_abc123")
    if err != nil {
        panic(err)
    }
    fmt.Println(batch.Status)
}

来源示例 37(java):

// [中文] 取消Batch后先进入cancelling,等待进行中请求结束。
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;

String batchId = "batch_abc123";

System.out.println(client.batches().cancel(batchId).status());

来源示例 38(ruby):

## [中文] 取消Batch后先进入cancelling,等待进行中请求结束。
require "openai"

client = OpenAI::Client.new
batch = client.batches.cancel("batch_abc123")
puts(batch.status)

来源示例 39(bash):

## [中文] 取消Batch后先进入cancelling,等待进行中请求结束。
curl https://api.openai.com/v1/batches/batch_abc123/cancel \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -X POST

来源示例 40(bash):

## [中文] 取消Batch后先进入cancelling,等待进行中请求结束。
openai batches cancel \
  --batch-id batch_abc123

7. 列出全部批处理

可随时列举;数量多时用limit和after分页。

来源示例 41(javascript):

// [中文] 分页列出批处理任务;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);
}

来源示例 42(python):

## [中文] 分页列出批处理任务;limit和after控制列表范围。
from openai import OpenAI

client = OpenAI()

client.batches.list(limit=10)

来源示例 43(go):

// [中文] 分页列出批处理任务;limit和after控制列表范围。
package main

import (
    "context"
    "fmt"

    "github.com/openai/openai-go/v3"
)

func main() {
    client := openai.NewClient()
    list := client.Batches.ListAutoPaging(context.Background(), openai.BatchListParams{Limit: openai.Int(10)})
    for list.Next() {
        fmt.Println(list.Current().ID)
    }
    if err := list.Err(); err != nil {
        panic(err)
    }
}

来源示例 44(java):

// [中文] 分页列出批处理任务;limit和after控制列表范围。
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.batches.BatchListParams;

client
    .batches()
    .list(BatchListParams.builder().limit(10).build())
    .autoPager()
    .forEach(batch -> System.out.println(batch.id()));

来源示例 45(ruby):

## [中文] 分页列出批处理任务;limit和after控制列表范围。
require "openai"

client = OpenAI::Client.new
client.batches.list(limit: 10).auto_paging_each do |batch|
  puts(batch.id)
end

来源示例 46(bash):

## [中文] 分页列出批处理任务;limit和after控制列表范围。
curl https://api.openai.com/v1/batches?limit=10 \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json"

来源示例 47(bash):

## [中文] 分页列出批处理任务;limit和after控制列表范围。
openai batches list \
  --limit 10

模型可用性

多数模型支持Batch,仍应查看模型参考。GPT-6 Sol和Luna在Standard、Flex、Batch下支持欧盟驻留,见数据驻留资格。

GPT Image 2.5的gpt-image-2.5-flare、gpt-image-2.5-sunburst及其2026-09-08快照支持批量生成和编辑图像,分别使用图像生成/编辑端点;价格见Batch图像定价。

速率限制

Batch与同步模型限额独立,主要有三种限制:

  1. 单批最多50,000条请求,文件最大200MB;嵌入批处理所有请求合计最多50,000个嵌入输入。
  2. 各模型有待处理输入词元队列上限,见平台限制。
  3. 每小时最多创建2,000个批处理;需更多请求时可增加每批条数。

来源说明Batch目前没有输出词元限额;这不表示忽略单次模型自身输出限制。Batch独立池不会消耗标准同步模型速率配额。

批处理过期

超时后进入expired,未完成请求取消;已完成结果仍可通过输出文件获取,并按已完成请求消耗的词元计费。过期请求写入错误文件,可按custom_id查回输入:

来源示例 48(jsonl):

JSONL每个非空行是独立JSON对象,不能把多行整体当成单个JSON文档;保留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."}}
以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号