Agent 账单装个仪表盘——LiteLLM + Grafana 成本看板
Agent 账单装个仪表盘——LiteLLM + Grafana 成本看板
一句话结论
成本治理的最后一步,说白了就是“看得见”。用 LiteLLM 自带的 /spend/logs 做数据源,Prometheus + Grafana 做展示,再加一条 Slack/飞书告警规则,整个看板 30 分钟就能搭完,代码不超过 50 行。之后每天扫一眼,钱花在哪一目了然。

五个关键指标
搭看板之前,先想清楚该盯什么。不是所有指标都值得放面板上,太多反而眼花。
| # | 指标 | 为什么重要 | 告警阈值 |
|---|---|---|---|
| 1 | 日总费用 | 最直观,老板唯一会问的 | > ¥50 |
| 2 | 按模型费用分布 | 找出哪个模型是烧钱大户 | 单一模型 > 60% |
| 3 | 按 API Key / 用户费用 | 定位是哪个 Agent 或谁在烧 | 单 Key 突增 3× |
| 4 | 请求失败率 | 失败 = 重试 = 白烧 Token | > 5% |
| 5 | 单次请求平均 Token | 异常长请求通常是 prompt 或循环 bug | > 均值 2× |
前三个盯钱,后两个盯异常。五个都绿,账单基本就不会出意外。
数据源:LiteLLM Spend Log
LiteLLM 自带 spend log,记录了每一次调用的模型、Token、费用。不需要额外埋点,拿来就能用。
curl -s "http://localhost:4000/spend/logs?start_date=$(date -u -d '24 hours ago' +%Y-%m-%dT%H:%M:%S)" -H "Authorization: Bearer sk-litellm-master-key-change-me" | jq '.[0]'
返回结构长这样:
{"request_id": "gpt-4o-2024-05-13-abc123","model": "gpt-4o","api_key": "sk-agent-data-analyst","prompt_tokens": 3500,"completion_tokens": 800,"spend": 0.023,"user": "data-team","startTime": "2026-07-23T08:15:00Z"}
Prometheus 不认识 JSON API,所以需要加一层 exporter。最简方案:写一个 Python 脚本把 spend log 转成 Prometheus metrics,暴露在 /metrics 端点。
搭看板
Step 1:写一个最小 Prometheus Exporter
最小可用版本只做三件事:拉 LiteLLM Spend Log、按模型累加费用、把请求/Token 计数暴露出去。这样后续 Grafana 面板和告警查询就能直接用 Prometheus 的 rate() 函数了。
# spend_exporter.py — 把 LiteLLM spend log 暴露为 Prometheus metricsimport timefrom datetime import datetime, timedeltaimport requestsfrom prometheus_client import Counter, start_http_serverAPI = "http://localhost:4000/spend/logs"HEADERS = {"Authorization": "Bearer sk-litellm-master-key-change-me"}# 累积型指标:用 rate() 做趋势分析cost_total = Counter("agent_cost_rmb_total", "Cumulative API spend in RMB", ["model"])request_total = Counter("agent_request_total", "Total requests", ["model"])prompt_tokens_total = Counter("agent_prompt_tokens_total", "Total prompt tokens", ["model"])completion_tokens_total = Counter("agent_completion_tokens_total", "Total completion tokens", ["model"])# 只抓“自上次拉取以来新增”的日志,避免重复计数last_fetch = datetime.utcnow() - timedelta(hours=24)def collect():global last_fetchstart_date = last_fetch.strftime("%Y-%m-%dT%H:%M:%SZ")resp = requests.get(API,headers=HEADERS,params={"start_date": start_date},timeout=10,)resp.raise_for_status()logs = resp.json() if isinstance(resp.json(), list) else resp.json().get("data", [])for r in logs:model = r.get("model", "unknown")spend = float(r.get("spend", 0) or 0)prompt_tokens = int(r.get("prompt_tokens", 0) or 0)completion_tokens = int(r.get("completion_tokens", 0) or 0)cost_total.labels(model=model).inc(spend)request_total.labels(model=model).inc()prompt_tokens_total.labels(model=model).inc(prompt_tokens)completion_tokens_total.labels(model=model).inc(completion_tokens)last_fetch = datetime.utcnow()if __name__ == "__main__":start_http_server(9090)while True:collect()time.sleep(60)
跑起来也很简单:
pip install prometheus-client requestspython spend_exporter.py &curl localhost:9090/metrics | grep agent_
输出会类似:
agent_cost_rmb_total{model="gpt-4o"} 0.82agent_cost_rmb_total{model="gpt-4o-mini"} 0.15agent_cost_rmb_total{model="claude-sonnet-4-20250514"} 1.23agent_request_total{model="gpt-4o"} 13agent_prompt_tokens_total{model="gpt-4o"} 48200
Step 2:Prometheus 配置
# prometheus.ymlscrape_configs:- job_name: "agent-cost"scrape_interval: 60sstatic_configs:- targets: ["localhost:9090"]
Step 3:Grafana 面板
导入 Prometheus 数据源后,建一个 Dashboard,四个面板:
面板 1:成本趋势(折线图)
sum(rate(agent_cost_rmb_total[5m])) * 60
这条查询的含义是“每分钟成本速率”。如果想看单位小时的费用,改成 sum(rate(agent_cost_rmb_total[1h])) * 3600 即可。
面板 2:按模型成本占比(饼图)
sum by (model) (rate(agent_cost_rmb_total[5m]))
面板 3:请求失败率(单值)
如果有失败日志或单独的失败计数器,可以这样写:
sum(rate(agent_request_failures_total[5m])) / sum(rate(agent_request_total[5m])) * 100
如果只能拿到 LiteLLM spend/logs,那失败率通常要另行接入失败日志或业务侧状态字段,不建议直接拿 Token 数做分母。
面板 4:Top 5 模型成本(表格)
topk(5, sum by (model) (rate(agent_cost_rmb_total[5m])))
告警规则
看板是给人看的,告警是替人盯的。重点盯两个场景:
1. 单日费用超标
# prometheus alert rulesgroups:- name: agent_costrules:- alert: DailyBudgetExceededexpr: sum(rate(agent_cost_rmb_total[5m])) * 60 > 2for: 5mlabels:severity: warningannotations:summary: "Agent 成本速率异常"description: "当前费用增长速率为 ¥{{ $value }} / 分钟,请检查是否有异常调用"
这里的“超标”不再看某个瞬时 gauge,而是看“增长速率”。这样更符合成本监控的真实业务场景:你需要盯的是“是不是在持续烧钱”,而不是单一时刻的当前总量。
2. 单次请求 Token 突增
- alert: TokenSpikeexpr: sum by (model) (rate(agent_prompt_tokens_total[5m])) > 20000for: 1mlabels:severity: warningannotations:summary: "单个模型 Prompt Token 速率异常"description: "模型 {{ $labels.model }} 当前速率为 {{ $value }} tokens/秒"
连飞书/Slack 通知
Prometheus Alertmanager 自带飞书 webhook 支持:
# alertmanager.ymlreceivers:- name: "feishu"webhook_configs:- url: "https://open.feishu.cn/open-apis/bot/v2/hook/your-hook-id"send_resolved: true
搞定。费用超标时飞书机器人直接弹消息。
没有 Prometheus 的极简方案
如果你不想搭 Prometheus + Grafana 全家桶,一个 crontab 也够用:
# crontab -e每天 18:00 跑0 18 * * * curl -s "http://localhost:4000/spend/logs?start_date=$(date -u -d 'today 00:00' +%Y-%m-%dT%H:%M:%S)" -H "Authorization: Bearer sk-litellm-master-key-change-me" | python3 -c "import json,syslogs = json.load(sys.stdin) if isinstance(json.load(sys.stdin), list) else json.load(sys.stdin).get('data',[])total = sum(r.get('spend',0) for r in logs)print(f'今日费用: ¥{total:.2f}| 请求数: {len(logs)}')if total > 100:print('⚠️ 超预算!')"
单行命令,零依赖。先跑起来,不够用了再上 Prometheus。
一步汇总
| 方案 | 时间 | 适用 |
|---|---|---|
| crontab + curl | 5 分钟 | 个人项目、日均 < ¥10 |
| Python exporter + Prometheus + Grafana | 30 分钟 | 团队、多 Agent、日均 > ¥50 |
| 加 Alertmanager | +10 分钟 | 不想每天盯着看 |
先上 crontab,费用破 ¥50/天再升到 Grafana。
下一步
诊断 → 治理(Prompt + 工具 + 模型路由 + 缓存)→ 监控,四篇覆盖了一条完整链路。你手里现在有全套工具箱了。
下篇写一个综合案例:从头到尾治理一个真实 Agent,把四篇的方法论串起来走一遍,看最终省了多少。
你现在是怎么盯 Agent 费用的? 每天翻 LiteLLM 日志、靠月底账单惊吓、还是压根没看?评论区聊聊,我看看有多少人在裸奔。