dsh-preset-tool-guard:按 Agent preset 限制工具可見性

前言

在 DeepSeek Harness(dsh)裏,工具解析順序是 agent → preset → global。Preset 組合會掛載自己的工具行,但不會收窄從 global 層繼承下來的工具。因此,只要在宿主側掛過 computer-use 驅動、瀏覽器 MCP、圖像 provider 等,這些能力會出現在每一個 preset 的模型工具目錄裏——包括只打算暴露兩三個工具的 minimal 預設。

關掉這些 provider 不是好辦法:能力會整體丟失,且影響所有 preset 與會話。上游對 preset 側的討論見 deepseek-ai/deepseek-harness#5786。Harness 提供的公開接口是 agent 作用域上的 ctx.tools.restrict({ allow, deny }):它遮蔽的是該 scope 繼承來的層(global 與祖先 scope),不會動 scope 自己註冊的工具。下面介紹社區插件 dsh-preset-tool-guard(維護者 KouzakiUmi,分類 admin-security),如何把這條 seam 接到 preset 生命週期上。

這是什麼

dsh-preset-tool-guard 是 DeepSeek Harness 插件:在宿主層掛載一次,監聽 agent/created,讀取該 Agent 實際組合的 preset,並在 該 Agent 自己的 scope 上調用官方 ctx.tools.restrict()。效果是:每個 preset 只暴露應見的繼承工具,而重型 provider 仍保持全局掛載、無需拆下。

npm 包名 dsh-preset-tool-guard,當前資料中的發佈版本爲 0.1.2(MIT)。社區目錄頁:SkillHub - dsh-preset-tool-guard;源碼與說明:GitHub - KouzakiUmi/dsh-preset-tool-guard。

核心功能與行爲

插件掛載後,對模型與運行時產生如下變化(與 README 一致):

方面 效果
模型側工具 schema(每請求前綴) 被遮蔽的工具不再出現
PTC 模式 SDK 表面 同樣不可見(兩種投影讀同一視圖)
調度 被遮蔽的調用返回 UNKNOWN_TOOL,是真屏蔽而非展示層過濾
其他 Agent / preset 不受影響;限制按 scope 隔離
Provider 本身 仍掛載;保留在 allow 內的能力照常可用

要點簡述:

  1. 限制施加在 agent.ctx(Agent 自有 scope);restrict() 從調用上下文推導 scope,不能在無 scope 的 plain 上下文執行。
  2. 過濾在註冊時快照。allow 列表只保留快照時刻存在的名稱;之後纔出現在繼承層上的工具不會被自動放行。若需晚註冊的 provider 可見,應在其註冊後再創建新 Agent。
  3. 即使當前沒有任何工具被排除,allowlist 匹配仍會安裝 mask,以免 fail-closed 策略退化成 fail-open。
  4. 插件監聽 tools/change,對晚註冊且匹配 deny / 前綴 / 禁用分組的繼承工具追加拒絕;不會重建 allowlist 快照,也不會補錄晚到的 allowlist 名稱。
  5. 若 ToolRuntime.view() 不可用,插件會跳過遮蔽並說明,而不是誤用 schemas() 導致整次 restrict() 失敗。

加載時還會對 agents.list() 返回的已有 Agent 掃一遍並套用規則。

安裝與啓用

環境要求:Node ^22.19 或 >=24(見包內 engines);Harness 需暴露 ToolRuntime.restrict() 與 agent/created 事件。包自帶 cordis.patch.yml,安裝即掛載插件行。

在任意帶 dsh CLI 的環境(TUI、web profile 等)執行:

dsh plugin --profile <profile> add dsh-preset-tool-guard

從 GitHub 安裝:

dsh plugin --profile <profile> add github:KouzakiUmi/dsh-preset-tool-guard

本地目錄安裝:

dsh plugin --profile <profile> add /path/to/dsh-preset-tool-guard

固定版本示例:dsh-preset-tool-guard@0.1.2。

DSH Desktop 若 PATH 上沒有 dsh,需用桌面版自帶的 terminal shim(README 在 DSH Desktop 2.0.17-next、core 0.2.0-rc.2 上驗證過),例如 Windows PowerShell:

$env:ELECTRON_RUN_AS_NODE = '1'
& "C:\Program Files\DSH NEXT\DSH NEXT.exe" --expose-internals `
  "C:\Program Files\DSH NEXT\resources\app\lib\desktop-cli.js" `
  plugin --profile desktop add dsh-preset-tool-guard

--profile 爲必填;內置 dsh 在 Electron 路徑外不會啓動名爲 desktop 的 profile。

安裝後重啓 DSH:插件是宿主側 bundle,運行中的進程仍保留舊樹。卸載時用 remove 替換 add,並從 profile 的 patch 中刪除 preset-tool-guard 配置項;只刪包行會留下懸空配置塊。

配置

插件自帶 patch 默認爲保守模式(dryRun: true、無 allowlists)。真實策略應寫在 profile 的 cordis.patch.yml 中。同一 entry id 的 loader 配置會被整體替換,因此需寫全你關心的字段——包括 dryRun,否則代碼默認會變爲 false(開啓遮蔽)。

- id: preset-tool-guard
  config:
    allowlists:
      minimal: [bash, pwsh, str_replace_editor]
      standard: [read, write, edit, glob, grep, pwsh, skill, todo_write, web_search, memory_recall]
      text: [read, write, edit, glob, grep, pwsh, grok_imagine_edit]
    deny: []
    denyPrefixes: []
    groups: {}
    disableGroups: []
    skipUncomposed: true
    report: true
    reportFile: C:/Users/you/.dsh/logs/preset-tool-guard.log
    dryRun: false

常用字段(代碼默認值見 README 表格):

  • allowlists:{ presetId: [toolName, …] }。匹配的 preset 僅保留列表中的繼承工具,其餘繼承工具被遮蔽。空數組或無 restrictable 匹配時跳過 allowlist 並告警,不會清空繼承面;未出現在 map 中的 preset 無 allowlist,仍受 deny / 分組規則約束。
  • deny / denyPrefixes:對所有 Agent 按精確名或 startsWith 前綴移除工具。
  • groups / disableGroups:命名分組與要禁用的分組 id。
  • skipUncomposed(默認 true):無組合 preset 的 Agent 跳過 allowlist;deny / 分組仍生效。
  • report / reportFile:每次(重新)應用寫一行報告;默認 $DSH_HOME/logs/preset-tool-guard.log。
  • dryRun(代碼默認 false):只度量與報告,不改動;調參時建議先開。

典型用法

  1. 在宿主 profile 安裝插件並重啓 DSH。
  2. 在 profile 的 cordis.patch.yml 中爲 preset-tool-guard 配置 allowlists,按 preset id 列出應保留的繼承工具名;全局不想出現的工具用 deny 或 denyPrefixes(例如 README 示例中的 cua_driver_native__ 前綴)。
  3. 首次上線設 dryRun: true,查看 reportFile 中的報告,確認遮蔽範圍後再設 dryRun: false。
  4. 升級 provider 若改名,列表中不存在的名稱會被跳過(不拋錯),報告裏會有說明;需手動改配置或在新 Agent 上重試 allowlist 快照。

適用場景與注意

適合:同一 Harness 宿主上掛多種重型 provider,但希望 minimal、standard 等不同 preset 在模型側只看到各自設計的工具集;需要在不卸載 global provider 的前提下做 admin / 安全向的工具面收斂。

注意:

  • 插件以當前 dsh 進程權限運行,安裝前請自行審閱 源碼與 LICENSE,確認符合你的安全策略。
  • SkillHub 等爲社區目錄,與 DeepSeek / 幻方無官方從屬關係;安裝命令以 README 爲準。
  • allowlist 是快照語義:晚於 Agent 創建才掛載的、本應 allow 的工具不會自動進入白名單;規劃 provider 加載順序或重建 Agent。
  • 保留的 PTC 傳輸名 run_code 不會寫入過濾器。

結尾

dsh-preset-tool-guard 把 ctx.tools.restrict() 接到 agent/created,在保留 global provider 掛載的前提下,按 preset 收窄每個 Agent 可見的繼承工具,並配合 deny、前綴與分組做全局兜底。需要細節、字段說明與 Desktop 安裝方式時,以 GitHub README(含 README.zh.md)爲準。

  • 目錄頁:https://www.skillhub.cn/plugins/KouzakiUmi/dsh-preset-tool-guard
  • GitHub:https://github.com/KouzakiUmi/dsh-preset-tool-guard
羽毛球分组比赛记分
小程序二维码

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

小夜