dsh-runstat
DeepSeek Harness 运行状态与任务复盘插件。 在输入框下方显示 Agent 现在在干什么:是在等首包、在思考,还是在执行哪条命令;做到第几步、等了多久。任务结束后,它把这次执行的逐步日志和本地规则发现的线索整理成摘要,交给当前模型判断:哪些步骤能用脚本代替、能合并、能改批量、是重复的或多余的检查,按 P0/P1/P2 列出改法和改动草稿。
┌────────────────────────────────────────────────────────────┐
│ 帮我整理本周资料 │
└────────────────────────────────────────────────────────────┘
● 活动 ● 用量 ◐ 思考 1.2k 字 8.0s
▶ 运行测试 npm test 2/5 12s
└──────────── 本插件 ────────────┘
- 看得见模型在干什么:插件接入客户端的实时分片通道,区分等首包、思考、输出回复、生成工具调用和流停顿,不再一律显示“等待模型”。
- 看得懂工具在干什么:每次调用都按规则生成一句话描述,例如“运行测试 npm test → 退出码 0「131 项通过」”“读取 fold.js 第 600–800 行”“临时脚本 python3(12 行)”。
- 时间算得清:每轮、每步都按“总时长 = 模型 + 工具 + 审批等待”给出等式。
- 建议由模型判断:点「生成优化建议」后,插件把逐步日志(每步的耗时、输出量、发出的命令与结果摘要)和本地线索(输出被截断、整文件反复重写、同类文件逐个读取、读技能源码等)发给当前模型。提示词写明重点检查脚本替代模型、合并步骤、单条改批量、去掉重复、删减检查、固化流程。每条建议带位置、依据、改法和可直接使用的改动草稿;点「复制全部」把所有建议复制成一份 Markdown,直接发给 Agent 去改。
- 实时部分不花 Token:实时描述、计时、计数与时间等式全部由本地规则生成;只有点「生成优化建议」时调用一次模型(上限 40,000 字摘要),这次调用的耗时与 Token 单列,不计入任务。可先用
/runstat digest预览将发送的内容;设includeModelAssist: false则只用本地规则。
目录
安装
需要 macOS 上的 DeepSeek Harness 0.2.1-rc.2 或兼容版本,以及 Node.js 20 或更新版本。已针对前述 Harness 版本验证;其他版本或系统未验证。本插件不在 npm registry 上,无运行时依赖,无需构建。先从 GitHub 下载或克隆整个仓库(不要只下载 index.js),保持目录结构完整。dsh 命令行工具在应用包内,通常不在 PATH 里:
DSH="/Applications/DeepSeek Harness.app/Contents/Resources/runtime/cli/bin/dsh"
PLUGIN="/path/to/dsh-runstat" # 改成下载后解压或克隆的目录
"$DSH" plugin --profile desktop add "$PLUGIN"
# 卸载
"$DSH" plugin --profile desktop remove @local/dsh-runstat
浏览器端(client.js)热加载,刷新页面即可生效;宿主端(index.js、lib/)的改动需要重启 Harness。
安装后在输入框下方确认出现状态指示条;输入 /runstat 查看当前状态,任务结束后用 /runstat done 生成本地复盘。若初次安装没有出现指示条,重启 Harness 再查看。插件使用目录链接,请勿在安装后移动或删除下载目录;卸载时使用上述命令。
若官方 CLI 不可用,可手动把插件目录链接到 ~/.dsh/profiles/desktop/node_modules/@local/dsh-runstat,并在该 profile 的 package.json 中把 @local/dsh-runstat 加入 dsh.profile.bundles。修改前备份 profile 的 package.json;插件自带 cordis.patch.yml,不要在 profile 的 patch 文件里重复注册。
从旧名
dsh-exec-insight升级:先卸载@local/dsh-exec-insight,再安装本插件。以前用/insight done确认过的任务仍会被正确识别。
快速上手
- 正常发起任务。输入框下方的胶囊会实时显示当前动作和计时。
- 点击胶囊打开面板,查看“现在”区、本轮时长等式、指标和过程日志。
- 任务做完后点 生成优化建议(或输入
/runstat done):把摘要发给当前模型分析,通常需要 1–2 分钟。结果显示在面板的「优化建议」板块,对话里只留一句回执。 - 想知道发出去的是什么,先输入
/runstat digest:它只报分段字数、裁剪情况,并把摘要全文写到磁盘供逐字核对(不花 Token)。 - 发送下一条消息时开始新任务,统计与上一个任务分开。
一轮回答结束不等于任务完成。你继续追问或要求修改时,统计会累计到同一个任务里,直到你明确确认完成。
胶囊
胶囊固定分成五段:图标 动作 对象 进度 计时。图标的颜色表示状态类别(蓝色模型、绿色工具、橙色需要注意),计时段宽度固定,胶囊不会每秒跳动。
| 显示 | 含义 | 判断依据 |
|---|---|---|
⇡ 等首包 6.0s(平均 2.1s) |
请求已发出,还没收到第一个分片;后面是本会话首包的平均等待 | 实时分片 |
◐ 思考 1.2k 字 8.0s |
正在接收模型的思考内容 | 实时分片 |
✎ 输出回复 300 字 |
正在接收回复正文 | 实时分片 |
⚙ 准备调用 read×3 bash |
模型正在写工具调用,能提前看到本批要调哪些工具 | 实时分片 |
⏸ 流停顿 无新数据 8.0s |
已经开始接收,但超过 5 秒没有新分片 | 实时分片 |
↻ 重试中 限流 1/5 |
请求失败,正在退避后重试,并给出失败原因 | 会话事件 |
▶ 运行测试 npm test 2/5 12s |
正在执行工具,本批已完成 2 个,共 5 个 | 会话事件 |
▶ 并行 2 个 读取 a.js、搜索「x」 |
多个工具同时在跑 | 会话事件 |
⏸ 等待审批 / ? 等待回答 |
需要你操作才能继续 | 会话事件 |
○ 等你继续 |
本轮已答完,等你追问或点「生成优化建议」 | 会话事件 |
◌ 正在分析优化点… |
正在调用模型生成优化建议 | 插件自身 |
✓ 已复盘 P0×3 P1×1 |
已生成建议,后面是各优先级的条数 | 会话事件 |
○ 空闲 |
本会话还没有任务 | 会话事件 |
“等首包”时间长,说明网络、排队或模型处理慢;“流停顿”说明连接中途卡住。插件只陈述观察到的现象,不判定是哪一环出了问题。
拿不到实时通道时(例如旧版 Harness),模型阶段退回显示“等待模型”,其余功能不受影响。
详情面板
点击胶囊打开,按 Esc 或点击外部关闭。面板与输入框等宽、高度约为窗口的 86%,背景半透明,能看到后面的对话仍在推进。表头固定,正文只有一层滚动,分成四个带边框的板块;表头的导航可以直接跳到对应板块。
┌ 运行状态 ──────────────────────── 实际经过 1h2m(含空闲)┐
│ [当前状态] [耗时与用量] [优化建议 P0×2 P1×1] [过程日志 40 步] │
├──────────────────────────────────────────────────────┤
│ ┌ 当前状态 ────────────────────────────────────────┐ │
│ │ 待办 4/6 · 进行中:补技能测试 │ │
│ │ 本步 第 2 轮第 18 步 · 读取 ×3、运行测试 · ●○○ 1/3 │ │
│ │ 正在 ▶ 运行测试 npm test · 8.0s │ │
│ └──────────────────────────────────────────────────┘ │
│ ┌ 耗时与用量 2 轮 · 18 步 ─────────────────────────┐ │
│ │ 本轮(第 2 轮)2m10s = 模型 1m02s + 工具 48s + 审批等待 20s │ │
│ │ ▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒░░░ ■ 模型 ■ 工具 ■ 审批等待 │ │
│ │ [模型请求 18] [工具调用 31] [重试 0] [Token] [缓存命中] │ │
│ └──────────────────────────────────────────────────┘ │
│ ┌ 优化建议 P0×2 P1×1 ──── [复制全部(3 条)] [重新生成] ┐ │
│ │ 由 deepseek-v4 分析 · 耗时 1m4s · Token 15,234 … │ │
│ │ ▸ [P0][减少返工] 计划文件被整份重写 2 次 省 2m30s │ │
│ │ ▸ [P1][合并步骤] 开头 6 步准备动作每次都一样 │ │
│ │ ▸ 本地规则线索(7 条,已作为线索交给模型) │ │
│ └──────────────────────────────────────────────────┘ │
│ ┌ 过程日志 2 轮 · 18 步 · 新的在上 ─────────── [收起] ┐ │
│ │ … │ │
│ └──────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────┘
优化建议每条先显示一行:优先级、类别、结论和预计可省;点开后是位置、依据、改法、改动草稿、待确认事项和估算依据。模型分析成功时,本地规则的条目收进「本地规则线索」;模型分析没开或失败时,本地规则条目直接作为建议显示,并在来源行写明原因。
板块标题栏的 复制全部 把建议区正在显示的全部条目(按 P0 → P2,不含折叠的本地规则线索)复制成一份 Markdown,可以直接发给 Agent 让它逐条修改技能,也可以贴进文档:
# 技能「weekly-report-summarize」的优化建议(2 条)
请按下面的建议逐条修改对应的技能或流程。每条先确认位置和「需要先确认」的事项,再动手;不适用的条目说明原因后跳过。
## 1. [P0 · 减少返工] 计划文件被整份重写 2 次
- **位置**:第 2 轮第 1、12 步
- **依据**:第 2 轮第 12 步模型 107s、输出 15977
- **改法**:让校验脚本输出字段路径与期望值,模型只改对应字段
- **预计可省 2m30s · 25k Token**(两次整写的模型时间与输出)
改动草稿:
```
## 校验失败时
运行 node scripts/validate.js plan.json,按输出的字段路径用 edit 修改
```
## 2. [P1 · 合并步骤] 开头 6 步准备动作每次都一样
…
过程日志默认展开,新的轮次和步骤在上,每轮先给时长等式,再逐步列出:
第 2 轮「再加一节」
本轮 13s = 模型 8.0s + 工具 2.0s + 审批等待 3.0s
│ 第 2 步 · 模型 4.0s(首包 1.2s) · 工具 1.0s · 输入 42k(缓存 40k) 输出 300
│ 思考 1.2k 字:「先读 fold.js 看 batch 字段…」
│ · 运行测试 npm test → 退出码 0「131 项通过」 1.0s
│ · 修改 client.js +12/−3 行 → 已修改 1 处 0.1s
每行都由规则生成。命令按类别归纳(测试、构建、安装、Git、查看、搜索、等待、网络、运行脚本、临时脚本),结果取退出码、最后一行有效输出、匹配数或行数,思考和回复只截取开头。
面板只携带最近 40 步的明细,以控制每帧数据量。更早的步骤仍计入每轮的等式,并会提示“前面还有 N 步”。
优化规则
本节是本地规则:它们在本地先跑一遍,结果作为「本地线索」随摘要交给模型参考;模型分析没开或失败时,它们直接作为建议显示。规则来自公开的 Agent 工程经验:Anthropic 关于 Agent、技能、工具设计和上下文工程的文章,Manus 的上下文工程总结,LangChain 的“写入 / 选取 / 压缩 / 隔离”框架,以及计划缓存方面的研究。它们有一个共同前提:
Agent 的耗时和 Token 大致等于“模型往返次数 × 每次携带的上下文”。 每条规则不是减少往返,就是缩小每次携带的上下文。
每条规则只在这次执行的日志里出现对应模式时才会触发。建议会写明位置(第几轮第几步、哪条命令、哪个文件)、依据、改法,以及按本任务数据估算的可省时间和 Token。组内按预计收益排序。
| 优先级 | 规则 | 日志里怎么认出来 | 改法 |
|---|---|---|---|
| P0 | 1 确定性步骤交给脚本 | 模型现写临时脚本(heredoc、-c、cat > x.py、多行 shell);模型逐字写出结构固定的大文件;同一段动作反复手做 |
存进技能的 scripts/,在 SKILL.md 里写明直接运行;固定文件由脚本或模板生成 |
| P0 | 2 互不依赖的调用合并成批 | 连续多步,每步只调用一个只读工具,中间没有回复文字 | 在 SOP 里一次列全要读的内容,或写成一个汇总脚本 |
| P0 | 3 中间数据不进上下文 | 单次结果超过 20K 字符;同一文件反复整读 | 在脚本里完成筛选和统计,只返回结论;给大文件做索引 |
| P1 | 2 轮询改成阻塞等待 | 反复 sleep 或查看后台输出 |
改用阻塞式等待,或在脚本里循环检查 |
| P1 | 4 工具输出在源头截断 | 测试、构建类命令输出过长 | --quiet、| tail、| grep FAIL,或重定向到文件 |
| P1 | 5 技能内容按需加载 | 技能说明加载过多;先读脚本源码再运行 | SKILL.md 控制在 500 行内,参考资料按需读,脚本直接运行 |
| P1 | 6 前置条件写进 SOP | 调用失败后再修正(查看类的非零退出码不算) | 把正确参数、权限、“先读再改”写进执行前检查 |
| P1 | 7 前缀稳定、缓存命中 | 某一步缓存命中率骤降,并给出原因(换模型、间隔超过 5 分钟、前缀被改写) | 不在前缀放会变的内容,中途不换模型 |
| P1 | 8 减少等你的往返 | 多次提问或审批 | 一次问完;固定命令加放行规则 |
| P2 | 9 按难度选模型 | 机械步骤(查看、搜索、整理)思考很长 | 换快模型或交给小模型子 Agent |
| P2 | 10 子 Agent 隔离探索 | 主会话里大量读取和搜索 | 探索交给子 Agent,只带回摘要 |
| P2 | 11 上下文过长要拆分 | 单步输入超过 10 万 Token | 分段执行,用文件传递中间结论 |
| P2 | 12 跨次复用计划 | 同一技能的临时脚本结构在以往执行中也出现过 | 固化成固定步骤 |
识别到技能执行时(通过 skill 调用,或文件路径落在技能目录下),技能名会写进摘要,模型的建议会落到这个技能的 SKILL.md 与 scripts/ 上。
普通的讨论或探索会话通常不会触发 P0 规则,报告会直接说明“没有可固化的流程”,不会凑数给建议。
命令
| 命令 | 作用 |
|---|---|
/runstat 或 /runstat status |
以文本输出当前状态 |
/runstat done |
确认当前任务完成,生成复盘 |
/runstat digest |
预览将要发给模型的本地摘要:分段字数、裁剪情况,并把全文写到磁盘(不花 Token) |
/runstat done <备注> |
同上,并把备注写进复盘和历史 |
任务完成的确认记录在一条可重放的 command/run 事件里,重新打开会话后,任务边界和复盘都能还原。
统计口径
- 时长等式:每轮、每步的“总时长”定义为模型、工具、审批等待三项之和,所以等式总是成立。真实的墙钟时间单独显示在表头。
- 模型时长:从步骤开始(或上一次返回)到模型返回,失败的尝试也计入。
- 工具时长:并行调用去重后的忙碌时间,不会重复计算。
- 审批等待:等待审批和等待你回答(
ask_user_question)的时间,不计入工具时长。 - 不重复计数:会话压缩会重放历史事件,插件只统计
surfaceOp为append的事件;模型返回和工具结果必须配对到进行中的请求才计入。 - 缺失就是未知:模型没有上报用量时记为未知,不按 0 计算。
- 输入 Token:显示为“未命中缓存的输入 + 缓存读取”,即模型实际读入的量;缓存部分单列。
- 预计可省是估算:按本任务的中位步骤耗时、平均输入和字符数(约 3.5 字符/Token)推算,依据写在每条建议后面。输入里缓存命中的部分按缓存价计费,实际费用低于 Token 数字看上去的规模。
- 子 Agent:面板只统计父会话看得到的调用;
/runstat done会读取子会话并单独列出。
配置项
在 profile 的插件配置中设置,全部可选。校验失败不会阻止启动,会回退到默认值并输出警告。
| 配置 | 默认值 | 说明 |
|---|---|---|
maxSteps |
200 |
过程日志保留的模型步骤数(1 至 1000),超出的最早步骤丢弃并计数 |
maxTimeline |
400 |
保留的调用记录条数(1 至 2000),供建议规则使用 |
history |
true |
是否在本地保存跨次脚本指纹(规则 12) |
trackSubagents |
true |
是否统计子 Agent |
includeModelAssist |
true |
点「生成优化建议」时把摘要发给当前模型分析。设为 false 则只用本地规则、不发送任何内容。分析自身的耗时与 Token 单列 |
reportLanguage |
'zh' |
报告框架语言,'zh' 或 'en';建议正文只有中文 |
slowModelMs / slowToolMs |
60000 / 30000 |
口径说明里“偏慢”的阈值 |
隐私与本地数据
- 状态和统计保存在 Harness 自己的投影缓存里。插件不新增会话事件类型。
- 点「生成优化建议」时会向当前模型发送一次本地组装的摘要(只在你点按钮或输入
/runstat done时发送)。摘要包含任务统计、本地线索、每轮用户要求的开头(80 字以内)、逐步日志(每步耗时与用量、命令与调用说明、结果摘要)和待办;不含模型的思考与回复正文、文件内容或完整工具输出。命令、待办和结果摘要仍可能含有密钥、个人信息或业务内容,插件不保证自动脱敏。处理敏感任务时请设includeModelAssist: false;可先运行/runstat digest逐字检查。 - 摘要中普通文件路径通常压成短名,平台错误文本里的绝对路径压成
…/文件名;命令与流程可能原样保留,其中的路径和参数可能暴露敏感信息。 - 想先看再决定:
/runstat digest报出分段字数与裁剪情况,并把摘要全文写到$DSH_HOME/runstat/last-digest.json,可以逐字核对。它不花 Token。 - 深度分析自身的耗时与 Token 在报告里单列,不计入被分析任务,也不会再次触发复盘。
- 分析结果存在
$DSH_HOME/runstat/analysis.json(保留最近 40 条,按会话 + 任务开始时间索引),面板重建后仍能看到。 - 调用记录只保存规则生成的一句话描述、结果摘要和参数的哈希,不保存参数原文(例如
write的文件内容)。 - 规则 12 需要跨次比较,会在
$DSH_HOME/runstat/fingerprints.json(默认~/.dsh/runstat/)里按技能保存最近 20 次执行的脚本结构哈希和日期,不保存脚本正文和路径。设置history: false可以关闭。
已知限制
- 网络慢还是模型慢无法彻底拆开。 “等首包”包含网络、排队和模型处理;能明确说明原因的只有重试事件的失败代码(
RATE_LIMIT、TIMEOUT等)。 - 实时分片只在打开会话的页面上可见。 页面中途打开时,当前这次请求可能没有起点,计时退回到会话事件的时间。
- 预计剩余时间是估算,只基于本任务已观测的工具耗时。真实日志回测中误差中位数约 0.7 秒,但长时间批次基本估不准,所以不显示完成百分比。
- 工具结果体积按字符数计。 平台不提供工具结果的 Token 数。
- 建议正文只有中文。
- 模型分析的质量取决于模型,且只看得见摘要。 模型拿到的是本地组装的逐步日志(上限 40,000 字),摘要里没有的东西它无从判断;它给出的
saving只是估算,依据会一起显示出来。本地规则条目始终保留在「本地规则线索」里。 - 摘要裁剪是有损的。 长任务超过上限时,先把每条调用说明缩短到 40 字,仍超出就保留首尾步骤、省略中段,并写明省略了多少步、合计多少模型时间;
/runstat digest会报出裁剪情况。
项目结构
dsh-runstat/
├── index.js # 宿主端:注册投影 runstat 与命令 /runstat
├── client.js # 浏览器端:实时分片、胶囊与详情面板
├── lib/
│ ├── fold.js # 纯函数:会话事件 → 状态、任务统计、按轮/步的日志
│ ├── describe.js # 纯函数:调用与结果的规则描述、脚本结构指纹
│ ├── rules.js # 纯函数:12 条优化规则、P0/P1/P2 分组
│ ├── report.js # 纯函数:统计 → 复盘报告
│ ├── advice.js # 技能识别与流程草稿
│ ├── history.js # 跨次脚本指纹(只存哈希)
│ ├── digest.js # 发给模型的摘要:逐步日志与本地线索
│ ├── analysis.js # 可选的模型分析及本地结果存储
│ └── schema.js # 无依赖的配置校验
├── cordis.patch.yml # 把插件挂进 profile
├── locale/ # 插槽标题与描述
├── package.json # 插件元数据与客户端注入配置
└── README.md # 安装、使用及隐私说明
设计原则:
- 事实来自会话事件和实时分片,不新增自定义事件类型,避免旧版本无法重新打开会话。
- 折叠和规则都是纯函数,全部逻辑可以脱离 Harness 离线测试。
- 零运行时依赖,浏览器端只使用平台内置的
react和界面基础组件。
No comments yet. Be the first to write one.