安装
从 npm 安装(推荐)
dsh plugin --profile desktop add dsh-recursive-best-of-n@1.4.0
从 GitHub 安装
dsh plugin --profile desktop add "git+https://github.com/xiong4huo/dsh-recursive-best-of-n.git#v1.4.0"
也可以把仓库 clone 下来,在 GUI 的插件管理里安装本地 bundle 目录(link: 安装,便于改代码)。
安装后在 Web GUI 中使用:
- 打开 设置 → 通用 → Agent 预设(或新会话的 preset 选择器),选择 Recursive Best-of-N(递归择优树)。
- 新建会话后发任意请求。会话树/右侧 subagent 目录可看到并行开出的子代理。
- 想让主 agent 一次开更多,先按设置如何换算成树调整「设置 → Plugins → Subagent」;变化对下一轮请求生效。
若 GUI 里暂时看不到该预设:刷新页面;仍看不到时重启一次 DeepSeek Harness(插件包含 JS 插件模块)。
用 Git 地址安装时,
plugin_manager会先用git ls-remote检查仓库连通性,因此本机需要能访问github.com;直连受限时请给 Git 配置代理。npm 安装没有这个检查。
Recursive Best-of-N(递归择优树)· DSH Agent Preset 插件
一个 DSH 插件(bundle),新增 agent preset:recursive-best-of-n。
代理数量、并行宽度、递归深度全部跟随用户在「设置 → Plugins → Subagent」里的两个设置,插件不写死任何数字:
- 最大递归深度(
maxDepth) - 子智能体并行数量上限(
maxActiveSubagents)
每次请求时插件读取这两个值,自动算出一棵"并发不超上限、深度尽量深"的树,并把本节点要并行开几个子代理写进运行时上下文;主 agent 与每个内部节点一次并行开出这些子代理,等全部提交到齐后择优上送,最底层叶子真正干活。
目录
设置如何换算成树
一棵按层展开的树,若每层并行 f 个、深度 d,同时在线的子代理最多是
f + f² + … + f^d(父级在子级运行期间仍驻留、占名额)。所以插件:
- 以最小并行宽度 2,求并行上限内可达的最大有效深度(不超过用户设置的最大深度);
- 在该深度下,求仍放得下的最大并行宽度 f;
- 把
depth、fanout、以及"设置深度被容量折算"的说明写进每个节点的运行时上下文。
以并行上限 40 为例(当前 Desktop profile 的设置):
| 用户设置的最大深度 | 自动得到:每层并行 f | 有效深度 | 同时在线子代理峰值 | 一次请求代理总数 |
|---|---|---|---|---|
| 1 | 40 | 1 | 40 | 41 |
| 2 | 5 | 2 | 30 | 31 |
| 3 | 3 | 3 | 39 | 40 |
| 4 或更大(当前 10) | 2 | 4 | 30 | 31 |
说明:
- 若最大深度很大(如当前的 10),为不超 40 的并发上限,自动解是"每层 2 个、4 层";10 层、每层 2 个需要约 2046 个同时在线子代理,超出上限,所以运行时上下文会注明
configured maximum depth 10 is capacity-limited to 4。 - 想让主 agent 一次开更多:把"最大递归深度"调小——设为 1 就是一次并行开 40 个(一层平铺、主 agent 直接择优);设为 2 则每层 5 个;设为 3 则每层 3 个。这两项设置在每个新请求读取,改完下一轮即生效。
- 想真正递归 10 层,需要把并行上限提高到 ≥2046(或接受每层 1 个的退化形态)。
效果
以用户设置 最大深度 2、并行上限 14 为例(插件算出 fanout=3、有效深度=2):
用户请求
└─ 主代理 depth 0(ROOT) 一条消息并行派发 3 个子代理;等 3 份提交到齐后择优
├─ 子代理 A depth 1(INTERNAL) 先派 3 个叶子(一条消息);等 3 份到齐后择优上报
│ ├─ 叶子 A1 depth 2(LEAF) 真正干活
│ ├─ 叶子 A2 depth 2(LEAF)
│ └─ 叶子 A3 depth 2(LEAF)
├─ 子代理 B depth 1 …(同上)
└─ 子代理 C depth 1 …(同上)
- 每个内部节点(包括主 agent)都在同一条助手消息里并行调用
subagentN 次(N 由设置算出);随后只回一行状态、结束回合等待;提交分别到达时逐份计数,全部到齐后才比较择优,最终只输出一个答案。 - 递归深度由 subagent 服务的
maxDepth(用户设置)硬限制;插件按"容量可行的最大深度"提前把深度更浅的节点标成叶子,避免无意义的容量拒绝。 - 叶子(depth == 有效深度)只做任务,不再派发。
安装
本仓库根目录就是插件包根目录(package.json 的 dsh.bundle.patch 指向 cordis.patch.yml),所以可以直接从 GitHub 安装,不需要 &path: 子目录参数。
# 用插件管理器把本仓库安装到某个 profile(下例为 desktop)
dsh plugin --profile desktop add git+https://github.com/xiong4huo/dsh-recursive-best-of-n.git
也可以把仓库 clone 下来,在 GUI 的插件管理里安装本地 bundle 目录(link: 安装,便于改代码)。
安装后在 Web GUI 中使用:
- 打开 设置 → 通用 → Agent 预设(或新会话的 preset 选择器),选择 Recursive Best-of-N(递归择优树)。
- 新建会话后发任意请求。会话树/右侧 subagent 目录可看到并行开出的子代理。
- 想让主 agent 一次开更多,先按设置如何换算成树调整「设置 → Plugins → Subagent」;变化对下一轮请求生效。
若 GUI 里暂时看不到该预设:刷新页面;仍看不到时重启一次 DeepSeek Harness(插件包含 JS 插件模块)。
安装时
plugin_manager会用git ls-remote先检查仓库连通性,因此本机需要能访问github.com;直连受限时请给 Git 配置代理。
协议
persona 前缀(英文,模型面向)按运行时角色分两段(完整文本见 cordis.patch.yml):
- INTERNAL(ROOT 与更深内部节点,remaining > 0):从不自己做任务。
- 一次多开:在一条助手消息里把本节点该开的 N 个
subagent调用一起发出,每个 prompt 逐字包含完整任务 + 一句"你的回答会和其他独立答案比较"; - 回一行状态结束回合等待;子代理提交是
Background subagent ... finished通知,不是新请求;逐份计数,未到齐时只回一行状态(如"已收到 3 份提交中的 2 份;正在等待。"),不回答、不追加派发、不调用"消磨时间"的工具; - 全部到齐后比较、选最好的一个,原样转发;若部分
subagent调用被容量拒绝,只等实际启动的那些,若一个都没启动则自己做任务;全部提交不可用才再开一轮。
- 一次多开:在一条助手消息里把本节点该开的 N 个
- LEAF(remaining == 0):用工具真正执行任务,产出完整、自洽的答案(即给上一级的提交)。
- 所有深度通用:不向用户提问、不停留在计划、不越界改文件/提交。
实现要点
| 组成 | 作用 |
|---|---|
preset-recursive-best-of-n(@deepseek-ai/dsh-agent-preset) |
声明 preset:id: recursive-best-of-n,order 5 |
persona |
并行多开 + 逐份等待 + 择优上报协议 |
recursion-context(本插件包自带 JS 插件,index.js) |
每次请求读取 Host 的 subagents 设置:用 resolveMaxDepth() 取最大递归深度、用 subagents.config.maxActiveSubagents 取并行上限,按 f + f² + … + f^d ≤ 上限 求"最深可行 + 该深度下最宽"的树形,并把 fanout/深度/容量折算写进运行时上下文 |
tool-subagent |
provider: spawn、toolName: subagent,不配置 maxDepth,因此服务在每次委派时读取用户设置的 subagent.maxDepth 作为硬上限;子代理不指定 agentPreset,自动继承父代理当前 preset 版本 |
tool-bash / tool-pwsh(按平台) |
叶子的工作工具 |
tool-fs / tool-fs-search / tool-jobs / tool-web / tool-skill / tool-todo |
叶子的读取、搜索、后台任务、联网、技能、待办能力 |
agent-instructions / time-context |
AGENTS.md 指令与时间上下文 |
compaction 组 |
长任务的上下文压缩与工具结果裁剪 |
如何运行 / 复现验证
GUI 手动验证
在「设置 → Plugins → Subagent」把最大深度设成 2、并行上限设成 14(或任意值),新会话选择 Recursive Best-of-N,发"37×3 等于几?只回答数字"。预期:主 agent 一条消息里同时出现 3 个 subagent 调用;随后 3 个一级子会话各带 3 个二级子会话;主 agent 先显示"已启动 3 个…",逐份收到提交(1/3、2/3、3/3)后只输出一个答案。
命令行端到端验证(已实际跑通)
verification/ 目录包含端到端验证工具:用一次性临时 profile(dsh-base + dsh-web-app + 本插件 + 测试 bundle)启动独立 Web Host,测试插件直接创建绑定 recursive-best-of-n 的会话、提交任务、等待整棵树 settle,并记录子代理树。不经过 GUI。
最近一次实测(2026-10-24,deepseek-account/deepseek-flash,任务:37×3 只回答数字;测试 profile 的 Subagent 设置为 最大深度 2 / 并行上限 14):
- 插件按设置算出 fanout=3、有效深度=2(
f + f² = 3 + 9 = 12 ≤ 14); - 子代理树:主代理 3 个一级子代理,每个一级再各 3 个叶子,共 12 个子代理;
- 主代理在同一条助手消息里发出 3 个
subagent调用;状态依次为"已启动 3 个…"→"已收到 3 份中的 1 份"→"2 份"→ 3 份到齐输出111; - 一级节点同样一条消息并行开 3 个叶子、逐份等待、择优上报;叶子直接输出
111; - 整轮约 9–11 秒,无报错。
逐层轨迹见 verification/README.md。该目录仅用于验证,不要把 dsh-recursive-e2e 安装到日常 profile。
成本与耗时
一次请求的代理总数 = 1 + f + f² + … + f^d,其中 (f, d) 由两个设置自动算出(见上表)。并行展开的层同时跑,墙钟时间约为"深度次叶子任务 + 各级择优"。当前 Desktop 设置(10 / 40)下的自动解是每层 2 个、4 层,约 31 个代理;把最大深度调到 1 则是一次 40 个平铺候选、41 个代理。属于"值得多花 token 换更好答案"的模式,闲聊也会完整走树。
自定义
- 只有两个旋钮:就是用户设置里的「最大递归深度」与「并行数量上限」;插件每次请求读取,改完下一轮生效。
- 若想强制某个形状,可把这两项设成对应值(例如深度 1 + 上限 8 = 一次开 8 个、单层)。
- 工具集:直接在 cordis.patch.yml 的
plugins列表增删(例如加present、tool-ask-user);只有叶子会真正用工作工具。 - 模型:子代理默认继承父代理路由;如需单独指定,可在
tool-subagent.config增加modelSelectionSettings等(参考dsh-tool-subagentREADME)。
限制
- 两个设置是上限:插件取"深度尽量深、容量内最宽"的可行解,所以深度大时会自动变窄并在上下文里注明;并非"每层都开满并行上限"(那会瞬间占满容量,无法继续递归)。
- 每层产生过程消息("已启动…/已收到 k 份"),这是模式本身的可视化,不是失败。
- 子代理是 in-process 新会话,看不到父会话上下文;父代理必须在 prompt 里逐字带上完整任务(协议已要求)。
- 子代理权限在启动时固定,不能从内部提权;需要审批的操作会在子代理内被拒绝。
- 该 preset 依赖 Web/Desktop profile 的 Host 服务(
subagents+spawnprovider、agentPresets、systemPrompt等),不适用于不组合这些服务的 headless/SDK profile。
卸载
在 GUI 的插件管理里移除 dsh-recursive-best-of-n,或调用 plugin_manager 的 remove_bundle。移除后该预设从列表消失;已存在的会话保留它们启动时的组合。
文件清单
| 文件 | 说明 |
|---|---|
package.json |
bundle 清单:dsh.bundle.patch,主模块 index.js,locale/icon |
cordis.patch.yml |
插入 preset 声明(persona、recursion-context、工具、compaction) |
index.js |
recursion-context 插件:读取用户 Subagent 设置,计算树形并注入运行时上下文 |
locale/en.json、locale/zh.json |
插件清单显示名/描述(中英) |
icon.svg |
插件图标(递归树,原创) |
README.md |
本文件 |
LICENSE |
MIT 许可证 |
.gitignore |
忽略构建与临时产物 |
verification/ |
端到端验证工具与最近一次实测结果,见 verification/README.md |
No comments yet. Be the first to write one.