现场是这样的。批量跑批的文件上传时沿用了微调脚本里的 purpose=fine-tune,文件本身传上去了,创建 batch 时却报 invalid purpose for batch,bytes 和行数都对得上。

中间走过弯路,把「assistants 检索用的文件要选 assistants,混用会被检索接口拒绝」当成主因,改完现象没变。

这类报错背后常见的原因有几处,逐个排除就行。purpose 决定文件用途,batch 必须传 batch,微调才是 fine-tune;一个文件只能绑定一种用途,传错只能重新上传一份;旧版 SDK 把 purpose 默认成 fine-tune,代码没显式传也会写错。

先查已上传文件的 purpose 与大小

curl -s https://api.openai.com/v1/files/file-abc -H "Authorization: Bearer $OPENAI_API_KEY" | jq '.purpose,.bytes'

再往下用 batch 用途重新上传同一份文件

curl https://api.openai.com/v1/files -H "Authorization: Bearer $OPENAI_API_KEY" -F purpose=batch -F file=@batch.jsonl

接着按用途过滤确认新文件已就位

curl -s "https://api.openai.com/v1/files?purpose=batch" -H "Authorization: Bearer $OPENAI_API_KEY" | jq -r '.data[0].id'

等前面都确认过,再把 purpose 改成脚本参数避免复制粘贴带上旧值

python -c "import sys;print(sys.argv[1] if len(sys.argv)>1 else 'batch')" batch

别只看报错消失,验证要多做一步。文件详情里 purpose 是 batch,用这个 id 创建批次返回 200 并进入 validating,日志里不再出现 invalid purpose。

这里还有个坑。purpose 是上传时就固化在文件上的属性,不能事后修改,报错时重新传一份比去找转换接口快。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。

作者 9823189