🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

先问后干 yinghan-123/dsh-ask-first

DeepSeek 客户端
yinghan-1236 天前有提交已提供中文文档扫描:未发现敏感能力兼容 / 相关生态

让智能体动手前先向你确认,避免擅自替你决定

29.4/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/11/2 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

相关生态插件(非 dsh 原生,按其对应运行时安装)
git clone https://github.com/yinghan-123/dsh-ask-first.git

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:仅索引
是什么
生态应用
桌面端 / Web 外壳,不以 dsh plugin add 安装
装得上吗
本站尚未做安装检查
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 6 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🟢 扫描:未发现敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描未发现敏感能力:最多只发网络请求、读取自身元数据或只读文件,未发现执行命令、文件写入或敏感信息读取。

扫描于 2026/11/3(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

依赖的 DSH / Cordis 模块
@deepseek-ai/schemastery
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

DSH 插件:让 Agent 在替用户做决定前先提问(先问后干)。三层机制:常驻提问纪律、连续变更未提问提醒、不可逆操作硬闸;自带设置页。

README

由 DeepSeek 最新模型翻译生成
dsh-ask-first(先问后干) GitHub:https://github.com/yinghan-123/dsh-ask-first · 一行安装:pnpm add github.com/yinghan-123/dsh-ask-first 让 DeepSeek Harness 的智能体在替用户做决定之前先问一句,而不是自己挑个默认值把事做完。 起因 DSH 内核本来就带「随时向用户提问」的能力,而且默认启用: | 组件 | 作用 | | @deepseek-ai/dsh-user-questions | 提问服务 ctx.userQuestions(校验 + 等待用户作答) | | @deepseek-ai/dsh-tool-ask-user | 把服务暴露成模型工具 ask_user_question(standard preset 里 id: tool-ask-user) | | @deepseek-ai/dsh-client-ui-user-questions | 在 Web GUI 里渲染提问卡片(选项 / 多选 / 自由作答) | 问题不在能力,在行为:模型倾向于「自己拍板」——需求有歧义时不问、方案有取舍时不问、要动不可逆的东西时也不问,做完才解释。工具存在 ≠ 模型会主动用。 本插件补的就是这一层,分三层,强度递增。
展开完整文档(README 剩余 1 节)
dsh-ask-first(先问后干)

GitHub:https://github.com/yinghan-123/dsh-ask-first · 一行安装:pnpm add github.com/yinghan-123/dsh-ask-first

让 DeepSeek Harness 的智能体在替用户做决定之前先问一句,而不是自己挑个默认值把事做完。

起因

DSH 内核本来就带「随时向用户提问」的能力,而且默认启用:

| 组件 | 作用 |
| @deepseek-ai/dsh-user-questions | 提问服务 ctx.userQuestions(校验 + 等待用户作答) |
| @deepseek-ai/dsh-tool-ask-user | 把服务暴露成模型工具 ask_user_question(standard preset 里 id: tool-ask-user) |
| @deepseek-ai/dsh-client-ui-user-questions | 在 Web GUI 里渲染提问卡片(选项 / 多选 / 自由作答) |

问题不在能力,在行为:模型倾向于「自己拍板」——需求有歧义时不问、方案有取舍时不问、要动不可逆的东西时也不问,做完才解释。工具存在 ≠ 模型会主动用。

本插件补的就是这一层,分三层,强度递增。

一、提示词层(每次请求都带)

向系统提示注入两部分,互相配合:

1. 纪律段(app:ask-first,system prompt section):把「什么必须问 / 什么不该问 / 怎么问」写成可直接执行的判断标准(含例外清单,避免变成「凡事都要问」的噪音)。
2. 常驻提醒(app:ask-first-reminder,runtime context):每个模型请求前都注入一条约 150 字的规则(默认是「必须 / 不得 / 禁止」的强硬版)。runtime context 每一步都会重算并渲染在快照里,所以长会话里纪律段在 prompt 前段的注意力衰减时,这条仍然在场。文本固定(不带计数)时不破坏 prompt 缓存;正文可在设置页的 standingReminder 里整体改写。

常驻提醒可在设置页单独关掉(alwaysRemind),关掉后只剩纪律段 + 变更提醒 + 硬闸。

二、提醒层

监听 tools/post-execute,按智能体统计「连续做了多少次变更性操作却一次都没提问」。
达到阈值(默认 3,之后 6、12、24)时,在这一次工具结果后面插入一条 notice 消息:

⚠ ask-first 提醒:本回合你已经连续做了 3 次变更性操作(最近一次:write),却还没有向用户确认过任何一次。

以下任一情况计数清零:调用 ask_user_question;用户发来新消息。

什么算「变更性操作」

- 结构性变更(默认名单):write edit remove move publish spawn_teammate interrupt_agent subagent subagent_fork team_task_create team_task_update schedule_create schedule_update schedule_delete create_worktree create_goal update_goal terminal_send terminal_close terminal_signal
- shell 通道(bash / pwsh / terminal_send):按命令特征判断(>、rm、mv、 git commit、pnpm add、chmod…),只读命令不计。
- python 通道:按代码特征判断(open(...,'w')、os.remove、shutil.、subprocess.…),纯计算与只读脚本不计。

只读工具(read glob grep web_fetch web_search session_search todo_write …)
永远不计——读十个文件不等于擅自做主。

三、硬闸层(不可逆操作必须先问)

对没有回滚路径的操作注册 tools.guard():本回合还没问过用户时,直接拒绝这一次调用, 不执行,并返回一条可行动的拒绝理由:

ask-first 硬闸:remove 属于不可逆操作,本次调用已被拒绝,没有执行。
请先调用 ask_user_question 向用户确认……拿到明确同意后再重试这一次调用。

模型随后调 ask_user_question → 用户同意 → 重试 → 守卫放行。

什么算「不可逆操作」

- 工具名(默认):remove、move、publish
- shell / python 文本里命中危险模式:rm、rmdir、mkfs、dd if=、truncate -s 0、 git reset --hard、git clean -fdx、git push --force、shutil.rmtree(、os.remove(、
os.unlink(、os.rmdir(、.unlink(、.rmtree(

放行条件(满足任意一条就不拦)

1. 本回合问过,且问的就是这件事:ask_user_question 的提问正文(问题 / 标题 / 选项 label 与 description)里必须出现这次操作的目标。只问了一个无关问题不解锁——这是 user-approval 的「授权只对请求的那个动作有效」语义;
2. 用户这条消息里点名了该目标(参数里的路径 / basename 出现在用户消息里)——用户说「删掉 a.txt」就直接放行,不必再问一遍;
3. 它只是本会话自己创建的文件:本会话由 write 创建过、且路径完全相同的文件,清理自己的临时产物不需要确认(照抄官方 auto-review 的 low 规则);
4. 调用者是子代理(委派它出来的父代理对用户负责,在子代理里拦会把团队任务卡死)。

只读沙箱下让位

ctx.sandboxPolicy.resolve() 读出当前 mode。当它是 read-only 时,变更请求本来就会被
文件系统层已经拒绝,硬闸再拦一次只是把同一个失败原因说两遍;提醒层统计「变更未提问」也没有意义(根本没有生效的变更)。所以两层都静默。开关:respectSandboxMode(默认 true)。

UNKNOWN 即确认

名单内的工具若参数里读不出被操作的目标,视为「不知道」,直接拒绝而不是放行——「不知道」≠「安全」(OpenHands 的默认)。拒绝文案会要求模型把目标写进参数并先问用户。

总开关 hardGate 关掉后,硬闸完全不参与,只剩前两层。

刻意不做

- 不拦创作型操作:write / edit / python 的 open(...,'w') 一律放行。它们可重写、可回滚,而开发任务里每一步都在用;拦了只会把正常任务卡死。
- 不拦子代理(理由见上)。
- 不新增提问工具:提问复用内核 ask_user_question,少一层 API 面,跟随上游升级。
- 不写客户端代码:不碰 UI,只贡献系统提示与一条消息;设置项走 DSH 内置的「设置 → 插件 → ask-first」自动表单。
- 守卫自身绝不阻断:guard 回调整体包在 try/catch 里,内部任何异常都放行——插件的问题不该把工具链卡死。

安装

一行安装(DSHM 端侧的 pnpm 是 Host 布置的假壳,add 会走安装队列并同步返回结果):

pnpm add github.com/yinghan-123/dsh-ask-first

手工落盘时:包放进 profile 的 node_modules 后,在 profile 的 package.json 里把包名加进 dsh.profile.bundles:

"dsh": {
"profile": {
"bundles": [
"…", "dsh-ask-first" ] } }

本包的 package.json 声明了 dsh.bundle.patch → ./cordis.patch.yml,后者只 insert 自身一行(id: ask-first / name: dsh-ask-first),不改写任何官方装载行。

实测(2026-10-24,DSHM 0.2.1-rc.2+dshm.73):包放进 node_modules 并在 dsh.profile.bundles 追加一行后,DSHM 的 loader 会 reconcile 出 include:ask-first (fiberPhase: active),不需要重启应用;下一次请求的 system prompt 就带上了纪律段,提醒层也当场触发验证通过。旧版本或改法不同的环境若没热挂载,重启一次 DSHM 即可。

回滚

1. 从 dsh.profile.bundles 删掉 dsh-ask-first 一行,重启即可(包文件留着不影响);
2. 只想停某种行为:设置页把「硬闸」单独关掉(只剩提示词 + 提醒),或把总开关关掉;
3. 彻底删除:删掉 node_modules/dsh-ask-first/ 目录。

设置界面

DSH 的「设置 → 插件」页只渲染官方插件的 companion 页面;第三方 bundle 的配置必须由本包自己的浏览器半部注册到 slot 上。所以本包带一个手写、无构建步骤的 lib/client.js (window.__ModuleLoader__.load 协议):它把一页「先问后干」挂到 settings.section,通过 ctx.configForms.get("ask-first") 读写本插件命名空间。

页面内容:总开关、常驻提醒开关、硬闸开关、自建对象免授权、按 sandbox 模式让位(五个开关,点完立即生效)、 提醒正文编辑框(多行,留空 = 内置强硬版默认)、 提醒阈值(数字输入)、以及三份工具名单(已提问工具 / 计入变更的工具 / 硬闸拦截的工具,逗号或换行分隔)。底部「保存」一次写入全部字段,「恢复默认」把所有字段 unset 回默认值。

| 字段 | 默认 | 说明 |
| enabled | true | 总开关(三层全部受它控制) |
| alwaysRemind | true | 每个模型请求前都注入一条常驻纪律提醒 |
| standingReminder | 内置强硬版 | 常驻提醒的正文(留空 = 内置默认;改完下一轮生效,不用重启) |
| hardGate | true | 硬闸开关:不可逆操作没问过就拒绝执行 |
| threshold | 3 | 连续多少次变更性操作没提问后提醒(最小 1) |
| askTool | ask_user_question | 哪个工具算「已经问过」 |
| mutatingTools | 见上文 | 计入变更性操作的工具名列表 |
| irreversibleTools | remove move publish | 硬闸拦截的工具名列表 |
| selfCreatedExempt | true | 自建对象免授权:本会话 write 创建过的文件,删除/移动不再要求先问 |
| respectSandboxMode | true | 按 sandbox 模式让位:只读模式下变更本来就不可能执行,硬闸与提醒静默 |

七个字段都是 volatile:保存后立即生效(写入 profile 行 + 热更新运行中的 host 实例),不需要重启。

首次加载 client 半部需要重启一次 DSHM:loader 要重新扫描该包的 dsh.client 声明,之后刷新页面就能看到设置侧栏的「先问后干」一页;此后改配置都是热的。

边界(如实声明)

- 判断是启发式:shell / python 的写入与危险命令靠特征匹配,可能漏判(少拦一次 / 少提醒一次),也可能在等价场景下多判。阈值与名单都能在设置页调。
- 硬闸的放行靠「本回合问过」而不是「问的就是这件事」:模型理论上可以问一个无关问题来解锁。这是刻意的取舍——要做到语义级绑定,就得解析提问内容,脆且难维护;提示词层已经要求「问题里说清要动什么」。
- 提醒与硬闸都是面向行为的,不改权限策略:DSHM 端侧仍是 danger-full-access + approval = never,硬闸是插件自己的判断,不是沙箱或审批。
- 真正「随时提问」的通道(选项 / 多选 / 自由作答、等待与超时语义)仍由内核提供,本插件不改变它。
预览分享卡片长什么样 ↓yinghan-123/dsh-ask-first
分享 · DeepSeek Harness Hub
yinghan-123/dsh-ask-first

让智能体动手前先向你确认,避免擅自替你决定

这是你的仓库?认领条目

回到顶部