前言¶
在 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