前言¶
用 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、步数与轮次。官方会话级行与插件本轮行之间有一条分割线,避免把「会话平均」和「本轮」当成同一套数字。
- 目录页:https://www.skillhub.cn/plugins/suufon/dsh-turn-speed
- 源码与说明:https://github.com/suufon/dsh-turn-speed
- 当前 package 版本:0.2.0(MIT)
弹窗里多了什么¶
官方原生项与插件追加项在视觉上用分割线分开(样式复用弹窗标题分隔线,跨两列网格以免断成短横线)。示意如下:
会话统计
──────────────────────────
模型用时 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
本地开发(link)¶
改源码即时生效时,用无空格的本地路径:
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):
- 进行中的那一步没有完整计时(
partial仅含 turn/step/blocks),速度类读数在步边界更新;「本轮用时」在本地每秒 tick。 - 最新一轮若尚无可采样结算,会显示上一轮并将标签改为「上一轮」,不编造数字。
- 数字由浏览器半折叠;宿主半负责诊断通道与落盘。
结尾¶
dsh-turn-speed 把官方会话统计的投影算法缩到单轮,并在弹窗里用分割线与双 TPS 口径把「模型有多快」和「用户等了多久」分开写清楚。安装后重启 web 服务即可使用。