前言¶
DeepSeek Harness(DSH)內核已經提供「向用戶提問」的能力:ctx.userQuestions 服務、ask_user_question 工具,以及 Web GUI 裏的提問卡片。默認也會啓用這些組件。實際跑任務時,問題往往不在「能不能問」,而在 Agent 的行爲——需求有歧義時不問、方案有取捨時不問、要動不可逆資源時也不問,做完再解釋。工具在列表裏,不等於模型會主動用。
社區插件 dsh-ask-first(維護者 yinghan-123,分類:工作流)補的是這一層行爲約束:在替用戶做決定之前先提問。README 把它概括爲三層機制——常駐提問紀律、連續變更未提問提醒、不可逆操作硬閘——並自帶設置頁。下面按安裝、機制與配置說明可覈對的事實。
這是什麼¶
dsh-ask-first 是 DSH 的 bundle 插件,包名 dsh-ask-first,當前資料中的版本爲 1.6.0(MIT)。它不新增提問工具,提問仍走內核的 ask_user_question;也不改客戶端提問 UI,只通過系統提示、運行時上下文、工具執行後 notice,以及部分工具的 guard 攔截,把「先問後幹」寫進 Agent 的日常節奏。
- 目錄頁:https://www.skillhub.cn/plugins/yinghan-123/dsh-ask-first
- 源碼與文檔:https://github.com/yinghan-123/dsh-ask-first
SkillHub 等社區目錄與 DeepSeek / 幻方無官方從屬關係;安裝前建議自行查看源碼與許可證。插件在 DSH 進程權限下運行,硬閘與提醒是插件側啓發式判斷,不替代 DSHM 的沙箱或審批策略。
三層機制¶
一、提示詞層(每次請求都帶)¶
向系統提示注入兩部分:
- 紀律段(
app:ask-first,system prompt section):寫明什麼必須問、什麼不該問、怎麼問,含例外清單,避免變成「凡事都要問」。 - 常駐提醒(
app:ask-first-reminder,runtime context):每個模型請求前注入約 150 字的規則(默認可在設置頁用standingReminder整體改寫)。長會話裏紀律段注意力衰減時,這條仍會出現在快照裏。
可在設置頁用 alwaysRemind 單獨關閉常駐提醒;關閉後仍保留紀律段、變更提醒與硬閘(若未關總開關)。
二、提醒層¶
監聽 tools/post-execute,按 agent 統計「連續多少次變更性操作卻一次都沒提問」。達到閾值(默認 3,之後 6、12、24)時,在工具結果後插入 notice,例如:
⚠ ask-first 提醒:本回合你已經連續做了 3 次變更性操作(最近一次:`write`),卻還沒有向用戶確認過任何一次。
以下情況計數清零:調用 ask_user_question;用戶發來新消息。
變更性操作包括:默認名單裏的結構性工具(如 write、edit、remove、move、publish、spawn_teammate 等);bash / pwsh / terminal_send 裏帶寫入或危險特徵的命令;python 通道里帶 open(...,'w')、os.remove、shutil.、subprocess. 等特徵。只讀工具(read、glob、grep、web_fetch 等)不計入。
三、硬閘層(不可逆操作必須先問)¶
對沒有回滾路徑的操作註冊 tools.guard():本回合尚未按規則「問過」時,拒絕本次調用、不執行,並返回可行動的拒絕理由,引導先 ask_user_question 再重試。
默認按工具名攔截 remove、move、publish;shell / python 文本命中 rm、git reset --hard、git push --force、shutil.rmtree( 等模式時同樣攔截。參數裏讀不出操作目標時按 UNKNOWN 處理,拒絕而不是放行。
放行(滿足任一即可):本回合問過且提問內容覆蓋本次操作目標;用戶當前消息裏已點名該目標;本會話由 write 創建的同路徑文件(selfCreatedExempt);調用者是子代理。只讀沙箱模式下,若 respectSandboxMode 爲 true,提醒層與硬閘層靜默讓位。
總開關 hardGate 關閉後,硬閘不參與。刻意不攔創作型 write / edit 及等價 python 寫入,以免卡死正常開發流。
安裝與啓用¶
DSHM 端側一行安裝(資料原文):
pnpm add github.com/yinghan-123/dsh-ask-first
手工落盤時,將包放入 profile 的 node_modules,並在 profile 的 package.json 裏把包名加入 dsh.profile.bundles:
"dsh": {
"profile": {
"bundles": [
"…",
"dsh-ask-first"
]
}
}
包通過 dsh.bundle.patch 指向 cordis.patch.yml,僅 insert 自身 bundle 行。README 記載:在 DSHM 0.2.1-rc.2+dshm.73 環境下,bundles 追加後 loader 可 reconcile 出 include:ask-first,下一次請求即可帶上紀律段;舊環境若無熱掛載,重啓 DSHM 一次。兼容範圍:dsh >=0.2.0-rc.1 <0.3.0-0,Node >=20。
設置頁 client 半部首次加載需重啓一次 DSHM,以便掃描 dsh.client 聲明;之後改配置爲熱更新。
回滾:從 bundles 刪掉 dsh-ask-first 並重啓;或僅在設置頁關 hardGate / 總開關 enabled;徹底刪除可移除 node_modules/dsh-ask-first/。
設置頁¶
路徑:設置 → 插件 → 先問後幹(第三方 bundle 由包內 lib/client.js 註冊到 settings.section)。五個開關可即時生效:enabled、alwaysRemind、hardGate、selfCreatedExempt、respectSandboxMode;另有 standingReminder 多行文本、threshold(默認 3,最小 1)、以及三份名單:askTool(默認 ask_user_question)、mutatingTools、irreversibleTools。底部「保存」一次寫入,「恢復默認」 unset 回內置默認。
典型行爲(來自 README)¶
- Agent 連續多次
write/edit等變更而未調用ask_user_question→ 出現閾值 notice,提示先確認。 - Agent 在未問用戶時調用
remove或 shell 裏rm …→ 硬閘拒絕,要求先提問並取得同意後再重試。 - 用戶消息已寫「刪掉 a.txt」→ 硬閘對
a.txt放行,不必重複問。 - 只讀 sandbox +
respectSandboxMode: true→ 提醒與硬閘不重複攔已在 FS 層失敗的變更。
適用場景與邊界¶
適合希望 Agent 在歧義、取捨、不可逆動作前主動確認的工作流場景;閾值與工具名單可在設置頁按團隊習慣調整。
README 如實聲明:shell / python 判斷是啓發式,可能漏判或多判;硬閘「本回合問過」在實現上未做完整語義綁定,依賴提示詞要求問清要動什麼;守衛內部異常會放行,避免插件拖死工具鏈。提問通道的選項、等待與超時仍完全由內核 @deepseek-ai/dsh-user-questions 等組件提供。
結尾¶
dsh-ask-first 用提示詞、變更計數提醒和不可逆硬閘三層,把 DSH 已有的提問能力變成更穩定的行爲習慣,而不是依賴模型自覺。安裝命令以 README 爲準:pnpm add github.com/yinghan-123/dsh-ask-first。更多細節見 GitHub 倉庫 與 SkillHub 目錄頁。