
7 个 JSONL 文件、一个模型访问密钥,以及计算出来的 7.04 美元成本——这就是我们通过 DigitalOcean 统一的 批量推理(Batch Inference)API 对 25 万条真实消费者投诉进行分类和信息补充所需要的全部东西:为每条记录标记产品类别、分析情绪和紧急程度、提取实体、生成摘要,并在最后将每个答案与数据集自带的真实标签进行评分对比。如果使用完全相同的 Token 量、按无服务器推理(Serverless Inference)价格计算,成本则为 14.07 美元。我们分别使用 GPT-5 和 Claude 模型完整跑了一遍,并详细记录了整个过程中的经验和问题。
简而言之!批量推理(Batch Inference)这套逻辑站得住脚,封装层确实很薄——你发给无服务器推理的请求体原封不动变成 JSONL 文件里的一行,通过同一个基础 URL 和同一个密钥提交。全部 25 万个请求零失败完成,速度比我们预算的还快。不过有几个细节值得提前了解:同一个 API 上有三种不同的模型命名规范;账号层级限制可能低于文档说明值;两种容易忽略的静默失败模式;以及缓存的小字条款——我们的生产环境跑下来其实一点缓存都没用到。这篇文章会带你逐一搞清楚这些坑在哪。

你的无服务器推理(Serverless Inference)请求只需改一层包装和一个模型 ID,就能享受批量推理(Batch Inference)的价格。同一个基础 URL,同一个模型访问密钥;请求体其余部分完全不变。
本文会完整介绍整个任务流程,包括数据集、JSONL、文件切分、任务提交、状态轮询、结果评分和成本计算,然后再把 DigitalOcean 的批量推理(Batch Inference) 与 OpenAI、Anthropic 和 AWS Bedrock 各自的批量推理方案进行对比,并说明各自更具优势的地方。
核心内容摘要
- 25 万次请求被拆分成 7 个批量推理工作,全部完成且 0 失败;99.99% 的返回结果符合 JSON Schema,模型与数据集自带产品标签的一致性达到 83.6%。
- 最大的推理任务每个包含 40,000 次请求,完成时间为 1.4~2.2 小时,远低于 24 小时的 Completion Window。一个包含 25,000 次请求、使用 Claude 模型的批量推理任务只用了 17 分钟。
- 按公布价格计算,整个 25 万条记录跑下来批量推理成本为 7.04美元,同样 token 量无服务器推理为 14.07美元。DigitalOcean 批量推理定价最高可享无服务器推理定价五折。
-
- 你的请求体不用变,变的是包装层。跟无服务器推理使用同一个基础 URL、同一个模型访问密钥。但模型命名在无服务器推理、OpenAI 批量推理和 Anthropic 批量推理之间有三套不同规范,而且有两种失败模式是静默的。
- 在完全相同的记录上,Claude Haiku 4.5 的准确率比 GPT-5 Nano 高 1.26 个百分点(84.9% vs 83.6%,p<0.0001),但计算成本大约高 35 倍。一个塞入大量 Taxonomy 信息、更长的 Prompt 反而让准确率下降,而不是提升。无论升级模型还是加长 Prompt,花钱之前都应该先测试。
- OpenAI 和 Anthropic 模型的批量推理都支持 Prompt Caching,但不同模型都有最低可缓存 Prefix 长度:GPT-5 Nano 为 1,024 Token,Claude Haiku 4.5 为 4,096 Token。我们的生产 Prompt 只有 460 Token,低于最低要求,因此完全没有命中缓存;当 Prefix 超过最低要求后,我们实测 OpenAI 和 Anthropic 的缓存都能通过 DigitalOcean 正常生效。低于阈值时系统不会报错,只是什么都不会缓存;至于 Batch 中 Cached Token 的最终计费价格,我们无法通过当前账号确认。
- 开始使用批量推理还有一个前提:截至 2026 年 8 月我们的测试,Batch 只支持 OpenAI 和 Anthropic 商业模型,而且这些模型要求使用 Tier 3+ DigitalOcean 账号。Tier 1 和 Tier 2 账号无法访问 Anthropic 或 OpenAI 商业模型,文档明确的例外是开放权重 gpt-oss 模型。新注册DigitalOcean 的用户,如需使用商业模型,可直接联系卓普云开通权限。
- 本文所有实验都可以复现:测试 Harness、汇总数据和 Probe Notes 都已经开源在 github.com/bnarasimha21/technical-deep-dives 的
batch-inference/目录中。
本文中的测试方法
本文中所有可靠性、准确率、token 数和时间数据均来自我们自己的实测,执行时间为 2026 年 8 月 3 日至 13 日。这个时间点比通常更重要:平台行为在该窗口期内发生了变化(Anthropic 的模型 ID 规范和队列行为在我们两次测试日期之间都有变动),所以下面所有行为相关的结论都附带了观察日期。
文中的美元金额是计算结果,而不是实际账单金额:我们读取 API 自身 Usage 字段中的实际 Token 数,再乘以 DigitalOcean 官方公开价格,其中 Batch 最高比 Serverless 便宜 50%。我们的测试账号免计费,因此没有实际 Invoice 可以截图;所以本文直接展示计算过程,也不会声称我们在真实账单中亲眼看到了 50% 折扣。由于 Batch 官方价格本身就定义为 Serverless 官方价格的一半左右,因此“我们的测试成本低了 50%”只是数学计算,不是实验证据。真正由这次测试验证的是其他部分:Token 数是真实的、可靠性是真实的、耗时是真实的,而且整个 Pipeline 中没有因为 Failure、Retry 或 Partial Result 导致实际 Token 数超过估算。
还有三个限制需要提前说明。第一,缓存 token 在整个计算中按全额输入价格保守估算,因为 DigitalOcean 没有公布批量推理缓存计费价目表,所以所有缓存相关数字都是上限值。第二,我们最初的长提示词 vs 精简提示词对比方法有误(非配对,不同样本);文章中公布的是修正后的配对版本——同样 5000 条记录在两种提示词下跑,使用 McNemar 检验。第三,有几项发现是单次观测:一次取消探测、一个卡住的作业、一次 17 分钟的 Anthropic 周转。请把这些当作带时间戳的存在性证明,而非分布统计。
所有脚本和汇总数据都已经公开,你可以自行重新运行。本文引用的价格和限制信息采集于 2026 年 7 月 31 日到 8 月 13 日。如果你晚些时候才看到本文,在为自己的任务制定预算之前,请重新检查 DigitalOcean 最新的价格和文档,因为两者都可能发生变化。
从 Serverless 切换到 Batch:请求相同,只是外层封装不同
如果你已经通过 DigitalOcean 的无服务器推理(Serverless Inference)调用 OpenAI 或 Anthropic 模型,那么距离 Batch 基本只差一个文件格式。比如下面这个 Serverless 请求:
import requests
resp = requests.post(
"https://inference.do-ai.run/v1/chat/completions",
headers={"Authorization": f"Bearer {DO_MODEL_ACCESS_KEY}"},
json={
"model": "openai-gpt-5-nano", # serverless: DO catalog ID
"messages": [
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": f"Complaint:\n{narrative}"},
],
"response_format": {"type": "json_schema", "json_schema": TICKET_SCHEMA},
"max_completion_tokens": 1000,
"reasoning_effort": "minimal",
},
)
变成批量推理输入文件中的一行。请求体逐字节完全相同,只有模型 ID 变了——后面的经验总结第 1 条会详细解释:
{"custom_id": "main-9915470", "method": "POST", "url": "/v1/chat/completions",
"body": {"model": "gpt-5-nano", "messages": ["..."], "response_format": {"...": "..."},
"max_completion_tokens": 1000, "reasoning_effort": "minimal"}}
Base URL 相同,Model Access Key 相同。无论 OpenAI 还是 Anthropic 模型,都通过同一套 Job API 完成提交、轮询和下载。而 Batch 价格最高比 Serverless 官方标价低 50%。
不过,在继续强调它有多方便之前,也要把边界说清楚:“不需要修改 Schema”只对同一家模型提供方内部成立。OpenAI Request Body 可以原样放进 OpenAI 的批量推理任务。如果在统一 API 内切换到 Anthropic 模型,操作虽然方便,但仍然需要适配 Anthropic 自己的 Batch Line 格式(custom_id + params)、自己的 Structured Output 方式(使用 Tool Use,而不是 response_format),以及第三套 Model ID 规则。真正实现统一的,是请求外围的部分:同一个 Endpoint、同一个 Key、同一套 Job Lifecycle,以及统一查看所有任务的地方。
工作负载:使用真实标签给 25 万条消费者投诉分类
我们希望做一个不仅能跑,还能评分的 Demo。CFPB Consumer Complaint Database 是美国政府公开的公共领域数据集,里面包含数百万条真实金融服务投诉。其中经过消费者授权公开的部分包含自由文本 Narrative,数据中的个人身份信息在 CFPB 发布前已经统一用 XXXX 隐去。更重要的是:每一条记录都有官方 Product Label。你可以把它理解成一大堆已经提前有人做好分类的 Support Ticket,因此可以大规模检查模型到底分得准不准。
每条记录的任务包括:分类产品线、指出具体问题、给出情感和紧急程度评分、提取实体、写一行摘要。一次调用完成分类和富化。
我们写了两个版本的系统提示词,下文会一直沿用这两个名字。精简提示词(约 460 token)只包含任务说明、产品类别名称和输出 schema;这就是 25 万条记录主跑所用的版本。长提示词(约 2400 token)额外嵌入了完整的 CFPB 分类体系,包括全部 110+ 个问题级类别,理论上是想用更多上下文换取更高准确率。长提示词还有一个后续会变得很重要的副作用:它是唯一长度足够超过 OpenAI 1024 token 提示缓存阈值的版本,所以长提示词那轮运行同时也是我们的缓存测试。因此成本表里标为"胖 /长(fat)+ 缓存(cache)"。
Sample 使用的是 2017 年以后、带 Narrative(投诉的详细文字描述)的投诉数据,并按照比例进行 Reservoir Sampling,共抽取 250,000 条;每条 Narrative 最多保留 1,500 个字符。这个限制主要为了让 Token 支出更可预测,它对准确率的影响我们没有单独测量。
我们自己定的一条原则:下文所说的"准确率"指的是与 CFPB 自带标签的一致性,而不是绝对真理。这些标签是消费者在投诉时自己选的,而且类别边界确实存在重叠(一笔在信用报告上的争议债务,完全可以算作三种不同的产品)。在看按类别细分表格时请记住这一点。
DigitalOcean 批量推理 Pipeline:从 7 GB CSV 到评分结果,6 步走

从 7 GB CSV 到最终评分结果,整个过程全部使用 Streaming,没有一次性把原始文件加载进内存。数据来源:我们在 2026 年 8 月 3 日到 13 日期间,基于 DigitalOcean Unified Batch Inference API 的实际 Pipeline。
Step 0:提交之前先估算。
先对 1% Sample 做 Tokenization,再外推整体规模。我们的 Lean Prompt 平均每条记录约 468 个输入 Token、82 个输出 Token,因此 25 万条数据大约需要 1.37 亿 Token。开始构建任务之前,先按照官方价格检查预算,同时确认不会超过 Enqueue Token Limit。按照当前限制文档,每个账号、每个模型最多可以排队 100 亿 Token。
Step 1:生成 JSONL。
每条记录一行。OpenAI 使用 response_format: json_schema 强制输出严格 JSON;Anthropic 模型对应的方式是强制工具调用:
{"custom_id": "haiku-9915470",
"params": {"model": "claude-haiku-4-5-20251001", "max_tokens": 300,
"system": [{"type": "text", "text": "..."}],
"messages": [{"role": "user", "content": [{"type": "text", "text": "Complaint:\n..."}]}],
"tools": [{"name": "record_ticket", "input_schema": {"...": "..."}}],
"tool_choice": {"type": "tool", "name": "record_ticket"}}}
结构化输出的效果很好:25 万条 OpenAI Response 中,99.99% 可以被程序正常解析为 JSON,只有 20 行异常;25,000 条 Anthropic Response 则达到 100.00%。
Step 2:超过限制时需要切分文件,包括那些只有 Error Message 才会告诉你的限制。
官方文档写的是每个文件最多 50,000 次请求、200 MB。我们第一次把 25 万条数据切成 6 个文件,每个最多 45,000 请求。结果 6 个文件里有 5 个瞬间校验失败:
batch contains 45000 requests; tier limit is 40000 for provider openai
这说明账号自身还有一个低于文档公开上限的 Tier Limit——我们在 2026 年 8 月 3 日测试时,每个文件实际只能放 40,000 次请求。文档确实提醒,不同 Security Tier 会有额外限制,但没有公开具体数字,所以很多时候你第一次知道自己的真实上限,就是看到这个 Error。好消息是:错误信息会直接告诉你真实数字,而且“校验失败”是不产生费用的。于是我们重新按每个文件 40,000 次请求切分,25 万条数据最终拆成 7 个文件。
Step 3:以幂等方式提交。
提交分三步:创建文件 intent(返回 file_id 和一个有效期约 15 分钟的预签名上传 URL),PUT 上传原始字节,然后创建批量推理 Job 并引用 file_id,再加上你自己选的 request_id。这个 request_id 就是你的崩溃保险,我们验证了它合约的两面(2026-08-03)。用相同的 request_id 和相同的 file_id 重放创建请求会返回已有 Job,不会重复创建,所以你的提交循环崩溃后可以安全重跑。但用相同的 request_id 搭配重新上传的相同内容则会返回 409 "request_id is already associated with a different input file"。所以首次上传后要把 file_id 持久化下来,重试时复用,不要再上传。
OpenAI Job 还需要传 endpoint(/v1/chat/completions 或 /v1/responses),与每行的 url 匹配;Anthropic Job 则必须省略该字段。
Step 4:轮询并下载。
Job 状态会依次显示 validating → queued → in_progress → completed,也可能进入 failed / expired / cancelled,同时会返回每个 Job 的 Request Count。结果最长保留 30 天。Results API 会返回一个 Presigned URL,用来下载一个 output.jsonl;文档还定义了单独的 Error File(error_file_url,只有真正生成时才会出现)。但我们制造出的所有失败案例中,包括一个 20 次请求全部失败的 Probe,Error 都直接出现在 Output File 每一行里,并没有出现 error_file_url(测试日期 2026 年 8 月 4 日)。因此生产代码应该同时支持两种形式:检查每一行的 error 字段,也检查 Results Payload 是否包含 error_file_url。
这里还有一个来自真实失败的 Resilience 经验:下载一个约 47 MB Output File 时,我们中途遇到 HTTP/2 Stream Reset(Stream 1 was reset by remote peer,2026 年 8 月 4 日)。处理方法是重新执行整个 GET;每次调用 Results Endpoint 都会生成新的 Presigned URL。
Step 5:合并并评估。
根据 custom_id 把 Output Join 回 Input,解析 JSON,再与 Label 做比较。完整 Pipeline 可以在后面的 Reproduction Kit 里找到。
Step 6:重新提交失败项——这才是生产环境真正会用到的循环。
收集所有 Error Line,生成一个只包含剩余失败项的 JSONL,再用新的 request_id 提交。我们已经实现了这条代码路径,但正式 25 万条数据测试恰好 0 Failure,因此没有真正可以讲的 Failure Story。这其实是对“Resilience”更准确的理解:这个机制重要,正是因为你无法预测什么时候才会真的需要它。
可靠性与完成时间:25 万次请求全部完成,最大 Job 不到 2.2 小时
所有 Job 都在几小时内完成,而 SLA 是 24 小时。所有 Job 均为 0 Failed Request;正式 25 万条数据的 7 个 Job 并行执行。下面这些都是单次观察值,不是统计分布。
| Job | 请求数 | 状态 | 总耗时(Submit → Complete) |
|---|---|---|---|
| main2-000 … main2-004(GPT-5 Nano) | 每个 40,000 | completed,0 failed | 1.4~2.2 小时 |
| main2-005 + main-005(GPT-5 Nano) | 每个 25,000 | completed,0 failed | 40 分钟 / 1.5 小时 |
| haiku25k(Claude Haiku 4.5) | 25,000 | completed,0 failed | 17 分钟 |
| fat5k(GPT-5 Nano,已缓存) | 5,000 | completed,0 failed | 约 11 分钟 |
| Cancel Probe(GPT-5 Nano) | 500 | completed | 约 3 分钟 |
7 个正式 Job 同时运行,并没有互相排队。所有数字都来自 Reproduction Kit 里的 Job Timing Log。需要强调的是,24 小时是 SLA,而不是典型情况;但架构设计时仍然应该按照 SLA 做准备。
准确率:25 万条数据与数据集原始标签的一致率为 83.6%
整体 Product Label 一致率为 83.62%,其中 99.99% 的输出符合 JSON 格式。各类别 Recall 如下:
| CFPB 产品类别(Sample 占比) | Recall |
|---|---|
| Credit reporting / personal consumer reports(70.2%) | 92.4% |
| Mortgage(3.0%) | 87.7% |
| Money transfers / virtual currency(3.4%) | 74.1% |
| Checking or savings account(5.2%) | 67.5% |
| Student loan(1.3%) | 64.6% |
| Debt collection(11.1%) | 59.9% |
| Credit card(3.0%) | 57.5% |
| Vehicle loan or lease(1.4%) | 46.2% |
| Prepaid card(0.3%) | 38.2% |
| Payday / title / personal loan(1.0%) | 16.1% |
| Debt or credit management(0.2%) | 0.3% |
长尾数据很有启发意义:模型出错的类别恰恰是那些 CFPB 定义边界模糊的类别(一笔发薪日贷款的催收问题,到底算发薪日贷款还是债务催收投诉?)。在 25 万规模上,你看到的是分类体系本身的缝隙,而不仅仅是模型的缺陷。
25 万条数据使用 DigitalOcean 批量推理要多少钱:7.04 美元,而无服务器推理为 14.07 美元
由于我们的测试账号免计费,因此没有实际 Invoice。这一节展示的是任何人都可以核查的数学计算:使用 API Usage 字段中的真实 Token 数,再乘以 DigitalOcean 官方公开的每 Token 价格,其中 Batch 最高比 Serverless 低 50%。

“半价”是定价规则本身,所以真正值得关注的是比例,而不是我们的账单。下面都是计算结果,并非实际 Invoice。Cached Token 为保守起见仍按完整 Input Rate 计算。价格采集于 2026 年 8 月,正式使用前请重新确认。
| 测试 | 记录数 | 输入 / 输出 Token | Batch 官方价计算 | Serverless 官方价计算 | 测试日期 |
|---|---|---|---|---|---|
| GPT-5 Nano,Lean Prompt | 250,000 | 117.0M / 20.6M | 7.04 美元 | 14.07 美元 | 2026-08-03 |
| Claude Haiku 4.5,Lean | 25,000 | 30.1M / 3.9M | 24.91 美元 | 49.83 美元 | 2026-08-11 |
| GPT-5 Nano,Fat Prompt + Cache | 5,000 | 9.2M / 0.4M | 0.30 美元* | 0.61 美元 | 2026-08-11 |
- 这里对 Cached Token 采用保守计算,仍按照完整 Input Rate 计价。DigitalOcean 价格页面公布了无服务器推理 Cache Read Rate——截至 2026 年 8 月 11 日,GPT-5 Nano 为 0.005 美元 / 1M Token,是普通输入价格的十分之一,因此实际成本理论上还可能更低。但 DigitalOcean 没有公布 Batch Cache Rate,我们也无法通过当前账号确认 Batch 中 Cache Hit 是否会按照更低费率计费;我们只能确认 API 的确会返回 Cache-hit Token 数。
换算到每 1,000 条记录,GPT-5 Nano 的成本为 0.028 美元,Claude Haiku 4.5 为 1.00 美元,均按照 Batch 官方标价计算。25 万条记录分类只需要 7 美元当然很吸引眼球;但相同工作负载如果按 Serverless 价格计算为 14 美元,本质上只是 Batch Pricing 正常发挥作用,并不是我们的实验发现了什么隐藏优惠。
模型选择的成本账:更贵的模型确实更好,但“更聪明”的 Prompt 反而更差
三个方案都在完全相同的记录上评分,并进行了显著性检验:

多花钱确实有一点帮助;增加更多 Prompt 反而让结果更差。这里的 Accuracy 依然指与 CFPB 原始标签的一致率。Mini vs Nano 使用 2,500 条 Pilot 数据;Haiku vs Nano 使用同样的 25,000 条数据成对比较;长提示词 vs 精简提示词则使用同一个模型、同样的 5,000 条数据。
| 对比(Paired,McNemar) | Accuracy | Δ(百分点) | p | 计算成本比 |
|---|---|---|---|---|
| GPT-5 Mini vs Nano(n=2,500) | 81.2% vs 80.8% | +0.4 | 0.58(不显著) | 5x |
| Claude Haiku 4.5 vs Nano(n=25,000) | 84.9% vs 83.6% | +1.26 | <0.0001 | 约 35x |
| Fat Prompt vs Lean,同模型(n=5,000) | 80.8% vs 82.9% | −2.06 | <0.0001 | 约 2x |
第三行值得再看一次:我们把完整的产品/问题分类体系塞进提示词(2400 token 而不是 460),期望准确率提升。结果它显著下降了,同时每条记录的成本还翻了一倍(缓存折扣之前)。而且分类体系原本的目的——问题级标签——跟 CFPB 那 110+ 个重叠的问题类别相比,一致率只有 20.2%。更多提示词不等于更高准确率,在证明之前,它只是更多 token 而已。
什么时候应该用批量推理,什么时候继续用无服务器推理?
作为对比,我们还用完全相同的提示词和记录跑了 2000 条无服务器推理对照组(2026-08-03):每请求延迟 p50 2.31 秒 / p95 3.40 秒,答案一条一条流回来;而批量推理是把 25 万条丢进队列,90 分钟后一起收结果。批量推理用交互性换吞吐量;如果没有下游需求需要在秒级内拿到单个答案,那你本来也没用到那份交互性。
适合使用 Batch 的场景:
- 下游没有任何用户或系统在等待某一条独立答案,例如历史数据 Backfill、数据集富化、夜间分类、评估、内容审核批量扫描。
- 数据量足够大,折扣才真正有意义。我们的 25 万条数据使用批量推理的成本计算为 7.04 美元,相同 Token 按无服务器推理的价格计算为 14.07 美元。
- Pipeline 可以接受最长 24 小时完成。我们实际测试通常快得多——40,000 Request Job 只需要 1.4~2.2 小时——但平台唯一承诺的是 24 小时。
应该继续使用 Serverless 的场景:
- 用户或系统正在等待每一个答案。我们测的无服务器推理延迟是每请求 p50 2.31 秒;批量推理在 Job 完成之前什么都不会返回。
- 工作负载较小或者只是一次性任务。几千条数据以下,绝对节省金额可能只是几美分,而 JSONL 封装本身反而增加额外工作。
- 你需要每请求流式输出、工具循环或立即重试。
而且两者不竞争同一份容量:DigitalOcean 文档说明批量推理作业跑在隔离的低优先级容量上,不会消耗你的实时配额,也不会让生产环境 p99 延迟恶化超过 5%(文档中有此承诺,我们未做测试)。用同一个密钥同时跑两种模式只是一个配置选择,不是架构变更。
如果需要更详细的比较,也可以参考我们的 《无服务推理、专用推理、批量推理,怎么选?》 教程。
大规模使用 DigitalOcean 批量推理后,我们总结出的 8 个经验
1. 同一个 API 上有三套模型命名规范(2026-08-11 实测)。无服务器推理要的是 DigitalOcean 目录 ID(openai-gpt-5-nano、anthropic-claude-haiku-4.5)。OpenAI 批量推理要的是原生名称(gpt-5-nano);用目录 ID 会校验失败。Anthropic 批量推理要的是 Anthropic 的带日期快照 ID(claude-haiku-4-5-20251001);目录 ID 和不带日期的别名都会被拒,报"not available on DigitalOcean"。DigitalOcean 自己的教程示例里用了不带日期的别名(claude-3-5-sonnet-latest),我们测试中该名称被拒了,所以当文档和报错信息打架时,请相信报错。ID 填错 = 即时、免费、会告诉你模型名称的校验失败。
2. 你的 Tier Limit 不一定等于文档上限。 我们账号上每个文件 4 万请求 vs 文档中的 5 万(2026-08-03)。Anthropic 侧的文档限制(发布公告说是每文件 10 万)我们没测过;我们最大的 Anthropic 作业是 2.5 万。
3. Reasoning Model 不接受传统的 Body Parameter。 我们第一次测试 GPT-5 Nano 时传了 temperature + max_tokens,结果 20 次请求全部逐行失败。应该改用 max_completion_tokens 和 reasoning_effort,同时给 Output 留出足够空间,因为 Reasoning Token 也按照输出计费,即使用户最终只看到一个 JSON Object。
4. 有两种 Failure Mode 不会明确报错。 重复的 custom_id 和混合模型的文件都能通过前置校验,正常入队,然后静默失败,没有任何报错信息。每条作业只能有一个模型,这是文档有说明的;但文档没说的是违反这条规则会在入队后静默失败,而不是在校验阶段 loudly 报错。除此之外我们扔给校验的所有其他情况(格式错误的 JSON、缺少 custom_id、端点 URL 错误、用错提供商的 schema、空文件)都能快速失败,并返回清晰的、可引用的报错。请在本地做唯一性和单模型检查;API 不会告诉你这些。
5. Cancellation 是 Best-effort,而且两个方向都是如此。 尚未 Forward 给底层 Provider 的 Job 无法取消,会返回 409:batch job has not been submitted to the provider yet。文档把 409 描述为临时状态(等作业离开 validating 再重试),但我们遇到的是一个已经在 queued 状态卡了八天的作业,等是永远等不出结果的(见下一条)。而一个正在运行的作业可能比你取消得更快:我们 500 请求的探测在 cancel 落地时已经完成了 99%(状态变成 "cancelling" 之类的)。它最终跑完了,交付了结果,在正常账号上会按 completed 计费。我们从未抓住过一个正在运行的大作业,所以"取消一个 4 万请求作业的一半"这个场景未经测试。不要围绕取消来设计成本控制。
6. Queue Behavior 会因 Provider 不同而变化,甚至同一个 Provider 不同周也可能不同。 我们在 2026 年 8 月 3 日提交的一个 Anthropic 模型批量推理任务,在 queued 状态停留了 8 天,从未 Forward 给底层 Provider,无法取消,而且自己的 Expiry Timestamp 已经过期,却没有被处理。2026 年 8 月 11 日重新测试时,相同内容的文件却开始严格 Validation,并在几秒内 Forward,25,000 次请求只用了 17 分钟就完成。两次测试之间平台行为明显发生变化,但我们不知道 DigitalOcean 内部具体做了什么,也不知道为什么。两个结果都说明了同一件事:架构设计应该按照 24 小时 SLA 来规划,而不是按照典型速度;另外,记录平台行为时最好同时保存测试日期。
7. Prompt Cache 有三个容易忽略的细节。
(a) 最低可缓存 Prefix 长度因模型而异:GPT-5 Nano 为 1,024 Token,Claude Haiku 4.5 为 4,096 Token,后者是很多团队直觉预期的 4 倍。我们的正式生产 Prompt 只有 460 Token,因此 25 万次请求里缓存 Token 为 0——也就是说,文章标题里的 7.04 美元成本完全没有获得缓存帮助。
(b) 在一次满足 Cache 条件的 OpenAI 模型 Batch Test 中(2,400 Token Prefix、5,000 Request),55.6% 的 Input Token 被标记为 Cache Hit,而一个只有 20 Request 的小型 Probe 则达到 81%。这种差异符合一种可能的解释:Batch 会把请求分散到多个 Parallel Worker,每个 Worker 都需要单独 Warm Cache。不过这个机制没有得到确认,因为我们看不到 Scheduler。做成本估算时,应该参考大规模测试数字,而不是小型 Probe。
(c) 低于 Minimum Threshold 时,不会缓存,也不会有 Warning。我们最初的 Anthropic Probe 使用了 1.3k~3.6k Token Prefix,完全没有 Cache Activity,一度误以为 DigitalOcean 不支持 Anthropic Cache。后来把 Prefix 提高到 5,975 Token 再测,Serverless 和 Batch 都正常缓存:Serverless 第一次 Call 写入 Cache,第二次 Call 读回全部 5,975 Token;一个包含 10 次请求的 Batch Job 则有 70% 的 Input Token 来自 Cache。在判断“缓存坏了”之前,先检查目标模型文档中的 Minimum Threshold。
8. Output Schema 属于底层 Provider,而不是 DigitalOcean。 OpenAI Batch Line 需要按照 OpenAI Batch Output 格式解析(response.body.choices[...]);Anthropic 返回结果则需要按照 Message Batches Output 解析(result.message.content[...],其中包含 Tool-use Block)。虽然 Job 创建、提交、轮询和结果获取使用的是统一 API,但 Merge Code 仍然需要针对不同 Provider 分别处理。另外,Anthropic Usage Block 会返回 service_tier: "batch",这是一个很方便的检查方式,可以确认当前请求确实进入了你预期的 Batch Tier。
DigitalOcean 与 OpenAI、Anthropic、AWS 的批量推理方案:客观对比
DigitalOcean 这一列在特别注明的地方来自我们的实际测试;其他平台数据来自各自截至 2026 年 8 月公开的文档和价格。如果你准备根据这张表做平台选型,请先重新检查各平台最新文档,因为价格和限制会变化。
| 对比项 | DigitalOcean Batch | OpenAI Batch | Anthropic Message Batches | Bedrock Batch |
|---|---|---|---|---|
| 相比实时推理的折扣 | 最高 50% | 50% | 50%(包括 Cache + Thinking Token) | 相比 On-demand 低 50% |
| 单 API 支持的平台 | OpenAI + Anthropic(实测) | OpenAI | Anthropic | 多平台,按 Region |
| 单 Job 上限 | 文档 50k / 200 MB;我们的 Tier 实测为 40k | 50k / 200 MB | 100k / 256 MB | 50k / 200 MB,部分模型有额外 Minimum |
| Completion Window | 24h;我们实测 3 分钟~2.2 小时 | 24h,多数为 1~6h | 24h,多数 <1h | 24h |
| Storage 配置 | 无需配置(Presigned URL) | Files API | 无需配置 | S3 + IAM Role |
| 幂等提交 | request_id,两个行为均实测验证 | 没有同等 First-class 机制 | 没有同等 First-class 机制 | Client Token |
| Batch 中使用 Cache | OpenAI + Anthropic 超过各自模型 Minimum Prefix 后,都能通过 DigitalOcean 返回 Cache Hit(实测);最终 Billing Rate 未验证 | 历史上不能叠加;请核对最新文档 | 支持,可叠加,Cache Hit 为 Best-effort | 没有明确 Batch Cache 机制 |
| Upfront Validation | 大部分 Error 可以提前发现(实测);Duplicate custom_id + Mixed-model 会在后面静默失败(实测) | Duplicate custom_id 会提前拒绝 | 每条 Request 返回 succeeded / errored | S3 侧 Validation |
| Partial Completion 计费 | 官方文档:只对 Completed Request 计费 | 请确认 | 请确认 | 请确认 |
| 主要优势 | 一个 API / Key / Bill 同时处理两家 Provider,无需额外 Storage 配置 | Endpoint 类型更丰富(Embedding、Image、Moderation),成熟度高 | 单 Batch 上限最大、典型完成速度最快、Cache 规则更明确 | 数据无需离开 AWS 账号,IAM / Governance 完整 |
DigitalOcean 的差异化更多体现在运维体验,而不是价格本身。各家的 Batch 折扣都大约是 50%。DigitalOcean 的不同之处在于,OpenAI 和 Anthropic 模型的 Batch Job 可以共用一个 Endpoint、一个 Key、一套 Job API 和一张账单。
从 25 万扩展到数百万:在触及 100 亿 Token Queue Limit 之前基本线性增长
基于我们的实测数字,整体可以基本按线性关系外推,因此计算并不复杂。下面全部按照官方 List Price 估算:
| 记录数 | Token(按我们的数据分布) | 文件数(40k Tier Limit) | GPT-5 Nano Batch 计算成本 |
|---|---|---|---|
| 250k(实测) | 137M | 7 | 7.04 美元 |
| 1M | 约 550M | 25 | 约 28 美元 |
| 10M | 约 5.5B | 250 | 约 282 美元 |
真正先遇到的限制很可能不是成本,而是两个平台约束。第一,Enqueue Token Limit——每个账号、每个模型最多 100 亿 Token。按照我们的 Token Profile,大约处理到 1,800 万条记录时就会触及这个限制,之后需要一边等待 Queue 消化,一边继续补充任务。第二,文件数量:当文件达到 25 个甚至更多时,就应该采用前文展示的 Manifest + Idempotent Submit Loop,因为迟早会有某个任务需要 Retry。我们这次并发运行 7 个 Job(5 个 40k + 2 个 25k),全部在 2.2 小时以内完成;一次提交 250 个文件会不会表现一样,我们没有测试。我们预计 Token Quota 会比 Concurrency 更早成为瓶颈,但这只是预期,不是测量结果。
Quickstart:大约 30 行 Python 跑一个 DigitalOcean Batch Job
先说一个前提:OpenAI 和 Anthropic 商业模型要求 Tier 3+ DigitalOcean 账号。如果 Batch API 返回 403,在排查其他问题之前,请先到 Resource Limits Page 检查自己的 Tier。
下面是不依赖 Framework 的最小流程:
import json, time, requests
BASE = "https://inference.do-ai.run/v1"
H = {"Authorization": f"Bearer {KEY}"} # your DO model access key
# 1. file intent -> presigned URL (valid ~15 min)
intent = requests.post(f"{BASE}/batches/files",
headers=H, json={"file_name": "job.jsonl"}).json()
# 2. upload raw bytes
with open("job.jsonl", "rb") as file:
upload = requests.put(intent["upload_url"], data=file)
upload.raise_for_status()
# 3. create the batch (request_id = safe retries; keep file_id if you must retry)
batch = requests.post(f"{BASE}/batches", headers=H, json={
"file_id": intent["file_id"],
"provider": "openai", # or "anthropic"
"endpoint": "/v1/chat/completions", # REQUIRED for openai, OMIT for anthropic
"completion_window": "24h",
"request_id": "my-job-001",
}).json()
# 4. poll
while True:
b = requests.get(f"{BASE}/batches/{batch['batch_id']}", headers=H).json()
if b["status"] in ("completed", "failed", "expired", "cancelled"):
break
time.sleep(60)
# 5. download (retry the GET whole if the stream resets; the URL refreshes each call)
res = requests.get(f"{BASE}/batches/{batch['batch_id']}/results", headers=H).json()
out = requests.get(res["output_file_url"]).text
for line in out.splitlines():
r = json.loads(line) # per-line "error" field on failures (also check
# res.get("error_file_url"): documented, not seen in our runs)
常见问题
1. DigitalOcean Batch 比 Serverless 便宜多少?
DigitalOcean 的 Batch 价格最高比 Serverless 官方标价低 50%。在我们 25 万条数据的测试中,按照实际 Token 数计算,Batch 成本为 7.04 美元,而相同 Token 如果使用 Serverless,则为 14.07 美元。
2. 一个 Batch Job 要多久?
根据 2026 年 8 月的测试:40,000 Request Job 用时 1.4~2.2 小时;25,000 次 Anthropic 模型请求用时 17 分钟;500 Request Job 约 3 分钟。SLA 是 24 小时,因此架构设计时应该按照这个上限规划。
3. 我需要重写代码吗?
如果还是同一家 Provider,不需要。Request Body 保持不变,只需要按照该 Provider 的 Batch JSONL Line Format 包装,并调整 Model ID 规则。如果切换到另一家 Provider,则还需要采用对方自己的 Line Shape 和 Structured Output 机制。OpenAI 和 Anthropic 两种情况下,Job / Submit / Poll / Results API 是相同的。
4. 请求失败后会发生什么?
在我们的测试中,每条失败 Request 的 Error 都直接写在 Output File 对应行中;文档还定义了可能生成的独立 Error File(error_file_url),因此生产代码最好同时支持两种情况。单条 Request Failed 不会让整个 Job Failed,而且 DigitalOcean 文档说明只对 Completed Request 计费。可以把 Error Line 收集到一个 Remainder File,再使用新的 request_id 重新提交。(正式 25 万条数据测试中 0 Failure,因此这次没有真实案例可以展示。)
5. Batch 中支持 Prompt Caching 吗?
根据 2026 年 8 月的测试:支持 OpenAI 和 Anthropic 模型,但 Shared Prefix 必须达到目标模型文档规定的 Minimum。GPT-5 Nano 为 1,024 Token,Claude Haiku 4.5 为 4,096 Token。在符合 Cache 条件的 OpenAI 模型 Batch Test 中,有 55.6% Input Token 被报告为 Cache Hit;当 Prefix 超过 Claude Haiku 4.5 的 4,096 Token Minimum 后,Anthropic 的 cache_control 在 Batch 和 Serverless 场景中都能正常工作。低于阈值时不会报错,只是什么都不会缓存。我们无法通过当前账号验证 Cached Token 的最终 Billing Rate。
6. 可以使用哪些模型?
截至 2026 年 8 月我们的测试,只支持 OpenAI 和 Anthropic 商业文本模型:不支持 Open-source 或 DigitalOcean-hosted Model,不支持 Multimodal,而且一个 Job 只能使用一个模型。还要注意账号要求:Tier 1 和 Tier 2 无法访问 Anthropic 或 OpenAI 商业模型,文档明确的例外是开放权重 gpt-oss,因此通过这两家 Provider 使用 Batch 实际上要求 Tier 3+。同时还要注意前文提到的三套 Model Naming Convention。
总结:Request Body 基本不变,计算成本减半,但有几套规则需要提前掌握
Batch Inference 是少数几种几乎可以零成本接入的优化手段:如果你的工作负载不要求几秒内返回答案,那么你原本已经在发送的 Request Body,只需要整理成 JSONL 文件,经过 3 次 API Call 提交,再加一个 Poll Loop,就可以使用大约一半的 List Price。我们的 25 万条数据测试没有一条请求失败,完成速度也比预期更快,按照公开价格计算的总成本为 7.04 美元。
但这篇文章真正值得继续读下去的地方,是标题之外那些我们实际踩到的细节:三套 Model Naming Convention、低于文档上限的 Tier Limit、两类 Silent Failure、Best-effort Cancellation、一个排队时间远超预期的 Job,以及只有超过 Threshold 才真正生效、而我们的生产 Prompt 恰好没有达到要求的 Prompt Cache。这些问题都不足以成为不使用 Batch 的理由,但它们恰恰决定了你做出来的是一个 Demo,还是一条可以反复稳定运行的生产 Pipeline。
最后,还有一个来自 25 万条答案评分的更普遍结论:便宜模型已经够用;更贵的模型确实有可测量的提升,但价格高了约 35 倍;而我们自认为“更聪明”的 Prompt 反而让结果变差。使用 Batch Price,在自己的真实工作负载上跑一次这样的实验可能只需要个位数美元,而且我们的完整 Harness 已经开源。在相信任何人的 Benchmark 之前,最好先自己跑一次——包括本文的数据。
延伸阅读
如果想先理解这些数字背后的整体框架,可以参考 DigitalOcean 的推理模式对比指南,其中从高层介绍了 Serverless、Dedicated、Batch 和 Inference Router。Batch Inference How-to 文档和 API Reference 则介绍完整 Job Lifecycle;Inference Limits 文档页面 提供当前单文件、Token 和 Tier Limit;卓普云的官网 可以查看当前每 Token 价格。如果你正在比较批量推理和自己运行 GPU这两个方案,我们之前的教程 《大模型推理选型:无服务器 API、专用推理与 GPU 实例自建成本实测与盈亏平衡点指南》 完整测试了这种取舍。其他平台的官方资料可以参考:OpenAI Batch Guide、Anthropic Message Batches 和 Bedrock Pricing。这次实验后续还会发布配套视频讲解,链接之后补充。
完整的 Reproduction Kit,包括 Harness、汇总数据和 Probe Notes,已经开源在 github.com/bnarasimha21/technical-deep-dives 的 batch-inference/ 目录中,你可以直接在自己的账号上重新执行整个 Pipeline:
export DIGITALOCEAN_INFERENCE_KEY="<your model access key>"
python prepare_jsonl.py --profile
python prepare_jsonl.py --sample 250000
python prepare_jsonl.py --emit --sample-file sample_250000.csv \
--provider openai --model gpt-5-nano --prompt lean --tag main
python submit.py --tag main && python poll.py --tag main
python download_results.py --tag main
python merge_results.py --tag main --sample-file sample_250000.csv --provider openai
python evaluate.py --tag main
python costmodel.py --tag main --model gpt-5-nano
本文中的价格、限制和平台行为记录于 2026 年 7 月 31 日至 8 月 13 日。如果你在更晚的时候阅读本文,方法仍然值得参考,但具体数字请重新核对。
最后,如果你对于DigitalOcean AI 推理服务有任何疑问,都可以直接咨询DigitalOcean中国区战略合作伙伴卓普云(aidroplet.com)。
相关产品与选型



