dsh-speed-meter: Real-time tok/s Speedometer beneath Composer

前言

在 DSH(DeepSeek Harness)里跑智能体时,流式输出是否在「正常速度」往往只能靠体感:等到整轮结束,也很难立刻知道这一次模型调用真实的 token 吞吐。社区里已有 @feiyang666/dsh-usage-plugin 一类插件,侧重调用结束后的 token 与费用台账,并不在生成过程中给出 tok/s。维护者 deepseekv41flash 的 dsh-speed-meter 补的是「流式过程中 + 单次调用精确速率」这一空位:在输入框下方的 composer dock 常驻一枚胶囊,只绑定当前会话,自校准每模型的 chars→tokens 系数。

下面介绍它是什么、怎么装、界面上会看到什么,以及使用时需要知道的边界。

这是什么

dsh-speed-meter 是 DSH 生态下的模型推理类插件,由 dsh.bundle 装配(宿主半 + Web 客户端半在同一 npm 包内)。当前 package 版本为 0.2.0,许可证 MIT,源码与说明见 GitHub 仓库,目录页为 SkillHub 插件页。

一句话:宿主挂在 llm/stream 上统计每次流式调用的增量字符与时间,流结束时用 API 的 outputTokens 反推精确 tok/s 并校准系数;客户端通过 HTTP/SSE 拉快照,在 composer dock 渲染胶囊。

核心功能

会话作用域

胶囊只显示当前会话。请求带 ?session=<sessionId>,宿主按会话维护 last/recent,并对 running 做归属过滤。其他窗口在生成时,本会话不会显示别人的速率;tooltip 会提示「其他会话正在生成(不显示)」。

胶囊上显示什么

状态 含义
流式生成中 最近约 1.2 秒滑动窗口的瞬时速率(tok/s,经自校准系数换算)
等待首字 请求已发出、尚未收到第一个增量
一轮结束 该轮会话的平均速率与累计用量:总 outputTokens ÷ 本轮净生成耗时;一轮内多步/工具回合全部累加
无本轮数据 退回显示上一次调用的精确速率
短突发调用 不显示速率,只显示 token 数与耗时(见可靠性判据)

「轮」的边界对应智能体 running → idle。流式过程中胶囊仍显示瞬时速率;tooltip 里另有「本轮累计」。悬停可见 sessionId、model、purpose、累计字符数、ratio、耗时等;点击可展开最近 12 次调用与每模型校准状态。

统计与校准原理

  1. 宿主半包在 llm/stream waterfall 上,逐块统计 text-delta / reasoning-delta / tool-call-delta 的字符数,并记录首个与最后一个增量的时间。
  2. 流结束时 API 提供 usage(含 outputTokens)。宿主用 outputTokens ÷ 已统计字符数 得到该模型每次调用的 chars→tokens 比率,并以 EMA(α=0.2)持续校准;运行中的即时速率乘以该系数,估值会逐步贴近真实 token 数。
  3. 客户端通过 SSE(/speed-meter/api/stream,宿主约每 400ms 推送完整快照)更新 UI;SSE 不可用时退回约 900ms 轮询。

可靠性判据:短于 500ms 且 token 少于 40 的调用(例如会话标题、缓存回放、单块 tool-call 参数)时间分母更接近传输突发而非生成耗时,会算出失真极高的 tok/s。这类调用标记 reliable=false、tokSec=null,界面只显示 token 数与耗时,不显示速率。

安装与启用

插件通过 DSH 的 bundle 机制安装,官方命令为:

dsh plugin --profile <profile> add dsh-speed-meter

将 <profile> 换成你实际使用的 profile 名。本地开发可将包 link 进 profile 后重启 DSH NEXT;客户端半的改动需要刷新页面或重启应用才会重新加载。

安装前建议自行查看仓库源码与 MIT 许可证:插件以当前 DSH 进程权限运行,会拦截并统计流式模型调用相关的宿主数据。

典型用法

安装并重启/刷新 DSH NEXT 后,无需额外配置文件:在对话 composer 下方应出现速度胶囊。正常对话、工具调用触发的流式生成都会进入统计。

若需对接或调试数据,可使用 README 中描述的 HTTP 接口(均需带会话时加 session 参数):

  • GET /speed-meter/api?session=<id>:该会话快照 JSON(不带 session 则为进程级最新一次调用),含 turn(本轮汇总)。
  • GET /speed-meter/api/stream:SSE,数据变化时推送与上面同结构的 JSON;空闲时发注释行保活。

宿主内调试可发事件同步取快照(桌面宿主对普通浏览器关闭 HTTP 时适用):

ctx.emit('speed-meter/snapshot', reply => ...)

快照中的 debug 字段(如 apiHits、sseHits、generation 等)可用于判断客户端是否连上、以及 Cordis 热重载后路由是否仍由上一代 handler 占用。

适用场景与注意

适合:需要在同一会话里实时观察模型输出吞吐、对比不同模型或不同 prompt 下体感速度;需要单次调用精确 tok/s 与最近 12 次历史,而不必另开外部监控。

注意:

  • 状态保存在进程级全局单例(globalThis[Symbol.for('dsh-speed-meter/state-v1')]),是为 Cordis 热重载后表盘不冻结;DSH 重启后数据归零。持久化台账请用 dsh-usage-plugin。
  • 流被中断或超时时可能拿不到精确 usage,只能按校准系数估算并标 exact=false。
  • 多会话并行时,表盘可能显示「最近活跃的那一次调用」;快照里的 sessionId 可区分。
  • EventSource 连接不会跨 fiber 迁移;Cordis 热重载或插件升级后,最稳妥的做法是刷新页面(Ctrl+R)让客户端重新连 SSE。

结尾

dsh-speed-meter 把 tok/s 从「事后猜」变成 composer 旁的常驻读数:流式看滑动窗口瞬时速率,结束看精确 tok/s 与本轮累计,并按模型自校准 chars→tokens。若你在 DSH 里做智能体开发与调优,可以把它当作会话内的轻量速度表盘。

  • 目录页:https://www.skillhub.cn/plugins/deepseekv41flash/dsh-speed-meter
  • GitHub:https://github.com/deepseekv41flash/dsh-speed-meter
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye