哪些任务应该进 Batch
我会先按用户期待分层。
| 层级 | 用户期待 | 示例 | 是否适合 Batch |
|---|---|---|---|
| 实时 | 当前页面马上要结果 | 聊天回复、搜索改写 | 不适合 |
| 短异步 | 几十秒内可接受 | 单篇文章摘要、一次质检 | 看体量 |
| 离线 | 几分钟到数小时可接受 | 批量标注、历史数据重算 | 适合 |
| 后台维护 | 用户不直接等待 | embedding 回补、分类迁移 | 适合 |
OpenAI 文档把 Batch API 定位为批处理接口,需要提交请求文件、创建 batch、查询状态、取回结果。它不是把普通 API 换个 endpoint 就完事,而是把产品交互从「立即返回」改成「任务生命周期」。
对独立开发者来说,Batch 的价值不是炫技,而是把低优先级、可延迟、可重跑的 AI 工作从高峰期挪走。
backlog 数据建模
我建议建一张 ai_jobs 表,字段少一点,但一定要能恢复。
| 字段 | 用途 |
|---|---|
job_id | 你自己的任务 id |
user_id | 归属用户 |
task_type | summarize、classify、extract |
priority | paid、trial、free、maintenance |
status | received、queued、submitted、running、succeeded、failed、partial |
provider_job_id | OpenAI batch id |
input_file_id | 提交文件 id |
attempt | 第几次提交 |
deadline_at | 用户承诺时间 |
error_summary | 给客服看的失败原因 |
不要只存 OpenAI 的 batch id。供应商 id 是外部状态,你自己的 job id 才是产品状态。将来换模型、拆供应商或回补任务时,这一点很救命。
状态机设计
给用户看的状态保持简单:
- 已接收:任务进了你的数据库。
- 排队中:还没提交给 OpenAI,等待凑批或额度窗口。
- 处理中:已提交 batch,等待结果。
- 已完成:结果可下载或已经写回产品。
- 部分失败:一部分行失败,用户可以下载成功部分。
- 失败:任务无法完成,需要用户修改或联系客服。
后台可以保留更细的 OpenAI 原始状态,但不要原样丢给用户。用户不关心 validating 和 finalizing 的区别,用户只关心「我什么时候能拿到结果」。
页面文案也要克制。不要承诺「马上完成」。我会写成:系统已接收,通常在低峰期处理;大文件和免费账户可能更慢。给一个刷新按钮和邮件通知,比让用户一直盯页面好。
重试和回补
Batch 失败分两类:提交前失败和提交后失败。
提交前失败通常是 JSONL、文件大小、请求格式或模型参数问题。这类不要自动重试,把验证器写好。每一行请求都要带 custom_id,方便结果回来后按行匹配。
提交后失败要看错误类型:
| 错误 | 动作 |
|---|---|
| 临时服务错误 | 退避后重新提交失败行 |
| 单行输入过长 | 切片或标记失败 |
| 参数不支持 | 修模板后重建 batch |
| 鉴权错误 | 暂停队列,通知管理员 |
| 部分行失败 | 成功部分先入库,失败部分进入回补 |
我不喜欢整批重跑。除非输入文件整体错误,否则只重跑失败行。这样既省钱,也避免用户看到重复结果。
成本和优先级控制
Batch 队列容易堆积,堆积后最容易做错两件事:给所有任务提优先级,或让所有任务无限等待。
我的优先级顺序是:
- 付费用户快到承诺时间的任务。
- 小体量、能快速完成的任务。
- 失败回补任务。
- 免费用户大批量任务。
- 后台维护任务。
每个用户要有每日离线额度。Batch 再适合离线,也不是无限资源。你还要记录估算 token、实际 token、失败重跑 token。否则月底只知道「账单变高了」,不知道是哪类任务造成的。
如果你同时用 OpenAI 和 Claude 做离线任务,可以把成本口径统一到多模型统一计费的 API 中转,尤其适合一人团队看余额、模型、重试和失败回补。关键是让每个 batch job 都能追到具体模型和具体用户。
用户预期管理
产品上要讲人话。
差的文案:任务已进入 Batch API,等待处理。
更好的文案:文件已接收,系统会在后台处理。你可以关闭页面,完成后会收到邮件;大文件可能需要更久,失败行会单独列出。
通知也要分层:
- 任务完成:给下载链接或跳回结果页。
- 部分失败:告诉用户成功多少、失败多少、失败原因分类。
- 完全失败:给下一步动作,例如缩小文件、修正字段、联系客服。
- 超过承诺时间:主动说明仍在排队,不要等用户来问。
这类体验细节,比你在后台把 batch 写得多漂亮更影响留存。
上线前检查清单
我的上线清单:
- JSONL 生成器有单元测试。
- 每行都有
custom_id。 - 任务状态能从任意中间状态恢复。
- 失败行可以单独重跑。
- 用户页面不暴露供应商原始错误。
- 免费和付费用户有不同优先级。
- 每个 batch job 有成本估算和实际成本。
- 超过 SLA 的任务会报警。
Batch 系统的难点不在提交 API,而在失败后能不能把账、数据和用户体验收回来。