前言¶
DSH(DeepSeek Harness)Web profile 会把每次会话的日志落盘,但自带的界面只告诉你对话内容,不会汇总“这次跑了多少 token、缓存命中了多少、这个月用了多少”。想自己统计,只能在日志里手动翻 assistant/message 的 usage,费时且口径不一。
下面介绍的插件 genius-alray/dsh-plugin-session-token-stats 解决这个问题:它直接读取真实的会话日志,生成一个 Token 用量看板,包含总量、按月用量、缓存命中率、每日时间线,以及按会话分层明细。由 genius-alray 维护,属于客户端分类,以 MIT 许可证发布。
它只统计 token,不显示成本或预算。原因是这些会话没有可靠的计费 API,作者的选择是不要把猜测当成事实呈现。
一、它展示什么¶
插件接管后,左侧边栏底部会出现一个柱状图入口 Token stats。打开后是一个面板,分四块。
1、汇总卡片¶
显示总量 token(拆成未缓存输入 / 命中缓存的输入 / 输出)、会话数(回合数,以及合并进来的子代理会话数)、本月已用 token,以及整体缓存命中率。
2、Token 时间线¶
最近 7 / 30 / 90 天的每日堆叠柱状图,三类分别是未缓存输入、命中缓存输入、输出。鼠标悬停在柱子上可以看到当天精确数字。时间范围是浏览器侧的设置项。
3、按会话用量¶
每个主会话一行,按最新排序。子代理会话会被合并到派生它的那个会话里,不会单独列出一行。选中一行展开,可以看到按模型拆分的用量、合并进来的子代理数量、创建与最近活动时间戳,以及 session id。
4、CPU 与内存¶
面板右侧列出系统级指标:CPU 使用率(120 秒的迷你折线)、1/5/15 分钟负载均值、DSH 进程的 CPU 和 RSS、系统内存、核心数、进程运行时长,以及主机标识。
二、计数口径¶
Host 端通过 ctx.sessionQuery.listSessions() / readSession(id) 读取持久化会话日志,逐条统计 assistant/message 里的 usage,字段口径如下:
| 字段 | 对应来源 |
|---|---|
| 未缓存输入 | usage.inputTokens(DeepSeek 在此字段中不包含缓存命中部分) |
| 命中缓存 | usage.cacheReadTokens |
| 输出 | usage.outputTokens |
| 总量 | 未缓存 + 命中缓存 + 输出(若 provider 提供了 cacheWriteTokens 则再加) |
| 缓存命中率 | 命中缓存 ÷(未缓存 + 命中缓存) |
为了让这些数字可信,插件做了两条去重规则:
- Fork / 继承会话:日志开头是复制自父会话的一段前缀,那段用量已经在父会话里计过了。只统计
inheritedEventCount之后的事件(最新的session/title仍从整条日志读取)。 - 子代理会话:
header.parentSession指出派生会话,顺着这条链把子代理会话归并到最顶层的主会话,合并成一行。
持久化会话是不可变的,所以每条日志只读一次并缓存;活跃会话则在每次刷新时重新读取。首次打开会解压并对所有日志做回放校验(500+ 条日志大约 10–20 秒),期间以 { done, total } 汇报进度并快速轮询;之后再刷新只重读正在运行的会话。
三、安装与启用¶
插件是一个标准的 dsh bundle:注册一行 Host 和一行 Client,不覆盖任何内置组件。
UI 安装¶
在 Plugins → Add plugin → Install third-party plugin 中粘贴(该字段也支持本地目录或 Git URL):
dsh-plugin-session-token-stats
CLI 安装¶
# 本地检出(开发场景)
dsh plugin --profile web add /absolute/path/to/dsh-plugins/session-token-stats
# 或直接取该仓库
dsh plugin --profile web add https://github.com/genius-alray/dsh-plugin-session-token-stats
安装完成后刷新页面,左侧边栏底部会出现柱状图入口 Token stats。
四、接口与数据¶
插件注册了两个同源 Host 路由,都经过 Connection 服务做 owner 鉴权(未认证返回 401;缺少 Connection 服务返回 403,fail-closed):
GET /session-token-stats/data:总量、每日分桶、按会话聚合结果、扫描进度。GET /session-token-stats/live:CPU / 负载 / 内存采样环形缓冲区(1 Hz,保留最近 120 个样本)。
Host 端的逻辑集中在 server.js:日志折叠、子代理归并、CPU 采样和两个 JSON 路由;Client 端在 client.js:主面板、边栏入口、时间线、表格与设置。多语言元数据放在 locale/*.json,cordis.patch.yml 只插入本插件的 Host 行。
五、运行与验证¶
依赖很简单,只需要一个 DeepSeek Harness Web profile,且 dsh >= 0.2.1-rc.2;Host 端的 sessionQuery、webServer、connection 三个服务在出厂的 Web profile 中都已存在。
在本地检出里跑自检和测试(测试使用 node:test,不需要第三方依赖):
npm run check # 对 server.js 和 client.js 各做一次 node --check
npm test # node --test tests/
Host 测试通过假的 Cordis 上下文驱动 apply(),用合成语料覆盖用量折叠、波峰/波谷分桶、继承前缀排除、子代理归并、扫描缓存和路由鉴权;Client 测试用 stub module loader 加载浏览器 bundle,覆盖 token 格式化、缓存命中率、时间线补零、浏览器侧偏好和字典一致性。
六、适用场景与注意事项¶
适合需要长期跟踪会话 Token 消耗、关注缓存命中率,或想确认本地 DSH 进程资源占用的开发者。如果只是偶尔查一句话的用量,直接翻日志成本更低。
几个要注意的点:
- 插件以当前 dsh 进程的权限运行。它可以读取本机的会话日志与系统指标,安装前应先查看源码,确认 trust 边界符合预期。许可证为 MIT。
- 500+ 条日志的首次扫描需要几秒(解压 + 回放校验),之后的刷新只重读运行中的会话。
- 时间线保留 120 天。更早的用量仍会出现在会话行和总量里,但不会进入每日图表。
- 当父会话已不在本地语料中(归档或清理),其子代理会话会各自成为一行顶层记录。
- 标题跟随最新的
session/title事件;老日志没有该事件时,回退到第一条用户消息。 - 不显示成本/预算是设计决定。要自己计价,就用插件给出的 token 拆分去算。
七、小结¶
这个插件的价值在于把 DSH 已落盘的会话日志转换成一个口径明确、可核对的用量面板:总量、缓存命中率、按月趋势、按会话分层,外加进程级资源监控,同时刻意不做成本估算。安装是一个 bundle + 一行命令,Host 端做了继承前缀去重与子代理归并,保证统计结果可信。
目录页:https://www.skillhub.cn/plugins/genius-alray/dsh-plugin-session-token-stats
GitHub:https://github.com/genius-alray/dsh-plugin-session-token-stats