Batch API 适合评测、分类、嵌入、批量摘要和其他离线任务,不适合聊天、实时搜索或必须立即返回的请求。当前官方说明它相对同步 API 提供 50% 成本折扣、使用独立限额池,并在 24 小时完成窗口内处理;是否支持具体模型与端点,提交前仍要查模型文档。
官方资料(2026-10-29 核对):Batch API 指南 · Create batch API Reference · Batch API FAQ · API Pricing
Batch API 与同步请求有什么区别?
| 维度 | Batch API | 同步 API |
|---|---|---|
| 返回方式 | 异步,完成后下载输出文件 | 当前连接直接返回或流式返回 |
| 完成时间 | 当前仅支持 24h completion_window | 单次请求等待响应 |
| 成本 | 官方当前说明相对同步 API 折扣 50% | 按所选模型的同步价格计费 |
| 限额 | 独立 Batch 限额池与排队 Token 限制 | 普通模型 RPM、TPM 等限制 |
| Streaming | 不支持 | 取决于端点与模型 |
| 适用场景 | 评测、分类、离线生成、批量嵌入 | 聊天、交互功能、即时工作流 |
完整流程:从 JSONL 到结果文件
- 选定端点与模型:确认模型支持 Batch;一个输入文件只放同一端点和同一模型的请求。
- 生成 JSONL:每一行都是独立 JSON 对象,包含唯一
custom_id、method、url和body。 - 上传文件:通过 Files API 上传,
purpose必须是batch。 - 创建批次:传入
input_file_id、统一端点和当前唯一支持的24hcompletion window。 - 轮询状态:记录 batch ID,等待
completed;不要用浏览器连接一直等待。 - 下载结果:成功行在
output_file_id,失败行在error_file_id;按custom_id与原任务对齐。
第 1 步:正确准备 JSONL
JSONL 不是一个 JSON 数组,而是“一行一个 JSON 对象”。下面示例使用 Responses API;把占位模型替换成模型文档明确支持 Batch 的当前模型。
{"custom_id":"job-0001","method":"POST","url":"/v1/responses","body":{"model":"YOUR_BATCH_SUPPORTED_MODEL","input":"把这条反馈归类为 positive、neutral 或 negative"}}
{"custom_id":"job-0002","method":"POST","url":"/v1/responses","body":{"model":"YOUR_BATCH_SUPPORTED_MODEL","input":"用一句话总结这段产品评价"}}custom_id在整个输入文件中必须唯一,建议直接使用数据库主键或不可变 Job ID。- 每一行的
url必须与创建 Batch 时的endpoint一致,否则可能出现 prefix-match 错误。 - 不要设置
stream:true;Batch 不支持流式返回。 - 先用 2~10 条测试文件验证格式,再生成大文件,避免整批在 validating 阶段失败。
第 2 步:上传文件并创建 Batch
# 1. 上传 JSONL,purpose 必须为 batch
curl https://api.openai.com/v1/files \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-F purpose="batch" \
-F file="@batch_input.jsonl"
# 2. 使用返回的 file ID 创建 Batch
curl https://api.openai.com/v1/batches \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"input_file_id": "file_REPLACE_ME",
"endpoint": "/v1/responses",
"completion_window": "24h"
}'API Key 只能保存在服务端环境变量或受控 Secret 中。后台批处理建议使用项目级 Service Account,并限制它只拥有任务需要的权限。
第 3 步:查询状态与下载输出
创建后保存 batch_id。查询 GET /v1/batches/{batch_id},直到状态进入终态。不要假设所有任务都会成功,也不要只检查批次是否 completed。
| 状态 | 含义 | 操作 |
|---|---|---|
| validating | 正在校验输入文件 | 等待;失败时查看 errors 中的行号和参数 |
| failed | 文件校验未通过 | 修正 JSONL 后重新创建,不应盲目轮询 |
| in_progress | 正在处理 | 按合理间隔轮询,避免高频请求 |
| finalizing | 正在整理结果文件 | 继续等待 output_file_id |
| completed | 批次处理完成 | 同时下载输出与错误文件并核对计数 |
| expired | 未在完成窗口内完成 | 保存已完成结果,仅重提未完成 custom_id |
| cancelling / cancelled | 正在取消或已取消 | 下载已完成结果,不要重复提交成功任务 |
# 查询状态
curl https://api.openai.com/v1/batches/batch_REPLACE_ME \
-H "Authorization: Bearer $OPENAI_API_KEY"
# 下载成功结果
curl https://api.openai.com/v1/files/file_OUTPUT_ID/content \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-o batch_output.jsonl
为什么必须按 custom_id 合并结果?
官方明确说明输出行顺序可能与输入顺序不同。成功请求写入输出文件,失败请求写入错误文件;因此应把 custom_id 作为幂等主键,把每条任务状态更新为 success、retryable_error 或 permanent_error。
处理程序还应核对 request_counts.total、completed 与 failed,并保存错误码。只把明确可恢复的失败重新生成新 Batch,避免把已成功任务再次收费执行。
限制、价格与“省 50%”的边界
- 当前单个输入文件最多 50,000 条请求、最大 200 MB。
- Embeddings 还限制单批所有请求合计最多 50,000 个 embedding inputs。
- Batch 的排队 Prompt Token 上限按模型和使用层级变化,应查看 Platform Limits 页面,不要把别人的数值当成自己的额度。
- 官方当前说明相对同步 API 提供 50% 折扣;总费用仍取决于模型、输入/输出 Token、成功数量和重跑。
- 已完成请求会计费。Batch 过期或手动取消,不代表所有费用撤销。
上线前先用OpenAI API Usage建立同步任务的 Token 与成本基线,再比较同一数据集的 Batch 费用。价格会调整,不要在业务代码中写死网页价格。
常见失败与修复
| 现象 | 常见原因 | 处理 |
|---|---|---|
| validating 后 failed | JSONL 不是一行一对象、字段缺失或参数非法 | 读取 errors 的 line 与 message,先用小文件重现 |
| URL does not prefix-match | 行内 url 与创建时 endpoint 不一致 | 统一 endpoint 和每行 url |
| 部分请求失败 | 单行输入、模型参数或内容问题 | 读取 error_file_id,只重做失败 custom_id |
| 一直 in_progress | 任务仍在 24 小时窗口内或排队 Token 较多 | 降低轮询频率;到期后按 expired 结果处理 |
| 找不到 Batch 或文件 | Project、Organization 或 Key 不一致 | 核对资源创建时的 Project 与当前身份 |
| 同步 429 仍存在 | Batch 仅使用独立限额池,不会修改同步调用限制 | 同步请求继续按429 限流指南处理 |
数据保留与安全注意事项
OpenAI 当前帮助文档说明 Zero Data Retention 不适用于 Batch API。输入、输出、错误和中间文件按 Batch、File Service 与相关保留政策处理。涉及个人信息、客户数据或受监管内容时,先确认组织合同、数据驻留、保留与删除要求,再决定是否使用 Batch。
- 不要把 API Key、Authorization 头或其他 Secret 写入 JSONL。
- 输入文件只包含任务必需字段,并在上传前完成脱敏。
- 保存 Batch ID、input/output/error file ID、Project、模型、创建时间和数据版本。
- 下载结果后按内部政策保存或删除,不要依赖第三方文件永久存在。
生产上线检查清单
- 使用小批次验证 JSONL、模型、端点与输出解析。
- 给每条任务分配稳定且唯一的 custom_id。
- 服务端安全存放 Key,必要时使用受限 Service Account。
- 设置低频状态轮询与 24 小时后的 expired 处理。
- 同时读取 output_file_id 和 error_file_id。
- 用 custom_id 去重,只重提未完成或可恢复失败。
- 记录 Usage、成本和失败率,建立同步 API 对照基线。
- 确认 Batch 的数据保留政策符合业务要求。
如果当前账号和事件类型支持 Webhook,可参考 OpenAI Webhooks 验签、去重与重试指南搭建接收端;Batch 的结果文件、custom_id 与部分失败处理仍按本页执行。
提交前审核输入、结果文件落地后审核输出,并明确失败任务如何转人工;实现细节见 OpenAI Moderation API 指南。
purpose、到期、file_id、下载与删除规则见 OpenAI Files API 指南;Batch 仍需遵守 JSONL 和 200 MB 限制。
常见问题
OpenAI Batch API 是什么?
它把多条 API 请求写入 JSONL 文件后异步处理,适合评测、分类、嵌入、批量摘要等不要求即时返回的任务。当前官方说明采用独立限额池,并在 24 小时完成窗口内处理。
Batch API 一定比同步 API 便宜吗?
官方当前说明 Batch 相对同步 API 提供 50% 成本折扣,但实际总成本仍取决于所选模型、输入和输出 Token、失败重跑及图片或视频等资源。提交前应查看当日官方定价页。
Batch API 可以实时流式返回吗?
不可以。Batch 是异步处理,官方明确说明不支持 streaming。应轮询 Batch 状态,完成后通过 output_file_id 下载成功结果,并通过 error_file_id 检查失败请求。
Batch JSONL 的结果顺序和输入顺序一致吗?
不保证一致。每行必须使用唯一 custom_id,下载结果后按 custom_id 与原始任务关联,不能依赖行号或返回顺序。
一个 Batch 最多可以放多少请求?
当前 API 参考说明单个输入文件最多 50,000 条请求且不超过 200 MB;Embeddings 还限制所有请求合计最多 50,000 个 embedding inputs。账户可排队 Token 上限应以 Platform Limits 页面为准。
Batch 超过 24 小时或被取消会怎样?
未在窗口内完成的批次会进入 expired;未完成请求被取消,已完成结果仍可下载,并按已完成工作计费。手动取消同样会返回已经完成的结果,已完成部分仍计费。
Zero Data Retention 适用于 Batch API 吗?
OpenAI 当前帮助文档说明 ZDR 不适用于 Batch API。输入、输出、错误和中间文件按 Batch 与 File Service 的保留政策处理;涉及敏感数据时必须先核对组织的数据要求。
端点选择:Batch 输入可以调用受支持的 Responses 或 Chat Completions 端点;两者的请求体和结果形状不同,批量改造前先查看 Responses API 与 Chat Completions 区别。
模型、维度、输入限制和向量检索流程见 OpenAI Embeddings API 教程。