dsh-tokstat
kongjianguan/dsh-tokstat
dsh usage & performance statistics: settings-panel plugin + TUI (tokens / TTFT / TPS / cost)
安装
dsh plugin --profile web add github:kongjianguan/dsh-tokstatREADME
dsh-tokstat
读取 DeepSeek Harness (dsh) 会话日志的实时使用量与性能 TUI 统计面板 —— Tokens / TTFT / TPS / 成本一屏看全



Overview
dsh-tokstat 直接读取 dsh 的会话日志(~/.dsh/sessions/**/session.jsonl.zstd,
zstd 帧级增量解析),把散落在多个会话文件里的每一次 LLM 请求还原成可分析的
指标:输入/输出/缓存 Tokens、TTFT(首 token 时延)、TPS、耗时、重试与失败、
估算成本。
项目提供两种形态:
- dsh 设置面板插件:在 dsh Web 设置页增加「统计」section,实时展示概览 / 模型 / 会话 / 请求,2s 轮询;
- Python TUI:独立终端仪表盘(7 个视图,
o t m p s r e切换)。
适合谁:
- 想了解自己每天在 dsh 上花了多少 token / 钱的用户;
- 想评估模型与供应商性能(TTFT、TPS 分布)的用户;
- 想排查重试、失败步骤的 agent 重度用户。
7 个视图(o t m p s r e 切换):
| Tab | 内容 |
|---|---|
| 总览 | 请求数 / 总 Tokens / 平均 TTFT(TPS)(含 p50·p95)/ 成功率 / 缓存命中率 / 成本 / 耗时 Hero 卡 + Tokens 构成条 + 4 条实时火花线 + Top 模型/会话 |
| 趋势 | 按小时/天(h/d)的柱状图:请求数、Tokens(输入+缓存 vs 输出)、平均 TTFT(绿≤5s/黄≤120s/红>120s)、平均 TPS |
| 模型 / 供应商 | 各模型/供应商的用量、缓存命中率、TTFT 中位+p95、TPS、重试、成本,点击表头排序 |
| 会话 | 每个会话的用量/性能/成本/用户消息/最后活动;点击行可查看单会话详情 |
| 请求 | 逐条请求日志(1200 条上限),f 过滤,点击表头排序 |
| 错误 | 重试原因分布(TRANSPORT/SERVER/TIMEOUT…)、逐条重试事件、失败步骤 |
指标设计参考了 cc-switch 的用量统计、new-api 与 sub-api 的数据看板,指标口径与
dsh 官方 sessionStats 投影一致(见 指标定义)。
Compatibility
- 数据格式基于 dsh 0.1.0-rc.6 的会话日志结构验证(2026-08-15),并已与
服务器端
session_projcache.json投影交叉验证(llmMs/decodeTokens 精确相等, TTFT 误差 <10%;历史验证 <2%,个别新日志批量 chunk 近似可达 ~9%)。 - 插件形态:Node half 需要 Node ≥ 23.6(dsh 运行时 Node 26 已验证);client
面板运行在 dsh Web 设置页;peerDependencies 声明了
@deepseek-ai/*版本范围。 - TUI 形态:Python 3.11+;依赖 textual ≥8.0、zstandard ≥0.23、PyYAML。
- 会话日志格式由 dsh 演进决定;若升级 dsh 后发现读取异常,请到仓库反馈。
Install / Uninstall
方式一:dsh 设置面板插件(推荐)
从 Git 仓库安装到指定 profile(例如 web-dev):
dsh plugin --profile web-dev add https://github.com/kongjianguan/dsh-tokstat.git
# 启动 dsh Web
dsh --profile web-dev --port 3199
安装后打开 http://127.0.0.1:3199/,进入 设置 → 统计 即可看到面板。
插件数据通过 /tokstat/stats 由 dsh 进程内的 Node half 提供,无需额外服务。
本地开发安装:
dsh plugin --profile web-dev add /path/to/dsh-tokstat
# 或使用仓库内辅助脚本(自动写 package.json + 建 node_modules 链接)
node scripts/link-profile.mjs --profile web-dev
卸载:
dsh plugin --profile web-dev remove @kongjianguan/dsh-tokstat
方式二:Python TUI
git clone https://github.com/kongjianguan/dsh-tokstat.git
cd dsh-tokstat
./run.sh # 自动创建虚拟环境并安装依赖(等价于下方手动步骤)
或手动:
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
.venv/bin/python main.py
TUI 升级:
git pull
.venv/bin/pip install -r requirements.txt # 依赖有变更时
TUI 卸载:
rm -rf dsh-tokstat # 工具无后台进程、无系统级安装、无写出的数据文件
Quick start
dsh 设置面板插件
dsh plugin --profile web-dev add https://github.com/kongjianguan/dsh-tokstat.git
dsh --profile web-dev --port 3199
# 浏览器打开 http://127.0.0.1:3199/ → 设置 → 统计
Python TUI
./run.sh # 默认范围:全部
./run.sh --range today # 只看今日
./run.sh --refresh 5 # 降低刷新频率
示例输出(总览页核心指标):
请求数 2,431 总 Tokens 384.33M 平均 TTFT 17.3s 平均 TPS 1889.9
成功率 99.6% 缓存命中率 98.8% 估算成本 ¥84.45 平均耗时 24.1s
快捷键:
| 键 | 作用 |
|---|---|
o t m p s r e | 切换 总览/趋势/模型/供应商/会话/请求/错误 |
1 2 3 4 | 时间范围:全部 / 今日 / 近7天 / 近30天 |
h d | 趋势粒度:小时 / 天 |
f | 聚焦请求日志过滤框(Esc 退出) |
space | 暂停 / 继续自动刷新 |
Ctrl+R | 立即刷新 |
q | 退出 |
Configuration
全部通过命令行参数与一个 YAML 文件配置,无环境变量依赖:
| 参数 / 文件 | 说明 |
|---|---|
--home PATH | dsh 数据目录(默认 $DSH_HOME 或 ~/.dsh) |
--refresh SECONDS | 轮询刷新间隔(默认 2) |
--range all|today|7d|30d | 初始时间范围(默认 all) |
--prices PATH | 价格表 YAML 路径(默认项目内 prices.yaml) |
prices.yaml 按每百万 token 定价(¥),内置 DeepSeek v4 官方价格,可增删:
deepseek-v4-flash:
input: 1.00 # 每百万输入 token
output: 2.00 # 每百万输出 token
cacheRead: 0.20 # 每百万缓存命中 token
模型 ID 自动归一化(去 owner/ 前缀、去 :后缀、@→-、去日期后缀),
deepseek-v4-flash-0731 先精确匹配、再逐级缩短匹配。未定价模型成本显示 -。
Permissions & data
- 只读:TUI 仅读取
~/.dsh/sessions/下的会话日志(session.jsonl.zstd)与~/.dsh/settings.yaml(用于定位数据目录);插件由 dsh 进程内的 Node half 通过sessionPersistence读取同一份会话日志;不修改任何 dsh 数据。 - 不联网:TUI 全程离线运行;插件 client 面板只访问本机 dsh Web 的
/tokstat/stats,无遥测、无上报。 - 价格表与自定义参数仅存于本地文件;不会读取或上传你的 API 密钥。
- 插件 client 面板运行在浏览器,不直接接触文件系统;所有数据由 Node half 聚合后 通过本机 HTTP 提供。
- 会话日志包含对话内容;请勿将包含敏感对话的
~/.dsh目录提交到任何仓库。
Troubleshooting
| 现象 | 处理 |
|---|---|
| 启动后"暂无数据" | 确认 --home 指向正确(默认 ~/.dsh),检查 sessions/ 下是否有 session.jsonl.zstd |
| 升级 dsh 后解析报错/数字异常 | 会话日志格式可能变化;提交 issue 并附 dsh 版本 |
| TTFT 偏大 | 口径为 step/start → 首 token,含排队/思考时间,请以 p50/p95 为准 |
| 刷新卡顿 | 降低 --refresh(如 5s);数据量大时总览/请求页重建较慢 |
| 成本数字与账单不符 | 成本为估算;中转渠道请在 prices.yaml 配置实际价格 |
| 设置页没有「统计」section | 确认 profile 已 dsh plugin --profile <name> add 本插件,并重启 dsh Web |
/tokstat/stats 404 | 插件未加载或该 profile 未启用 webServer;检查 boot 日志 |
Development
本项目的插件开发规范、设置面板扩展机制(
settings.sectionslot)与收录条件 对照,见 docs/plugin-development/。
结构
dsh-tokstat/
├── index.mjs # Node half:Cordis 插件入口(/tokstat/stats)
├── src/client/index.js # client half 源码(设置面板 React)
├── lib/client.js # client bundle 产物
├── src/host/ # Node half 聚合(fold/aggregate/pricing TS)
├── tui/ # Python TUI(独立可用)
│ ├── main.py
│ └── dshstats/
├── scripts/ # build-client / gate / panel-harness / cdp-shot
└── docs/
TUI 内部结构:
tui/dshstats/
store.py zstd 帧扫描 + 增量 tail + 事件折叠(与 dsh 官方投影同口径)
metrics.py 聚合:summary / 时间桶 / 分组 / 百分位
pricing.py 价格表 + 模型名归一化
ui/ textual 界面(7 个 tab + SortableTable/Bars/StatCard 组件)
插件构建与门禁
pnpm install # 首次安装依赖(已提交 lockfile)
pnpm run build:host # Node half → dist/index.mjs(esbuild 打包 TS)
pnpm run build:client # 同步 lib/client.js
pnpm gate # 结构门禁 + 三方对账 + 行为测试
pnpm gate --ci # CI/无真实 dsh 数据时:跳过三方对账,仍跑结构门禁 + 行为测试
不安装依赖也可直接跑(脚本只用 Node 内置能力/已提交 dist):
node scripts/build-host.mjs # Node half → dist/index.mjs(需要 esbuild,已装则可用)
node scripts/build-client.mjs # 同步 lib/client.js
node scripts/gate.mjs # 结构门禁 + 三方对账 + 行为测试
改 client 后建议跑无头 Chrome 回归:
node scripts/panel-harness.mjs --port 3320
# 另开 Chrome --headless=new --remote-debugging-port=9222
node scripts/cdp-shot.mjs "http://127.0.0.1:3320/" 8000 --click "请求"
测试与验证
- 插件数据正确性:
node scripts/gate.mjs会跑 TS/Python/官方 projcache 三方对账。 - TUI 无头功能测试:
App.run_test()+ Pilot 模拟按键/切 tab;app.save_screenshot()导出 SVG 核对布局。 - 数据正确性:解析结果与
~/.dsh/storages/session_projcache.json中官方sessionStats投影交叉对比(llmMs/decodeTokens 应精确相等,TTFT <10%)。 - 贡献:fork + PR 即可;改动涉及事件折叠时请在 PR 中附交叉验证结果。
License & security
- 本项目以 MIT 许可发布(见 LICENSE)。
- 安全问题请通过 GitHub issue 私下说明(避免在公开 issue 中粘贴密钥或会话内容), 或直接邮件仓库维护者。
指标定义
与 dsh 官方 sessionStats 投影一致:
| 指标 | 定义 |
|---|---|
| 请求数 | assistant/message 事件数(一次组装完成的 LLM 调用) |
| 输入/输出/缓存 Tokens | usage 的 inputTokens / outputTokens / cacheReadTokens |
| TTFT | step/start → 第一个非空 token delta;持久化日志缺失逐条 delta 时由批量 *-chunks 的 dt 近似(误差 <10%) |
| TPS | 输出 Tokens / 解码秒数 |
| 成功率 | 请求数 / (请求数 + 失败步骤数) |
| 缓存命中率 | 缓存读取 / (输入 + 缓存读取) |
| 成本 | 按 prices.yaml 估算 |
已知限制
- TTFT 定义与 dsh 官方一致,含排队/思考时间,长尾明显——请以 p50/p95 为准。
- 部分会话的持久化日志只有批量 chunk(
*-chunks),TTFT 为近似值(历史误差 <2%,个别新日志可达 ~9%)。 - 成本为估算,中转渠道价格请自行配置。
- TUI 形态是独立 Python 程序;仓库根同时提供 dsh 设置面板插件(Node half + client bundle),两者共享同一套指标口径。