前言¶
跑长工具链的 agent 有个常见现象:模型连续调用工具,几十分钟里界面上只有工具卡片在滚,直到最后才吐一段结果。新人不知道模型在干什么,只能等。dsh-progress-beat 就是解决这个问题的 DSH 插件:它在「思考 + 工具调用」的中途插入用户可见的进度说明,让 agent 边做边说,而不是一路静默到结束。插件由 Mabinogi-Cichol 维护,分类为「工作流」。
这是什么¶
一句话定位:一个 DSH 插件,把进度播报塞回 agent 执行过程。它不改会话内容、不吞工具结果、不阻塞调用,注入的提醒走 source.form = 'notice',模型可见、带归属、可审计。
它针对的是较新的 flash 类模型(如 1017 版本)在 agent 任务里「连续调用工具、只在最终答复时输出文本」的行为倾向。插件不试图改写模型,只通过常驻规则加周期提醒提高它开口的概率。
三条互补的机制¶
插件提供三条机制,默认开启「常驻进度规则 + 沉默提醒」,用户轮提醒默认关闭。
1、常驻进度规则,挂在 ctx.systemPrompt.section(),每次请求都带一段规则,要求模型预计多次调用时先讲计划,进入新阶段或长时间没说明时先播报。节奏由 promptEvery(文案里「每约 N 次」的 N,默认 6)和 sectionOrder(插入位置,默认 4)控制。
2、用户轮提醒,挂在 agent/pre-step,按轮次在该轮 messages 注入一条提醒。开关字段 nudgeOnUserTurn,默认关;打开后按 nudgeEveryTurns(默认 1,可取 1–20)的节奏注入,同一轮的后续 step 不重复。
3、沉默提醒,同样挂在 agent/pre-step,但它是按沉默算、不按调用总数算:自上次播报以来累计 N 次调用、或沉默超过 T 秒,先到先算。节奏字段是 every(默认 8)、silentSeconds(默认 180 秒),另有 minGapSeconds / maxRemindersPerTurn / dripSeconds 控制间隔与预算。资料提到一次 200 次调用的实测里,这路只注入 6 条。
三路都关掉时,插件只贡献一个 system prompt section,连 agent/pre-step 钩子都不注册。
控制面板与配置¶
插件列表里 dsh-progress-beat 这一行多出「配置」入口,打开是可视化表单,不必手改 YAML。面板按三个机制分成三个可折叠分组,折叠态只留机制名与开关,展开才露出细项。面板是「暂存 + 保存」模型:改动先留在表单里,点保存才写入;每个字段可单独重置,也可以全部重置,被改过的字段旁会显示「已覆盖」。
保存走宿主的 settings 服务,写进 profile 的 cordis.patch.yml,由 Loader 热应用,重启后仍然有效。插件侧的 Config schema(每个字段声明了 .volatile())是这套表单的依据,宿主把它投影成表单,面板只负责渲染与暂存,不自建存储。面板注册在插件管理页的 plugins.row.config 插槽,键为 dsh-progress-beat#dsh-progress-beat。
也可以直接在 profile patch 里写配置,等价于面板保存的结果:
- insert:
- id: dsh-progress-beat
name: 'dsh-progress-beat'
inject: [systemPrompt]
config:
# ① 常驻进度规则(system prompt section)
injectPrompt: true # 是否注册常驻规则
promptEvery: 6 # 规则文本里「每累计约 N 次」的 N(2–50,仅影响过程播报)
sectionOrder: 4 # section 排序号(0–99,默认 4,工具声明在 100 起)
# ② 用户轮提醒(agent/pre-step)
nudgeOnUserTurn: false # 是否随用户输入注入(默认关)
nudgeEveryTurns: 1 # 每几轮提醒一次:1 每轮,3 每三轮(1–20)
# ③ 沉默提醒(agent/pre-step,按沉默而非调用总数)
nudgeOnToolCalls: true # 是否开启(默认开)
every: 8 # 沉默调用阈值:自上次播报以来累计多少次调用(2–100)
silentSeconds: 180 # 沉默时间阈值(秒),与调用次数先到先算
maxRemindersPerTurn: 6 # 每轮预算;0 表示关掉这一路
minGapSeconds: 60 # 两条提醒之间的最小间隔(秒)
dripSeconds: 300 # 预算用尽后的慢速提醒间隔(秒),不会彻底静音
# promptText / userTurnText / nudgeText 可整段替换,支持 {{every}} / {{count}} / {{seconds}} / {{remind}} 占位
安装与启用¶
profile 名按入口选:桌面版 GUI 启动的是 desktop profile,dsh web / 浏览器版用的是 web profile。从 GitHub 直接装:
dsh plugin --profile desktop add github:Mabinogi-Cichol/dsh-progress-beat
也可以本地克隆后装:
git clone git@github.com:Mabinogi-Cichol/dsh-progress-beat.git
dsh plugin --profile desktop add <克隆目录的绝对路径>
装完确认 profile 的 package.json 里 dsh.profile.bundles 含 dsh-progress-beat。运行中的 loader 会热加载新增条目;若「插件列表」没刷新,切走再切回该标签页(它只在挂载时拉一次快照),或刷新页面让浏览器半侧重新入图。装错 profile 时插件在界面上完全不可见,因为「插件列表」是 cordis loader 条目的只读投影。
依赖解析:Host 半侧 import @deepseek-ai/schemastery。以 link: 方式安装时,Node 从仓库目录向上解析,因此本机需要一个指向 DSH 安装的 node_modules:
$target = "<DSH>\resources\app\dsh\node_modules\@deepseek-ai"
New-Item -ItemType Junction -Path .\node_modules\@deepseek-ai -Target $target
node_modules/ 已在 .gitignore 内。缺少这一步时插件加载失败、进度播报整体不生效,而不仅是面板。
卸载:
dsh plugin --profile desktop remove dsh-progress-beat
# 并从 profile package.json 的 dsh.profile.bundles 中删掉同名条目
自测¶
仓库自带两个冒烟脚本:
node test\smoke.mjs # Host:注入节奏、配额、block 透传、轮次清零
node test\panel-smoke.mjs # Client:注册键、注入面、summary/page 两视图
smoke.mjs 覆盖 section 注册与占位符替换、注入节奏、单轮配额、block 分支透传、无 agent 直连调用不计数、新用户提示词清零、关闭 prompt 注入。panel-smoke.mjs 用 mock 的 ModuleLoader 与 React 执行浏览器半侧,覆盖 factory 能被 load() 接收、apply 不抛错、面板注册到 plugins.row.config、注入面含表单控制器、字段与保存控件都被渲染。
适用场景与注意¶
适合在长工具链任务里给用户可见反馈的 DSH 使用者,或者说给那些界面上只有工具卡片在滚、没人知道进度的 agent 场景。想节奏更密就把 every 调到 2–3;觉得吵就调到 6–8,或把 injectPrompt 关掉只留兜底提醒。
要注意的是:进度是否「说得好」本质仍是模型行为,插件只能通过常驻规则加周期提醒提高概率,不能 100% 程序化锁死。插件以当前 dsh 进程权限运行,装前应检查源码与许可证(MIT);许可证、版本号(0.3.1)、字段默认值都以仓库 README 和 package.json 为准。
结尾¶
dsh-progress-beat 的价值在于把「静默执行」改成「边做边说」,且默认不过度打扰:常驻规则 + 沉默提醒即可工作,需要更密或更安静时再调参。目录页:https://www.skillhub.cn/plugins/Mabinogi-Cichol/dsh-progress-beat ;仓库:https://github.com/Mabinogi-Cichol/dsh-progress-beat 。社区目录是独立站点,与 DeepSeek / 幻方无官方从属关系。