Skip to content

plugin-usage-stats — 用量统计 ​

包名: @aalis/plugin-usage-stats
源码: packages/plugin-usage-stats/src/index.ts
子系统: llm

概述 ​

记账插件:订阅 api-llm 的 llm:usage,把每次模型调用记进数据目录的账本,经页面契约提供「用量统计」页,按天、按周、按模型列出输入、缓存命中与输出 token。配置里填了单价才有费用一列;有服务商的模型实现了余额查询才有「余额」一页。

不装 webui-server 时照样记账,只是没有页面。

插件声明 ​

ts
definePlugin({
  name: '@aalis/plugin-usage-stats',
  displayName: '用量统计',
  subsystem: 'llm',
  configSchema,
  uses: {
    config,
    logger,
    lifecycle,
    events,
    paths: hostPaths,
    webui: optional(webuiServer),
    llm: optional(llm),
    plugins: optional(pluginsService),
  },
  apply: run,
});

配置 ​

键类型默认值说明
pricesmap{}单价:每百万 token 的价格,键是模型 id,值依次写输入、缓存命中、输出三个价,用逗号隔开,如 deepseek-chat: 2, 0.5, 8。填了才有费用一列,没填单价的模型不算进费用。写错(不是三个不小于 0 的数)时插件起不来,错误写明是哪个模型
currencystring'CNY'费用一列标的币种,只用于显示

账本 ​

  • 位置: state/usage/llm-calls.jsonl(经 host-paths 取数据目录),只追加,一次调用一行:at(毫秒时刻)与 llm:usage 的各字段(服务商、模型、调用方、会话、用途、输入、缓存命中、输出)。后一行等前一行写完;追加失败记 warn,这一次只留在内存里的合计中。停用或停机时等排着的写完。
  • 启动时读回: 按行流式读回(不把整个账本读成一个字符串),按本地时区的日期与(服务商,模型)合计。读不懂的行(不是 JSON、缺字段、数不对)跳过并记一条 warn 写明几行;账本读不出来(不是不存在,如权限、路径是目录)时插件起不来,不照空账本往下记。
  • 不清理: 账本按调用增长(一行约 230 字节),启动读回的耗时随之增长;要清掉旧记录就删这个文件(重启后从空起步)。

「用量统计」页 ​

位置为插件详情(/p/@aalis%2Fplugin-usage-stats/usage-stats),声明式。按天、按周、按模型三个标签各一张表,有余额时另有「余额」:

标签行首列
按天每天一行,新的在前日期(2026-10-04)
按周周一起算,新的在前周(2026-09-28 – 10-04)
按模型每个(服务商,模型)一行,按输入加输出从多到少模型,另有一列服务商(插件的显示名,非默认实例带实例名,插件已不在的写实例 id)
余额有服务商的模型实现了余额查询才有:每个服务商查一次,一个币种一项;查不到的写「查不到:原因」—
  • 数列是输入、缓存命中、输出,填了单价另有费用(四舍五入到分)。缓存命中只加服务商报了的,一行里一次都没报时空着(与 0 不同)。费用只算填了单价的模型,一行里一个都没有时空着;表格上写明「费用按配置里的单价估算,没填单价的模型不算在内」。
  • 窄时(手机、340 宽的容器)只留首列、输入,以及费用(填了单价时)或输出(没填时)。
  • 每次记账后作废按天、按周、按模型三张表,开着的页面重取;余额不跟着记账重查,只在打开或手动刷新时查,时限 10 秒。
  • llm 服务可能变了(service:changed)时重看有没有服务商实现余额查询,有无变了就以同一个 key 重新登记这一页,「余额」随之出现或消失。

相关 ​

文档对应 dev@c4e046e41,core 0.21.0,构建于 2026-11-02
基于 MIT 许可发布