跳转至

LiteLLM 价格获取机制深度解析

数据源

https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json

直接读取 LiteLLM 官方 GitHub 仓库的原始 JSON 文件(packages/internal/src/pricing.ts:4)。


核心架构(三层)

第一层:通用 Fetcher 类

文件: packages/internal/src/pricing.tsLiteLLMPricingFetcher

模式 行为
在线模式(默认) fetch() 下载完整价格 JSON,用 valibot 逐条校验每个模型的价格字段,存入 Map<string, LiteLLMModelPricing>,内存缓存避免重复请求
离线模式 调用构造时注入的 offlineLoader 回调加载本地快照
降级策略 网络请求失败时自动 fallback 到离线缓存(handleFallbackToCachedPricing

实现了 Disposable,支持 using 语法自动清理缓存。


第二层:构建时宏(打包优化)

文件: apps/ccusage/src/_macro.ts — 用 with { type: 'macro' } 声明

// _pricing-fetcher.ts:3
import { prefetchClaudePricing } from './_macro.ts' with { type: 'macro' };

构建时执行一次,将仅 Claude 模型的价格数据过滤出来,直接打包进二进制产物作为 PREFETCHED_CLAUDE_PRICING 常量。

作用: 离线用户也能使用构建时的价格快照,无需网络请求。


第三层:应用级封装

文件: apps/ccusage/src/_pricing-fetcher.tsPricingFetcher

继承 LiteLLMPricingFetcher,注入 Claude 专属的 provider 前缀和离线加载器:

const CLAUDE_PROVIDER_PREFIXES = [
  'anthropic/',
  'claude-3-5-',
  'claude-3-',
  'claude-',
  // ...
]

模型名匹配逻辑

getModelPricing(modelName) 按优先级查找(pricing.ts:204-236):

优先级 策略 说明
1 精确匹配 直接用 modelName 查 Map
2 前缀补全 尝试 anthropic/claude-sonnet-4-20250514 等带 provider 前缀的变体
3 模糊匹配 大小写不敏感的包含关系匹配(最后兜底)

阶梯价格计算

支持 Anthropic 的 200k token 阶梯计费pricing.ts:284-310):

输入 token 费用:
  ├── ≤ 200,000 tokens:按 input_cost_per_token 计
  └── > 200,000 tokens 部分:按 input_cost_per_token_above_200k_tokens 计

涵盖四种 token 类型:

类型 字段
标准输入 input_cost_per_token
标准输出 output_cost_per_token
缓存写入 cache_creation_input_token_cost
缓存命中读取 cache_read_input_token_cost

架构小结

JSON 数据源(GitHub Raw)
LiteLLMPricingFetcher          ← 通用层:fetch + 校验 + 缓存 + 降级
构建时宏(_macro.ts)           ← 打包层:过滤 Claude 价格,嵌入产物
PricingFetcher                 ← 应用层:注入前缀规则 + 离线快照
getModelPricing(modelName)     ← 查询层:精确 → 前缀 → 模糊
阶梯价格计算                    ← 计算层:200k 分段 × 4 种 token 类型