快速结论:当你在 LiteLLM Proxy 的 litellm_settings 中配置了全局 max_budget 与 budget_duration(例如 1d),却发现预算不会按配置周期重置、请求持续返回 429 时,通常遇到的是这个 Issue。优先排查:全局预算的 budget_duration 是否被真正用于限额统计窗口(LiteLLM 目前对全局预算使用的是硬编码的滚动 30 天总花费)。
适用环境:Issue 讨论中出现的对象为 LiteLLM Proxy(涉及 litellm/proxy/proxy_server.py、litellm/proxy/auth/auth_checks.py、litellm/proxy/auth/user_api_key_auth.py、litellm/proxy/db/create_views.py),以及后台重置任务 ResetBudgetJob。Issue 中未明确给出具体的 Python、CUDA、PyTorch、显卡或依赖版本,这些项目无证据可确认。
最快修复方案:暂无确认的一步修复方案。该 Issue 在 2026-07-25 被关闭,评论中提出的“将全局花费基线查询按 budget_duration 窗口化(对 LiteLLM_SpendLogs 按 NOW() - budget_duration 求和)”属于计划性修复方案,尚未在 Issue 中确认已合并或已发布,因此只能作为“可优先尝试”的方向。
注意事项:Issue 正文指出,仅依赖 default_user_id(proxy-admin)行的 spend 并不能作为全局预算的替代来源,因为该计数器只统计管理员用户自身的花费,而非全代理总量。评论中提出的窗口化方案也明确表示会保留共享的 MonthlyGlobalSpend 视图(供管理界面使用)不动。若自行改动,需确认改动后全局预算仍能被 ResetBudgetJob 正确重置,并避免影响按用户、按团队、按密钥的预算行为。
问题场景
用户在 LiteLLM Proxy 的配置中设置全局预算,例如:
litellm_settings:
max_budget: 100
budget_duration: 1d
期望这是一个每日(1d)封顶的预算,但实际行为与预期不符:budget_duration 对全局预算被静默忽略,实际执行的是最近 30 天的滚动总花费。一旦滚动 30 天合计超过 max_budget,代理会对每个请求返回 429,并且不会按配置的周期重置,只有在花费逐步滚出 30 天窗口后才会恢复。
报错原文
[Bug]: `litellm_settings.max_budget` ignores `budget_duration`; global proxy budget is a hardcoded trailing-30-day cap
相关的内部报错信息(配置加载时):
budget_duration is required to use max_budget
以及 Issue 中引用的硬编码 30 天窗口 SQL:
WHERE "startTime" >= (CURRENT_DATE - INTERVAL '30 days')
sql_query = """SELECT SUM(spend) AS total_spend FROM "MonthlyGlobalSpend";"""
原因分析
最可能的原因是全局预算的“重置接线”与“执行检查”使用了两个不同的计数器,导致 budget_duration 被存储和重置,但在限额执行时从未被读取:
- 配置加载时,
_add_proxy_budget_to_db(litellm/proxy/proxy_server.py)会在budget_duration未设置时报错,然后写入 proxy-admin 用户行(default_user_id),带上max_budget、budget_duration和budget_reset_at。 ResetBudgetJob会在重置时间到达时把这个行的spend清零,说明重置逻辑是有意为之的(参考 PR #27488 中关于budget_reset_at回填的注释)。- 但执行检查走的是另一条路径:
_global_proxy_budget_check(litellm/proxy/auth/auth_checks.py:370)把litellm.max_budget与一个缓存的全局花费累加器(default_user_id:spend)比较,其基线来自litellm/proxy/auth/user_api_key_auth.py:447,随后在内存中按请求递增(litellm/proxy/proxy_server.py:2860)。 - 该基线查询使用
MonthlyGlobalSpend视图,而这个视图是硬编码的最近 30 天窗口(litellm/proxy/db/create_views.py:68),没有 duration 或 reset 的概念。
因此,1d、7d、30d 全都表现成最近 30 天封顶。按用户、按团队、按密钥的预算各自使用自己的可重置 spend 计数器,所以它们能正确遵循 budget_duration;全局预算是唯一无法做到这一点的。
环境排查
- 确认 LiteLLM Proxy 的部署方式与版本(Issue 未给出具体版本号,请以你实际运行的版本为准)。
- 确认配置文件中的
litellm_settings.max_budget与budget_duration是否同时设置。 - 确认全局花费是否来自
MonthlyGlobalSpend视图(涉及数据库为带INTERVAL语法的 SQL,通常为 PostgreSQL)。 - 检查
default_user_id行的spend、budget_reset_at是否按预期被ResetBudgetJob重置,以确认重置逻辑本身是否生效。 - Issue 未提供具体的 Python、CUDA、PyTorch、显卡或依赖版本,无需在这些项目上做无依据的推断。
解决步骤
- 先确认现象:设置一个较短的
budget_duration(如1d),观察超过max_budget后代理是否持续返回 429,以及是否在配置周期到达后恢复。若表现为“只随 30 天窗口滚动恢复”,即命中该 Issue。 - 确认全局预算执行路径:检查
_global_proxy_budget_check与_load_global_spend是否仍从MonthlyGlobalSpend视图取基线(对应硬编码 30 天窗口)。 - 可优先尝试的方向(来自 Issue 评论的修复计划,尚未确认已发布):将全局花费基线查询按配置的
budget_duration窗口化,即对LiteLLM_SpendLogs按NOW() - budget_duration求和,使封顶跟随滚动周期,并在花费滚出窗口后恢复。此改动应保留MonthlyGlobalSpend视图供管理界面使用,并避开default_user_id行(因为它只统计管理员用户自身花费)。 - 若你的部署确实采用固定 30 天窗口策略,另一条路径是:不再要求全局预算必须设置
budget_duration,并在文档中明确max_budget是最近 30 天封顶,而不是要求一个会被静默忽略的周期。 - 无论采用哪条路径,都需要覆盖回归测试:断言
budget_duration确实驱动限额统计窗口,而不是被固定 30 天视图覆盖。
验证方法
配置一个较短的 budget_duration(例如 1d)并触发超出 max_budget 的花费,确认在配置周期到达后预算能恢复、请求不再持续返回 429,且恢复时机与 budget_duration 一致,而不是固定等到 30 天窗口滚动。对于自行修改代码的情况,还需运行针对该行为的回归测试,确认时长驱动窗口统计。由于 Issue 中给出的修复方案尚未确认发布,若当前版本仍表现为 30 天封顶,请以实际版本行为为准,并关注上游修复进展。
参考来源
BerriAI/litellm PR #27488(fix: reset proxy budget when initial reset duration is null then updated)
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。
![[Bug]: Responses bridge returns a narrated tool call as TWO chat choices (text in choices[0] with finish_reason stop, function_call in choic](https://www.chat-gpts.plus/wp-content/uploads/2026/10/43316-2d1db511-768x403.jpg)
![[Security]: litellm PyPI package (v1.82.7 + v1.82.8) compromised — full timeline and status](https://www.chat-gpts.plus/wp-content/uploads/2026/10/24518-7eaf0753-768x403.jpg)
