dsh-hitl:在 DSH Web UI 裏爲任意工具調用加上人工審批門

前言

在 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。

安裝後:

  1. 刷新瀏覽器頁面一次(首次安裝必須;已打開頁無法拿到注入 token,僅靠熱重載不夠)。
  2. 在 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
羽毛球分组比赛记分
小程序二维码

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

小夜