dsh-turn-speed:在会话统计里看清「本轮」输出速度

前言

用 DeepSeek Harness(DSH)跑多步智能体时,官方「会话统计」弹窗给出的是整段会话的聚合:模型用时、工具调用、首 token 平均(TTFT)、输出速度(TPS)等。这些数字回答的是「这次聊天整体怎么样」,但当你只想判断刚结束的这一轮模型跑得有多快、用户实际等了多久时,会话级平均值会把多轮混在一起,容易误读。

下面介绍的 dsh-turn-speed(维护者 suufon,分类为客户端插件)在官方那几行下方追加本轮读数,算法与官方 @deepseek-ai/dsh-session-stats 的 sessionStats 投影同源,只是范围缩到当前轮次。

这是什么

dsh-turn-speed 是 DSH 的 web 客户端插件:打开「会话统计」弹窗后,在官方「输出速度(TPS)」行下面追加本轮 TPS(decode 口径)、本轮端到端速度、TTFT、用时、输出 tokens、步数与轮次。官方会话级行与插件本轮行之间有一条分割线,避免把「会话平均」和「本轮」当成同一套数字。

弹窗里多了什么

官方原生项与插件追加项在视觉上用分割线分开(样式复用弹窗标题分隔线,跨两列网格以免断成短横线)。示意如下:

会话统计
──────────────────────────
模型用时            12.4秒
工具调用用时         3.1秒
首 token 平均(TTFT) 1.2秒
输出速度(TPS)      262 tok/s
──────────────────────────   ← 分割线:以上是官方原生项
本轮输出速度(TPS)   268 tok/s   ← 本插件
本轮端到端速度       231 tok/s
本轮首 token(TTFT)  1.1秒
本轮用时            18.7秒
本轮输出 tokens     5,014 tok
本轮步数               6
轮次                第 42 轮

实现上通过 DOM 注入:在 <dl data-session-stats-details> 尾部追加 dt/dd 行。官方弹窗没有可注册 slot,因此只能补丁详情列表;耦合点限于该属性、<html lang> 与标准标签语义,不依赖上游哈希类名。弹窗关闭时插件行随面板卸载清理;每次渲染会校验尾部是否仍为本插件块,必要时重建以与 React 更新收敛。

两行速度分别表示什么

插件刻意保留两种 TPS,口径不同,不应互相替代:

行 口径 回答的问题
本轮输出速度(TPS) Σ 本轮输出 tokens ÷ Σ(首 token → 该步完成) 模型生成有多快:排除 TTFT 与工具等待,与官方「输出速度(TPS)」同一算法,范围仅为本轮
本轮端到端速度 Σ 本轮输出 tokens ÷ 本轮墙钟时间 用户实际等了多久:TTFT、工具调用、重试等全部计入

decode 口径通常高于端到端口径,差额反映等待成本。本轮各指标与官方投影逐项对齐,例如「首 token 平均」为 Σ÷步数,而非取最快一步,以免相邻行自相矛盾。

数值从哪来

插件不读官方弹窗内部状态,而是从 Session Controller 的事件窗口折叠,与官方 apply 逻辑逐行移植:

ctx.sessions.list.getSnapshot().current   → 当前会话 id
ctx.sessions.binding(id).eventSource      → 事件窗口 { entries }

折叠细节与官方一致:同一时刻只有一个 open step;首 token 时间按 assistant/attempt → live chunk → settlement 流顺序取第一个可用值;一步多次 settle 只计一次;包式流记录按 time0 + 累加 dt 还原时间,与 @deepseek-ai/dsh-llm 的 assistantStreamFirstTokenTime 对齐。

安装与启用

DSH 生态里插件通过 CLI 安装;社区目录站点 SkillHub 与 DeepSeek / 幻方无官方从属关系,安装前建议自行查看仓库源码与 MIT 许可证。插件在当前 dsh 进程权限下运行,与宿主同源。

从 GitHub 安装(推荐)

dsh plugin --profile web add github:suufon/dsh-turn-speed

固定版本可加 tag:

dsh plugin --profile web add github:suufon/dsh-turn-speed#v0.2.0

安装后需要重启 dsh web:web 端 boot manifest 在服务启动时组装,仅刷新页面不会让新插件生效。

# 仓库脚本:探测 DSH_HOME / dsh CLI,并验证 /turn-speed-api/health
pwsh -File .\scripts\restart-web.ps1

卸载:

dsh plugin --profile web remove dsh-turn-speed

改源码即时生效时,用无空格的本地路径:

dsh plugin --profile web add link:<无空格的本地路径>

路径含空格时可用 junction 绕开(README 中有 PowerShell 示例)。

典型用法与验证

日常使用:在 web 客户端正常对话,打开「会话统计」即可在官方行下方看到本轮指标。无需额外配置项。

自证与诊断(可选):宿主半提供 loopback 免鉴权路由,便于确认插件是否激活、是否看到弹窗、折叠是否有误,而不必开浏览器控制台:

curl http://127.0.0.1:3080/turn-speed-api/health
curl http://127.0.0.1:3080/turn-speed-api/state

/state 返回 latest(如 activated、rows、lastError 等)与 pages;最后一次上报会写入 $DSH_HOME/storages/dsh-turn-speed.json。诊断路由失败不影响 UI,仅丢失诊断信息。

仓库在浏览器外跑验证脚本:

node scripts\verify.mjs

README 说明该脚本含 98 项检查,覆盖 bundle、折叠数学、弹窗补丁与宿主路由等。

适用场景与注意

适合谁:需要在 DSH web 里区分「整段会话」与「当前/上一轮」性能的智能体开发者;尤其关心 decode TPS 与端到端 TPS 差异、TTFT 与步数时。

已知边界(来自 README):

  1. 进行中的那一步没有完整计时(partial 仅含 turn/step/blocks),速度类读数在步边界更新;「本轮用时」在本地每秒 tick。
  2. 最新一轮若尚无可采样结算,会显示上一轮并将标签改为「上一轮」,不编造数字。
  3. 数字由浏览器半折叠;宿主半负责诊断通道与落盘。

结尾

dsh-turn-speed 把官方会话统计的投影算法缩到单轮,并在弹窗里用分割线与双 TPS 口径把「模型有多快」和「用户等了多久」分开写清楚。安装后重启 web 服务即可使用。

羽毛球分组比赛记分
小程序二维码

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

小夜