登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  科技周边 >  人工智能

Batch API 怎样提交离线任务

来源:17golang原创

时间:2026-10-25 12:04:26 126浏览 收藏

我第一次把一批不需要即时返回的文本任务从同步接口改成 Batch API 时,真正容易出错的不是“异步”两个字,而是把请求集合、输入文件和 Batch 任务混成了一个对象。正确做法是:先按 JSONL 每行一个请求准备输入文件,再用 Files API 上传,最后用返回的文件 ID 创建 Batch。

官方地址:https://platform.openai.com/docs/guides/batch

Batch API 适合评测、批量分类、批量生成嵌入等不要求立即返回的任务。它的入口顺序固定为“JSONL → purpose=batch 文件 → Batch → output_file_id”,不要把它当成一次普通的同步请求。

先看清这次能力变化

Batch API 把一组请求放进一个 JSONL 文件,任务提交后在后台处理。官方文档当前列出的 endpoint 包括 Responses、Chat Completions、Embeddings、Completions、Moderations,以及图像生成和编辑接口;同一个输入文件中的请求应面向同一个模型。它提供独立的批处理限额,完成窗口当前使用 24h,适合能容忍延迟的工作。

这和同步调用的关键差别是返回时机,而不是请求体被“批量改写”。每行的 body 仍然使用对应 endpoint 的参数,custom_id 则负责把最终结果认回原始任务。

准备 JSONL:一行就是一个请求

先写一个 batchinput.jsonl。下面只放两个 Chat Completions 请求,字段保持严格 JSON,不在其中加入注释;custom_id 要在这份文件里唯一,后续处理输出时就用它做关联键。

{"custom_id":"summary-001","method":"POST","url":"/v1/chat/completions","body":{"model":"gpt-6-sol","messages":[{"role":"user","content":"把这段会议纪要整理成三条要点"}],"max_tokens":300}}
{"custom_id":"summary-002","method":"POST","url":"/v1/chat/completions","body":{"model":"gpt-6-sol","messages":[{"role":"user","content":"把这段产品反馈归纳成问题清单"}],"max_tokens":300}}

每行包含四个核心部分:唯一标识 custom_id、请求方法 method、目标 url 和透传给目标接口的 body。如果你的任务换成 Embeddings,就让每行的 url 和 body 都切换到 Embeddings 的形态,不要在同一个输入文件里混用不同模型。

上传文件,再创建离线任务

上传阶段的目的不是立即执行请求,而是取得可供 Batch 引用的文件对象。Python SDK 的最小骨架如下;示例中的文件关闭交给 with,异常则交给调用方处理,避免把一个失败的上传误判成任务已创建。

from openai import OpenAI

client = OpenAI()

with open("batchinput.jsonl", "rb") as batch_file:
    # purpose=batch 表示该文件会作为 Batch API 的输入。
    input_file = client.files.create(file=batch_file, purpose="batch")

# 只把上传返回的文件 ID 交给 Batch,不把本地路径当作 input_file_id。
batch = client.batches.create(
    input_file_id=input_file.id,
    endpoint="/v1/chat/completions",
    completion_window="24h",
)

print(batch.id)

这里最容易写错的是三个值:input_file_id 必须使用上传结果里的 ID;endpoint 必须和 JSONL 每行的 url 对应;completion_window 当前按官方接口使用 24h。创建成功后,状态通常会从 validating 开始。

Batch API 输入文件、上传文件和离线任务之间的静态关系说明图
图1:Batch 输入装配结构说明图,展示 JSONL 请求、purpose=batch 文件和 Batch 任务之间的关系;这是说明图,不是运行截图。

状态完成后,按文件 ID 取结果

提交后不要用创建接口的返回值猜测最终答案,而是根据任务状态处理。validating 表示输入还在校验,in_progress 表示正在执行,finalizing 表示结果整理中,completed 才表示结果文件可取。若状态为 failed、expired 或 cancelled,先读取任务对象中的错误信息或错误文件,再决定如何修复输入。

from openai import OpenAI

client = OpenAI()
batch = client.batches.retrieve("batch_abc123")

if batch.status == "completed":
    # output_file_id 指向结果文件,不能拿 input_file_id 代替。
    result_file = client.files.content(batch.output_file_id)
    with open("batch_output.jsonl", "wb") as output:
        # 结果文件按行保存,后续用 custom_id 关联业务记录。
        output.write(result_file.read())
else:
    print(f"当前状态:{batch.status}")

结果行不保证按输入文件的原顺序返回,所以业务层应读取每行的 custom_id,再写回自己的任务表。这样即使输入顺序和完成顺序不同,也不会把一个客户的结果写到另一个任务上。

Batch API 状态对象、输出文件和错误文件之间的静态关系说明图
图2:Batch 状态与结果文件说明图,展示状态对象、output_file_id、错误文件和 custom_id 的静态关系;这是说明图,不是运行截图。

我的最小迁移清单

  • 能延迟返回的任务才放入 Batch;需要用户马上看到结果的请求继续使用同步接口。
  • 每个 custom_id 都绑定一条业务记录,输出处理不要依赖行号。
  • 创建前确认 JSONL 的 url、body.model 与 Batch 的 endpoint 一致。
  • 把 failed、expired 和单行错误分开记录,不要只保存一个“批次失败”字符串。

相关问题

Batch API 能不能混用多个模型? 同一个输入文件按官方说明只面向一个模型;需要不同模型时拆成不同输入文件和 Batch。

为什么创建后还没有 output_file_id? 任务仍处于校验、执行或整理阶段,等状态变为 completed 再取结果。

离线任务过期怎么办? 读取错误文件定位未完成的 custom_id,缩小任务或修正输入后重新提交新的批次。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>