
1. 从一条response_costNone日志说起如果你正在用 LiteLLM 做多模型网关大概率见过这条报错LiteLLM:ERROR: litellm_logging.py:1265 - Modelinternlm2 not found in completion cost map. Setting response_cost to None它的意思很直白LiteLLM 内置的model_cost字典里没有internlm2这个模型名所以它算不出这次请求花了多少钱只能把response_cost置为None。结果就是——请求能通但计费字段是空的/global/spend/keys里看不到这条消耗LiteLLM_SpendLogs表里也查不到有效 spend。这就是 LiteLLM 计费模型处理的核心矛盾它内置了一张成本表但你的模型名不一定在里面。LiteLLM 的计费逻辑集中在litellm/cost_calculator.py日志钩子在litellm_core_utils/litellm_logging.py只要模型名匹配不上completion_cost_map计费链路就断了。这篇面向需要统一管理多模型计费与 Key 的开发者给出两件事一是用 TaoToken 统一 Key/API 通道把模型名收敛到可控范围二是给出一份可直接复制的config.toml配置骨架并演示一次计费模型请求的验证动作确认计费字段与模型映射正确返回。适合已经在跑 LiteLLM Proxy、但被自定义模型计费卡住的同学。2. TaoToken 前置统一 Key 与模型映射LiteLLM 的计费依赖模型名到价格的映射而模型名又依赖上游 provider。如果每个 provider 各接一套 Key、各写一套模型名model_cost永远补不完。TaoToken 在这里的作用是提供一个统一的 API 通道把上游模型收敛成一套 OpenAI 兼容接口你只需要在 LiteLLM 里维护一份模型映射。先拿到统一 Key。访问控制台创建https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite创建后在 API Keys 页面复制 Keyhttps://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewriteAPI 基地址统一用https://taotoken.net/api注意这里不加 UTM 参数它是给程序调用的。Key 形如sk-xxxx后面 LiteLLM 的api_key字段就填它。模型名怎么定建议在 TaoToken 侧先确认可用模型清单再决定 LiteLLM 里的model_name。你可以用模型对话页面手动发一条请求确认模型 ID 拼写https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite这一步很关键。LiteLLM 的计费匹配是字符串精确匹配internlm2和internlm-2在它眼里是两个模型前者匹配不上就None。所以模型名必须在 TaoToken 和 LiteLLM 两侧保持一致。3. config.toml 配置骨架可复制片段LiteLLM Proxy 支持config.yaml也支持config.toml。下面这份骨架按「统一通道 自定义计费」组织你可以直接改 Key 和模型名。3.1 基础模型列表与统一通道[general_settings] master_key sk-your-litellm-master-key database_url postgresql://user:passlocalhost:5432/litellm [model_list.internlm2] model_name internlm2 litellm_params { model openai/internlm2, api_base https://taotoken.net/api, api_key sk-your-taotoken-key } [model_list.qwen-plus] model_name qwen-plus litellm_params { model openai/qwen-plus, api_base https://taotoken.net/api, api_key sk-your-taotoken-key }这里model openai/xxx是让 LiteLLM 走 OpenAI 兼容协议api_base指向 TaoToken 统一通道。model_name是你在 LiteLLM 里对外暴露的名字也是计费匹配用的名字。3.2 自定义计费补上缺失的成本映射LiteLLM 允许通过model_cost覆盖或新增成本项。单位是「每 token 美元」注意是 token 不是千 token写错会差三个数量级。[model_cost.internlm2] input_cost_per_token 0.0000005 output_cost_per_token 0.0000015 [model_cost.qwen-plus] input_cost_per_token 0.0000004 output_cost_per_token 0.0000012如果你不想在 TOML 里硬编码也可以在 LiteLLM 的 UI 里配置自定义计费模型效果等价请求进来后会走你定义的费率。3.3 计费落库与回调[litellm_settings] success_callback [postgres] failure_callback [postgres]postgres回调会把每次请求的 spend 写入LiteLLM_SpendLogs这是后面查MonthlyGlobalSpendPerKey视图的数据源。如果你要接外部计费系统可以换成自定义 callback但内置模式已经够用。4. 验证请求确认计费字段与模型映射配置写完启动 Proxylitellm --config ./config.toml --port 40004.1 发一次计费模型请求curl -X POST http://localhost:4000/v1/chat/completions \ --header Authorization: Bearer sk-your-litellm-master-key \ --header Content-Type: application/json \ --data { model: internlm2, messages: [{role: user, content: 你好测试计费}] }返回体里除了choices重点看usage{ usage: { prompt_tokens: 8, completion_tokens: 12, total_tokens: 20 } }4.2 查 Key 维度计费curl http://localhost:4000/global/spend/keys?limit5 \ --header Authorization: Bearer sk-your-litellm-master-key \ --header Content-Type: application/json正常返回应该能看到total_spend不再是 0[ { api_key: 4a232c5264640946b61ec32fb3304278af1a34cc26482066aa66e250cddde75e, key_alias: internlm2, key_name: sk-...ZeoQ, total_spend: 28.4 } ]如果total_spend还是 0回到日志看有没有response_costNone说明model_cost没匹配上。4.3 直接查库确认select * from MonthlyGlobalSpendPerKey a join LiteLLM_VerificationToken b on a.api_key b.token;MonthlyGlobalSpendPerKey是个视图定义大致是CREATE VIEW MonthlyGlobalSpendPerKey AS SELECT date(LiteLLM_SpendLogs.startTime) AS date, sum(LiteLLM_SpendLogs.spend) AS spend, LiteLLM_SpendLogs.api_key FROM LiteLLM_SpendLogs WHERE LiteLLM_SpendLogs.startTime (CURRENT_DATE - 30 days::interval) GROUP BY (date(LiteLLM_SpendLogs.startTime)), LiteLLM_SpendLogs.api_key;还有LiteLLM_VerificationTokenView可以关联 team、budget 等信息它基于LiteLLM_VerificationToken表左连LiteLLM_TeamTable。这两个视图是排查计费归属的主要入口。5. 本篇常见错排查5.1response_costNone反复出现最常见原因是model_name和model_cost的键不一致。LiteLLM 用model_name去查成本表你写internlm2却在model_cost里写internlm-2就匹配不上。统一命名即可。5.2 计费金额明显偏大或偏小检查input_cost_per_token的单位。LiteLLM 用的是每 token不是每千 token。如果你按「每千 token 0.5 元」填成0.5实际会放大 1000 倍。正确写法是0.0000005这种量级。5.3 请求通了但LiteLLM_SpendLogs没数据先确认success_callback里有没有postgres再确认database_url能连上。回调写库失败不会阻断请求所以现象是「请求正常、计费为空」。看 Proxy 启动日志里有没有数据库连接报错。5.4 特定 Key 的统计查不到/global/spend/keys只返回有 spend 记录的 Key。如果某个 Key 从没成功计费过它不会出现在列表里。先用该 Key 发一次请求再查。5.5 模型映射对了但上游 404api_base要写https://taotoken.net/api不要带/v1后缀LiteLLM 会自己拼/v1/chat/completions。多写一层路径会 404。6. 继续接入与长期编码计费链路跑通后下一步是把 Key 管理和模型映射固化下来。如果你还在排障阶段建议先把 API Keys 和接入文档过一遍确认 Key 权限和通道地址https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite想先验证某个模型名和计费字段是否对得上用模型对话页面手动发一条最快https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite如果你要把 LiteLLM 长期挂在编码 Agent 或自动化流程后面Key 会频繁调用、模型会经常切换这时候用 Coding Plan 把通道和额度固定下来更省心https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite我自己的做法是config.toml里只保留model_name和model_cost两份清单新增模型时两边同时加加完立刻用/global/spend/keys验证一次total_spend有没有涨。涨了就说明计费字段和模型映射都对上了没涨就回去看日志里的response_cost。这套动作重复几次比事后翻数据库快得多。