快速结论:在 LiteLLM 代理中设置 litellm_settings.max_budget 并指定 budget_duration 后,budget_duration 被忽略,全局预算实际按硬编码的过去 30 天滚动总花费生效,导致配置的每日/每周上限不重置。优先检查是否将 max_budget 与 budget_duration 配合使用,并确认实际行为是否为 30 天窗口。
适用环境:LiteLLM 代理(proxy)配置了 litellm_settings.max_budget 和 budget_duration 的场景。Issue 不涉及特定操作系统、Python、CUDA 版本。
最快修复方案:暂无确认的一步修复方案。该问题在代码层面尚未合并修复补丁,当前需要等待 LiteLLM 官方修复或手动修改源码。若有紧急需求,可优先尝试自行修改 litellm/proxy/auth/user_api_key_auth.py 中的 _load_global_spend 函数,将查询窗口从硬编码的 MonthlyGlobalSpend 视图(30 天)改为根据 budget_duration 动态计算窗口(例如使用 NOW() - budget_duration 条件),但此改动未经官方验证且可能影响其他功能。
注意事项:Issue 中提到的方案(窗口化基线查询)仅是开发者计划,尚未合入主分支,自行修改需谨慎测试,并注意保留 MonthlyGlobalSpend 视图(用于管理界面)不破坏。另外,default_user_id 行的 spend 仅记录管理员用户自己的花费,不可作为代理总花费直接替代。
问题场景
用户在 LiteLLM 代理配置文件中设置全局预算和预算周期(如 max_budget: 100,budget_duration: 1d),预期每日花费不超过 100 单位,实际却变成过去 30 天滚动总花费限制,且一旦触发 429 响应后无法按预期周期恢复。
报错原文
# 配置示例
litellm_settings:
max_budget: 100
budget_duration: 1d
# 实际行为:budget_duration 被忽略,全局预算基于 trailing-30-day 窗口
# 超出后所有请求返回 429,直到 30 天前花费过期才恢复
# 内部错误:ResetBudgetJob 重置了 default_user_id 行的 spend,但强制执行从不读取该计数器
# 相关查询:SELECT SUM(spend) AS total_spend FROM "MonthlyGlobalSpend";
# MonthlyGlobalSpend 视图定义:WHERE "startTime" >= (CURRENT_DATE - INTERVAL '30 days')
原因分析
可能原因:LiteLLM 代理内部存在两个相互矛盾的计数器:
- 重置计数器:
default_user_id(代理管理员用户行)的spend按budget_duration被ResetBudgetJob定期清零,但这个计数器仅记录管理员自身花费,不是代理总花费。 - 强制执行计数器:
_global_proxy_budget_check读取的是全局花费累加器,其基线来自MonthlyGlobalSpend视图,该视图硬编码为过去 30 天窗口。 budget_duration被存储并用于重置,但强制执行从未读取这个窗口,导致配置的周期(1d、7d、30d)全部表现为 30 天滚动上限。这是设计上的不一致:全局预算作为唯一不读取自身重置计数器的预算类型。
环境排查
- 确认 LiteLLM 版本(建议至少 1.0.0+,Issue 在 2026 年提出,版本可能较新)
- 检查代理配置中
litellm_settings.max_budget和budget_duration是否同时设置 - 使用数据库客户端查询
MonthlyGlobalSpend视图内容,确认窗口为 30 天 - 检查
ResetBudgetJob是否正确执行,并能看到default_user_id行的spend被重置(但不影响全局限制)
解决步骤
- 确认问题影响范围:通过以下步骤验证
budget_duration被忽略: - 设置
max_budget: 100、budget_duration: 1d,触发超过 100 花费后所有请求返回 429。 - 等待超过 1 天(或预期重置时间),观察 429 是否解除。如果仍然阻塞(需等到 30 天前的花费过期),则确认问题存在。
- 临时工作绕行:如果无法等待官方修复,可考虑手动修改源码(风险自负):
- 定位到
litellm/proxy/auth/user_api_key_auth.py中的_load_global_spend函数。 - 将原来查询
MonthlyGlobalSpend视图的逻辑改为直接查询LiteLLM_SpendLogs表,窗口条件设置为NOW() - budget_duration(需要从代理设置中获取budget_duration值)。 - 注意保留对未设置
budget_duration时的回退行为(默认 30 天)。 - 添加单元测试确保窗口正确。
- 等待官方修复:关注 Issue #31292 的进展,或提交 Pull Request 以合并修复。
验证方法
修改后重新启动代理,用测试用户反复产生花费,确认:
- 设置
budget_duration: 1d且max_budget: 100,第一天达到 100 后应返回 429。 - 第二天(超过 1 天窗口)请求应恢复正常。
- 观察数据库日志确认查询窗口不再是固定的 30 天。
- 检查
ResetBudgetJob是否仍正常重置但不再影响全局限制。
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。
![[Question]: [ERROR]Generate embedding error:SILICONFLOWEmbed.encode got invalid response from https://api.siliconflow.cn/v1/embeddings](https://www.chat-gpts.plus/wp-content/uploads/2026/07/8183-92f3ad0a-768x403.jpg)
![[Question]: Successful parsing and chunking but Retrieval Testing always has 0 Files](https://www.chat-gpts.plus/wp-content/uploads/2026/07/8001-c0eccc63-768x403.jpg)
