前言¶
DeepSeek Harness(DSH)的运行时上下文里有一行来自 @deepseek-ai/dsh-time-context 的耗时信息:
Elapsed since the preceding model-visible message: 6m 42s
模型只能看到「上一条可见消息」和「现在」两个时间点。审批是唯一会让这个数字突然变大的日常路径——你去开会、去倒水,回来才点「允许一次」。
于是模型很容易把「时间很长」和「出问题」划等号:要么怀疑命令卡住、要么觉得前面改法不对、要么觉得环境不稳定。这些推理岔路都建立在「时间 ≠ 结果」这个并不存在的因果上。本插件把那段空档的归因补上:等待超过阈值时,在工具结果之后追加一条明确的提示,说明「这段是审批等待,不是工具失败或代码问题」。
它是什么¶
dsh-approval-latency 是 DSH 的一个工作流插件,由 UPxianyu 维护。它把「这次工具调用在等人类点审批」这件事回传给模型,避免模型把人的响应延迟误判为代码或环境问题。插件纯 host 侧运行,不访问网络、不读写文件,也不改变审批结果本身。
核心功能¶
插件在需要审批的工具调用之后,追加一条 notice 形式的用户消息,内容格式统一为「Approval wait: …」:
- 通过:说明等待时长、这是人的延迟、不要因此重开前面的工作。
- 被拒绝:说明等待时长、迟到的「否」可能是过期/误触,应先与用户核对再改。
- 取消 / 无人应答:说明等待时长、空档不代表调用或代码有问题。
消息长度有硬约束(约 41 token),且只包含三个要素:等了多久 → 这是人的延迟而不是失败 → 只判这次结果。这样模型不会因为解释性从句而跑偏。
安装与启用¶
在 DSH 中(桌面版默认 profile 为 desktop),使用以下命令安装:
dsh plugin --profile desktop add github:UPxianyu/dsh-approval-latency
安装后重启 dsh web 或桌面版即可生效。插件会随 profile 的 cordis.patch.yml 插入 approval-latency 这一行。
如需卸载:
dsh plugin --profile desktop remove dsh-approval-latency
配置方式¶
插件管理在主界面左侧的「全局面板图标」(风车图标)→「插件」→「已安装」→ dsh-approval-latency 卡片。点击带 › 的标题行进入配置页。
配置页提供两个主要控件:
- 自适应 开关:开启(默认)时,门槛跟随本机审批响应速度变化;关闭时使用固定时长。
- 固定时长 输入框:秒数,默认 30。回车或失焦才写入,0 或非数字会被拦截。
配置写入后由 Host 落到 profile 的 Cordis patch,不需要重启,从下一次审批开始生效。
阈值与行为¶
「太长」不是常量,而是基于本机速度计算的门槛。
- 通过门槛:等待 ≥ 通过门槛且最终通过时,追加提示。
- 拒绝门槛:默认为通过门槛的一半,等待 ≥ 该门槛且最终被拒绝时,追加提示。
- 取消 / 无人应答:等待 ≥ 通过门槛且最终取消或无人应答时,追加提示。
- 低于对应门槛、或该调用没有经过审批时,不追加任何内容。
可通过 reportDenials: false 开关只回传通过的等待,忽略拒绝 / 取消 / 无人应答。
阈值怎么配¶
配置以 YAML 形式写在 profile 的 cordis.patch.yml 中,使用同 id 覆盖会整块替换 config,因此只写需要修改的字段即可。
| 写法 | 生效 |
|---|---|
| 不写任何字段 | mode: auto(自适应) |
mode: auto |
自适应,使用本机速度;fixedMs 不参与 |
mode: fixed |
固定 fixedMs,默认 30000(30 秒) |
只写 fixedMs: 45000 |
自动按 mode: fixed 处理 |
只写 thresholdMs: 45000(旧写法) |
同上,视为 fixedMs 的别名 |
固定时长模式¶
- id: approval-latency
name: dsh-approval-latency
config:
mode: fixed # 不写 fixedMs 就用默认 30000 = 30 秒
- id: approval-latency
name: dsh-approval-latency
config:
mode: fixed
fixedMs: 45000 # 45 秒
默认 30 秒:低于 30 秒基本是正常点击速度,提醒只会变成噪音;到 30 秒以上,模型更容易把「时间很长」与「出问题」联系起来,这时一条明确的「这是审批延迟」最有价值。
自适应模式(默认)¶
通过门槛 = clamp( multiplier × median(最近 20 次真实回答的耗时), floorMs, ceilingMs )
- 样本只收「真的回答了」的审批(
allowed-once与rejected),取消 / 无人应答不计入。 - 每条样本先夹到
ceilingMs(默认 5 分钟)。 - 用中位数而不是均值,偶发的长等待不会移动基线。
- 样本不足
minSamples(默认 3)时使用 30 秒冷启动值。 - 正在被判断的这次等待不进样本,避免自举。
拒绝门槛 = clamp( 通过门槛 × rejectionScale, min(floorMs, 通过门槛), 通过门槛 )
默认 rejectionScale: 0.5,即拒绝门槛为通过门槛的一半;设为 1 即与通过同门槛。
全部字段¶
- id: approval-latency
name: dsh-approval-latency
config:
mode: auto # auto = 自适应;fixed = 固定 fixedMs
fixedMs: 30000 # 固定模式的门槛(毫秒);不写 mode 时填了它即按 fixed
floorMs: 10000 # 自适应门槛下限
ceilingMs: 300000 # 自适应门槛上限,同时截断单条样本
multiplier: 3 # 几倍本机中位数算「异常长」
minSamples: 3 # 攒够几条真实回答才从冷启动切到学习值
rejectionScale: 0.5 # 拒绝门槛 = 通过门槛 × 该系数
reportDenials: true # 是否也回传拒绝 / 取消 / 无人应答
适用场景¶
适合开启的情形:
- 离开电脑,审批挂了很久(实测最长 9 分 8 秒)。
- 长跑 / 无人值守的 Agent,审批弹出来半天才看见。
- 耗时的那次结果又不理想,没有时间归因时模型容易把「久」和「错」连起来。
- 拒绝几乎总是发生在回来之后,模型容易理解成「方案被否了」,而实际可能是过期提示。
不需要的情形:
- 总是秒批(本机中位数约 4.6 秒),默认档几乎不会触发。
- 没有审批的操作(读文件、写工作区内文件)。
- 想解释「非审批」造成的耗时(如打断后处理别的事、机器休眠、模型排队、网络慢)。
- 使用
never策略(审批被确定性拒绝),没有等待,也就没有通知。
生态背景¶
DSH 理念是「一切皆插件」,本插件是其生态中的一员。社区目录 https://www.skillhub.cn/plugins/UPxianyu/dsh-approval-latency 提供了插件索引,与 DeepSeek / 幻方无官方从属关系。
短结尾¶
dsh-approval-latency 通过在审批等待后追加明确的时间归因,帮助模型区分人的响应延迟与代码或环境问题,减少不必要的重算与怀疑。如果你在 DSH 中经常遇到审批等待导致模型误判的问题,这个插件是一个低成本、低侵入的解决方案。
- 插件目录页:https://www.skillhub.cn/plugins/UPxianyu/dsh-approval-latency
- GitHub 仓库:https://github.com/UPxianyu/dsh-approval-latency