dsh-approval-latency:把「审批等待」回传给模型

前言

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    # 是否也回传拒绝 / 取消 / 无人应答

适用场景

适合开启的情形:

  1. 离开电脑,审批挂了很久(实测最长 9 分 8 秒)。
  2. 长跑 / 无人值守的 Agent,审批弹出来半天才看见。
  3. 耗时的那次结果又不理想,没有时间归因时模型容易把「久」和「错」连起来。
  4. 拒绝几乎总是发生在回来之后,模型容易理解成「方案被否了」,而实际可能是过期提示。

不需要的情形:

  1. 总是秒批(本机中位数约 4.6 秒),默认档几乎不会触发。
  2. 没有审批的操作(读文件、写工作区内文件)。
  3. 想解释「非审批」造成的耗时(如打断后处理别的事、机器休眠、模型排队、网络慢)。
  4. 使用 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
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye