r600a-code/dsh-swarm-router
DSH plugin: sub-agent matrix swarm — routes heterogeneous tasks to the most suitable model (OpenRouter-like + cfgpu.com/llm/square), dispatches each via in-process subagents. 32/32 benchmark green.
已收录
1
Model
Bundle 已验证
预览
功能介绍
子智能体矩阵蜂群:把异质任务路由到最合适的模型(OpenRouter 类网关 + cfgpu.com/llm/square),通过进程内子智能体或直接 LLM 调用下放,并按模型统计 token 消耗、用真实反馈驱动排名。
适合
- 需要批量下放推理、编码、长上下文和快速任务等异质工作的团队。
- 可通过 OpenRouter 类网关和 cfgpu.com 使用多个模型,并希望按任务路由的用户。
- 需要按模型统计 token,并根据真实结果调整排名的工作流。
- 希望通过路由服务注册额外模型或任务类型的插件开发者。
不适合
- 固定使用单一模型或偶尔只处理单个任务的工作流,路由和排名价值有限。
- 无法访问已配置模型提供方或缺少凭据的部署;不可用模型无法调用。
- 无法归入现有任务类型、且不准备注册自定义类型的任务。
- 不希望反馈和用量数据持久化到本地排名及用量文件的用户。
README
dsh-swarm-router
| English | 中文 |
A DeepSeek Harness bundle that turns a batch of heterogeneous tasks into a sub-agent matrix swarm: it routes each task to the most suitable model from an OpenRouter-like gateway plus the cfgpu.com/llm/square catalog, then dispatches each assignment in parallel as a real in-process subagent (or a direct ctx.llm call) pinned to that model — quick tasks land on fast/cheap models, hard tasks on strong reasoning models. A formal design write-up lives in docs/PAPER.md.
子智能体矩阵蜂群:任务是行、候选模型是列,路由器为每一行选中一格,再通过 DSH 的
ctx.subagents把每格变成一个绑定到所选模型的子智能体并行下放,按任务难度匹配模型、省时提效。论文见docs/PAPER.zh.md。
The four contributions
| Contribution | What | |
|---|---|---|
| ① | Model aggregation registry + PR flow |
models/registry.json is the canonical catalog; scripts/validate-registry.mjs enforces structure (CI-ready); CONTRIBUTING.md documents the add-a-model PR flow. |
| ② | Plugin extension point |
ctx.provide('swarmRouter', api) — other plugins inject: ['swarmRouter'] to register runtime models, custom task kinds, subscribe to feedback, read rankings/usage. |
| ③ | Real-task feedback + ranking |
swarm_feedback records {correct, quality 1-5}, persisted to rankings.json; swarm_ranking shows per-model/per-kind success rate & quality; proven models are boosted in routing, failing ones demoted. |
| ④ | Token-consumption statistics (cfgpu highlighted) |
direct mode captures exact per-call prompt/completion/total from ctx.llm.stream; subagent mode captures via a global llm/stream listener attributed by sessionId; persisted to usage.json; swarm_stats shows totals/byProvider/byModel/byKind + cfgpuHighlight. |
Tools
| Tool | Mode | Calls models? |
|---|---|---|
swarm_route_preview |
— | No (pure routing plan) |
swarm_dispatch |
subagent (default) | direct
|
Yes (parallel) |
swarm_models |
— | No (list registry) |
swarm_feedback |
— | No (records an outcome) |
swarm_ranking |
— | No (reads accumulated feedback) |
swarm_stats |
— | No (reads accumulated usage) |
The router rules (how a task becomes a model)
A task is { id, kind, prompt, maxTokens? } where kind ∈ {reasoning, coding, longcontext, fast, general}. The router is pure and O(1) per task — it spends zero model-time deciding which model; the saving goes into parallel dispatch.
Step 1 — infer the kind. An explicit kind wins; otherwise the first truthy hint among {reasoning, coding, longContext, fast} is used, defaulting to general.
Step 2 — capability gate (hard filter). Each kind requires a capability tag; a model lacking it scores -∞ and is dropped:
-
reasoningrequiresreasoning;codingrequirescoding;longcontextrequireslongContext;fast/generalrequire nothing.
Step 3 — effort-matched weighted score. For the surviving models, a kind-specific linear score is computed from the catalog’s 1–10 ranks (strength, speed, cost) and capacities (contextWindow, maxTokens):
| kind | weight vector |
|---|---|
reasoning |
reasoning×3 + strength×2 + coding×0.3 + contextWindow×0.000004 |
coding |
coding×3 + strength×2.5 + longContext×0.3 |
longcontext |
contextWindow×0.00002 + strength×0.5 + coding×0.3 |
fast |
speed×3 + cost×1.5 + strength×0.3 |
general |
strength×2 + speed×0.6 + cost×0.3 + coding×0.3 |
Step 4 — penalties (the effort-matching core).
-
kind ≠ fastandmodel.fast→ −2.0 (a fast/cheap tier is under-powered for quality work). -
kind = generalandmodel.reasoning→ −2.0 (a reasoning flagship is overkill — slower, pricier — for general work). -
kind = codingandmodel.reasoning→ −0.5 (reasoning helps code but is not required; slight demotion vs. a pure coding-strong peer). -
model.unstable→ −4 (route was flaky during catalog capture). -
model.available = false→ −1000 (e.g. OpenRouter without a key). -
Ranking feedback boost (when
useRankings: true):successRate ≥ 0.9over ≥ 3 trials → +1.5;successRate ≤ 0.4→ −3.0. Real outcomes override the static catalog.
Step 5 — pick & explain. Highest score wins; ties broken by strength, then lexicographic id (deterministic). The tool returns the winner plus top-5 candidates with scores and a human-readable rationale.
Why these numbers. The penalties are asymmetric on purpose: rewarding cheapness on quality tasks is the failure mode this design exists to avoid, so the fast-model penalty (−2.0) and the reasoning-overkill penalty (−2.0) are large enough to flip a tie but small enough that a genuinely-strong cheap model can still win general when it earns it. The ranking boost (±1.5/−3.0) is smaller than the static penalties so a model must clear a real quality bar before feedback can override the catalog.
Why the design
-
Matrix, not a single pipeline. A diverse batch fans out across several models — the
distinctModelssummary is the signal that routing is doing something rather than collapsing to one model. -
Distinct LLM routes (
cfgpu-swarm,openrouter), not the machine’scfgpu.llm-pi-aimerges provider routes by key (composition base ∪ settings); distinct keys union without clash, so the swarm’s catalog never disturbs the orchestrator’s own model. A patch replaces a row’s wholeconfig, so we add routes rather than editing settings. -
Pure router, then dispatch. Separating “decide” from “do” makes routing free, testable, and preview-able (
swarm_route_preview), and lets dispatch (directvssubagent) be chosen per task. -
directmode for token truth. A one-shotctx.llm.streamreads theusagechunk directly — exact per-call accounting including cfgpu’sreasoning_tokens(when the adapter emits it).subagentmode is for tasks needing the agent loop; its usage is captured via a globalllm/streamlistener attributed bysessionId == child run.id(the only mechanism that catches child calls without scope filtering — confirmed by source research). - Feedback closes the loop. Static catalog ranks are author guesses; real task outcomes, persisted and folded into a boost, let a model that looks strong but fails in practice get demoted, and a sleeper get promoted.
Install & run
# against the default DSH_HOME (~/.dsh — needs the cfgpu credential there)
dsh plugin --profile headless add github:r600a-code/dsh-swarm-router
dsh --profile headless --dump-config | grep -E 'cfgpu-swarm|swarm-router'
# sandboxed away from ~/.dsh: a workspace-local DSH_HOME seeded with the credential
export DSH_HOME=/path/to/.dsh-home # put .credentials.yaml (CFGPU_API_KEY) + settings.yaml there
dsh plugin --profile headless add /path/to/dsh-swarm-router
The cfgpu route needs CFGPU_API_KEY in $DSH_HOME/.credentials.yaml (or env). The OpenRouter route needs OPENROUTER_API_KEY; without it the router reports it unavailable and never dispatches to it, so the profile still boots.
Benchmark
benchmark/benchmark.json is the minimal subset: 5 cheap, heterogeneous tasks across fast/reasoning/coding/general. Success is judged by content (expected answer substring / CJK), not by the run merely completing.
dsh --profile headless "$(cat benchmark/benchmark_prompt.txt)" # subagent mode, 5 tasks
node benchmark/verify_benchmark.mjs # 27/27 green
dsh --profile headless "$(cat benchmark/benchmark_direct_prompt.txt)" # direct mode, 3 tasks
node benchmark/verify_benchmark.mjs benchmark_direct_RESULT.json # 31/31 green
Recorded: subagent 5 tasks → 4 distinct real cfgpu models, all correct (17×23=391, bat-ball=0.05, real is_prime, CJK translation, widgets=5). Direct 3 tasks → exact token capture per task.
Files
-
package.json—dsh.bundlemanifest. -
cordis.patch.yml—cfgpu-swarm+openrouterroutes,swarm-routerplugin row. -
index.js— the plugin: service + 6 tools. -
catalog.js— registry loader + catalog builder. -
router.js— the pure, effort-matched router. -
ranking.js— feedback → ranking + routing boost. -
store.js—rankings.json+usage.jsonpersistence. -
models/registry.json— the model aggregation registry. -
scripts/validate-registry.mjs— registry validator (CI). -
CONTRIBUTING.md— add-a-model PR flow. -
benchmark/— tasks, prompts, recorded results, verifier. -
docs/PAPER.md/docs/PAPER.zh.md— formal design write-up.
Marketplace
- Official discoverability: the
dsh-pluginGitHub topic (applied). - Community curated list: PR to
awesome-dsh-plugin; thedsh-marketplugin pulls from it automatically.
License
MIT.
常见问题常见问题
在启用了 DSH 的终端中执行已验证命令 dsh plugin --profile default add github:r600a-code/dsh-swarm-router。命令会解析公开 package 元数据,并保持插件与本页展示的目录身份一致。
兼容性以页面上展示的 bundle 与 profile 状态为准。如果某个 profile 尚未检测到,请先保持禁用,并在生产启用前阅读仓库文档。
GitHub 链接和 activity 元数据是 release 与维护状态的来源。新版本发布后重新查看本页,确认目录已经观察到最新版本。