前言¶
在 DeepSeek Harness(DSH)里用 Agent Teams 时,Lead 会通过 spawn_teammate 拉起队友。内置的 spawn_teammate 不带 provider、model、reasoning_effort 等路由字段;ctx.agentTeams.spawnTeammate() 也只把 provider 名称传给 ctx.subagents.startContinuable(),而队友作为 continuable 子智能体,实际由 ctx.agents.create() 物化,并不会走子智能体 provider 的 start()。结果是:即便你想给不同队友换模型,它们往往仍继承 Lead 的路由。下面介绍的插件在现有 Team 契约不变的前提下,让 Lead 为每个队友单独选择 provider、model 和 reasoning effort,并在 Subagent 模型选择白名单下做校验。
这是什么¶
Team Model Routing(npm 包名 dsh-plugin-team-model-routing,仓库 Lingrui98/dsh-plugin-team-model-routing)由维护者 Lingrui98 发布,分类为工作流。一句话定位:让 Agent Teams 的 Lead 在拉起队友时指定该队友的 provider、model 和 reasoning_effort,并与 Subagent model-selection 允许列表对齐。
为什么需要插件而不是改 provider¶
README 里说明了机制边界:包装 subagent provider 无法路由队友,因为 continuation 注册表物化队友时不会调用 provider 的 start(),队友会静默落在继承路由上。
插件利用的接缝是:
spawn_teammate_routed按(Lead、队友名、context)记录路由;- 仍调用内置的
agentTeams.spawnTeammate(...),契约不变; ctx.agents.create()创建子智能体并排队初始 prompt;- 在子作用域的
agent/pre-step钩子里认领路由并重写child.options; AgentLoop.prepareRequest()每一步都读this.options,从而把路由带到请求头、assistant 消息来源及后续每一步。
agent/pre-step 在 step() → prepareRequest() 之前以 waterfall 方式执行;且 loop 与 Agent 共享同一 options 引用。队友名需从当步的 payload.messages 读取(恢复中的队友可从 transcript 回退),在 agent/created 时读 session 快照会拿不到信息——这是早期实现的已知坑点。
核心功能¶
工具(仅安装在 Lead 自己的 Agent 作用域)¶
| 工具 | 作用 |
|---|---|
spawn_teammate_routed |
与 spawn_teammate 相同契约,额外支持 provider / model / reasoning_effort;三者全省略则继承 Lead 路由 |
list_teammate_models |
列出可选 provider,再列出某 provider 下可选 model,以及该 model 的 reasoning efforts |
队友侧看不到这两个工具。
白名单与校验¶
当 @deepseek-ai/dsh-tool-subagent/model-selection-settings 为 enabled: true 时,显式指定且不在 allowedModels 内的路由会在创建队友之前被拒绝;纯继承不受限。若启用但白名单为空,则任何显式路由都不可选,继承仍可用。
路由还会经 llm.resolveCallConfig() 校验,未知 model 或不支持的 reasoning effort 会以适配器自己的错误信息失败,而不是拖到回合中途才暴露。
配置项¶
通过 cordis.patch.yml 注入,典型片段如下(字段名以仓库 README 为准):
- id: team-model-routing
name: 'dsh-plugin-team-model-routing'
config:
toolName: spawn_teammate_routed
listToolName: list_teammate_models
freshProvider: spawn
forkProvider: fork
routeTtlMs: 120000
freshProvider / forkProvider 是交给内置 Team 服务的 provider 名称,须为已注册的 subagent provider(默认示例为 spawn、fork)。未认领的路由记录在 routeTtlMs 后过期,对失败在创建子智能体之前的 spawn 无害。
安装与启用¶
包已发布在 npm:dsh-plugin-team-model-routing。安装命令如下。
npm install dsh-plugin-team-model-routing
也可让插件管理器指向已安装的包或工作区目录:
plugin_manager({ action: 'install_bundle', target: 'dsh-plugin-team-model-routing' })
安装会加载模块一次;Node 按解析路径缓存 ES 模块,替换包内代码后需重启 Harness 才能在当前进程生效。插件在 DSH 进程内以当前进程权限运行,安装前请自行查看源码与 MIT 许可证。
典型用法¶
先让 Lead 查询可选模型(工具名以配置中的 listToolName 为准,默认为 list_teammate_models),再带路由拉起队友。README「Verified live」中记录过类似调用(环境为 2026-10-15 的 desktop profile,且启用了 subagentModelSelection 白名单):
spawn_teammate_routed({ provider: 'model-server', model: 'glm-5.3', reasoning_effort: 'high' })
成功时 host 日志会出现 team-model-routing: teammate "…" now runs on model-server/glm-5.3 (effort high) 一类信息;list_agents 会显示该队友的 model 已被改写,而 Lead 仍保持原模型。若在白名单外显式指定路由,会在创建前报错,例如 README 中的 bosc/gpt-5.6-luna 被拒绝,且不会创建队友。
三者全部省略时行为与继承 Lead 路由一致,不受白名单限制。
适用场景与注意¶
适合谁:需要在同一 Team 里按任务给队友分配不同 LLM(含 reasoning effort)的团队 Lead;且你已启用或计划启用 Subagent model-selection 白名单,希望错误在 spawn 前就返回。
已知限制(来自 README):
- 路由记录在进程内存中,仅在本进程创建子智能体时有效;Harness 重启后冷恢复的队友会回退到
subagent/descriptor里记录的agentOptions。要跨重启保留路由需要持久化记录,README 将其标为自然后续方向。 - 对
agent.options的运行时改写依赖非公开接口,因此以插件形式发布;上游若能在ContinuableCreateSpec或 team spawn 请求中接受agentOptions会更干净。 - 现场验证未覆盖
forkcontext,也未覆盖冷恢复后的路由存活。
逻辑层可用仓库内测试(不随 npm 包发布):
node packages/team-model-routing/test/logic.test.mjs
README 说明该套件对 logic.js 做 18 项检查;agent/pre-step 接缝本身仍需实机运行验证。
结尾¶
Team Model Routing 在不改动内置 Team 服务契约的前提下,为 Lead 提供 spawn_teammate_routed 与 list_teammate_models,在子智能体首步之前把 provider、model 和 reasoning effort 写入队友的 options,并与白名单、resolveCallConfig 双重校验。社区目录页:skillhub.cn 插件页;源码与详细设计见 GitHub 仓库。