指导和见解

通过 AI API 网关统一批处理作业:持久队列、提供商适配器和租户级计费

一种通过一个多模型 API 运行耐延迟 AI 工作负载的实用架构:持久作业记录、提供商批量适配器、幂等结果摄取、预算预留和租户级分析。

批处理不应被视为 AI API 网关周围的侧门。如果评估、文档丰富、提取、审核扫描或嵌入作业离开同步请求路径,它们仍然需要租户控制、成本归因、重试、可审计性和使用分析。

实现模式是使批量执行成为一流的网关子系统。网关应公开一个与提供商无关的工作合同,同时在幕后适应 OpenAI、Anthropic、Gemini 和未来提供商批处理 API。

读者问题:批处理 API 意图相似,操作不同

耐延迟工作负载非常适合批处理执行。困难的部分不是决定一份工作是否可以等待。困难的部分是跨提供商一致地操作批处理工作。

已验证的事实:OpenAI 的 Batch API 是异步的,从上传的文件读取请求,将响应写入输出文件,目前使用 24 小时处理窗口。 OpenAI 列出了诸如验证失败进行中最终确定已完成过期取消已取消等状态。 Anthropic 的 Message Batches API 异步处理许多 Messages 请求,独立处理每个请求,需要轮询,并在处理结束后返回结果。 Anthropic 还建议使用有意义的 custom_id 值,因为无法保证结果顺序。 Gemini 的 Batch API 公开了长时间运行的操作式方法,例如列表、取消、删除和更新方法,并且其取消操作被描述为尽力而为。

一旦添加实际业务需求,这些差异就很重要:

  • 哪个租户、客户、项目或 API 密钥拥有每个项目?
  • 在作业离开网关之前是否预留了预算?
  • 如果批量,哪些已完成的项目是可计费的过期或被取消?
  • 如何在不重复成功工作的情况下重试部分失败?
  • 检索结果文件需要多长时间,网关应存储什么?
  • 合作伙伴能否在不暴露上游提供商凭据的情况下构建客户范围的批处理?

答案不是隐藏每个提供商的差异。答案是标准化操作合约,同时保留提供者本机元数据以进行调试、协调和支持。

推荐的公共 API:将批处理作业与同步完成分开

建议:将批处理作业公开为它们自己的 API 表面,而不是作为聊天完成上的特殊标志。同步请求和异步批处理作业具有不同的生命周期、计费、重试和结果检索语义。

实用的网关合约包括以下操作:

  • create_job:创建租户、项目、密钥或合作伙伴客户拥有的草稿作业。
  • append_itemsupload_manifest:添加具有稳定项目的单个请求标识符。
  • 提交:验证、预留预算、选择提供商、调度和锁定提交的清单。
  • get_status:返回标准化作业和项目计数。
  • list_results:分页浏览标准化项目结果、错误和使用情况。
  • 取消:请求取消,但不承诺立即执行终止。
  • export_usage:导出分析或计费系统的作业级和项目级成本记录。

公共作业对象示例:

{
  "job_id": "job_01j7...",
  “tenant_id”:“tenant_acme”,
  “customer_id”:“cust_123”,
  “端点”:“聊天完成”,
  "model": "分析-大",
  “状态”:“正在运行”,
  “计数”:{
    “已提交”:50000,
    “已完成”:31240,
    “失败”:180,
    “过期”:0
  },
  “成本”:{
    “估计”:“184.20”,
    “保留”:“205.00”,
    “解决”:“117.43”,
    “货币”:“美元”
  },
  “创建时间”:“2026-08-19T10:00:00Z”,
  “提交时间”:“2026-08-19T10:05:00Z”,
  “retrieval_deadline”:“2026-09-17T10:00:00Z”
}

默认情况下,公共对象不应公开提供程序文件 ID、操作名称或原始上游错误。这些属于面向操作员的元数据。

使用持久作业记录作为事实来源

网关拥有的批处理层在向上游提交任何内容之前需要持久状态。不要依赖提供商批次记录作为您唯一的状态存储。提供商记录是必要的,但他们不知道您的租户层次结构、预算预留、内部模型别名、合作伙伴客户或分析要求。

最小数据库模型

有用的架构具有三个级别:

1.批处理作业

batch_jobs
- 工作 ID
- 租户 ID
- 项目 ID
- customer_id 可为空- api_key_id
- 终点
- 请求的模型
-resolved_provider
-resolved_provider_model
- 状态
- 项目计数
- 估计输入令牌
- 估计输出令牌
- 保留金额
- 已结算金额
- 创建于
- 提交时间
- 完成时间
- 过期时间
- 检索截止日期
- cancel_requested_at

2.批次项目

batch_items
- 工作 ID
- 项目 ID
- 自定义 ID
- 幂等性键
- 请求哈希值
- 状态
-provider_request_index可为空
- 估计的代币
-实际输入令牌可为空
-实际输出令牌可为空
-解决的金额可以为空
- result_pointer 可为空
- error_code 可为空
- retry_of_item_id 可为空
- 创建于
-解决_at

3。提供者元数据

batch_provider_metadata
- 工作 ID
- 提供者
-provider_batch_id可为空
- input_file_id 可为空
-output_file_id 可为空
- error_file_id 可为空
- 操作名称可为空
- 终点
- 区域可为空
- 本机状态
- native_request_counts jsonb
- 最后轮询时间
- raw_error_pointer可为空

将提供程序元数据与公共作业合同分开,使网关能够在不破坏面向租户的API的情况下发展提供程序适配器。

在分派之前需要稳定的项目标识符

建议:生成网关job_id并在分派之前需要每个项目custom_id或幂等密钥。切勿按顺序协调结果。

Anthropic 明确警告结果顺序无法保证,并建议有意义的 custom_id 值。即使提供商似乎维护秩序,网关也不应该依赖它。作业会被分块、重试、取消、部分完成和重新摄取。排序假设最终会失败。

安全的项目标识符格式具有描述性,但不敏感:

tenantA.invoice_extraction.2026-08-19.row_000381

避免将原始电子邮件、姓名、文档标题或客户机密放入标识符中。将敏感相关数据存储在您自己的租户数据库中,而不是存储在提供商可见的 ID 中。

在不删除提供商详细信息的情况下标准化状态

提供商批处理 API 公开不同的生命周期。网关应将它们规范化为仪表板、计费和自动化可以理解的小型内部状态机。

建议规范化生命周期:

  • 草稿:作业存在,但仍可编辑。
  • 验证:网关或提供商验证正在运行。
  • 排队:接受但尚未处理。
  • running:提供程序正在处理项目。
  • finalizing:提供程序已完成计算并正在准备结果工件。
  • 已完成:所有接受的项目均已达到最终成功。
  • completed_with_errors:某些项目成功,某些项目失败。
  • expired:提供程序窗口在所有项目之前结束工作已完成。
  • cancel_requested:租户要求取消,但最终计费工作尚未解决。
  • 已取消:取消已解决。
  • 失败:作业级故障阻止了有用的执行。

不要过早地将本机提供者错误折叠到通用标签中。调试时,操作员仍然需要访问本机状态、验证错误、请求计数、文件 ID 和操作名称。

提交前根据功能矩阵进行验证

建议:在预算预留和提供商调度之前运行预检验证。批处理模式不仅仅是带有延迟的同步模式。提供商的批处理 API 可能不支持某些模型、端点、请求功能、区域和工具配置。

您的内部能力矩阵应检查:

  • 支持的端点:聊天、消息、嵌入、审核或生成。
  • 批处理模式的模型资格。
  • 最大作业大小、项目数、请求大小和上传的文件大小。
  • 是否流式传输禁止使用工具和函数调用。
  • 结构化输出或 JSON 模式支持。
  • 图像、音频或多模式输入支持。
  • 区域和居住限制。
  • 提供程序保留和结果检索窗口。
  • 特定于批次的速率限制和队列限制。
  • 取消语义。

良好的预检响应是具体:

{
  “错误”:“batch_capability_not_supported”,
  "message": "所选的提供者批处理适配器不支持流式响应。删除stream=true或选择同步端点。",
  "field": "items[*].request.stream"}

这比接受作业并在上游验证通过后失败更有用。

保留租户预算,然后确定实际使用情况

批量执行会使计费复杂化,因为在结果文件可用之前,网关可能会失去对确切使用情况的同步访问。安全模式是报价、保留、提交、提取、结算和协调。

已验证的事实:OpenAI 指出,与同步 API 相比,Batch API 定价有折扣,过期或取消的批次仍可能返回已完成的可计费工作。 Anthropic 指出,高吞吐量批处理可能会稍微超出工作空间支出限制,因此网关端预留和结算后变得非常重要。

建议:在提交之前使用估计代币、选定的提供商价格规则和安全边际预留租户预算。获取结果后,在项目级别确定实际使用情况。如果估计值太高,则释放未使用的预留。如果太低,请应用租户配置的超额政策。

实际分类帐事件:

batch.estimated
批次保留
批量提交
批次项目结算
批次.项目.退款
批处理.cancel_requested
批次.过期batch.reconciled

项目级账本至关重要。如果 45,000 个项目已完成,而 5,000 个项目已过期,则租户应为已完成的提供程序工作付费,而不是为作为单个无差别 blob 的原始清单付费。

将提供程序适配器构建为转换器,而不是业务逻辑所有者

每个提供程序适配器应了解如何将网关作业转换为提供程序的批处理格式、提交、轮询或检索状态、下载结果以及将本机结果映射回规范化记录。

将租户策略保留在适配器之外。适配器不应决定客户是否有足够的预算、合作伙伴客户是否被暂停或是否可以存储提示。这些是网关决策。

适配器职责

  • 呈现提供程序特定的请求清单。
  • 上传输入文件或创建提供程序操作。
  • 在元数据中存储提供程序标识符。
  • 将本机状态映射到规范化状态。
  • 检索输出和错误工件。
  • 解析项目级结果。
  • 在以下情况下返回本机使用记录:可用。
  • 表面可重试与终端错误。

网关职责

  • 验证租户和 API 密钥。
  • 应用团队、项目和客户控制。
  • 解决模型别名和提供程序路由策略。
  • 验证批量功能。
  • 预留和结算预算。
  • 坚持作业和项目状态。
  • 执行保留策略。
  • 公开分析和导出。

这种分离使添加新提供商变得更加容易,而无需重写计费、分析或租户治理。

幂等地提取结果

结果提取是许多批处理系统意外重复收费或丢失部分工作的地方。将摄入视为一个可重复的过程。下载相同的输出文件两次、处理相同的提供程序操作两次或重播相同的 Webhook 事件两次应该是安全的。

建议:使用项目级幂等性密钥和账本唯一性约束。即使重试提取,job_id + custom_id 的结果也应该准确解决一次。

强大的提取流程:

  1. 获取作业或结果工件的短期锁定。
  2. 获取提供程序输出和错误工件。
  3. 将记录解析为标准化项目结果事件。
  4. 通过以下方式匹配每个记录custom_id 或网关项目 ID。
  5. 在事务中写入结果元数据和使用情况。
  6. 仅在分类帐结算事件尚不存在时才创建。
  7. 根据项目状态而不是假设更新作业计数。
  8. 在已知所有终端状态时释放未使用的预算预留。

如果 Webhook 可用,请验证签名并防止重播。如果需要轮询,请使用自适应轮询:在接近预期完成时频繁轮询,在长时间运行期间后退,并在最终结算后停止。

重试项目,而不是整个作业

建议:尽可能在项目级别重试。整个作业重试很简单,但会增加重复工作的风险,并使计费变得更加困难。

在重试之前对失败进行分类:

  • 验证错误:通常会终止,直到请求得到修复。
  • 提供商 5xx 错误:通常可通过退避重试。
  • 配额或速率限制失败:仅在容量达到后重试
  • 安全块:不要盲目重试;路由到策略处理。
  • 过期项目:如果租户仍希望工作且预算允许,则可以在新作业中重试。

重试应创建链接到原始项目的新项目:

{
  "item_id": "item_retry_002",
  "retry_of_item_id": "item_001",
  “custom_id”:“tenantA.eval.row_901.retry_1”
}

不要仅仅因为已完成的项目属于以 completed_with_errorsexpired 结束的作业的一部分而重新提交。

决定存储什么:原始结果、指针或哈希

批处理系统是累积提示和输出的诱人场所。 这对于导出和调试可能很有用,但会增加数据保留责任。

建议:使存储策略可由租户配置。 对于敏感工作负载,存储元数据、哈希值、使用情况和结果指针,而不是原始提示和输出。对于敏感度较低的工作负载,如果保留窗口、访问控制和删除工作流程清晰,标准化结果存储可能是可以接受的。

至少跟踪:

  • 是否存储了原始输入。
  • 是否存储了原始输出。
  • 提供程序结果工件所在的位置。
  • 提供程序检索截止日期。
  • 网关删除截止日期。
  • 用于审计的请求和响应的哈希值,无需进行审核内容曝光。

已验证事实: Anthropic 状态批次结果在创建后 29 天内可用,并在工作区中隔离。 这种特定于提供商的检索窗口应反映在网关的元数据和面向租户的导出中。

公开与团队运作方式相匹配的分析

批量分析应存在于作业和项目级别。 产品负责人想知道夜间强化是否完成。 财务管理员需要按租户、模型和客户划分的成本。 工程师想知道要重试哪个故障类别。

有用的指标包括:

  • 已提交、已完成、失败、过期和取消的项目计数。
  • 估计成本与结算成本。
  • 保留预算仍然保留。
  • 按提供商和模型划分的输入和输出令牌。
  • 提供商公开的缓存命中指标。
  • 重试计数和重试成功率。
  • 排队、运行和完成状态的平均时间。
  • 按端点和模型划分的主要验证错误。
  • 合作伙伴客户归因。

对于合作伙伴 API 用户,将批处理作业公开为客户范围的资源。 这使得机构和 SaaS 构建者能够提供离线 AI 处理,同时在网关内保留上游提供商凭证、计费对账和速率限制处理。

明确的权衡

网关抽象与特定于提供商的功能:统一的合同简化了集成,但它不能使每个提供商的功能都相同。 保持能力错误明确。

预算预留与估算准确性:预留可以保护租户免受工作失控的影响,但估算可能是错误的。 账本必须支持调整、退款和超额处理。

轮询与 Webhooks:轮询简单可靠,但可能会浪费 API 调用并延迟完成。 Webhooks 速度更快,但需要签名验证、重放保护和监控。

原始结果存储与保留最小化:存储标准化结果可改进导出和分析,但会增加合规性负担。 敏感的租户可能更喜欢指针和哈希。

大批量与分块批量:大批量可以提高提供商端效率,但较小的块可以减少爆炸半径并使重试更容易。

实施清单

  • 创建单独的批量作业 API 界面。
  • 在提供商提交之前保留作业和项目记录。
  • 需要网关作业ID 和每个项目的自定义 ID。
  • 在存储本机提供程序元数据时标准化状态。
  • 为每个提供程序批量适配器构建功能矩阵。
  • 在预留预算之前验证清单。
  • 在分派之前预留租户预算。
  • 在摄取后在项目级别解决实际使用情况。
  • 使结果摄取幂等。
  • 重试失败的项目选择性地,而不是盲目地完成整个作业。
  • 跟踪提供商检索截止日期和网关保留策略。
  • 向租户和合作伙伴客户公开作业和项目分析。

预测:此模式的发展方向

预测:批量执行将成为人工智能自动化基础设施的正常部分,而不仅仅是折扣机制。 随着团队运行更多的评估、数据清理任务、安全审查和丰富管道,他们将期望异步工作负载具有与同步 API 调用相同的治理。

预测:提供商批处理 API 将继续以有用的方式出现差异。 有些将针对文件进行优化,另一些将针对长时间运行的操作进行优化,还有一些将针对托管数据集或事件回调进行优化。 网关适配器层将变得更有价值,而不是更有价值,因为适配器之上的操作契约可以保持稳定。

可操作的结论

不要将批处理作为特定于提供商的逃生舱口绑定到 AI API 网关上。 将其构建为一个持久的子系统,具有自己的作业记录、项目标识符、状态模型、提供商适配器、预算预留、幂等摄取和分析。

最重要的设计选择是项目级会计。 一旦批次中的每个请求都有稳定的身份,网关就可以协调无序的结果,仅重试失败的工作,仅对已完成的提供商工作进行计费,并向租户显示发生的情况。这就是向提供商发送文件和为异步工作负载操作可靠的多模型 API 之间的区别。

相关阅读

FAQ

常见问题

网关是否应该直接公开提供者本机批处理 API?
通常不会。公开本机 API 可以直接让开发人员访问提供商的功能,但会削弱租户级别的计费、分析、重试和治理。更好的模式是提供者中立的工作合同,其中提供者特定的元数据可供操作员使用。
为什么需要每个项目的custom_id?
批次结果可能不会按照提交的顺序返回。稳定的每个项目标识符使网关能够协调结果、确定使用情况、重试失败的项目并避免重复收费。
取消或过期的批次应如何计费?
仅在获取并核对结果后对已完成的提供者工作进行计费。取消或过期的作业仍可能包含已完成的项目,因此仅作业级别状态不足以准确计费。
网关是否应该存储批处理作业的原始提示和输出?
对于敏感租户来说默认情况下不是。存储元数据、哈希值、使用情况和结果指针,除非租户明确启用具有明确保留策略的原始结果存储。