前言¶
在 DeepSeek Harness(DSH)里跑智能体时,一旦工具调用触发权限审批,原生流程往往会让整轮对话停在那里,直到你在界面上点允许或拒绝。你稍走开几分钟,模型就只能干等,同一回合里本来还能做的其它步骤也推进不了。ask_user_question 若一直等用户回答,同样会占住回合。
社区插件 dsh-deferred-approvals(维护者 Hao0311,分类 admin-security)把这两类交互改成「可稍后处理」:审批先挂成待办、工具立刻拿到「未执行」结果,模型继续干活;用户对问题的回答则走 DSH 内置的 timed 模式,超时后模型先继续,卡片仍保留供你补答。下面介绍它的定位、权限边界、安装配置与使用上需要注意的限制。
这是什么¶
dsh-deferred-approvals 是一个 DSH 插件 bundle,当前包版本 0.3.1(MIT 许可证),要求 DSH ≥0.2.1-0。它做两件事:
- 非阻塞审批:宿主本来就要弹审批的工具调用,由插件拦截并记为待办(编号如
#A1),同一 assistant 回合可继续做其它工作;你在输入框附近的「待处理审批」卡片里再允许或拒绝。 - 定时提问:把 standard 预设里的
ask_user_question配成 timed 模式(能力来自@deepseek-ai/dsh-tool-ask-user),提问后默认最多等一段时间,超时返回{pending:true, callId},模型不阻塞。
目录页:SkillHub 插件页。源码与说明:GitHub — Hao0311/dsh-deferred-approvals。
权限边界(使用前先弄清)¶
审批权限属于宿主(sandbox / approval 层),不是对话里的「口头批准」。
- 模型在
workspace-write沙箱下只能发起sandbox_permissions升级请求;是否要审批完全由原生策略/沙箱决定。会话策略为never或原生不需要审批时,插件默认不介入(forceAskPolicy默认为false,不会擅自改会话策略)。 - 插件在
approval/request最外层拦截请求,给工具返回「未执行」,并登记待办;唯一授权来源是你在 UI 上点击(允许一次 / 本对话允许同类)。宿主记录「工具 + 参数指纹」的一次性授权,默认 5 分钟过期、用掉即销。 - 批准后模型收到的是宿主事件通知(在 Chat 里多为上下文行,不是用户气泡),用于提示可以重试;对话内容不能授予权限。重试时
command等实际参数必须与指纹一致,justification/description/timeoutMs不参与指纹。
弄清这一点,可以避免误以为「模型说已批准」就等于已授权。
核心功能:非阻塞审批¶
和原生行为的对比¶
- 以前:审批一出现,整个 turn 停住,必须等你点击。
- 现在:审批变成后台待办;模型可跑其它子任务或换不需要提权的路径;你回来再在卡片里处理。允许一次后,重试时宿主按一次性授权放行,不再弹框。「本对话允许同类」会为会话记规则,之后同类请求直接放行,并已排队的同类待办可一并批准。
会话列表里对应对话旁会出现与原生审批类似的橙色小点,提示有待处理项。
工作方式概要¶
- 拦截:在审批瀑布最外层拿到请求,台账记下工具名、参数指纹、权限级别与理由,立刻对本次调用返回 rejected(工具层显示未执行)。
- 改写结果:经
tools/post-execute把文案改成「已挂起为待办 #A1,不要等待也不要反复重试」等说明;若已用其它方式完成,可调用pending(action="cancel")撤销。 - 模型继续:同一回合内继续后续步骤。
- 用户决定:允许一次、本对话允许同类、拒绝或忽略;拒绝可带备注引导模型换方式。
- 送达:用户决定后通过宿主事件(
source.kind = 'deferred-approval')通知模型。模型空闲时用agent.followup;若正在长考且本会话没有工具在执行,默认会中断当前思考再投递(interruptOnDecision默认为true);有工具在执行则退回到agent.steer,避免杀掉运行中的命令。 - 台账与幂等:批准/拒绝/忽略/过期/撤销都会记入「最近决定」;
pending的list/cancel可给出确定答复。同一按钮重复点击幂等;decide带sessionId时会校验待办归属。 - 过期:待办默认 15 分钟过期,静默作废、不唤醒模型。
插件还提供 pending 工具,用于查询待办、最近决定和已放行规则;HTTP 路由在 /api/deferred-approvals/*(Host 侧)。
核心功能:定时提问(合并自原 dsh-timed-questions)¶
同一 bundle 通过 cordis.patch.yml 覆盖 standard 预设,把 ask_user_question 设为 timed 模式:
- 提问后最多等
timeout秒(默认 20);超时返回{pending:true, callId},模型继续工作。 - 问题卡片保留,可随时回答;回答作为用户消息送回(模型在跑则下一步收到,空闲则开新一轮)。
- 单次调用可用
timeout覆盖;-1 表示这次必须等到回答。
生效范围是新会话;已存在会话沿用启动时的预设组合,需新开对话才能用到 timed 配置。
DSH 升级后官方 standard 预设可能与本地 patch 副本漂移;插件启动时会对比并尝试重新生成(保留 mode: timed 与 timeout),并提示需重启后新会话才生效。也可手动执行:
node check-preset-drift.mjs --regenerate
安装与启用¶
面向 Web profile 的官方安装命令如下(与 README 一致,注意仓库名为 Hao0311):
dsh plugin --profile web add github:Hao0311/dsh-deferred-approvals
开发时可在工作区 plugins/dsh-deferred-approvals 目录,通过 plugin_manager 的 install_bundle 以该绝对路径为 target 安装。安装后 Client 半通常会自定加载;Host 半源码修改需重启 DSH 才生效(已 import 的模块默认不热替换,除非开启 HMR 源码监听)。
依赖方面,插件仅使用 node:crypto 与 ctx 服务(tools / approval / agents / systemPrompt,以及可选的 connection、typertGateway);Client 侧使用 slots / locale / uiSession。
卸载时用 plugin_manager 的 remove_bundle(target 为 dsh-deferred-approvals),审批与定时提问会恢复原生行为。
配置¶
配置写在 profile patch 里该插件 id 下的 config 字段,全部可选;仓库未导出 Config schema,加载期不做校验。
| 键 | 默认 | 含义 |
|---|---|---|
ttlMinutes |
15 |
待办有效期(分钟) |
grantMinutes |
5 |
「允许一次」的一次性授权有效分钟数 |
softCapAway |
20 |
无在线客户端时的待办上限 |
forceAskPolicy |
false |
是否把显式 never 的根会话策略切回 ask |
requireLiveClient |
true |
无在线 Web 客户端时交回原生审批,不做挂起 |
excludeTools |
[] |
不接管列出的工具的审批 |
interruptOnDecision |
true |
用户决定时,纯长考场景是否中断思考并立即送达 |
sweepMs |
20000 |
过期清理间隔 |
示例片段:
- id: deferred-approvals
config:
ttlMinutes: 15
softCapAway: 20
典型用法(流程侧)¶
没有单独的「一键 Demo」脚本;实际使用跟随 DSH 里会触发审批的工具调用即可。可按下面 mental model 自测:
- 在 ask 策略且 Web 客户端在线 的会话中,让模型发起需要审批的命令(例如沙箱外写盘、需要
sandbox_permissions的调用)。 - 观察工具结果是否为「已挂起为待办 #Ax」,且模型是否在同一回合继续其它步骤。
- 在输入框附近的待处理卡片选择「允许一次」或「本对话允许同类」,确认模型收到通知后重试且宿主放行。
- 若模型已用其它方式完成同一目标,应依提示调用
pending(action="cancel"),避免重复执行。
定时提问侧:新开会话后让模型调用 ask_user_question,等待超过默认 timeout,确认模型继续执行且卡片仍可作答。
仓库内回归测试(零依赖,Node ≥18):
node test/run.mjs
退出码 0 表示当前文档记载的 38 项断言全部通过。
适用场景与注意¶
适合谁:长时间 unattended 跑任务、又偶尔需要点审批的 DSH 用户;希望审批与追问不要占满整轮 turn 的智能体开发者。
务必注意:
- 插件在当前 DSH 进程权限下运行;安装前请自行查看源码与 MIT 许可证,确认符合你的安全策略。
- 待办只在 Host 内存里,DSH 重启后丢失;原生审计对挂起记 rejected,批准细节 v1 未落盘。
- 需要
ask策略 + 在线 Web 客户端(requireLiveClient默认 true);never时审批在插件之前就结束,插件收不到请求。 - 批准后不会自动执行工具,由模型核对后重试,以保证调用仍出现在会话日志与 UI。
- 参数一改指纹即变,会重新挂起,这是权限边界设计,不是误杀。
- 社区目录 SkillHub 与 DeepSeek / 幻方无官方从属关系;DSH 生态是「一切皆插件」,本介绍事实均来自上述 GitHub README 与 package 元数据。
结尾¶
dsh-deferred-approvals 把审批变成可稍后处理的待办,并把 ask_user_question 接到 timed 模式,减少「人等机器、机器等人」的空转。若你经常在 DSH Web 里跑需要点头的工具链,可在 profile 里安装后,结合 ask 策略与在线客户端条件试一轮。
- 目录页:https://www.skillhub.cn/plugins/Hao0311/dsh-deferred-approvals
- 源码:https://github.com/Hao0311/dsh-deferred-approvals