LiteLLM 价格获取机制深度解析¶
数据源¶
直接读取 LiteLLM 官方 GitHub 仓库的原始 JSON 文件(packages/internal/src/pricing.ts:4)。
核心架构(三层)¶
第一层:通用 Fetcher 类¶
文件: packages/internal/src/pricing.ts — LiteLLMPricingFetcher
| 模式 | 行为 |
|---|---|
| 在线模式(默认) | 用 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.ts — PricingFetcher
继承 LiteLLMPricingFetcher,注入 Claude 专属的 provider 前缀和离线加载器:
模型名匹配逻辑¶
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 |