litellm 1.52 的 proxy 起了三个副本,给虚拟 key 设了 max_budget 5,spend 已经到 8.3 美元,请求照样 200,重启 proxy 和重建 key 都试过。

一开始怀疑是「spend 写入走异步队列,多副本各自记账,检查时对不上」,查了一圈,方向不对。

真正麻烦的地方在于,几个原因的现象几乎一样。只写了 max_budget 没写 budget_duration,窗口判定和预期不一致。也可能是调用用的是 master key,虚拟 key 的预算根本不参与校验。

不容易想到的是,预算按美元记账,请求里的用量没折算成成本。

动手时先查这个 key 的 spend 和预算字段

curl -s http://127.0.0.1:4000/key/info -H "Authorization: Bearer sk-master" -d "key=sk-test" | jq '.info'

带上虚拟 key 发一次最小请求

curl http://127.0.0.1:4000/v1/chat/completions -H "Authorization: Bearer sk-test" -H "Content-Type: application/json" -d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"hi"}],"max_tokens":1}'

接着把预算周期补上再更新 key

curl -X POST http://127.0.0.1:4000/key/update -H "Authorization: Bearer sk-master" -H "Content-Type: application/json" -d '{"key":"sk-test","max_budget":5,"budget_duration":"30d"}'

末了看 spend logs 是否记到了这次调用

curl -s "http://127.0.0.1:4000/spend/logs?api_key=sk-test" -H "Authorization: Bearer sk-master" | jq '.[0]'

排查用的命令都是临时敲的,没有写成脚本,事后才整理。

恢复的判定其实很直接。spend 超过 5 美元后同一个 key 的请求返回 400 budget exceeded,spend logs 能在几秒内查到这次调用。

这里还有个坑。预算靠代理自己记账,多副本部署要把数据库和 Redis 配好,否则每个副本各算各的,限额永远拦不住。报错文案容易误导,真正的原因往往在相邻那一层的日志里。

作者 9823189