快速结论:当 OpenAI 兼容聚合器(aggregator)在响应或流式 usage 块里返回非 USD 单位的 usage.cost 字段时,LiteLLM 会把它原样当成美元计入 spend,绕过你为模型配置的 input_cost_per_token/output_cost_per_token,导致记账金额被放大若干数量级并瞬间触发 max_budget。优先排查上游返回的 usage.cost 单位,以及该请求是流式还是非流式。
适用环境:Issue 中确认的场景为自托管 LiteLLM proxy(镜像 ghcr.io/berriai/litellm-database:main-latest),前置 OpenAI 兼容聚合器(MixRoute、cortecs.ai),使用 custom_llm_provider: openai + model: openai/<model> + api_base。问题在 v1.98.1、v1.102.0、v1.104.0 上均被复现。Issue 未提供操作系统、Python、CUDA、显卡等环境信息。
最快修复方案:暂无确认的一步修复方案。Issue 明确说明 v1.104.0 中该场景仍然存在,PR #39441 只修了 xAI 路径并限制了 OpenRouter 的 header 快捷方式,通用路径未修复。若你正被预算锁死,Issue 报告者恢复方式是手动执行 UPDATE "LiteLLM_UserTable" SET spend = 0 ... 并重启容器(spend 在进程内缓存),但这只是清账、不是修复。
注意事项:不建议仅靠“等官方修复”恢复生产;Issue 报告者验证过所有 custom-callback 钩子点都在 cost 被写入之后才执行,因此无法用 callback 在配置层面覆盖该值。上面的 SQL 清零会丢失真实的历史 spend 记录,属于应急手段;重启是必须的,否则进程内缓存的 spend 不会被刷新。
问题场景
你在自托管 LiteLLM proxy 后面接一个 OpenAI 兼容的聚合器/网关,通过 custom_llm_provider: openai 加 api_base 的方式把上游当作 openai/ 模型调用(例如 model: openai/grok-4.5),并为该模型组配置了自定义的 input_cost_per_token/output_cost_per_token。当上游在 chat completion 响应的 usage 里附带一个非标准的 cost 字段(流式请求会出现在拼接后的 usage 块中),LiteLLM 会把这个数字直接当作美元花费记账。
Issue 中两个真实案例:MixRoute 的 usage.cost: 3144000 实际是纳美元(nano-dollar,1e-9 USD),真实成本约 $0.003144,却被记为 $3,144,000;cortecs.ai 用微单位(micro-unit),真实成本 $0.000500878 的流式请求被记为 spend = 503.0,而同一请求的非流式版本记账正确。两条路径下自定义定价从未被使用,cost_breakdown.total_cost 为 0。因为 proxy 的预算控制直接读取这个膨胀后的 spend,一次请求就能把密钥预算打穿。
报错原文
Provider-reported usage.cost is trusted verbatim as USD spend with no unit validation — causes astronomical phantom spend
Budget has been exceeded! Current cost: 26364009.05191107, Max budget: 25.0
上游返回的原始 usage 片段示例:
"usage": {
"prompt_tokens": 209,
"completion_tokens": 19,
...
"cost": 3144000
}
Issue 中 LiteLLM_SpendLogs 的两条异常记录:
request_id 9e9da91a-... spend 368424000 prompt_tokens 18335 completion_tokens 65
request_id 2981dd9e-... spend 26364000 prompt_tokens 743 completion_tokens 228
原因分析
按 Issue 中的代码追踪,根因在成本计算链路对 provider 上报值的“无单位信任”:
litellm/types/utils.py中Usage.cost: Optional[float] = None是一等 Pydantic 字段,本意是给 Perplexity、OpenRouter 这类会自己上报准确 USD 成本的 provider 使用。litellm/litellm_core_utils/streaming_handler.py的_propagate_usage_cost_to_hidden_params():只要拼接后的流式响应里usage.cost不为None,就原样写进response._hidden_params["additional_headers"]["llm_provider-x-litellm-response-cost"]。litellm/cost_calculator.py的response_cost_calculator()里,只要get_response_cost_from_hidden_params()返回非None,就直接return provider_response_cost,完全跳过按 token 和配置单价的本地计算。
Issue 报告者进一步指出这是个 fail-open 的设计问题:v1.104.0 中 litellm/main.py:8868 的 _CALCULATOR_PRICED_REPORTED_COST_PROVIDERS 只有 {LlmProviders.XAI.value} 一个例外,即“原样信任”是所有 provider 的默认行为,xAI 反而是唯一被排除的;非流式路径本已通过 _without_provider_stated_cost()(cost_calculator.py:1194)在存在自定义定价时剥离 provider 上报成本,流式路径却绕过了它,所以同一部署下流式与非流式记账结果不一致。
由于裸数字不带单位(xAI 自己的数值就需要除以 10,000,000,000 才是 USD),任何 provider 新增或改变一个 cost 形状的字段,都会静默改变 custom_llm_provider: openai 这一整个自定义端点生态的计费行为。这是 可能原因层面的判断:Issue 已确证流式路径会原样采用上报值,但具体到你自己的上游 cost 字段是什么单位,需要用 curl 直接验证。
环境排查
- 确认 LiteLLM 版本:Issue 在 v1.98.1、v1.102.0、v1.104.0 上均复现,v1.104.0 仍 live。
- 确认部署方式与镜像标签(Issue 使用
ghcr.io/berriai/litellm-database:main-latest)。 - 确认模型配置里
custom_llm_provider是否为openai,model是否带openai/前缀,以及api_base指向的聚合器地址。 - 确认
model_info/litellm_params中是否配置了input_cost_per_token/output_cost_per_token(Issue 中该配置存在但被忽略)。 - 确认请求是否为流式(stream),因为流式与非流式路径行为不同。
- 确认
litellm_settings.max_budget的设置值,用于判断打穿预算的阈值。 - 用 curl 直连上游
api_base,不带 LiteLLM,检查响应usage里是否存在cost字段及其数量级——这是判断单位的关键证据。 - Issue 未涉及 Python、CUDA、PyTorch、显卡版本,无需据此排查。
解决步骤
- 先用 curl 绕过 LiteLLM 直接请求上游,抓取原始响应(流式请求要拿到拼接后的 usage 块),确认
usage.cost是否存在、数值大约是多少,并对照真实费用推算其单位(纳美元 ×10⁹、微单位 ×10⁶ 等)。 - 在 proxy 数据库中查询
LiteLLM_SpendLogs,按request_id对比记录下来的spend与prompt_tokens/completion_tokens,看是否存在与 token 数完全不匹配的异常大额记录。 - 同时发一条流式请求和一条完全相同的非流式请求,比较两者记账。Issue 中非流式走的是
_without_provider_stated_cost()路径、记账正常,流式则被上游数值覆盖——这个对比可以快速定位是流式路径的问题。 - 确认自己确实被
max_budget锁死(报错形如Budget has been exceeded! Current cost: ... Max budget: ...)后,按 Issue 报告者做法应急恢复:对LiteLLM_UserTable(以及相关 team/key 预算表)执行UPDATE ... SET spend = 0,然后重启容器,因为 spend 在进程内缓存,不重启不会刷新。 - 等待或跟进上游修复。PR #39441 只修了 xAI 路径并限制了 OpenRouter 的 header 快捷方式,没有解决通用场景;Issue 报告者建议的方向是:存在运维配置定价时该定价不可被响应覆盖、仅由 adapter 显式声明 USD 契约时才信任上报值、加入与 token 计算成本的 10× 量级校验,以及提供
trust_provider_cost: true之类的显式开关。这些属于建议而非已验证的一步修复。 - 如果无法立即升级且上游字段无法关闭,可优先尝试的缓解方向是临时切到非流式调用,或与上游沟通去掉该
cost字段——但这只是规避,Issue 中并未给出经过验证的配置级禁用方式,且报告者已验证所有 custom-callback 钩子点都在 cost 写入之后执行。
验证方法
修复或规避生效后,重放同一条会触发问题的流式请求,再查 LiteLLM_SpendLogs:该条记录的 spend 应当与按 input_cost_per_token/output_cost_per_token 和实际 token 数算出的金额一致(Issue 中对应场景应只有几分钱),而不是出现 368424000、26364000、503.0 这类量级的数字。同时确认不再触发 Budget has been exceeded!,并且流式请求与非流式孪生请求的记账结果一致(Issue 中的异常正是两者不一致)。
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。
![[Bug]: Streaming failure callbacks bypass duplicate logging guard and enqueue repeated S3 uploads](https://www.chat-gpts.plus/wp-content/uploads/2026/10/42988-00a3ce71-768x403.jpg)

