恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
基于LiteLLM与Grafana构建AI应用成本监控仪表盘实战
首页
资讯中心
/
基于LiteLLM与Grafana构建AI应用成本监控仪表盘实战
基于LiteLLM与Grafana构建AI应用成本监控仪表盘实战
发布时间:2026/8/14 22:51:15
1. 项目概述为什么我们需要一个AI成本仪表盘最近几个月我身边搞AI应用开发的朋友们十个里有八个都在抱怨同一个问题成本失控。大家纷纷把各种大模型API比如OpenAI的GPT-4、Anthropic的Claude还有国内的一众模型集成到自己的Agent、聊天机器人或者自动化流程里一开始觉得调用一次才几美分毛毛雨啦。结果月底账单发过来好家伙直接傻眼少则几百刀多则几千上万钱花哪儿了完全是一笔糊涂账。这其实就是典型的“云账单恐惧症”在AI时代的翻版。以前用云服务器好歹有AWS Cost Explorer、阿里云费用中心这类工具能按服务、按实例、按时间粒度看个明白。但现在你的成本分散在十几个不同的模型提供商那里每家计费方式还不一样——有的按Token有的按请求次数有的还有复杂的阶梯定价。更头疼的是当你在一个系统里同时调用了GPT-4做推理、Claude写文档、Whisper转语音时你根本分不清是哪个功能、哪个用户、甚至哪段代码产生了主要开销。没有可视化的数据优化成本就无从谈起只能凭感觉瞎猜。所以当我看到“Agent账单装个仪表盘”这个需求时立刻觉得这太有必要了。它的核心价值就是把原本黑盒的、分散的AI API调用成本通过一个统一的中间层进行收集、聚合和可视化让你能像看股票大盘一样实时掌握你的“AI算力开销”。而LiteLLM和Grafana的组合恰好是解决这个痛点的“黄金搭档”。LiteLLM作为一个轻量级的代理和标准化层能无缝对接几十种大模型API并统一记录每一次调用的详细日志Grafana则是数据可视化的王者能将这些日志转化为直观、可交互的仪表盘。这个项目本质上是在为你的AI应用搭建一个“财务总监”。2. 核心组件选型与架构设计2.1 为什么是LiteLLM不仅仅是代理市面上做模型代理和统一接口的工具不少比如LocalAI、OpenRouter但我最终选择LiteLLM是因为它在成本监控这个场景下有几个不可替代的优势。首先它的定位极其精准。LiteLLM的核心目标就是“标准化”和“可观测性”。它提供了一个统一的Python接口让你用completion(model‘gpt-4’, messages…)这样的方式调用任何支持的模型背后它会自动处理不同API的认证、参数映射和响应解析。这本身就简化了代码。但更重要的是它内置了强大的日志和审计功能。每一次通过LiteLLM发起的调用其请求内容、响应内容、使用的模型、消耗的Token数包括Prompt和Completion、响应延迟、以及——最关键的一一根据内置的定价表计算出的本次调用成本都会被完整记录。这些数据可以直接输出到控制台、文件或者通过Callback函数发送到任何你指定的地方比如数据库。这就为我们后续的成本分析提供了最原始、最细粒度的数据源。其次它的社区定价表是活的。大模型API的定价变动不算频繁但偶尔也会有调整。LiteLLM维护着一个开源的价格列表社区会持续更新。这意味着你计算成本时可以相对准确地反映市场价格而不是用一个过时的静态数字。当然对于成本管控要求极高的场景你也可以完全覆盖这个定价表使用你自己的合同价。最后它足够轻量和灵活。你不需要部署一个庞大的服务集群可以把它直接集成到你的应用代码中也可以作为一个独立的代理服务器litellm --model来运行。这种灵活性使得它既能适应快速验证的小项目也能支撑有一定规模的线上服务。注意LiteLLM本身不存储历史日志它只负责生成和输出。因此架构设计的核心之一就是如何可靠、高效地收集并持久化这些日志数据。2.2 为什么是Grafana可视化与告警的标杆有了成本数据下一步就是让人能看懂。Grafana几乎是这个领域的事实标准原因有三数据源兼容性无敌它支持从Prometheus、MySQL、PostgreSQL、Elasticsearch、Loki等几十种数据源中查询数据。无论你把LiteLLM的日志存到哪里Grafana大概率都能连上。面板丰富且灵活时间序列图、柱状图、饼图、表格、状态图……你可以自由组合创建一个高度定制化的看板。比如一个总览图展示今日总成本曲线一个饼图展示各模型成本占比一个表格列出最“烧钱”的十个用户或功能。告警功能成熟这是成本管控的灵魂。你可以设置阈值告警例如“当过去一小时内GPT-4的成本超过50美元时自动发送Slack消息或邮件”。这能让你在成本失控前及时干预而不是等到月底看账单。我们的架构思路因此变得清晰LiteLLM作为数据生产者负责在每次AI调用时生成带成本的日志一个中间件如Python脚本或Fluentd负责收集这些日志并存入一个时序数据库或关系型数据库Grafana则连接这个数据库进行查询和可视化展示。2.3 整体架构设计图逻辑层面虽然不能画图但我们可以用文字描述清楚这个数据流[你的AI应用/Agent] | v (通过LiteLLM Client发起调用) [LiteLLM Proxy/Integration] | v (生成结构化日志包含timestamp, model, prompt_tokens, completion_tokens, cost, user_id, custom_tag等) [日志收集器 (如将日志写入文件/stdout或被Filebeat/Fluentd采集)] | v [数据存储层 (如: Prometheus Pushgateway, InfluxDB, 或 MySQL/PostgreSQL)] | v [Grafana (配置对应数据源编写查询SQL/PromQL绘制仪表盘)]这个架构的关键在于数据存储层的选择它直接影响了查询的效率和仪表盘的灵活性。3. 数据链路搭建从日志生成到存储3.1 配置LiteLLM生成详细成本日志首先我们需要确保LiteLLM能吐出我们需要的所有信息。这里有两种主流集成方式方式一代码集成适用于应用内集成在你的Python代码中初始化LiteLLM时开启logging并设置一个自定义的callback函数。import litellm from litellm import completion import json from datetime import datetime # 定义一个回调函数处理每一条日志 def cost_log_callback( kwargs, # 包含请求参数如model, messages completion_response, # 包含响应和usage start_time, end_time # 请求开始和结束时间 ): log_entry { “timestamp”: datetime.utcnow().isoformat(), “model”: kwargs.get(“model”), “user”: kwargs.get(“user”, “default”), # 可以传递用户ID “project”: kwargs.get(“metadata”, {}).get(“project”, “default”), # 自定义标签 “prompt_tokens”: completion_response[‘usage’][‘prompt_tokens’], “completion_tokens”: completion_response[‘usage’][‘completion_tokens’], “total_tokens”: completion_response[‘usage’][‘total_tokens’], “cost”: completion_response[‘cost’], # LiteLLM自动计算 “response_time”: (end_time - start_time).total_seconds() } # 将日志写入文件生产环境建议用异步或发送到消息队列 with open(“/var/log/litellm_cost.log”, “a”) as f: f.write(json.dumps(log_entry) “\n”) # 设置litellm的回调 litellm.success_callback [cost_log_callback] litellm.failure_callback [cost_log_callback] # 失败请求也记录用于排查 # 现在你的所有completion调用都会被记录 response completion( model“gpt-4”, messages[{“role”: “user”, “content”: “Hello”}], user“user_123”, # 标识用户 metadata{“project”: “customer_support_bot”} # 自定义标签 )方式二代理服务器模式适用于多语言或解耦架构如果你不想改代码或者你的应用是用其他语言写的可以独立运行LiteLLM代理。# 启动代理指定模型和API key litellm --model gpt-4 --api_key sk-xxx --port 8000 # 你的应用只需向 http://localhost:8000 发送OpenAI兼容的请求即可。在这种模式下你需要配置LiteLLM将日志输出到标准输出或文件然后使用日志收集工具如Fluentd, Vector, 或简单的Python脚本来抓取并解析这些日志行。实操心得在生产环境强烈建议将日志写入一个结构化的日志文件如JSON Lines格式并立即被日志收集器拖走避免文件无限增长。同时务必在日志中加上能区分业务、用户、功能模块的自定义标签如project,feature,environment这是后期做多维度成本分析的基础。3.2 选择与配置数据存储日志数据需要存到一个Grafana能方便查询的数据库里。这里有几个主流选择方案APrometheus Pushgateway适合云原生环境Prometheus是监控领域的王者擅长处理时序数据。优点与Grafana天生一对查询语言PromQL强大适合做聚合分析和告警。缺点不适合存储高基数high cardinality的标签数据比如每个不同的用户ID都作为一个标签值且数据通常有保留时间。如何做写一个小的Python脚本读取LiteLLM的日志文件将cost指标按model、project等标签推送到Pushgateway再由Prometheus抓取。方案BInfluxDB专为时序数据优化InfluxDB是另一个流行的时序数据库。优点写入和查询性能高专门为监控、IoT等场景设计。缺点开源版本OSS功能有限集群版需要商业许可。方案CMySQL/PostgreSQL关系型数据库通用灵活如果你的团队对SQL更熟悉或者成本数据需要与其他业务数据关联查询这是个好选择。优点灵活支持复杂查询易于维护数据持久化。缺点对于时间序列数据的聚合查询如“每分钟平均成本”性能可能不如专门的时序数据库数据量大时需要良好的索引设计。我个人推荐的选择对于大多数中小型项目使用PostgreSQL是一个平衡了灵活性、性能和上手难度的方案。下面以PostgreSQL为例进行说明。首先创建一张表来存储成本日志CREATE TABLE litellm_cost_logs ( id SERIAL PRIMARY KEY, timestamp TIMESTAMPTZ NOT NULL, model VARCHAR(100) NOT NULL, user_id VARCHAR(100), project VARCHAR(100), feature_tag VARCHAR(100), prompt_tokens INTEGER, completion_tokens INTEGER, total_tokens INTEGER, cost_usd DECIMAL(10, 6), -- 成本单位美元 response_time_sec DECIMAL(10, 3), metadata JSONB -- 用于存储其他任意标签 ); -- 创建索引以加速按时间和维度的查询 CREATE INDEX idx_litellm_logs_time ON litellm_cost_logs (timestamp); CREATE INDEX idx_litellm_logs_model ON litellm_cost_logs (model); CREATE INDEX idx_litellm_logs_project ON litellm_cost_logs (project);然后修改之前的cost_log_callback函数将日志直接写入PostgreSQL生产环境建议使用连接池和异步写入如asyncpg库避免阻塞主线程。# 示例使用psycopg2同步写入适用于低压力场景或测试 import psycopg2 conn psycopg2.connect(database“your_db”, user“user”, password“pass”, host“localhost”) cursor conn.cursor() def cost_log_callback_db(kwargs, completion_response, start_time, end_time): insert_sql “”” INSERT INTO litellm_cost_logs (timestamp, model, user_id, project, prompt_tokens, completion_tokens, total_tokens, cost_usd, response_time_sec) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s) “”” cursor.execute(insert_sql, ( datetime.utcnow(), kwargs.get(“model”), kwargs.get(“user”), kwargs.get(“metadata”, {}).get(“project”), completion_response[‘usage’][‘prompt_tokens’], completion_response[‘usage’][‘completion_tokens’], completion_response[‘usage’][‘total_tokens’], completion_response[‘cost’], (end_time - start_time).total_seconds() )) conn.commit()4. Grafana看板配置实战数据入库后最激动人心的部分来了——用Grafana让它“活”起来。假设我们已经安装好Grafana并添加了PostgreSQL作为数据源配置过程略主要是填写数据库地址、用户名密码。4.1 创建第一个面板总成本趋势图这个面板让你一眼看清成本随时间的变化是仪表盘的“头条”。新建Dashboard-Add panel。数据源选择你的PostgreSQL。查询编辑器中编写SQLSELECT $__timeGroupAlias(timestamp, ‘1h’), SUM(cost_usd) as “total_cost” FROM litellm_cost_logs WHERE $__timeFilter(timestamp) GROUP BY 1 ORDER BY 1$__timeFilter和$__timeGroupAlias是Grafana的宏会自动替换为当前仪表盘选中的时间范围和聚合间隔。这里按1小时聚合总成本。可视化类型选择“Time series”。面板设置Title:总成本趋势 (USD)Y轴单位选择“currency” - “USD”。可以开启“Show points”以便更清晰地看到每个数据点。保存面板。4.2 创建第二个面板模型成本占比饼图了解钱主要花在哪个模型上是优化成本的第一步。Add panel。查询SQLSELECT model, SUM(cost_usd) as “cost” FROM litellm_cost_logs WHERE $__timeFilter(timestamp) GROUP BY model ORDER BY cost DESC可视化类型选择“Pie chart”。面板设置Title:模型成本分布在“Pie chart”设置中将“Value”字段设置为cost“Label”字段设置为model。建议开启“Donut”模式和“Legend”看起来更美观。4.3 创建第三个面板Top N “烧钱”用户/项目定位到具体的使用者或业务线才能进行有效的问责或优化。Add panel。查询SQL以project为例SELECT project, SUM(cost_usd) as “total_cost”, SUM(total_tokens) as “total_tokens”, ROUND(SUM(cost_usd) * 100.0 / (SELECT SUM(cost_usd) FROM litellm_cost_logs WHERE $__timeFilter(timestamp)), 2) as “cost_percentage” FROM litellm_cost_logs WHERE $__timeFilter(timestamp) AND project IS NOT NULL GROUP BY project ORDER BY total_cost DESC LIMIT 10可视化类型选择“Table”。面板设置Title:项目成本排行 (Top 10)在“Column styles”中可以为total_cost列设置单位USD为cost_percentage列添加百分号后缀。4.4 创建第四个面板成本与Token消耗关联分析成本直接由Token驱动分析两者的关系能帮你判断使用效率。Add panel。查询SQL这里用Stat面板展示聚合值SELECT SUM(cost_usd) as “总成本”, SUM(total_tokens) as “总Token数”, ROUND(SUM(cost_usd) / SUM(total_tokens) * 1000, 4) as “千Token平均成本 (USD)” FROM litellm_cost_logs WHERE $__timeFilter(timestamp)可视化类型选择“Stat”。面板设置Title:成本效率概览在“Field”设置中为每个值设置合适的单位和小数位数。“千Token平均成本”是一个非常重要的效率指标横向对比不同模型或不同时间段能直观看出哪里的“性价比”发生了变化。4.5 高级技巧设置成本预算告警仪表盘用于事后查看告警用于事前预防。在“总成本趋势图”面板中进入“Alert”标签页。Create alert rule。设置查询选择你的总成本查询。表达式使用一个简单的阈值表达式例如B 100表示当最近一个评估周期如1小时的总成本超过100美元时触发。更精细的可以设置increase()函数监控成本增速。条件设置评估频率如每5分钟和触发条件持续多久超过阈值。通知渠道配置连接你的Slack、钉钉、邮件或Webhook填写告警信息模板。实操心得告警阈值不要设得太敏感避免被“噪音”频繁打扰。可以先观察一周的正常成本波动再设定一个合理的阈值比如日均成本的150%。同时可以针对特定“烧钱”的项目或模型设置单独的告警。5. 生产环境部署与优化建议把上述组件拼装起来在本地跑通只是第一步要应用到生产环境还需要考虑稳定性、性能和可维护性。5.1 日志收集与写入的可靠性保障直接在你的应用主线程里同步写数据库或文件一旦数据库抖动或磁盘IO慢会直接影响你的AI服务响应。必须采用异步和非阻塞的方式。推荐模式消息队列MQ解耦。这是最健壮的方案。在cost_log_callback中不要直接写DB而是将日志条目作为一个消息发送到Redis Streams、RabbitMQ或Kafka这样的轻量级消息队列中。然后单独部署一个或多个消费者服务专门从队列里取出消息批量写入数据库。这样即使数据库临时不可用日志消息也会在队列中堆积不会丢失待数据库恢复后继续处理。简化模式异步写入或本地文件缓冲。如果不想引入MQ可以使用Python的asyncioasyncpg进行异步数据库写入或者先将日志写入本地一个高性能的日志文件如用structlogjson格式然后通过Filebeat或Fluentd这样的日志采集器将文件内容实时发送到数据库或Elasticsearch中。5.2 数据库性能与数据治理索引是关键如前所述在timestamp,model,project,user_id上建立复合索引能极大提升Grafana面板的查询速度。特别是按时间范围筛选的查询必须有时间戳索引。考虑分区表如果成本日志量非常大日增百万条以上建议对PostgreSQL表按时间进行分区例如按月分区。这能显著提升查询和维护如删除旧数据的效率。定期清理旧数据成本数据通常不需要永久保存。可以设置一个定时任务如cron job定期删除比如3个月前的数据以控制表大小。DELETE FROM litellm_cost_logs WHERE timestamp NOW() - INTERVAL ‘90 days’;。对于需要长期留存做年度对比的数据可以归档到冷存储。5.3 Grafana看板的维护与共享使用Dashboard Variables变量在Grafana仪表盘设置中创建变量比如一个下拉菜单选择project一个选择model。这样你可以在所有面板的SQL查询中使用WHERE project $project实现看板的动态过滤一个看板就能满足不同团队或项目的查看需求。导出与导入配置好的Dashboard可以导出为JSON文件纳入版本控制如Git方便团队共享和回滚。权限控制Grafana支持文件夹和Dashboard级别的权限管理。可以为财务团队设置只读视图为开发团队设置更详细的视图。6. 常见问题与排查技巧实录在实际搭建和使用过程中你肯定会遇到一些坑。以下是我和同事们踩过之后总结出来的经验。6.1 数据类问题问题1Grafana面板显示“No data”。排查步骤检查时间范围首先确认Grafana右上角的时间选择器是否覆盖了有数据的时间段。可以先选一个“Last 24 hours”试试。检查数据源连接在Grafana的数据源配置页面点击“Save Test”看是否能成功连接数据库。检查SQL语法在Panel的“Query”编辑框里点击“Query inspector”然后点“Execute query”。这会直接运行SQL并返回原始结果和可能的错误信息。这是最有效的调试手段。检查数据是否存在直接用数据库客户端如psql连接你的数据库手动执行面板中的SQL替换掉Grafana宏看是否有数据返回。问题2成本数字对不上和官方账单有出入。原因与解决定价表过时LiteLLM内置的定价表可能不是最新的。去LiteLLM的GitHub仓库查看model_prices_and_context_window.json文件对比官方价格。如有差异可以在初始化LiteLLM时通过litellm.modify_params覆盖特定模型的价格。Token计数差异不同模型、甚至不同版本的Tokenizer可能导致Token计数有微小差异。LiteLLM使用的是近似计数对于成本精确性要求极高的场景如对外计费建议使用官方SDK的Token计数功能或像tiktoken这样的库进行校准。未记录的调用检查是否有AI调用绕过了LiteLLM直接使用了原生SDK。6.2 性能与架构问题问题3日志写入导致应用变慢。现象集成了LiteLLM回调后AI服务的响应时间明显变长。解决这几乎肯定是同步I/O写文件或DB阻塞导致的。必须改为异步。参考5.1节引入消息队列或者至少使用asyncio.to_thread()将写日志操作放到线程池中执行避免阻塞主事件循环。问题4数据库查询慢Grafana面板加载卡顿。排查与优化使用EXPLAIN ANALYZE在数据库中对慢查询SQL执行EXPLAIN ANALYZE查看执行计划确认是否用上了索引。优化索引确保查询条件WHERE和分组字段GROUP BY上的索引有效。对于时间序列查询(timestamp, model)这样的复合索引通常效果很好。增加查询缓存Grafana本身有查询缓存功能对于变化不频繁的聚合数据如昨日总成本可以适当增加缓存时间减轻数据库压力。考虑物化视图对于非常复杂、耗时的聚合查询如按小时、按项目、按模型的多维度聚合可以在数据库端创建物化视图并定时刷新如每5分钟让Grafana直接查询物化视图速度会快很多。6.3 功能扩展思路需求我想按自定义标签如“对话场景”、“任务类型”来细分成本。实现这完全依赖于你在调用LiteLLM时传递的metadata参数。确保你的业务代码在调用时能添加上这些业务标签。例如metadata{“scene”: “customer_service”, “task”: “summary_generation”}。然后在建表时为这些常用标签创建单独的列或者全部存入一个JSONB类型的metadata字段中。Grafana查询时可以使用PostgreSQL的JSON操作符来提取和过滤例如WHERE metadata-‘scene’ ‘customer_service‘。需求我想预测本月的总成本。实现这需要一些简单的数据分析。可以在Grafana中创建一个新的Stat面板使用SQL进行预测计算。例如基于过去7天的日均成本预测本月剩余天数所需花费WITH daily_avg AS ( SELECT AVG(daily_cost) as avg_daily_cost FROM ( SELECT DATE(timestamp), SUM(cost_usd) as daily_cost FROM litellm_cost_logs WHERE timestamp NOW() - INTERVAL ‘7 days’ GROUP BY DATE(timestamp) ) t ) SELECT avg_daily_cost as “过去7天日均成本”, avg_daily_cost * EXTRACT(DAY FROM (DATE_TRUNC(‘month’, NOW()) INTERVAL ‘1 month’ - INTERVAL ‘1 day’) - CURRENT_DATE) as “本月剩余天数预测成本” FROM daily_avg这只是一个简单线性预测更复杂的可以使用Grafana的预测插件或外部分析工具。搭建这样一个成本看板初期可能需要投入一两天的时间但它带来的价值是长期的。它不仅能帮你守住预算红线更能通过数据洞察驱动你的技术决策——比如发现某个场景下便宜的gpt-3.5-turbo效果和gpt-4差不多那替换后立即可见成本大幅下降或者发现某个功能Token消耗异常可能意味着代码里有循环调用或提示词过于冗长。从“成本黑盒”到“数据驱动”这个仪表盘就是你AI应用运维体系中不可或缺的那块拼图。