前言¶
在 DeepSeek Harness(DSH)裏跑智能體時,工具調用往往會在你未看清參數前就執行:改文件、跑 shell、調 MCP 等,一旦誤觸很難撤回。常見做法是自己在插件裏寫一層確認邏輯,或只在少數危險工具上手工攔截,維護成本高,且不同插件之間行爲不一致。
下面介紹社區插件 dsh-hitl(維護者 YunpengDon,分類:工作流):它把「執行前先讓人看、再批准 / 修改 / 拒絕」做成可掛載的門,目標工具不必改業務代碼,也可由其他插件通過 API 一行掛載。
這是什麼¶
dsh-hitl 是 DSH 的可安裝 bundle 插件:在工具真正執行前,在 DSH Web UI 展示決策卡片(標題、待執行提案、批准 / 修改 / 拒絕按鈕)。簡介原文爲:Human-in-the-loop gate for DSH tool calls: mount any tool behind an approve / modify / reject decision card in the DSH Web UI.
實現上爲零依賴、零構建的純 JS(index.js 宿主側 + client.js 瀏覽器側 + lib/),安裝後刷新頁面即可注入 window.__DSH_HITL__。npm 包版本爲 0.2.1,許可證 MIT,Node 引擎要求 ^22.19.0 || >=24.0.0。
核心功能¶
掛載方式¶
- 配置一行:在
cordis.patch.yml的hitl插件config.protect裏列出要保護的工具名(支持mcp__*等模式)。 - API 一行:其他插件
inject: ['hitl']後調用ctx.hitl.protect(...),建議傳入調用方ctx作爲owner,以便插件卸載時自動解除掛載。
決策卡片與提案展示¶
執行前展示標題與待執行內容;提案字段可配置爲:並排 diff(只讀)、純文本輸入、可編輯 / 可渲染的 Markdown;文本與 Markdown 可只讀或可編輯。未配置 fields 時,默認展示該次調用的全部參數(鍵名或 schema 的 title,值以 Markdown 輸入形式展示,非字符串爲格式化 JSON)。
修改與拒絕¶
編輯提案文本後,主按鈕由【Approve】變爲【Modify】,修改內容作爲修訂意見回傳給智能體。【Reject】可帶反饋框,拒絕原因一併返回。
倒計時¶
可配置倒計時及三種結束行爲:自動批准、自動拒絕、將超時報告給智能體。
與 DSH 運行模型的配合¶
- 進程內子智能體透傳:
spawn/fork子 Session 內的工具調用同樣過門;請求會掛在子 Session 與當前查看的 Session 下,卡片可標註「from subagent Session xxx」並提供【Open that Session】。文檔說明進程外後端不會經過此門。 - 不在對話頁時的提醒:在插件頁、設置頁或未選中 Session 時,頁面頂部浮動通知(數量、工具名、來源 Session、剩餘時間 + 批准 / 拒絕 / 打開 Session),避免必須停在原對話才能處理。
服務 API(診斷與生命週期):protect(matcher, options?, owner?)、unprotect(matcher)、list()、pending()。同一工具多次掛載時,以最近一次爲準(配置行先註冊,插件可覆蓋配置)。
安裝與啓用¶
官方安裝方式如下(<your profile> 換成你的 profile 名):
# 從 npm(推薦)
dsh plugin --profile <your profile> add dsh-hitl
# 從 GitHub(無需構建)
dsh plugin --profile <your profile> add github:YunpengDon/dsh-hitl
# 本地目錄(開發時改代碼後需重啓 dsh)
dsh plugin --profile <your profile> add /path/to/dsh-hitl
也可在 GUI:Settings → Plugins → install bundle。
安裝後:
- 刷新瀏覽器頁面一次(首次安裝必須;已打開頁無法拿到注入 token,僅靠熱重載不夠)。
- 在
cordis.patch.yml配置protect列表,或讓其他插件調用ctx.hitl.protect(...)。
卸載:
dsh plugin --profile <profile> remove dsh-hitl
典型用法¶
方式一:僅改配置,不動目標工具代碼¶
在 cordis.patch.yml 中爲 hitl 插件增加或覆蓋一行(注意:patch 覆蓋整行 config 時需寫全仍要保留的鍵):
- id: hitl
name: 'dsh-hitl'
config:
protect:
- tool: bash
title: Confirm before running
countdown: { seconds: 30, action: reject }
reject: { feedback: true }
方式二:在自有插件代碼裏掛載¶
export const name = 'my-plugin'
export const inject = ['hitl']
export function apply(ctx) {
ctx.hitl.protect('bash', {
title: 'Run this command?',
countdown: { seconds: 30, action: 'reject' },
reject: { feedback: true },
}, ctx)
ctx.hitl.protect(['write', 'edit'], {
title: 'Confirm before editing',
diff: { path: 'file_path', before: 'old_string', after: 'new_string' },
countdown: null,
}, ctx)
}
matcher 支持工具名、含 * 的 glob、RegExp、數組或 (exec) => boolean。若掛載未隨插件卸載而消失,可用 ctx.hitl.list() 排查,並用 ctx.hitl.unprotect('bash') 或在插件頁開關 hitl 行重建狀態。
適用場景與注意¶
適合:需要在 DSH Web UI 統一給 bash、寫文件、MCP 工具等加人工門的工作流;多插件生態裏由各自 protect 綁定生命週期,避免散落手寫確認框。
注意:
- 插件與當前 dsh 進程同權限 運行,安裝前請自行查看 GitHub 倉庫 源碼與 MIT 許可證。
- 社區目錄 SkillHub 插件頁 爲獨立生態站點,與 DeepSeek / 幻方無官方從屬關係;DSH 本身遵循「一切皆插件」,本插件是其中一類工作流擴展。
- 更多交互示例見項目 Landing 站點。
結尾¶
dsh-hitl 把「工具執行前的人工決策」收斂成可配置、可 API 掛載的一層,減少每個工具各自實現確認 UI 的重複勞動。需要試用或查文檔時,可訪問目錄頁與倉庫:
- 目錄頁:https://www.skillhub.cn/plugins/YunpengDon/dsh-hitl
- GitHub:https://github.com/YunpengDon/dsh-hitl