前言¶
在 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 內的能力照常可用 |
要點簡述:
- 限制施加在
agent.ctx(Agent 自有 scope);restrict()從調用上下文推導 scope,不能在無 scope 的 plain 上下文執行。 - 過濾在註冊時快照。allow 列表只保留快照時刻存在的名稱;之後纔出現在繼承層上的工具不會被自動放行。若需晚註冊的 provider 可見,應在其註冊後再創建新 Agent。
- 即使當前沒有任何工具被排除,allowlist 匹配仍會安裝 mask,以免 fail-closed 策略退化成 fail-open。
- 插件監聽
tools/change,對晚註冊且匹配 deny / 前綴 / 禁用分組的繼承工具追加拒絕;不會重建 allowlist 快照,也不會補錄晚到的 allowlist 名稱。 - 若
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):只度量與報告,不改動;調參時建議先開。
典型用法¶
- 在宿主 profile 安裝插件並重啓 DSH。
- 在 profile 的
cordis.patch.yml中爲preset-tool-guard配置allowlists,按 preset id 列出應保留的繼承工具名;全局不想出現的工具用deny或denyPrefixes(例如 README 示例中的cua_driver_native__前綴)。 - 首次上線設
dryRun: true,查看reportFile中的報告,確認遮蔽範圍後再設dryRun: false。 - 升級 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