llm-bill-analyzer:把 LLM 用量导出变成账单分析
AlexRyan92/llm-bill-analyzer
开源工具 llm-bill-analyzer 可将 Anthropic Console、OpenAI Platform 导出的用量 CSV 在本地完成账单分析,数据不出本机。它按模型和日期估算花费,给出实际缓存命中率与已节省金额、稳定前缀缓存机会,以及把高价模型流量按比例迁移到低价模型的节省测算,支持 CLI 与库调用,价格表可替换。
Turn a raw LLM usage export into the analysis the invoice never gives you. Zero dependencies, fully local: your billing data never leaves your machine.
Drop in the CSV from your provider console (Anthropic Console → Usage → Export, OpenAI Platform → Usage → Export) and get:
- Spend by model and by day, estimated against a hand-verified price table (or your own)
- Your actual cache hit rate, and what cache reads already saved you
- The caching opportunity: what caching a stable prefix share of your uncached input is worth
- The routing question: what moving a share of your most expensive model's traffic to a cheaper model saves (the quality side is an evals question; this is the money side)
Export formats drift, so columns are detected heuristically and the mapping is overridable. There is a hosted version that runs entirely in the browser tab.
Install
npm install llm-bill-analyzer # library npx llm-bill --help # CLI, no install
CLI
$ npx llm-bill usage.csv --route-to haiku-4-5 --route-share 30 estimated spend: $1,826 tokens: 499.93M in / 89.99M out / 35.26M cache-read cache hit rate: 6.6% by model: claude-opus-5-5 $1,013 55.5% claude-haiku-4-5 $595 32.6% gpt-6-sol $217 11.9% caching: realized savings: $60.37 opportunity at 60% stable prefix: $514 routing: moving 30% of claude-opus-5-5 to Claude Haiku 4.5: $229 run it behind an eval gate before you believe it.
--prices my-prices.json swaps the bundled snapshot for your own table (same shape: { models: [{ id, name, in, out }] }, USD per million tokens). --json emits the full report.
Library
import { analyze, parseCSV, detectColumns, matchModel } from 'llm-bill-analyzer'; const report = analyze(csvText, priceTable, { stablePrefixShare: 0.6, routeTo: priceTable.find(m => m.id === 'haiku-4-5'), routeShare: 0.3, }); report.estimatedTotal; // USD report.cacheHitRate; // 0..1 report.perModel; // Map<rawName, { input, output, estimatedCost, matched, ... }> report.cache; // { realizedSavings, opportunity, hitRate, ... } report.routing; // { fromModel, toModel, savings }
Assumptions, stated plainly
Cache economics are Anthropic-style (reads at 10% of input price, writes at 125%); unmatched model names fall back to your cost column when the export has one. Daily-aggregate exports cannot show per-request shapes, so routing reprices tokens, not requests. The bundled price snapshot in data/models.json carries its verification date and source; it is a convenience, not an oracle. This is a planning tool, not an invoice.
License
MIT © Alexander Ryan. Price data snapshot from the LLM Model Reference, verified by hand and dated.
来源:GitHub · github.com