汇总各会话用量,看清每天花在哪
29.9/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/24 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add 361533652/dsh-token-bi该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:仅索引
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
DeepSeek Harness 的 token 消耗看板:每日柱状图、每小时节奏、模型与工作区拆分、调用树、逐轮时间线。
README
由 DeepSeek 最新模型翻译生成dsh-token-bi
DeepSeek Harness 的 token 消耗看板 —— 把散落在各个会话里的用量汇总成一张表:每天烧了多少、哪个模型最贵、哪些工作目录在消耗、父子会话各占几成、每一轮具体花在哪。
DSH 自带单会话的 token 统计,但没有跨会话的视图。这个插件补上这一层,并对齐 Host 自己的计量口径,不会出现「插件显示的数字和会话里对不上」。
看板总览
目录
- 它解决什么问题
- 安装
- 界面说明
- 数据从哪来、怎么算
- HTTP 接口
- 配置
- 设计取舍
- 已知限制
- 开发
- 许可
它解决什么问题
用 DSH 一段时间后,几个问题会冒出来:
- 这个月一共花了多少 token?散在 20 多个会话里,没有一个地方能看总量。
- 哪天突然变多了?是哪次任务把用量拉高的?
- 缓存命中率怎么样?—— 这一项容易被忽略但影响最大:cacheRead 通常是总量的绝大部分,因为每轮都要把整个上下文重新读一遍。
- 让子代理并行干活时,父会话和子会话各占多少?
这个插件把会话日志里 provider 上报的用量折叠成上述维度。
展开完整文档(README 剩余 1 节)
dsh-token-bi
DeepSeek Harness 的 token 消耗看板 —— 把散落在各个会话里的用量汇总成一张表:每天烧了多少、哪个模型最贵、哪些工作目录在消耗、父子会话各占几成、每一轮具体花在哪。
DSH 自带单会话的 token 统计,但没有跨会话的视图。这个插件补上这一层,并对齐 Host 自己的计量口径,不会出现「插件显示的数字和会话里对不上」。
看板总览
目录
- 它解决什么问题
- 安装
- 界面说明
- 数据从哪来、怎么算
- HTTP 接口
- 配置
- 设计取舍
- 已知限制
- 开发
- 许可
它解决什么问题
用 DSH 一段时间后,几个问题会冒出来:
- 这个月一共花了多少 token?散在 20 多个会话里,没有一个地方能看总量。
- 哪天突然变多了?是哪次任务把用量拉高的?
- 缓存命中率怎么样?—— 这一项容易被忽略但影响最大:cacheRead 通常是总量的绝大部分,因为每轮都要把整个上下文重新读一遍。
- 让子代理并行干活时,父会话和子会话各占多少?
这个插件把会话日志里 provider 上报的用量折叠成上述维度。
安装
前置条件
- DSH Desktop 或 dsh CLI(Web 界面)
- Node.js ≥ 22.15(会话日志是 zstd 压缩的,需要 zlib 的 zstd 支持)
从本地目录安装(当前可用方式)
git clone https://github.com/361533652/dsh-token-bi.git
dsh plugin --profile desktop add "link:/绝对路径/dsh-token-bi"
Windows 路径示例:
dsh plugin --profile desktop add "link:E:\gitbub-project\dsh-token-bi"
link: 表示软链安装,改动仓库里的代码无需重装。安装完成后完全退出并重启 DSH Desktop(不是刷新页面)——客户端 bundle 的路径表在进程启动时构建一次。
验证
重启后左侧栏面板列表里会出现「Token 账单」,位置紧挨着「插件」。
如果没出现,按顺序检查:
1. 设置 → 插件 → 已安装插件 里是否有 Token 账单 且开关为开
2. dsh --profile desktop --dump-config 输出里是否有 id: token-bi 这一行
3. Host 日志(%APPDATA%\DSH Desktop\logs\host\)里搜 token-bi,看有无激活失败
插件在加载时会把 [token-bi] factory、[token-bi] apply、[token-bi] slot:xxx 写到浏览器控制台(用 console.error,因此会进 Host 日志)。这些标记能区分「代码没下载」、「下载了没激活」、「激活了没注册成功」。
界面说明
入口是左侧栏的全局面板(和「插件」「自动化任务」同级),不绑定某个会话——汇总数据天生属于全局层。
顶部数字
| 指标 | 含义 |
| 累计 token | 当前时间窗口内的四类 token 总和 |
| 今日消耗 | 本地时区下今天的总和 |
| 会话 | 窗口内的会话数,副标题是其中正在运行的个数 |
| 轮次 | 去重后的 turn 数 |
| 缓存命中占比 | cacheRead / 总量。这个数通常很高(80%+),说明上下文复用得多 |
图表
- 每日消耗 —— 堆叠柱状图,四段分别是输入、缓存读、缓存写、输出。悬停看当天明细。
- 最近 7 天节奏 —— 按小时聚合的折线,用来看「什么时候在烧 token」。
- 模型分布 —— 按 provider/model 拆分,附带占比。
- 工作区分布 —— 按会话的 cwd 分组,超过 8 个时折叠并显示被折叠部分的合计(避免让人误以为数据缺失)。
- 会话明细 —— 主表。点任意一行展开该会话的逐轮时间线(每轮一条三段式条形)。
- 调用树 —— 父会话下挂子会话,用深浅两种颜色区分「这个会话自己花的」和「它派生的子会话花的」。
时间窗口
右上角三档:7 天 / 30 天 / 全部。
切换会向 Host 重新取数并按日重算总量,不是只过滤已有数据——所以数字、图表、会话列表会一起变。
导出
右上角「导出 CSV」,导出当前窗口内的会话列表,带 UTF-8 BOM,Excel 直接打开不乱码。
数据从哪来、怎么算
数据源
两个来源,按会话 id 合并,活跃会话优先:
| 来源 | 读什么 | 作用 |
| ctx.sessions | 内存中的会话事件 | 当前打开的会话,永远最新 |
| ctx.sessionQuery | 冷启动的持久日志 | 历史会话,让没打开的会话也能统计 |
不需要读原始 .jsonl.zstd 文件——都走 DSH 的公开服务。
计量口径
这是本插件最需要讲清楚的部分。规则直接对齐 Host 的 tokenUsage 投影(@deepseek-ai/dsh-token-meter):
1. 只看 provider 上报的用量,不估算。来源是 assistant/message 事件的 usage 字段,或 stream 里最后一个 type: 'usage' 的 chunk。
2. 同一 (turn, step) 后到的样本替换先到的。一次重试会产生多个样本,这条规则保证重试的用量只计一次,不会重复累加。
3. 四个桶分开记:inputTokens / outputTokens / cacheReadTokens / cacheWriteTokens,总量是四者之和。
第 2 条是关键。如果不做替换,失败重试的会话数字会虚高。校验方式:拿一个会话跑一遍折叠,四个桶的数字应当和会话界面里显示的完全一致。
时间归属
按事件时间戳落到本地时区的日期。浏览器把 getTimezoneOffset() 传给 Host,Host 用它给每条记录分日——所以跨时区使用、或跨零点运行的长任务,日期归属都是对的。
缓存
- 单会话结果按 (会话 id, revision) 缓存,revision 是活跃会话的 seq 或持久会话的元数据;没变就复用。
- 整个报告缓存 10 秒,refresh=1 强制重建。
- 缓存键包含时间窗口,切换档位不会串数据。
HTTP 接口
插件在 Host 上注册一个前缀路由,浏览器用同源请求读数据。
GET /api/dsh-token-bi/report?offset=<分钟>&days=<窗口>&refresh=1 GET /api/dsh-token-bi/session?id=<会话 id>&offset=<分钟>
| 参数 | 说明 |
| offset | 浏览器时区偏移(分钟),默认取 Host 时区 |
| days | 窗口天数;0 或 all 表示全部 |
| refresh | 1 时跳过 10 秒缓存 |
report 返回:
{
"generatedAt": 1792500000000,
"offsetMinutes": 480,
"rangeDays": 30,
"cutoffDay": "2026-09-22", // 窗口起点;全部时为省略
"totals": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0, "total": 0,
"sessions": 0, "live": 0, "turns": 0, "steps": 0 },
"sessions": [ /* 每会话:id/title/cwd/parentSession/totals/models/days/... / ],
"models": [ / provider/model 汇总 / ],
"days": [ / 按日,含缺失日补零 / ],
"hours": [ / 最近 7 天按小时 / ],
"cwds": [ / 按工作目录 / ],
"errors": [ / 读失败的会话,不阻断整体 / ]
}
session 返回单个会话的逐轮 rows(turn/step/time/input/output/cacheRead/cacheWrite/total),供展开行按需拉取——所以首屏不会因为历史很长而变慢。
这个路由沿用 DSH 插件惯用的 webServer 前缀注册。注意:路由在进程级只注册一次,重载时替换 handler 而非重复注册——重复注册会让 webServer 抛错并使整个插件激活失败(这是开发过程中踩过的真实坑,见 test/reload.mjs)。
配置
没有配置项。 所有参数(时间窗口、筛选)都在界面上切换,不需要改 profile 配置。
插件在 profile 里只有一行:
- insert:
- id: token-bi
name: dsh-token-bi
设计取舍
几个刻意的决定,写下来免得后来的人以为可以随手改:
汇总放在全局面板,不放在会话里。 跨会话的数据放进单会话的界面是位置错误,用户会以为那是"这个会话的统计"。
只读日志,不写任何东西。 插件不追加会话事件、不落自己的数据库。DSH 的会话日志是唯一事实来源,任何派生数据都应该是可重建的缓存。
对齐 Host 口径而非自创公式。 用户会拿插件数字和会话界面比对;两边不一致比数字不准更糟。
不做成本估算。 不同 provider、不同模型、不同缓存策略的单价差异极大,硬编码一张价格表会给出误导性的确定性。想知道钱花了多少,看 provider 的账单。
没有设置页。 没有任何可配置项,加一个设置页会多出一个什么都不做的入口。
已知限制
- 只统计上报了用量的步。 如果某个 provider 不返回 usage,那一步对统计不可见。这不是漏算,是无从算起。
- 压缩掉的历史仍然计入。 统计是"日志口径"而非"当前可见上下文口径"——被压缩的消息仍然算在会话总量里,这符合"这轮对话花了多少"的直觉,但和"当前上下文多大"是两件事。
- 子会话独立计费、独立统计。 父会话的数字不包含子会话;调用树里两者分层显示,叠加才是整棵子树的花费。
- 极长的会话会截断逐轮列表。 展开行最多显示最近 60 轮,避免长会话拖慢渲染;总量不受影响。
- 数据只覆盖本机。 读的是本机 DSH 的会话存储;多机部署需要分别查看。
- 需要 Web 界面。 依赖 webServer 服务,纯 TUI profile 下不会激活。
开发
目录结构
index.js Host 半:注册 HTTP 路由 lib/collector.mjs 聚合:合并活跃/持久会话,产出报告 lib/usage.mjs 口径:把一份会话日志折叠成用量记录(纯函数,无 IO) lib/client.js 浏览器半:面板注册 + 页面与图表 cordis.patch.yml bundle patch:插入 Host 行
locale/{zh,en}.json 插件元信息(标题、描述、图标)
test/ 离线测试,见下
lib/usage.mjs 是纯函数模块,不碰文件系统和 Cordis,可以直接拿任意事件数组调用——口径逻辑都在这里,改动应当先补测试。
测试
npm test # locale 一致性、重载竞态、槽位注册、页面渲染
npm run test:store # 用本机会话存储跑一遍聚合(只读)
npm run test:route # 用桩 context 驱动 Host 路由
| 测试 | 覆盖什么 | 需要什么 |
| locale-check.cjs | 中英文字典键集一致、t() 用到的键都有定义 | 无 |
| reload.mjs | 热重载时不重复注册路由(回归:曾经导致插件消失) | 无 |
| slots.mjs | 对真实 SlotCore 跑注册,且不再注册设置页 | DSH_APP_DIR |
| render.mjs | 用最小 hooks 运行时把页面真渲染一遍,含展开行交互 | 本机会话存储 |
| harness.mjs | 聚合结果的人眼核对输出 | 本机会话存储 |
| route.mjs | 路由的 200/400/404 与 JSON 契约 | 本机会话存储 |
测试默认读 $DSH_HOME/sessions(默认 ~/.dsh/sessions),可用 DSH_SESSIONS 或命令行参数指向别处;没有历史数据时会建空报告而不是报错。
slots.mjs 需要 DSH 自带的 @deepseek-ai/dsh-client-ui-slots:
DSH_APP_DIR="E:\dsh\DSH Desktop\resources\app" npm test
找不到时该测试会打印 SKIP 并以 0 退出,不会假装通过。
改动时的注意事项
- lib/client.js 不能 require DSH 的客户端包(如 ui-primitives)。样式和控件要么自己写,要么照抄 Host 的实现后改成自己的前缀类名,只引用 --dsw-alias- 主题变量。
- 样式必须走主题 token,否则深色模式下会瞎。
- dsh.client.inject 填的是包名(如 @deepseek-ai/dsh-client-ui-renderer),不是运行时服务名(slots)——写错会导致模块一直停在 loading 并把整个页面拖成 "Failed to load plugins"。
- 客户端入口放在 lib/client.js,与生态里其他插件一致。
许可
MIT预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
361533652/dsh-token-bi
汇总各会话用量,看清每天花在哪
相关插件 · UI / 主题
破甲增强版JeffKeeping/dsh-purge-plus
dsh-purge 的非官方分支fork:适配 DeepSeek Harness 0.2.1-rc.2、破甲内核…
★ 387已汉化DeepSeek 客户端
71.9
无代码业务系统平台nocobase/nocobase
NocoBase 是什么
★ 24,804已汉化DSH
71.8
1Panel 服务器面板1Panel-dev/1Panel
全球 250 万+ 自托管用户共同喜爱。
★ 37,362已汉化DSH
71.4
终端编码代理esengine/DeepSeek-Reasonix
· 指南 · ACP · 扩展开发 · 规格 · 官方网站 · Discord · QQ
★ 36,076已汉化DSH
71.2
工作状态行动态ccch1mneyyy/working-activity
作者:chimney@ccch1mneyyy。社区项目,非 DeepSeek 官方项目。
★ 664已汉化DSH
71.2
多模型配置管家farion1231/cc-switch
跨平台桌面一体化助手,支持 Claude Code、Codex、OpenCode、DeepSeek Harness 等工具,唯一官网 ccswitch.io
★ 151,814已汉化DSH
71.1
这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。