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
羽毛球分组比赛记分
小程序二维码

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

小夜