中文EN

dsh-plugin-subagent-roles

model已测通过npmMIT

用文件定义子代理角色:角色放在项目级与全局级 .dsh/roles 目录,委派方每个角色只看到一行目录,子代理可见的工具由角色自己的工具策略决定。

下载量 / Downloads
1,485
依赖体积 / node_modules
14.57 MB
测试时间 / Tested
2026-11-06
DSH 版本 / Version
0.2.2-rc.1

安装

dsh plugin --profile web add dsh-plugin-subagent-roles

沙箱测试结果

阶段结果
1 安装✓
2 列装✓
3 挂载✓
4 启动—

四阶段在隔离沙箱里跑:安装(有网)→ 列装 → 挂载 → 启动(后三步断网)。

README

dsh-plugin-subagent-roles

[English](README.md) | 中文 | [更新日志](CHANGELOG.md)

![npm](https://www.npmjs.com/package/dsh-plugin-subagent-roles)

![CI](https://github.com/troytse/dsh-plugin-subagent-roles/actions/workflows/ci.yml)

![license](LICENSE)

概述

dsh-plugin-subagent-roles 用文件来定义子代理角色。一个角色就是一个 Markdown 文件:frontmatter 里是显示名、路由描述、可选的模型路由、工具策略和可选的工具调用预算,正文是子代理要遵循的 persona。项目级角色放在 <项目>/.dsh/roles/,全局角色放在 ~/.dsh/roles/;同 id 同时存在时项目级生效。

插件注册一个委派工具,并把当前工作区里的角色以一行行的紧凑目录告知主代理。委派到某个角色时,子代理带着该角色的 persona 启动,且只保留策略允许的工具——主代理的上下文里不会出现 persona 正文,没有角色文件的项目也不会看到任何目录。角色还可以限制子代理能用多少次工具:这是由框架自己的 tool/call 事件计数的硬上限,因此不肯收尾的子代理会被强制停下。

安装

桌面版(DSH 桌面 App)——在 App 侧栏的 Plugins 页里安装:粘包名即从 npm 拉取,粘绝对路径则安装本地检出。

dsh-plugin-subagent-roles
# 或本地检出
/path/to/dsh-plugin-subagent-roles

desktop 这个 profile 归 App 独占——dsh plugin --profile desktop … 会被明确拒绝(profile "desktop" is managed exclusively by the Electron application),所以桌面版走 Plugins 页。它会安装包、把 bundle 追加进 profile,随后该行会出现在设置页的清单里。宿主侧的行会即时加载;客户端界面(其它插件的侧栏/任务页/用量页)需要刷新一次页面才会出现。

命令行 profile(dsh web、TUI、headless)——按名字装进对应 profile,或 link 一个检出:

# 从 npm 安装
dsh plugin --profile web add dsh-plugin-subagent-roles

# 或本地 checkout
dsh plugin --profile web add link:/path/to/dsh-plugin-subagent-roles

装好后重启该 profile(dsh web)。包内自带 bundle patch,会自行插入它的那一行组合,无需手改 composition。要求 Node.js 20 以上,以及提供 @deepseek-ai/dsh-tools 与 @deepseek-ai/dsh-subagent 的 DSH 部署。

版本线:0.5.x 只支持 DSH 0.2.1-rc.1+;0.2.0 及更早请继续用 0.4.3。0.2.1 移除了 subagents.start / startContinuable、请求里的 persona / toolFilter 以及客户端设置服务,0.5.0 已按新 API 重写委派与 composition,角色文件格式与模型绑定不变。

快速开始

在项目里创建一个角色文件:

---
displayName: 代码审查员
description: 审查改动的正确性、安全性与测试覆盖,按严重级别给出结论。
provider: deepseek-official
model: deepseek-v4-flash
reasoningEffort: low
tools: [read, grep, glob]
---
你是代码审查员。先读改动再下结论,区分阻塞项与建议项,
每条问题都给出文件与行号。

然后让主代理委派——“让代码审查员角色审一下这个改动”——或直接调用工具:

subagent_role({ role: "code-reviewer", prompt: "审查已暂存的改动。", description: "审查暂存改动" })

角色在组装提示词时读取、在委派开始时再读取一次,因此改角色文件不需要重启 DSH。同风格的派发提示词见 examples/delegation-prompts.zh.md。

角色文件

角色从哪里读取

优先级 · 路径 · 说明

1 · <项目>/.dsh/roles/<id>.md · <项目> 是从会话工作目录向上找到的第一个含项目标记(默认 .git)的目录;找不到标记时就是工作目录本身。

2 · ~/.dsh/roles/<id>.md · 跨项目共用。可用 dshHome 改位置。

角色文件可以是符号链接。文件按文件名寻址,因此 id 就是文件名(去掉 .md),必须是 kebab-case。

文件格式

frontmatter 是 YAML 映射,正文是 persona。

字段 · 必填 · 含义

description · 是 · 目录里显示的一行描述,主代理据此判断要不要委派。

name · 否 · 写了就必须与文件 id 一致,用来拦住"改了文件名却没改声明"。

displayName · 否 · 人可读的名字,默认取 id。

whenToUse · 否 · 追加在目录行末尾的补充路由提示。

provider、model · 否 · 子代理的模型路由。两者必须同时出现或同时省略;省略时继承主代理的路由。

reasoningEffort · 否 · 子代理的思考力度,随路由一起生效。

tools · 否 · 允许清单简写,如 [read, grep, glob]。

toolFilter · 否 · 显式策略:{ allow: [...], deny: [...] }。

maxToolCalls · 否 · 子代理工具调用次数的硬上限,整数。省略则继承行配置的 defaultMaxToolCalls;写 0 表示显式不限,它会覆盖行默认值。

maxToolCallsScope · 否 · delegation(默认)每次委派重新计数——continuable 子代理的每个 turn/start(即一次后台唤醒)也算新的一次;session 则按该子代理整个生命周期累计。

onToolCallBudget · 否 · 额度耗尽时的行为:wrap-up(默认)、interrupt 或 off。

graceToolCalls · 否 · wrap-up 注入通知后额外放行的调用次数,默认 1;0 表示在触发的那一次调用上直接收口。

tools 与 toolFilter 只能二选一。未知的 frontmatter 键会被拒绝而不是忽略,避免拼写错误悄悄放宽角色的工具范围。

maxToolCalls 族字段需要插件 ≥ 0.4.0。旧版本完全不认识这些键,会把整个角色文件判为非法而跳过,因此角色文件与插件版本是绑定的:给某个角色加上额度,就意味着每个使用该工作区的机器都要升级插件。

persona 正文可以使用 {{cwd}}、{{model}}、{{provider}}——恰好是 agent loop 注册的那三个,由框架在子代理侧插值。部署里若另有插件注册了更多变量,可在 personaVariables 中列出;除此之外的任何引用都会在读取角色文件时被拒绝,因为未知变量会让该子代理的每一轮都抛错。引用按精确规则匹配(花括号内不能有空格);而目录字段——description、displayName、whenToUse——完全不能出现 {{,因为目录文本在到达模型之前同样会经过插值。

配置

行配置如下;在 profile patch 里按 id 覆盖即可:

# ~/.dsh/profiles/web/cordis.patch.yml
- id: subagent-roles
  name: dsh-plugin-subagent-roles
  config:
    catalogDescriptionMaxLength: 120

选项 · 默认 · 含义

toolName · subagent_role · 模型可见的委派工具名。

subagentProvider · spawn · 子代理传输 provider。

backgroundMode · one-shot · one-shot 或 continuable。

enableRunInBackground · true · 是否在工具上暴露 run_in_background。

maxDepth · 不设 · 委派深度上限;不设则由 provider 决定。0 表示拒绝任何委派。

defaultRole · 不设 · 调用未给 role 时使用的角色。

catalog · compact · compact 渲染角色目录;off 完全不渲染。

catalogScope · main · main 只向顶层 agent 展示角色;all 连子代理也展示。

catalogDescriptionMaxLength · 160 · 目录行里每条描述的截断长度。

projectRootMarkers · ['.git'] · 从会话工作目录向上寻找项目根的标记。

projectRootTtlMs · 5000 · 项目根结果被信任多久后重新向上查找,好让会话运行中 git init 也能被发现。

dshHome · $DSH_HOME 或 ~/.dsh · 全局 roles/ 目录所在位置。

maxBodyBytes · 65536 · persona 体积上限,按 UTF-8 字节计。超过该值加 64 KiB frontmatter 余量的文件在读取之前就被拒绝。

personaVariables · ['cwd', 'model', 'provider'] · 允许 persona 引用的提示词变量。仅当部署确实注册了更多变量时才扩充。

respectModelSelection · true · 是否遵守官方 subagent-model-selection 允许清单:先看会话已捕获的策略,再看实时设置。

onMissingTool · drop · 不可用的工具名:drop 告警后继续,error 直接拒绝委派。

timeoutMs · 不设 · 单次前台委派的工具调用超时。不设则不限时。

defaultMaxToolCalls · 0 · 角色文件未声明额度时使用的工具调用预算。0 表示不限,且默认就是 0:2277 个文件的大仓和一个小项目对"合理调用数"的定义不同,所以这个数字属于角色文件而不是全局硬编码。

maxToolCallsHardCap · 0 · 角色文件不得超过的上限,防止项目侧把额度开到失去意义。0 表示不设上限,且永不削顶显式的 maxToolCalls: 0——"不限"是哨兵值而不是数值零。

onToolCallBudget · wrap-up · 额度耗尽行为的行级默认值,可被角色文件覆盖。

graceToolCalls · 1 · 宽限次数的行级默认值,可被角色文件覆盖。

enableListTool · false · 是否注册诊断工具。

listToolName · subagent_roles · 诊断工具的名字,让第二行能与之共存。

childPromptTrim · full · 裁剪子代理提示词:full 丢弃子代理用不上的工具说明,外加命名过的提示词片段;tools 只丢前者;off 不注册该监听器。主代理的提示词永不改动。

childPromptTrimNames · `['harness:source', 'app:web-surface', 'ui:deliverable-file-references', 'context:file-r

…(truncated)

以上内容来自 npm 上的 README,我们只做格式化,不改内容。

版本

npm 上共发布:11,最后更新 2026-10-17

链接

GitHub · Homepage · npm

同类插件