🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

蜂群调度器 SadshiKoro/dsh-swarm-scheduler

DeepSeek Harness
SadshiKoro11 天前有提交已提供中文文档扫描:含敏感能力

DSH 并行编码调度器:Lead 只管调度,队友只管执行,就绪池落盘存储,原子认领。

31.2/100
综合分
2
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/24 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add SadshiKoro/dsh-swarm-scheduler
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:需留意
是什么
dsh 原生插件 · dev
装得上吗
实装验证未通过(unknown),装前请到仓库确认最近更新与 issue
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 11 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
⚠︎ 实装验证未通过(unknown · 2026/10/31) ——可能是验证环境差异,装前建议到 GitHub 仓库确认最近更新与 issue。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件
查看扫描证据(共 26 处,展示前 14 条)
  • 写入本地文件
    lib/index.js:293
    mkdirSync(this.dirPath, { recursive: true });
  • 读取本地文件
    lib/index.js:350
    if (!existsSync(this.dirPath)) return { tasks, io: { ok: true, degraded: this.#fallbackNote } };
  • 读取本地文件
    lib/index.js:351
    for (const name2 of readdirSync(this.dirPath)) {
  • 读取本地文件
    lib/index.js:356
    const text2 = readFileSync(join(this.dirPath, name2), "utf8");
  • 读取本地文件
    lib/index.js:396
    const text2 = readFileSync(join(this.dirPath, taskFileName(taskId)), "utf8");
  • 写入本地文件
    lib/index.js:431
    mkdirSync(this.dirPath, { recursive: true });
  • 写入本地文件
    lib/index.js:433
    writeFileSync(fd, body, "utf8");
  • 写入本地文件
    lib/index.js:455
    mkdirSync(this.dirPath, { recursive: true });
  • 写入本地文件
    lib/index.js:456
    writeFileSync(join(this.dirPath, taskFileName(task.task_id)), body, "utf8");
  • 读取本地文件
    lib/index.js:473
    return existsSync(target);
  • 读取本地文件
    lib/index.js:488
    return createHash("sha256").update(readFileSync(target)).digest("hex");
  • 写入本地文件
    lib/index.js:531
    mkdirSync(this.dirPath, { recursive: true });
  • 删除本地文件
    lib/index.js:608
    unlinkSync(lockPath(dirPath, taskId));
  • 执行外部命令来自配置/变量
    lib/index.js:1014
    const stdout = execSync(command, {
扫描于 2026/10/31(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

依赖的 DSH / Cordis 模块
@deepseek-ai/schemastery@deepseek-ai/cordis@deepseek-ai/dsh-tools
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

README

由 DeepSeek 最新模型翻译生成
dsh-swarm-scheduler(beta) 实验性插件(beta,0.x) 给下载并尝试安装此插件的朋友先作个声明:这是实验性插件,处在 0.x 阶段,建立在 DeepSeek Harness(DSH)的 Agent Teams 之上——它依赖的 @deepseek-ai/dsh-experimental-agent-team-profile 本身带 experimental 标记,且必须手动挂载,仍有许多不稳定性。欢迎改进这个插件;如果它让谁的工作受了损失,我深表歉意,也希望你把意见或改进方向提给我。 English — Before installing: this is an experimental (beta, 0.x) plugin built on DeepSeek Harness's Agent Teams layer. That layer comes from @deepseek-ai/dsh-experimental-agent-team-profile, a package marked experimental by its own label that must be mounted by hand. Expect instability. Improvements and bug reports are welcome. If this
展开完整文档(README 剩余 1 节)
dsh-swarm-scheduler(beta)

实验性插件(beta,0.x)

给下载并尝试安装此插件的朋友先作个声明:这是实验性插件,处在 0.x 阶段,建立在 DeepSeek Harness(DSH)的 Agent Teams 之上——它依赖的 @deepseek-ai/dsh-experimental-agent-team-profile 本身带 experimental 标记,且必须手动挂载,仍有许多不稳定性。欢迎改进这个插件;如果它让谁的工作受了损失,我深表歉意,也希望你把意见或改进方向提给我。

English — Before installing: this is an experimental (beta, 0.x) plugin built on DeepSeek Harness's Agent Teams layer. That layer comes from @deepseek-ai/dsh-experimental-agent-team-profile, a package marked experimental by its own label that must be mounted by hand. Expect instability. Improvements and bug reports are welcome. If this plugin cost you work, I am sorry — please tell me what broke or what should change.

采用 MIT License 授权,按 「as is」提供,不附带任何形式的担保。上面的声明只是善意提醒,不能替代 LICENSE 中的条款:不提供任何担保,作者对使用本插件造成的任何损失概不负责。

这是 DeepSeek Harness 的多会话并行编码调度插件。核心主张是「活找人」:Lead 只负责拆解和唤醒,worker 从共享的磁盘任务池里以原子认领的方式取活。

1. 解决什么问题

普通 Agent 是单线程的。它读文件、改文件、跑命令、推理,一次只走一步,所以一个涉及十几个文件的请求就是一条长长的串行链。本插件把这个 Agent 变成调度器:把请求拆成互相独立的块,写进任务池,唤醒几个 worker,每个 worker 认领块并并行执行——而 Lead 自己一行产品代码都不写。

关键的不对称在于谁发起交接。常见设计是「Lead 把任务派给某个具名 worker」(人找活)。这个插件反过来:块躺在池子里,worker 来抢——谁空谁拿。正因如此,它才能扩展,而 Lead 不必追踪谁闲着。

2. 核心概念

两层拆解

| 层 | 含义 | 存储为 |
| 大任务块(swimlane) | 请求中一块内聚的区域,例如「数据层」「HTTP 层」「集成」 | big_task_id |
| 小任务块 | 调度单元:一个 worker、一个上下文窗口、一份交付物 | 一条任务记录 |

小任务块的硬性约束

每个小任务块都必须能被一个全新会话独立执行,该会话只有任务描述:

1. 明确写出输入、输出和验收标准。
2. 与任何其他就绪块无写冲突——最小单位是一个函数、一个文件、一个配置项,或一个可独立验证的行为。
3. 用 blocked_by 声明真实依赖。不要「保险起见」串行化:那会把并行度压到 1。
4. 在 write_scopes 中声明会碰的文件。从 v0.2.6 起,这一点在认领时强制执行:一个范围与已认领任务重叠的任务会被拒绝,返回 scope_conflict,不会放行。所以声明范围时,要写最窄但仍如实反映情况的范围。重叠按目录粒度判定,详见 §9 的 write_scopes 条目。

角色

| 角色 | 身份 | 可以做 | 不可以做 |
| Lead | 当前会话 | 拆解(swarm_plan)、调整依赖(swarm_set_deps)、唤醒 worker、汇报进度 | 认领任务,或编写产品代码 |
| Worker | Lead 创建的队友 | swarm_ready → swarm_claim → 执行 → swarm_complete | 碰其他 worker 的任务,或修改依赖 |

3. 工作原理

Lead receives a large coding request
│
├─ swarm_plan(...) ← decompose into two layers, write the file pool
│ └─ .dsh-tasks/<task_id>.json per block (blocked_by forms a DAG)
│
├─ list_agents ← reuse idle teammates if any exist
│ ├─ idle workers found → send_message (wake them, method only, no task ids)
│ └─ none → spawn_teammate ×2-3
│
└─ swarm_status ← watch progress, report to the user

Worker (each, independently, in parallel)
├─ swarm_ready → what is ready right now
├─ swarm_claim → atomic claim (exclusive file creation)
│ └─ lost the race? already_claimed is a NORMAL result — take another block ├─ execute the task └─ swarm_complete → report the compressed outcome └─ back to swarm_ready for another round, until it returns 0

Lead, on a conflict report from a worker
└─ swarm_set_deps → serialise the conflicting blocks after the fact

任务池不会自己流动。 内核里没有任何东西会把工作推给空闲 worker;要由 Lead 唤醒它们。第一次唤醒之后,worker 会一直拉取任务,直到任务池为空。如果某个 worker 执行到一半消失了,Lead 可以用 swarm_release 把那个任务块放回池里。

4. 安装

4.1 前置条件:挂载 Agent Teams 配置档包

agentTeams 服务来自实验性包 @deepseek-ai/dsh-experimental-agent-team-profile。它不在任何默认配置档包里,所以这个服务永远不会被提供,必须显式挂载。把它加进配置档的 dsh.profile.bundles:

"dsh": {
"profile": {
"bundles": [
"@deepseek-ai/dsh-base",
"@deepseek-ai/dsh-web-app",
+ "@deepseek-ai/dsh-experimental-agent-team-profile",
...
]
}
}

⚠️ 不要把它加进 dependencies。 这些包随应用包(app.asar)一起分发,和官方的 @deepseek-ai/dsh-base 完全一样;从 npm 解析不到它们。加进 dependencies 会让 pnpm install 失败。

⚠️ 副作用。 这个包会禁用内置的子代理工具(subagent、subagent_fork、list_agents(原生)、interrupt_agent(原生)),换成 Team 版本(spawn_teammate、send_message、team_task_ 等)。这些工具会变,请留意。回滚时删掉 bundle 那一行再重启即可。

回滚。 要撤销这个副作用,必须把 @deepseek-ai/dsh-experimental-agent-team-profile 从配置档的 bundle 列表里删掉,然后重启 DSH。只删插件不会恢复原生 subagent 工具 —— 换掉它们的是 bundle,而 bundle 跟这个插件是独立的。

4.2 安装插件

dsh plugin --profile <your-profile> add link:/path/to/dsh-swarm-scheduler-beta

(或者在配置档的 dependencies 里加一条 file:/link: 条目,再把包名加到 dsh.profile.bundles。)

4.3 tasksRoot 必填 —— 空值会被拒绝

必须填绝对路径。 默认值是空的,而 DSH Desktop 里 process.cwd() 是配置档目录,不是会话工作区 —— 所以不设它,每个任务文件都会建到错的地方。

从 v0.2.7 起,插件不再静默回退:激活时直接抛错,fiber 报 failed,错误信息里写明是哪个设置、该加哪一行:

tasksRoot is empty. Refusing to place the task pool under process.cwd() (<cwd>) — in this deployment that is the profile directory, not the workspace being scheduled, so every task would land where you never look. Set it where this plugin is configured, e.g. tasksRoot: 'C:/path/to/the/workspace/being/scheduled'

这个报错说明插件挂上了但没配置:加上下面的 config 块再重启。tasksRoot 解析不出来之前,什么都不会写。

在配置档的 cordis.patch.yml 里给 swarm-scheduler 条目加一个 config 块:

- id: swarm-scheduler
config:
tasksRoot: 'C:/your/workspace/absolute/path'

用正斜杠,填绝对路径。任务池会建在 <tasksRoot>/.dsh-tasks/<task_id>.json。

4.4 插件加载不起来怎么办

把环境变量 DSH_SWARM_SCHEDULER_MODULE_PROBE 设成一个文件路径。模块被导入时,会往这个文件追加一行 MODULE EVALUATED pid=<pid>:

- 文件没生成 → 模块根本没被导入,问题在装配路径(patch 行、bundle 列表、包解析);
- 文件生成了,但没有 APPLY OK → 模块导入了,但 apply 没跑完,问题在激活内部。

这招管用,是因为探针在模块作用域执行,早于 apply —— 也只有这样才分得清这两类故障:加载器从不 await apply(),哪怕激活根本没跑,它照样报 fiberPhase: active。

APPLY OK / APPLY FAILED 是另外两行:只有设了插件的 debugLogPath 配置值才会写(默认空 = 完全不记日志)。

4.5 重启

必须重启 DSH。 工具、提示词段落、bundle 列表和 tasksRoot 都在启动时生效,没有热重载。

5. 用法

不必手动调用工具

插件以提示词段落的形式发布了一套调度协议(order: 590,位于策略区,紧挨着内核自带的 Team 策略之前)。当你交给智能体一个大任务——涉及多个文件、多个模块、多个步骤——它会自动切换到调度模式:调用 swarm_plan,唤醒或创建 worker,然后汇报进度,而不是自己动手写代码。

七个工具仍然可以直接调用,用于显式控制。

显式指令示例

Use the swarm scheduler for this:
1. swarm_plan — decompose the request into swimlanes and small blocks, with blocked_by and write_scopes.
2. list_agents — if there are idle teammates, wake them with send_message; otherwise spawn 2-3.
3. Wake message (method only, no task ids):
"Check swarm_ready for ready tasks, claim one with swarm_claim, execute it, report with
swarm_complete, then loop back to swarm_ready until it returns 0."
4. Never assign a specific task to a specific worker — which worker gets which block is the result of an atomic race.
5. Report progress with swarm_status.

6. 七个工具

| 工具 | 用途 | 主要参数 |
| swarm_plan | 提交任务分解,写入任务池 | tasks[](task_id、big_task_id、title、description、blocked_by、write_scopes) |
| swarm_ready | 列出 worker 当前可以开始的任务 | 可选 big_task_id 过滤 |
| swarm_claim | 原子地认领一个任务 | task_id / claimed_by |
| swarm_complete | 标记任务完成并保存结果 | task_id / result / completed_by |
| swarm_status | 一次调用查看整个任务池状态 | 无 |
| swarm_release | 把卡住的任务退回任务池(claimed → pending) | task_id / released_by |
| swarm_set_deps | 替换任务的 blocked_by 列表(仅 Lead 可用) | task_id / blocked_by / updated_by |

所有调度状态都保存在 <workspace>/.dsh-tasks/<task_id>.json。没有数据库,也没有后台守护进程。

7. swarm_set_deps 的两层校验

依赖原本只能在规划阶段声明,一旦串行关系写错,运行中途就无法修正。swarm_set_deps 补上了这个缺口,并校验依赖图必须满足的两件事:

| 检查项 | 返回码 | 原因 |
| 引用的每个 id 都存在 | invalid_dependency | 悬空的阻塞项会让任务永远无法就绪——不存在的任务永远不会算作已完成。 |
| 新边不构成环 | cycle_detected | 从拟新增的阻塞项向下遍历图来检测;如果遍历回到任务自身,就拒绝。自引用只是最短的环。 |
两种拒绝都发生在写入任何内容之前——被拒绝的任务保持原样,不会留下写了一半的状态。swarm_set_deps 刻意只允许 Lead 调用:blocked_by 是一张共享图,多个 worker 并发编辑可能交错出环,而这项检查正是为了防止成环。把决策串行到单个写入者,环检查才有意义。

8. 架构:路线 B(文件池是唯一事实来源)

池存放在磁盘上,它的七个工具是唯一的调度接口。内核的 Team 任务板只用来唤醒 worker,别的什么都不做。

为什么选路线 B。 目标是「工作找到 worker」。文件池的三个原语正好构成这条链——swarm_ready(谁可以干活)、swarm_claim(工作落到某个 worker 手里)、swarm_complete(结果回到池里)。Team 任务板的 reassign 走的是反方向:Lead 把工作指派给某个人。两个不同的目标,不是同一个目标的两种实现。

路线 B 还消除了路线 A 的三个缺陷——全部经过实测,见 DESIGN.md §12.1:

| 路线 A 下的缺陷 | 路线 B 下为何消失 |
| reassign 和 claim 争抢同一个状态槽 | Lead 从不调用 reassign;任务板上没有任何 claim |
| 两个存储之间没有互斥,一个任务可能被两个 worker 各抢一半 | 任务板完全不参与调度 |
| 被阻塞的任务无法镜像 | 就绪状态完全由文件池的 blocked_by 决定 |

已否决——路线 A(Team 任务板作为唯一事实来源): 派发由 Lead 的 reassign 驱动,worker 处于被动。可行,但把「工作找到 worker」又变回了「Lead 找到 worker」,与目标矛盾。

已否决——路线 C(丢掉文件池,只用任务板): 会丢掉原子自抢链,而这是整套设计的核心;还会让插件在调度上依赖实验性的 agentTeams 服务,而不只是用它来唤醒。

9. 已知限制

1. 没有可视化面板。 头部面板在 v0.2.0 中移除。它的数据路由(/api/swarm/board)需要 ctx.webServer,而从这个插件的 fiber 里无法可靠解析(实测:一次 ROUTE REGISTERED,其余都是 ROUTE SKIPPED webServer not mounted)。一个点开只显示「面板不可用」的按钮,还不如没有按钮。见 DESIGN.md §5。
2. 没有内存隔离。 插件契约不暴露内存服务。上下文以文件形式在块之间传递,不经过内存。
3. ctx.fs 沙箱降级。 通过 ctx.fs 写入需要每次调用都带沙箱策略;部署环境拒绝时,插件回退到 node:fs,并给每个结果打上 degraded。它从不静默——但回退确实绕过了 ctx.fs 的版本观测。
4. 成员无法移除。 agentTeams 没有成员删除 API——没有 remove、dismiss、release 或 evict。interrupt 只停止当前回合。名册只增不减,Lead 会话结束时清空。因此协议更倾向于复用空闲 worker,而不是新建。
5. 认领没有回收机制——已修复:worker 消失后,它的任务会永远停留在 claimed,所有被它阻塞的任务都变得不可达。swarm_release(v0.1.9)把这类任务放回池中,从 v0.2.6 起还会删除任务的 .lock 文件。swarm_claim 在认领前会清除残留锁(任务仍显示 pending 时存在的锁,即持有者在认领中途死亡留下的锁)。因此,死掉的 worker 留下的任务和过期锁都不会永久阻塞池。
6. swarm_set_deps 无法在运行时强制执行。 它仅凭描述和协议限定为 Lead 专用,没有权限检查——要检查就需要 agentTeams.membership,也就是重新引入路线 B 刻意移除的服务路由。
7. write_scopes 在认领时检查,且检查粒度是目录级。 如果任务的作用域与已被认领的任务重叠,认领会以 scope_conflict 拒绝,并指出冲突任务和重叠的作用域。这把纯建议性的姿态升级为硬性拒绝(v0.2.6)——准确说明变化:这个池本身从不发出重叠警告。 软性的早期视图是 swarm_ready,它列出每个任务声明的 scope:;硬性视图是准入时的拒绝。(writeScopeWarnings 是内核对团队板的规则——见 DESIGN.md 附录——不属于这七个工具。)注意粒度:两个任务都声明 src/ 时会被拒绝,即使它们编辑的是其中不同文件。需要更细粒度时,声明更窄的作用域——用 src/api/routes.ts 而不是 src/。
8. 这个插件依赖一个实验性包。 它需要 @deepseek-ai/dsh-experimental-agent-team-profile,该包不在任何 DSH 默认 bundle 中,必须手动挂载。这带来三个后果:
- 安装插件需要额外一步配置(挂载 bundle)才能工作;
- 该 bundle 可能随 DSH 更新而变化,本插件不保证与其长期兼容。experimental 是包自身的标签,不是这里添加的谨慎提示;
- 如果 DSH 将该包提升为默认 bundle,或将其移除,§4 的安装步骤会改变,本 README 可能过时。
9. 并发正确性靠手工验证;核心逻辑现在有回归测试。 单元测试覆盖 task-store.ts 的 claim / release / complete / setDependencies、write_scopes 准入检查、残留锁清理,以及就绪/过期判断。运行 npm test 即可(Node 内置测试运行器,无需额外依赖;它直接运行 .ts 源码,需要 Node 22.18+,或 22.6+ 加 --experimental-strip-types)。如果你的 shell 禁止子进程捕获管道 stdio——实测场景就是沙箱化的 DSH 会话——测试运行器无法为每个文件启动 worker,会报 spawn EPERM;这时改跑 npm run test:sandbox,它在单进程里跑同样的用例(--test-isolation=none)。目前仍需手动验证的是并发行为:单任务闭环、3 个 worker 的原子认领运行,以及 route-B 闭环。也就是说,逻辑已有回归保护;但「真实并发下安全」这一结论仍依赖那几次手动运行。如果你打算用于生产,请在你自己的场景里重跑一遍。

10. 踩过的坑

这些坑花掉了实打实的调试时间。记下来是因为每一个都静默失败——没有报错,没有日志,看不出哪里不对。

1. cordis.patch.yml 里的条目只会物化一次。 loader 第一次看到某个条目之后,改它的 name、改它的 id、或者重启应用,都不会重新物化。不要靠 patch 挂载反复试探测。
2. dsh-super-injector 在 Desktop 上不工作。 activeEntry=none,不记录失败原因,stats.json 的 reason 永远是空的。改用官方 bundle 组装。
3. ctx.<service> 受 inject 门控。 访问未声明的服务属性会抛 cannot get property "X" without inject——所以靠删掉* inject 再读属性来探测,是自证式的测试。正确的探测方式是 ctx.get('X'),它查询全局存储,能区分「服务不存在」和「服务在此处不可见」。
4. agentTeams 服务需要显式挂载 bundle。 它来自一个实验性包,不在任何默认 bundle 里。在 inject 里声明它、却没有任何东西提供它,fiber 会永远停在 pending——等一个永远不会出现的服务。
5. pnpm 会忽略改动过的 file: + .tgz 说明符。 如果路径和版本没变,它会报 "Already up to date" 并复用旧 tarball。升版本(或改文件名)。
6. pnpm install 完全由 lockfile 驱动。 它不会修复从磁盘上消失的 node_modules 条目,也不会重新解析自身依赖已变的本地包。--lockfile-only 重建 lockfile;必须重新解析时,删掉旧条目。
7. process.cwd() 不是会话工作区。 在这个部署里它是配置档目录,所以相对路径下的池会落到错误位置。因此根目录是显式配置值(tasksRoot),并且从 v0.2.7 起,空值会在激活时被拒绝,不再静默地按 process.cwd() 解析。
8. ctx.fs 的写入会被沙箱拒绝。 dsh-fs-sandbox 按每次调用的策略限制所有变更操作,并回退到部署默认值;插件不会伪造该策略,因此即使目标目录存在,写入也可能被拒绝。所以才有带标记的 node:fs 回退。
9. Get-Content 的行数不可信。 Windows PowerShell 默认按 GBK 解码 UTF-8,吞掉 LF 字节——实测一个 1,045 行的文件被报告为 786 行。请使用 -Encoding UTF8,或统计 0x0A 字节。
10. 只读快照会过期。 任务描述里写死预期值(「这个文件应该是 31033 字节」),产物一重建就失效。与其写「检查它等于 X」,不如写「报告实测值」。

11. License

MIT License — see LICENSE.

12. Contributing

欢迎提交 issue 和 pull request。如果你要改动调度器本身,请先读 DESIGN.md:§12.1 记录了塑造当前设计的那些缺陷,§12.2 记录了其余代码所假定的架构决策(路线 B)。
预览分享卡片长什么样 ↓SadshiKoro/dsh-swarm-scheduler
分享 · DeepSeek Harness Hub
SadshiKoro/dsh-swarm-scheduler

DSH 并行编码调度器:Lead 只管调度,队友只管执行,就绪池落盘存储,原子认领。

回到顶部