Token 消耗统计报告
用途
读取 WorkBuddy 本机会话记录,把散落在各个项目里的 token 消耗汇总成一份可交付报告:
调用次数、输入/输出 token、缓存命中、思考 token、平台 credit,
并按项目、任务(会话)、模型、日期四个维度拆开。
只统计用量,不做金额折算。 平台未公开 credit↔人民币换算率,也未公开内置模型
token 单价,任何人民币数字都只能靠猜。所以这个技能不产出金额,只给出真实记录到的
token 与 credit。用户若问"花了多少钱",如实说明:只能给 credit,给不了人民币。
何时使用
- 用户想知道"这个任务/项目花了多少 token""用了哪些模型""消耗了多少 credit"
- 需要一份用量报告用于复盘、了解消耗规模、或向他人说明消耗情况
- 需要排查为什么某个项目消耗异常高
快速开始
# 当前项目
python <SKILL_DIR>/scripts/token_report.py --scope current
# 全部项目(默认 HTML 报告写到当前工作目录)
python <SKILL_DIR>/scripts/token_report.py --scope all
# 指定项目 / 指定会话 / 指定时间范围
python <SKILL_DIR>/scripts/token_report.py --scope "C:/Users/xxx/WorkBuddy/2026-08-24-18-38-46"
python <SKILL_DIR>/scripts/token_report.py --scope session:<session_id>
python <SKILL_DIR>/scripts/token_report.py --scope all --since 2026-08-01 --until 2026-08-31
# 输出全部三种格式
python <SKILL_DIR>/scripts/token_report.py --scope all --format all --out ./token-report
<SKILL_DIR> = 本技能所在目录(默认 ~/.workbuddy/skills/token-usage-report)。
脚本既在 stderr 打印人类可读摘要,也在 stdout 输出一行 JSON 结果,
便于上层解析关键数字后直接回复用户。
参数
| 参数 | 说明 |
|---|---|
--scope |
current(当前目录,默认)/ all(全部)/ <项目路径> / session:<id> |
--cwd |
配合 scope=current 显式指定目录 |
--since / --until |
日期范围 YYYY-MM-DD,两端均含 |
--format |
html(默认)/ md / json / both / all |
--out |
输出目录,默认当前工作目录 |
--ledger |
外部 API 记账文件路径 |
--list-projects |
只列出全部项目及用量(不生成报告),便于挑选要看的项目 |
--quiet |
只输出最终 JSON,不打印进度 |
产物文件名:token-report-<scope>.html|.md|.json。
分项目查看
项目名取「任务标题」,不是目录名。 WorkBuddy 的 workspace 目录名是时间戳
(如 2026-08-24-18-38-46),对人毫无信息量。因此报告里的项目名 = 该项目内
用量最大的任务标题;标题缺失或为无效占位(如「?」)时回退为目录名。
标题来源为 sessions 表,用户手动改过的 custom_title 优先于 AI 生成的 title。
所以用户看到的会是「静噪取证」「云客公馆仪表盘」这类可辨认的名字。
两种查看方式,按需选:
① 报告内交互切换(推荐) —— 生成 --scope all 的报告后,HTML 顶部有
「分项目查看」栏,只有两个控件:
- 搜索框:按关键词过滤下拉列表,项目名 / 任务名 / 路径都能搜(中文也支持)。
- 下拉选择框:默认
全部项目。点开是两组选项——
项目(N)与任务(M),把历史上任意一个项目或任务都列出来,
每项后面带累计 token。选中即切换。
切换后 KPI、模型分布、内外部占比、主会话/子代理、每日趋势、模型表、任务排行
会全部变成所选范围的视图,无需重新扫描。
- 搜索把当前选中项过滤掉时,当前项会保留在列表里,不会莫名其妙跳回「全部项目」
- 报告是单文件、离线可用,数据已内联,切换不依赖网络
报告页面板块顺序(改动前请确认是有意的)
单页自上而下,顺序固定:
报告头 + 总览 KPI(6 张)
① 模型分布 ← 每行可点,进「模型作用域」弹窗
② 每日消耗趋势
③ 项目排行 (每页 20 条)
④ 任务排行 (每页 20 条)
⑤ 外部 API 调用 (依赖 ledger 自记账)
⑥ 技能使用频次 (来自 usage-log.json)
⑦ 内部 vs 外部 ┐ 全局占比类信息,不是主线「谁在烧钱」,
⑧ 主会话 vs 子代理 ┘ 所以排在几个明细板块之后
⑨ 数据口径与局限
⑦⑧ 两块由 renderScope(d) 按 id(#scopeBox / #kindBox)填充,
所以在模板里挪动位置不影响渲染,不用改任何 JS;但挪完必须重验一次
(顺序断言:取 document.querySelectorAll('section') 按 getBoundingClientRect().top
排序,再切一次作用域确认这两块仍会更新)。
项目排行与详情弹窗
项目排行显示全部项目(不是 Top 20),默认每页 20 条,底部分页器可翻页/跳页
(列表右侧显示「第 X-Y 条 / 共 N 个项目」)。排行按累计 Token 降序,与当前选中的
范围无关——它是全局排名。表里的「任务数」列就是该项目下的会话数量(一个任务 = 一次会话)。
任务排行同样全量 + 分页(每页 20 条,底部显示「第 X-Y 条 / 共 N 个任务」)。
一行 = 一个会话(任务),按累计 Token 降序。
弹窗含四块内容:
① 顶部指标条 —— 总 TOKEN / API 调用 / 缓存命中 / 输出 TOKEN / 平台 CREDIT /
有消耗天数(共 6 张卡)。缓存命中的命中率以小号灰字跟在数值后,
这样数值不换行、卡片等高。
② 每日消耗月历 —— 按自然月排布,周一起始,每月一张卡片。
- 每格显示「日号 + 该日 TOKEN 消耗」,颜色深浅表示相对消耗强度(4 级热力)
- 同一弹窗内所有月份共用一个单位(亿 / 万 / 原值),这样格内数字可以直接横向比较;
单位在月历上方标注一次
- 悬停单元格可看该日精确 TOKEN / credit / 调用次数
- 月卡头部显示该月合计 token、credit、有消耗天数
③ 模型用量 —— 该范围内用了哪些模型、各用了多少,按 TOKEN 降序:
模型 / 归属(内部·外部)/ 调用次数 / 总 TOKEN / 输出 / credit / 占该范围 TOKEN 比(含占比条)。
> 列表页不放模型。 项目排行和任务排行都不显示模型列——模型明细只在点击后的
> 弹窗里出现。项目可能混用十几个模型,铺在列表里只会把表格挤爆;而弹窗里有足够空间
> 把「各用了多少」讲清楚(含 token 与占比)。任务排行里保留的 N 子代理 徽标不是模型信息,
> 而是子代理调用次数,且不点弹窗就看不到,所以留在列表。
④ 技能 · MCP · 专家 —— 三栏,各自带次数与占比条:
- 技能 SKILL:Skill 工具调用次数(如 find-skills 17 次)
- MCP 服务:按服务归并(mcp__<服务>__<工具>),显示服务总次数 +
该服务下各工具明细(如 cloudbase(queryApps×24、manageApps×6)35 次)
- 专家 EXPERT:该项目下绑定了该专家的会话数(专家是会话级绑定,不是可调用对象,
所以口径是「几个会话」而不是「几次」,不要写成「N 次」)
弹窗右上角「切换到该视图」即把主报告切到该范围;Esc 或点遮罩可关闭。
(模型作用域没有这个按钮,原因见下。)
模型作用域(点「模型分布」表里的一行)
模型分布表的每一行都可点,点开是一个模型作用域弹窗。它的结构与项目/任务弹窗不同——
看单个模型时关心的是「什么时候烧的、烧在谁身上」,所以给趋势图 + 两张排行,而不是月历:
| 区块 | 内容 |
|---|---|
| 顶部指标条 | 同上 6 张卡,数值是该模型自己的用量 |
| 每日消耗趋势 | 该模型每天的 TOKEN(柱)与 credit(折线)。用趋势图而不是月历 |
| 项目排行 | 该模型在各项目的消耗,Top 15 + 「另有 N 个未列出,合计 X tokens(占该模型 Y%)」。列:调用 / 该模型 TOKEN / 输出 / credit / 占该模型比(含占比条) |
| 任务排行 | 同上,按任务(会话)维度 |
- 副标题形如「模型 · 涉及 N 个项目 · M 个任务」
- 排行里的行可以直接点,下钻到该项目/任务的详情弹窗(复用同一个
openDlg),
换范围继续看,不用关掉重开 - 模型弹窗不给「切换到该视图」:主页面是按项目/任务组织的一级视图,模型没有对应的
排行表;硬切过去会让项目/任务两张表的口径错乱(列名写着「总 Token」却在展示单模型用量),
所以模型只做只读下钻
> ⚠️ 三个口径必须盯住,错一个数字就整体不可信。全部在 build_scope_data() 里生成:
>
> 1. 排行里是「该模型在该项目/会话内的消耗」,不是该项目/会话的总消耗。
> 取自 proj_model[cwd][model] / sess_model[sid][model],是聚合阶段就分开记账的,不需要二次拆分。
> 2. 每日趋势取 by_model_day[model][日],不是全局 by_day。
> 3. 导出报告的「会话明细」给的是「该模型在每个会话里的用量」,同样不能拿会话总量充数。
>
> 自检方法:Σ项目排行 = Σ任务排行 = 该模型总量,三者必须完全相等(不是近似)。
> 验证时把这三条求和结果打出来对比即可;若不等,通常是任务排行里误用了「会话总用量」
> 而不是「该会话在该模型上的用量」。
导出报告(弹窗内)
弹窗头部有 「导出报告 ▾」 按钮,点开是三选一,导出的范围就是当前弹窗那个项目/任务/模型:
| 格式 | 文件名 | 内容 |
|---|---|---|
| 完整报告 · HTML | token-report-<名称>-<YYYYMMDD-HHMM>.html |
自包含单文件:指标条 + 与弹窗完全相同的区块(项目/任务是月历+模型用量+技能·MCP·专家;模型是趋势图+项目排行+任务排行)+ 每日明细表 + 会话明细 + 口径说明。可离线打开,也可直接打印成 PDF |
| 每日明细 · CSV | token-daily-<名称>-<时间>.csv |
日期 / 调用次数 / 总 TOKEN / 输入 / 输出 / 缓存命中 / credit,末行是合计。带 UTF-8 BOM,Excel 双击不乱码 |
| 摘要 · Markdown | token-report-<名称>-<时间>.md |
总览 + 模型用量 + 技能/MCP/专家 + 每日明细 + 会话明细;模型作用域额外多「项目排行 / 任务排行」两节 |
实现要点:
- 导出用 Blob + a.download 纯前端下载,file:// 直接打开也照常工作,不需要起服务。
- 导出的 HTML 复用主报告的 CSS(document.querySelector('style').textContent),
且主体区块与弹窗共用同一个 sectionsHtml(R)——弹窗加/改一个区块,导出报告自动跟着变。
同理 kpiCells / secHtml / dlgMeta 也是两处共用。这是本技能最重要的一条纪律:
凡「弹窗里要有、报告里也要有」的东西,一律抽成一个函数,绝不各写一份。
- 导出比弹窗多两块内容:每日明细表和会话明细表(弹窗里没有,报告里需要)。
- 导出头部元信息用 dlgMeta(R).sub(如「N 个会话 · c:/path」「涉及 N 个项目 · M 个任务」),
与弹窗副标题同源,不在导出里另写一套描述。
- 名称里的 / \ : * ? " < > | 会替换成 _,避免文件名非法导致下载失败。
- 导出异常会 alert 出来,不做静默失败——否则用户会以为「点了没反应」。
② 命令行单项目出报告 —— 需要把某个项目的报告单独交付时:
# 先列出项目,拿到路径
python <SKILL_DIR>/scripts/token_report.py --scope all --list-projects
# 再对该项目出报告
python <SKILL_DIR>/scripts/token_report.py --scope "c:/Users/xxx/WorkBuddy/2026-08-24-18-38-46"
工作流
- 判断范围:用户说"这个项目/当前任务" →
--scope current;说"所有""总的花了多少"
→--scope all。 - 拿不准用户想看哪个项目时,直接跑
--scope all—— 报告自带分项目切换,
用户可以在里面自己点选,不必反复重跑脚本。 - 运行脚本(默认即可产出 HTML + 终端摘要)。
- 用
present_files把 HTML 报告展示给用户,并在回复里给出关键数字
(调用次数、总 token、输入/输出、缓存命中率、credit),
同时提示报告顶部支持「分项目查看」。 - 若用户问"折合多少钱",直接说明口径:只统计用量、不做金额折算,并给出 credit。
数据源
全部为只读,不修改任何 WorkBuddy 文件:
| 数据 | 位置 |
|---|---|
| 逐次调用的 token 明细 | ~/.workbuddy/projects/<项目>/<会话>.jsonl → providerData.usage |
| 子代理的 token 明细 | ~/.workbuddy/projects/<项目>/<会话>/subagents/agent-*.jsonl |
| 平台计费单位 credit | 同上 → providerData.rawUsage.credit |
| 技能 / MCP 调用 | 同上 → type: "function_call" 记录的 name 与 arguments |
| 会话 → 项目路径 / 任务标题 | ~/.workbuddy/workbuddy.db → sessions 表 |
| 会话 → 专家 | ~/.workbuddy/workbuddy.db → sessions.expert_id / expert_runtime_identity |
| 官方 credit 汇总 | ~/.workbuddy/workbuddy.db → session_usage.credit_json |
| 技能使用频次(全局) | ~/.workbuddy/usage-log.json |
| 外部 API 调用 | ~/.workbuddy/token-ledger/external-usage.jsonl(自记账) |
字段细节、子代理归属规则、以及已排查确认"不含 token"的位置,见 references/data-sources.md。
模型 / 技能 / MCP / 专家 的口径
| 维度 | 判定方式 | 单位 |
|---|---|---|
| 模型 | 每次调用记录的 providerData.model,按模型名聚合(含 token / 次数 / credit) |
token、次 |
| 技能 | function_call 且 name == "Skill",取 arguments.skill(或 command / name) |
次 |
| MCP | function_call 且 name 形如 mcp__<服务>__<工具>;也包括 DeferExecuteTool 里 arguments.toolName 指向 mcp__* 的延迟调用(数量不少,漏了会少一半) |
次 |
| 专家 | sessions.expert_id(配合 expert_runtime_identity 取可读名) |
会话数 |
模型展示位置:
- 列表页(模型分布表)只给归属 + 汇总,点任一行进入模型作用域弹窗看明细。
- 详情弹窗的「模型用量」区块展示某范围内的模型构成
(模型 / 归属 / 调用 / 总 TOKEN / 输出 / credit / 占比),项目和任务共用同一套渲染。
数据包字段:项目与任务都是 m: [[模型名, 5 元素桶], ...]。
- 模型作用域的数据包字段(D.models[],见 build_scope_data()):
k 该模型总量 / d 该模型按日 / mp 按项目 [cwd, 项目名, 桶, 会话数] /
mt 按任务 [sid, 标题, 项目名, 桶] / s 会话明细(桶是该模型在该会话内的用量)/
nproj / nsess。数据源分别是 by_model / by_model_day / proj_model / sess_model。
三者都按归属会话归到项目:子代理文件里的工具调用归给其父会话
(与 token 归属规则一致,见下),因此项目级计数天然含子代理的调用。
expert_id 形如 ex_xxx 的是市场专家,哈希不可读,显示时回退到
expert_runtime_identity.pluginRegisteredName。
内部模型 vs 外部模型
- 内部(平台内置):
hy3、hy4-preview、deepseek-v4.1-flash、kimi-k3-2、
glm-5.2、minimax-m3-pay等,由 WorkBuddy 以 credit 计费。token 数据精确。 - 外部(自备 API Key):技能脚本直连火山方舟 / OpenAI 中转等。
这些调用不经过 WorkBuddy 本地记录,无法自动回溯,必须用ledger.py补记。
关于金额(本技能不统计)
报告不输出任何人民币数字,这是刻意的:
credit是平台真实记账值,来自每次调用返回的rawUsage.credit,不是估算,报告中正常展示。- 但平台未公开 credit↔人民币换算率,也未公开各内置模型的 token 单价。
任何折算都只能靠假设,属于编造。
所以:
- 用户问"花了多少钱" → 回答"只能给 credit,给不了人民币",并给出 credit 数字。
- 不要为了让报告"完整"而自行填入汇率或单价,也不要为此去查第三方价格表来折算。
- 历史遗留的
scripts/prices.json已停用(_meta.status = "dormant"),
主脚本不再读取它,仅作备查保留。
外部 API 记账
三方 API 的 token 不落 WorkBuddy 日志,需主动补记:
# 命令行
python <SKILL_DIR>/scripts/ledger.py add --model doubao-seedream-5.0-lite --images 4 --note "场景图"
python <SKILL_DIR>/scripts/ledger.py add --model doubao-seed-2-1-pro-260628 --input 12000 --output 3400
python <SKILL_DIR>/scripts/ledger.py list --limit 20
python <SKILL_DIR>/scripts/ledger.py summary
在技能脚本里 import 记账(推荐,随执行自动落账):
import sys; sys.path.insert(0, r"<SKILL_DIR>/scripts")
from ledger import record
record(model="doubao-seedream-5.0-lite", images=4, note="场景图生成")
--model 只用于归类展示,不做计价。
记账文件默认 ~/.workbuddy/token-ledger/external-usage.jsonl;
若因权限无法写入,会自动回退到系统临时目录并打印实际路径。
坑与注意事项
- DB 被占用:WorkBuddy 运行时会锁
workbuddy.db。脚本以只读 URI 打开并设 5s 超时,
失败时仅失去"任务标题",token 统计不受影响。 - 输入 token 远大于输出:LLM 每次请求都重传完整上下文,轮次越多累计输入越大。
这是真实计费口径,不是重复计算,不要"修正"它。 - 缓存命中通常占输入 95%+,报告中单列。缓存命中仍是输入 token 的一部分,
只是实际计费单价通常低于全新输入。本技能不做单价折算。 - 必须扫描两层会话文件:
projects/<项目>/<会话>.jsonl(主会话)
和projects/<项目>/<会话>/subagents/agent-*.jsonl(子代理)。
子代理记录内部的sessionId在sessions表里查不到,
归属需取subagents的父目录名。漏掉子代理对 token 总量影响很小(1% 量级),
但会让 credit 明显偏低(可达 5%~10%),因为子代理多用较贵的模型。 - 展示项目时绝不要用目录名:
projects/<时间戳>是 WorkBuddy 自动创建的,
对用户零信息量。一律换成任务标题,并过滤「?」「-」等 AI 生成失败的占位值,
否则用户会看到一排问号。 - 切换器只留「搜索 + 下拉」两件套:早期版本铺了一整片 chip 按钮墙(26 个 chip
占三行、还要滚动),用户明确要求砍掉。不要把 chip 墙加回来——
项目数会持续增长,按钮墙只会越来越长,下拉框才是能扩展的形态。 - 下拉里要给任务单独分组:只列项目是不够的,多任务项目(如「询问是否停工 2 任务」)
里的次要任务也要能单独选中,所以数据包里同时准备了projects和tasks两套
(结构同构,前端共用一套渲染函数)。 - 会话目录名即项目:WorkBuddy 每次新建任务会创建新的 workspace 目录,
因此"项目数"约等于"任务数"。跨目录的同一产品(如小程序迭代)会分散在多行,
这属于正常现象,不要合并或猜测归属。 - 不要为了工具调用再扫一遍文件:
projects/目录可达 GB 级、上百个文件。
技能/MCP 计数必须复用iter_usage_records的同一次读取(通过tool_sink参数),
单独再扫一遍要多花 6~7 秒。 tool_usage or {}是个陷阱:tool_usage是被扫描器边跑边填充的 sink,
传进aggregate()时还是空 dict(falsy),写成tool_usage = tool_usage or {}
会新建一个空 dict 把原引用丢掉,结果数据全丢、而且不报错。
必须写if tool_usage is None: tool_usage = {}。(同理适用于任何"边跑边填"的容器)[data-key][data-key!=""]不是合法 CSS 选择器:属性"不等于空串"在 CSS 里非法,
querySelector/closest会直接抛not a valid selector。
这会让整个 click 委托处理器崩掉,表现为所有行都点不动,且只有pageerror里能看到。
正确写法是closest('tr[data-key]')之后在 JS 里判空。- 月历格内数字必须统一单位:早期版本直接复用
fmt(),同一屏里会出现
「万」和「亿」两种单位,既不可比也塞不进格子。改为整个弹窗共用一种单位
(按最大值选 亿 / 万 / 原值),单位在月历上方标注一次。 - 专家是按会话绑定的,不是可调用对象:口径只能是「N 个会话用了该专家」,
不要写成「N 次」,也不要试图从日志里找"专家调用"。 SCOPE_JS必须保持 raw 字符串(r"""):JS 里有大量'\n'、'\ufeff'这类转义,
一旦把r"""改成普通""",Python 会先把它们变成真实换行 / 真实 BOM 字符,
嵌进 JS 单引号字面量里 → 字符串未闭合,整页 JS 直接崩(所有交互失效)。
改这个字符串的赋值方式前先想清楚。- 导出报告不要另写一套 CSS:导出的单文件 HTML 直接取主报告的
document.querySelector('style').textContent就能拿到全部样式,再配上同一批渲染函数
(calHtml/modelHtml/toolHtml),视觉自动一致。另起一套样式必然走样。 - 下载用 Blob +
a.download,不依赖服务端:主报告可能以file://打开,
用fetch/XHR 下载会因跨源或本地协议失败。Blob URL 在file://下同样可用。 - 会话对象要带
cwd:pack_session()和 tasks 里内联的s数组都带上了所属项目路径,
这样在「全部项目」视图下任务行内能标注该项目路径(renderSessions里的loc)。
项目/任务两种作用域共用同一份打包函数,别把cwd去掉。 - 两个排行表的
<tbody>都是 JS 渲染的,改 Python 侧无效:#projBody由
renderProjects()填、#sessBody由renderSessions()填,且render()在页面加载
时就会覆盖 Python 生成的初始行。改列表列结构必须同时改 JS 渲染函数,
Python 侧只负责表头骨架(否则改了看不到效果,会误判为没生效)。 - 任务标题旁的徽标要用
.tname-row包一层:.tname自带
white-space:nowrap; overflow:hidden; text-overflow:ellipsis,把徽标(如「N 子代理」)
直接塞进.tname会被省略号裁掉。正确做法是
<div class="tname-row"><span class="tname">标题</span><span class="pill ext">徽标</span></div>,
并给.tname-row .tname设flex:0 1 auto; min-width:0。 - 同一页面里两个 SVG 不能用同一个渐变
id:trendSvg()通过gid参数传渐变 id,
主页面趋势图用bg1、弹窗/导出用bgDlg。若两处都写bg1,后渲染的那个
url(#bg1)会解析到文档里第一个同名定义——本期只是配色相同看不出来,
一旦给弹窗换配色就会静默串色。 - 弹窗主体区块一律走
sectionsHtml(R),不要在 Python 里写死<section>:
写死后「弹窗有的区块导出报告没有」,加一个区块要改两处,必然漂移。
现在#dlgBody是空容器,由 JS 按范围类型填;导出 HTML 调同一个函数,
所以模型弹窗新增「趋势/排行」时导出报告零改动就同步了。 - 新增作用域类型(如模型)要同步这 4 处,少一处就是「点了没反应」:
①findData()加前缀分支(m:);②dlgMeta()给出 kind 与副标题描述;
③build_scope_data()产数据包;④ 触发入口带data-key(模型表行由renderModels()与
Python 两侧都要加,因为 JS 会覆盖 Python 生成的初始行)。 - 模型作用域刻意不接「切换到该视图」:主页面没有模型维度的一级列表,硬切过去
会让项目/任务排行的列名与数值口径对不上。openDlg里按 kind 隐藏该按钮。 - 调试前端时先看
pageerror:本报告大量逻辑在客户端,Python 侧生成成功
不代表页面可用(本次两个 bug 都是pageerror暴露的,日志里才看到)。 - 验证弹窗 DOM 时不要凭印象猜类名:本轮连续猜错两次
(把月份块猜成.cal-month、栏标题猜成.tcol h4),得到"月历数=0"的假警报,
白跑两轮。正确做法是先做一次 class 普查再写断言:
js const cls = {}; document.querySelector('#dlgCal').querySelectorAll('*') .forEach(el => el.classList.forEach(c => cls[c] = (cls[c]||0) + 1));
实际类名:月历.cal/.cal-h/.cal-g/.cw(星期) /.cell(日) /.pad(补位)
/.lv1~lv4(热度);工具区.tcol/.tch/.trow/.tnm/.tbar/.tvl/.tdet。 - 条形图宽度在内层
<i>上:结构是<div class="tbar"><i style="width:x%">,
读tbar.style.width永远是空串,要读.tbar i。另外 MCP 栏有意不画条形
(服务名 + 工具明细已占满行宽),只有技能/专家栏有条形,这是设计不是缺陷。 - 不要用
--scope current之外的路径硬编码,一律由用户语义判断范围。
目录结构
token-usage-report/
├── SKILL.md
├── INSTALL.md # 安装说明(分享给他人时对方看这个)
├── MANUAL.html # 使用说明书(面向使用者,含页面导览/交互/口径/FAQ)
├── scripts/
│ ├── token_report.py # 主脚本:扫描 → 聚合 → 出报告
│ ├── ledger.py # 外部 API 用量记账(只记用量,不记账金额)
│ └── prices.json # 【已停用】历史价格表,仅备查,主脚本不再读取
└── references/
└── data-sources.md # 数据源字段与口径详解
> 分享给他人前:确认文档里没有写死自己的真实统计数字(token 量、credit、
> 项目/会话数量等)。示例一律用占位写法(N 个项目、1% 量级),
> 避免把个人用量规模随包带出去。