前言¶
在 DeepSeek Harness(DSH)里,你可以在 agent 执行过程中追加消息(steering,插言),让模型在当轮或下一轮尽快读到新指令。默认的 agent loop 只在步骤边界从 next-step 收件箱领取消息:模型发起工具调用后,若工具要等待几十秒,你中途插一句「停一下」或「改方向」,这条消息往往要等到工具自己返回、进入下一步才会被读到。对依赖子代理结算、长时 jobs.wait 的工作流来说,这就是「界面已显示、agent 却还在傻等」的空档。
@ExboCooope/dsh-steering-interrupt 是社区维护者 ExboCooope 发布的工作流类插件(SkillHub 分类:工作流)。它在工具执行层注入协作式取消:当符合条件的插言写入会话时,中止已在途且超过宽限时间的工具等待,让 loop 尽快结束当前步骤并领取插言。下面介绍它的定位、机制、配置与安装方式。
这是什么¶
- 包名:
@ExboCooope/dsh-steering-interrupt(npm 风格名,与 profile 依赖、cordis.patch.yml条目需一致) - 版本(package.json):0.1.0,MIT 许可证
- 一句话:Let a mid-turn steering message interrupt in-flight tool waits in DeepSeek Harness.
- 维护与来源:需求、验证与发布由 ExboCooope 负责;实现标注为 DeepSeek-V4.1-Flash 1017(AI agent),2026 年 10 月。目录页:SkillHub 插件页;源码:GitHub。
插件不改动「插言排队到下一轮」(next-turn / followup)的语义,只补上「工具还在等、插言已经进来」这段时间的响应。
默认行为与痛点¶
DSH agent loop 在步骤 N 的典型顺序是:模型请求 → 工具调用(可能长时间阻塞)→ 步骤 N+1 才处理 next-step 里的新消息。因此:
步骤 N: [模型请求] -> [工具调用……等待 40 秒……] -> 步骤 N+1 才领取插言
没有本插件时,子代理结束通知、用户运行中直接说的话等,都要等当前工具 promise 结束才会被模型看到。
核心机制¶
插件通过 Cordis 补丁挂接现有能力,主要四步:
- 包装
tools/execute:把每次派发的exec.signal换成融合信号AbortSignal.any([上游, 本插件的控制器]),在finally里还原,避免污染后续调用。 - 监听
session/event的agent/inbox/spliced:当target === 'next-step',且插入消息的来源属于配置的「插言」类型时,对该会话中已在途超过minElapsedMs的调用触发控制器中止。 - 工具侧协作退出:工具若尊重
exec.signal(例如随包的jobs.wait),会提前返回,当前步骤结束,loop 在下一边界领取插言,模型即可读到新内容。 - 明确错误语义:被中止且以错误收尾的调用,结果会被替换成
TOOL_INTERRUPTED_BY_STEERING,表示本次调用未跑完、结果未知。
取消是协作式的:只通过 exec.signal 通知,不 race、不丢弃工具 promise。忽略信号的工具仍会让调用方继续等待——行为与 dsh-tool-call-timeout-policy 一致。
一次插言会打断该会话中所有在途且超过 minElapsedMs 的调用,不限于耗时最长的那一个。
配置¶
在 profile 的插件配置中增加条目(字段以 README 为准):
- id: steering-interrupt
name: '@ExboCooope/dsh-steering-interrupt'
config:
minElapsedMs: 250 # 太年轻的调用(比如刚起的 write)不动它
sourceKinds: # 哪些来源算「插言」
- user # 人类在运行中直接发的话
- subagent-settled # 后台子代理结束后的结算通知
- agent-message # 子代理/相邻 agent 发来的消息
exclude: [] # 永不打断的工具名
说明要点:
sourceKinds取值来自 DSH 的MessageSource.kind。followup(排队到下一轮)落在next-turn,不会触发打断——那是用户选择的「本轮结束后再处理」。- 默认
exclude为空,长命令也可被打断;若不想让构建/写入类命令被插言打断,可写入例如['pwsh', 'bash', 'terminal', 'write', 'edit']。
安装与启用¶
README 给出的安装方式是从本地检出写入 desktop profile(可指向 clones 目录),不是凭仓库名拼接 dsh plugin add github:...。
推荐用仓库内的安装脚本:
node install.mjs desktop # 写入 ~/.dsh/profiles/desktop
node install.mjs desktop --remove
脚本会在 profile 的 node_modules/@ExboCooope 建立到本目录的 junction,并把包加入 dsh.profile.bundles。profile 的 manifest 与 patch 由 dsh-hmr 监听,一般无需重启 DSH 即可生效;link: 目标下的插件源码也在监听范围内。
也可手动在 profile 的 package.json 里添加 link: 依赖,并在 dsh.profile.bundles 中列出包名:
{
"dependencies": {
"@ExboCooope/dsh-steering-interrupt": "link:path/to/dsh-steering-interrupt"
},
"dsh": {
"profile": {
"bundles": ["@ExboCooope/dsh-steering-interrupt"]
}
}
}
包名、cordis.patch.yml 的 name、profile 依赖名与目录链接三处必须一致,否则 loader 解析不到。install.mjs 会读取 package.json 的 name,并清理同一插件旧名字(如从 @local/... 迁移)留下的条目。
安装前请自行阅读仓库源码与 MIT 许可证;插件在当前 DSH 进程权限下运行,与任何 DSH 插件一样,只安装你信任的来源。
验证与可复现现象¶
仓库提供 node test.mjs,在假宿主上跑 16 项断言,覆盖:打断生效、非插言来源不触发、next-turn 不触发、忽略信号的工具不被 race、上游 signal 还原、宽限期、跨会话隔离等。
README 记载的 desktop profile 实测时间线(插件在线):
t=0.0s 启动 120 秒后台任务
t=0.0s 启动 5 秒子代理
t=0.2s 调用 job_output(wait, timeout 60s)
t=5.2s 子代理发回消息 -> 等待被打断,返回 TOOL_INTERRUPTED_BY_STEERING
同一调用在没有插件时会等满 60 秒。你可按 README 在本地 profile 复现类似会话。
适用场景与限制¶
适合:多子代理、长时 jobs.wait / job_output、运行中频繁改指令的桌面或自定义 profile 工作流;希望 subagent-settled、user、agent-message 类插言尽快进入模型上下文,而不是卡在工具阻塞上。
务必知晓的限制(README 原文归纳):
- 协作式,不是硬终止:只通知
exec.signal;忽略信号的工具照旧等完。 - 只作用于工具调用:LLM 流式响应不会被插言打断;轮次级取消需
agent.cancel()。 next-turn不打断:排队消息按设计等本轮结束。
生态上,DSH 强调「一切皆插件」;SkillHub 等社区目录是独立站点,与 DeepSeek / 幻方无官方从属关系。本插件星标以 GitHub 页面为准(抓取时为 0),选用时以你本机 DSH 版本与 profile 兼容性为准。
结尾¶
@ExboCooope/dsh-steering-interrupt 用最小的执行层补丁,把「插言已到达、工具还在等」的空档补上:插言触发协作式取消,模型通过 TOOL_INTERRUPTED_BY_STEERING 知道上次工具未完整执行,从而更快响应你的新指令。需要细节与更新时,请直接查看 GitHub 仓库 README 与 SkillHub 目录页。