如何在 API 网关上实施 LLM 支出限制
实用的实施指南,用于通过网关级策略、飞行前成本估算、预算预留、软硬阈值、流控制和对账来实时执行 LLM 支出限制。
提供商支出上限是有用的保障,但它们很少与公司实际拥有 LLM 支出的方式相符。财务部门希望受到团队、应用程序、环境、客户、合作伙伴或工作流程的限制。平台团队需要在请求分发到 OpenAI、Anthropic、Gemini、Azure OpenAI 或其他模型提供程序之前强制实施这些限制。正确的控制点通常是 API 网关,每个请求都可以在其中进行归因、估计、承认、降级、阻止和协调。
本指南介绍了 AI API 成本控制的网关层实现。它侧重于实时预算执行,而不是回顾性退款报告或广泛的成本优化计划。
提供商支出控制可以做什么和不能做什么
事实:主要提供商公开有用的控件,但它们在提供商定义的边界内运行。 OpenAI 记录组织和项目级别的每月 API 支出限制,以及组织限制、项目限制、分配的使用限制和耗尽的预付积分的明显错误。 Anthropic 记录工作区支出和速率限制,并提供 API 来检索配置的组织和工作区限制以进行内部警报。 Google 仅云预算提醒不会自动限制支出,而 Google 还记录符合条件的服务(例如 Gemini API 和代理平台)的支出上限预算。 Azure OpenAI 配额按订阅、区域、模型和部署类型以每分钟令牌为单位分配,速率限制计算可以包括提示估计和最大令牌,而不仅仅是最终计费令牌。
建议:保持启用提供商原生支出上限作为最后手段。不要将它们视为执行内部预算的主要机制。它们对于大多数所有权模型来说都过于粗糙,并且通常在请求路径已经脱离您的控制后触发。
预测:提供商控制将不断改进,但企业仍需要网关级政策,因为内部成本所有权的变化速度快于提供商帐户结构。
首先定义预算政策模型
从政策开始,而不是从代码开始。网关无法强制执行未准确描述的预算。
实用的政策记录应包括:
- 预算所有者:团队、部门、客户、合作伙伴、应用程序或工作流程所有者。
- 范围:与请求匹配的维度,例如
team_id、app_id、environment、customer_id和workflow_id。 - 重置间隔:每日、每周、每月、合同期或自定义时段。
- 软阈值:网关发出警告、降级、减少输出长度或路由至更便宜型号的点。
- 硬阈值:非关键流量被阻止的点。
- 允许的模型:此范围可以使用的模型。
- 后备型号:软阈值后允许使用更便宜或容量更低的型号。
- 关键性:工作负载是生产关键型、面向用户的、内部的、批量的还是实验性的。
- 紧急覆盖:谁可以延长限制、延长多长时间以及使用什么审核跟踪。
- 通知目标:Slack 频道、电子邮件组、事件服务、网络钩子或财务队列。
政策示例:
{
"budget_id": "budget_support_prod_monthly",
"owner_type": "team",
"owner_id": "customer_support",
"scope": {
"team_id": "customer_support",
"app_id": "support_assistant",
"environment": "production"
},
"currency": "USD",
"limit": 5000.00,
"reset_interval": "monthly",
"soft_threshold_percent": 80,
"hard_threshold_percent": 100,
"allowed_models": ["premium-chat", "standard-chat", "economy-chat"],
"fallback_models": ["standard-chat", "economy-chat"],
"criticality": "user_facing_production",
"on_soft_limit": ["notify", "downgrade_model", "reduce_max_output_tokens"],
"on_hard_limit": ["block_noncritical", "allow_emergency_override"],
"notification_targets": ["slack:#support-platform", "email:[email protected]"]
}
每个请求都需要所有权元数据
预算执行取决于归因。如果请求无法映射到预算范围,网关就无法做出可靠的准入决策。
要求内部客户发送稳定的所有权元数据:
{
"model": "premium-chat",
"messages": [...],
"max_tokens": 1200,
"metadata": {
"team_id": "customer_support",
"app_id": "support_assistant",
"environment": "production",
"customer_id": "cust_48291",
"workflow_id": "ticket_reply_draft"
}
}
建议:分阶段推出。首先记录未归属的流量。然后对其发出警告。然后在所有者有时间更新客户端后拒绝未归属的生产流量。对于开发流量,将其隔离到上限较低的默认预算中,而不是与生产支出混合。
还根据您的身份系统验证元数据。客户不应该能够通过更改 team_id 来索取其他团队的预算。将 API 密钥、服务帐户或合作伙伴凭据绑定到允许的预算范围。
发货前估算费用
预检评估是实时执行的核心。网关在将请求发送给提供商之前会估算最大可能的成本。
估算器需要:
- 输入、输出、缓存输入、批次、工具使用、图像、嵌入或其他计费维度的模型价格表。
- 每个模型系列的分词器或标记估计逻辑。
- 提示令牌计数或估计。
- 请求的
max_tokens或最大输出长度。 - 缓存假设(如果即时缓存影响计费)。
- 针对重试、工具调用、推理令牌、图像生成或多模式输入的提供商特定结算规则。
估算器输出示例:
{
"request_id": "req_7f1b",
"budget_scope": "team:customer_support/app:support_assistant/env:production",
"model": "premium-chat",
"input_tokens_estimated": 1850,
"max_output_tokens": 1200,
"estimated_cost": 0.0845,
"estimate_basis": "prompt_tokens_plus_max_output_tokens",
"confidence": "conservative"
}
建议:将飞行前费用视为保守的入场估算,而不是会计事实。如果用户请求 max_tokens: 4000,请保留该上限,即使响应通常停止于 700 个令牌。这降低了超支风险,但它可以拒绝在预算范围内完成的请求。这种权衡对于严格的财务控制来说是更可取的,而对于探索性内部工具来说吸引力较小。
发送请求之前预留预算
一种常见的失败模式是检查预算、找到可用余额,然后在记录支出之前允许许多并发请求通过。解决办法是保留。
入场顺序应为:
- 对调用者进行身份验证。
- 验证所有权元数据。
- 解决适用的预算政策。
- 估算请求费用。
- 自动从预算商店中预留预计费用。
- 仅当预订成功时才将请求发送给提供商。
- 完成后释放未使用的预留。
- 记录最终估计或提供商报告的使用情况。
预订存储必须支持原子更新。 Redis 可以使用 Lua 脚本、PostgreSQL 事务或专用账本服务。重要的属性是两个请求不能花费相同的剩余预算。
预订记录示例:
{
"reservation_id": "res_9d42",
"request_id": "req_7f1b",
"budget_id": "budget_support_prod_monthly",
"estimated_cost": 0.0845,
"state": "reserved",
"expires_at": "2026-09-28T12:45:00Z"
}
使用较短的预留期限,这样放弃的请求就不会永远锁定预算。后台清理程序应释放从未达到最终状态的过期预留。
将软限制与硬限制分开
软限制和硬限制的行为应有所不同。软限制是一个政策信号。硬性限制是一项录取决定。
软限制行为
当范围超过其软阈值时,网关仍然可以提供流量,同时减少支出压力。有用的回复包括:
- 向预算负责人和财务或平台渠道发送提醒。
- 添加显示限制状态和剩余预算的响应标头。
- 将非关键请求路由到更便宜的模型。
- 减少
max_tokens以获得详细的工作流程。 - 禁用昂贵的可选功能,例如多样本生成。
- 该预算范围内的新实验需要获得批准。
软限制响应元数据示例:
{
"budget_scope": "team:customer_support/app:support_assistant/env:production",
"limit_state": "soft_limit_exceeded",
"estimated_cost": 0.0310,
"remaining_budget": 912.44,
"applied_policy": ["downgrade_model", "reduce_max_output_tokens"],
"selected_model": "standard-chat"
}
硬限制行为
在硬阈值处,网关应使用可预测的错误协定来阻止非关键流量。
{
"error": {
"type": "budget_limit_exceeded",
"code": "llm_budget_hard_limit",
"message": "The budget for this scope has been exhausted.",
"budget_scope": "team:customer_support/app:support_assistant/env:production",
"retry_after": "2026-10-01T00:00:00Z",
"override_required": true
}
}
不要因网关预算失败而返回提供商形状的错误。内部客户端需要区分提供商速率限制、提供商支出上限、网关支出限制、身份验证失败和策略拒绝。
显式处理流式传输请求
流媒体会带来不同的执行问题。在网关知道最终输出令牌之前接受请求,并且生成的令牌可以在流打开时继续累积成本。
可行的模式是:
- 根据提示令牌和最大输出令牌保留保守的金额。
- 尽可能跟踪流期间生成的令牌。
- 如果预留量用完,则停止生成。
- 返回客户端可以处理的完成原因。
- 在提供商发送最终使用情况元数据后或在网关估计完成后协调实际使用情况。
流终止事件示例:
{
"type": "response.completed",
"finish_reason": "budget_exhausted",
"budget_scope": "customer:cust_48291/workflow:ticket_reply_draft",
"estimated_cost": 0.0845,
"remaining_budget": 0.00
}
权衡: 切断流可以保护预算,但可能会产生不完整的输出。对于需要完整结构化响应的工作流程,最好在流式传输开始之前进行预检阻止或模型降级。对于聊天式体验,如果客户可以要求用户稍后重试或继续使用更便宜的模型,那么考虑到预算的完成原因可能是可以接受的。
向客户公开预算状态
当呼叫者可以看到发生的情况时,预算执行就更容易采用。为内部客户端和合作伙伴 API 添加响应标头或元数据。
有用的字段包括:
budget_scopelimit_state:正常、soft_limit_near、soft_limit_exceeded、hard_limit_exceededestimated_costreserved_costfinal_cost_when_availableremaining_budgetapplied_policyselected_model
对于公共合作伙伴 API,如果具有商业敏感性,请避免泄露内部团队名称或成本基础。相反,公开租户安全的配额状态,例如remaining_quota、limit_state和retry_after。
使估算值与提供商的使用情况保持一致
请求时执行和会计级费用报告相关,但它们不是同一件事。网关估计在不确定的情况下做出录取决定。提供商结算导出、使用 API 和发票提供财务部门关心的记录。
建议: 至少每天将网关估算的支出与提供商报告的使用情况进行核对。差异可能来自标记器不匹配、提示缓存、批量折扣、重试、调用失败、提供商特定的舍入、图像或工具使用计费以及延迟计费导出。
调节作业应该:
- 导入提供商使用情况和费用数据。
- 将其标准化为网关的使用架构。
- 将提供商记录与可用的网关请求 ID 进行匹配。
- 将不匹配的提供商支出分配给最具体的已知范围。
- 针对预留过多或不足的情况调整预算分类帐。
- 按提供商、模型、团队、应用程序和环境发出差异报告。
对输入令牌、输出令牌、模型、提供商、请求 ID 和状态使用标准化遥测字段。 OpenTelemetry GenAI 语义约定定义令牌使用属性,有助于标准化跨提供商的使用遥测。
有意选择故障打开或故障关闭行为
廉价商店成为请求路径的一部分。这是实时执行的主要架构成本。
如果廉价商店不可用,则网关需要定义的行为:
- 打开失败:允许请求并标记它们以供以后协调。这可以保护可用性,但可能会超支。
- 关闭失败: 阻止请求,直到预算状态可用。这可以保护支出,但可能会破坏生产工作流程。
- 失败限制:仅允许关键生产流量、使用更便宜的模型、应用较低的每个请求上限,并阻止实验或批量工作负载。
建议:对大多数业务系统使用失败约束。关键生产工作流程继续运行,降低了成本风险,而可自由支配的工作负载则暂停,直到控制平面恢复。
实施清单
- 定义预算范围和所有权元数据。
- 将 API 个密钥或服务帐户绑定到允许的范围。
- 创建包含软限制、硬限制、允许的模型、后备、覆盖和通知目标的政策记录。
- 构建提供商感知的成本估算器。
- 在提供程序调度之前使用原子预算预留。
- 完成后释放未使用的预留。
- 通过稳定的合约实施硬限制错误。
- 添加流式令牌跟踪和预算敏感的完成原因。
- 通过内部标头或响应元数据公开预算状态。
- 启用提供商支出上限作为保障。
- 每天将网关估算值与提供商使用情况和费用报告进行核对。
- 针对差异、未归因流量、预算用尽和覆盖使用情况发出警报。
可行的结论
要可靠地执行 LLM 支出限制,请将决策放在请求进入系统的位置。提供商上限可以阻止帐户级损害,但网关政策可以强制执行领导者实际要求的业务限制:团队、应用、环境、客户、合作伙伴和工作流程预算。
最低可行设计很简单:需要所有权元数据、在调度前估算成本、自动保留预算、应用软阈值和硬阈值、单独处理流式传输以及与提供商使用数据进行协调。困难的部分不是第一个区块的决定。困难的部分是使系统具有足够的可预测性,以便财务部门信任它,并且制作团队可以在预算面临压力时继续运营。