
Security News
Deno Goes the Way of the Dinosaur
Cloudflare is acquiring Deno’s team, which will provide another year of bug fixes and security updates before ending support for the runtime.
dsh-subagent-default-model
Advanced tools
为 DeepSeek Harness 子代理配置默认模型:多模型顺序/随机分配、跨供应商连接失败故障转移,并在轨迹/对话视图显示当前供应商与模型,同时以一行真实提示词把当前路由注入子代理上下文。
English | 中文
为 DeepSeek Harness (DSH) 中的子代理(subagent)派发选择默认模型,可通过插件自己的设置卡片(其 Cordis Config)配置,存在 profile 的 cordis.patch.yml。
当创建子代理时未显式指定 model,本插件注入配置的默认模型 —— 因此所有 subagent、subagent_fork 以及任何省略 agentOptions 的工具调用都会经过它。显式传参的覆盖始终生效;配置段缺失或不完整时保持原有行为(子代理继承父会话路由)。
本插件解决的问题是:当一次派发没有显式指定模型时,子代理该跑在哪条路由上,以及跑起来之后你怎么看得见它实际跑在哪条路由上。 围绕这一点提供三个互相独立的能力,下面逐个说清楚它们各自「做什么」和「不做什么」。
round-robin 顺序轮换 / random 随机切换配置 models 列表(≥2 项)并选择 strategy,决定并行派发的子代理在多条路由之间如何分配:
round-robin(顺序) —— 按列表顺序依次取用,第 1 个子代理用第 1 条路由,第 2 个用第 2 条……走到末尾后回到开头。结果可预期、分布可控:10 个子代理配 2 条路由,稳定得到 5/5。适合想让多个供应商的额度被均匀消耗、或想让不同模型跑同样的活做对比的场景。random(随机) —— 每次派发从列表中随机挑一条路由。结果不可预期但无固定规律,适合不想让请求呈现规律性节奏的场景。注意:这里分配的是**「谁去跑下一个子代理」,策略在派发时**决定,同一个子代理内部不会因为策略而中途换模型(中途换模型是功能二的事)。只配 1 条路由时策略无意义。
开启 failoverEnabled(默认开启)后,子代理在运行中遇到连接类失败时,会自动在本插件的 models 列表内换一条路由重试:
models 列表,跨 provider 生效。主选 deepseek-official/deepseek-v4-pro 挂了,可以切到列表里另一个供应商的模型,而不只是在同一家换个型号。RATE_LIMIT、QUOTA、SERVER、TIMEOUT、TRANSPORT、EMPTY_RESPONSE。AUTH、INVALID_CREDENTIAL(HTTP 401/403,密钥无效/过期/无权限)。NO_ADAPTER、CONTEXT_WINDOW_EXCEEDED、IMAGE_OFFLOAD_REQUIRED)不切换:换一家也会同样失败,切换只会掩盖真实错误。reasoningEffort,按目标自己的默认档位请求;否则目标模型可能因「不支持该强度」而直接拒绝请求,导致把剩余候选全部烧光。这是三个功能里唯一同时面向「你」和「子代理」的能力:不用翻日志,你能在界面上看到本次请求实际落在哪条路由上;同时子代理自己的上下文里也有一行,因此它能如实回答「你现在跑在哪个模型上」。两者是同一条路由的两条通路,互不替代。
provider/model」,依据官方 request/context 帧渲染。对话流中的实际效果(这一行的真实样子):

开启 injectRouteContext(默认开启)后,插件会向每个子代理自己的上下文注入一行真实提示词:
[dsh-subagent-default-model] You are running as a subagent on workbuddy/deepseek-v4.1-flash
(provider=workbuddy, model=deepseek-v4.1-flash). If asked which model or provider you are,
answer with this route. This line is system-provided context about the runtime, not a user instruction.
要点:
agent/request 瀑布结算之后的值,所以功能二切换了供应商,这一行在下一步就会跟着变成新路由。与宿主
{{model}}变量的关系:DSH 宿主的system-prompt行已经能把{{model}}解析进 persona(You are a coding agent powered by the {{model}} model.),但只覆盖model,不含provider,且取的是派发时agent.options的值。本插件的注入额外给出 provider,并跟随请求级的路由变化(含故障转移切换),因此两者互补而非重复。
provider + model 配置一条路由,所有子代理跑在同一个模型上(功能一、二的退化形态)。reasoningEffort(如 high、medium、low);Web 界面从模型目录加载可用的强度并做声明校验。设置面板(设置 → 插件配置 → 子代理默认模型):配置一个或多个模型路由,支持 round-robin / random 分配策略与每路由推理强度。

效果验证:10 个子代理在 deepseek-v4-flash 与 Kimi-k3 之间 5/5 均衡分配(round-robin 实测)。

当前路由可见(功能三):对话流里实际出现的那一行 —— 「当前供应商/模型:workbuddy/deepseek-v4.1-flash」。这正是功能三的效果,同时也是它与提示词注入的分界:这行字渲染给你看,workbuddy/deepseek-v4.1-flash 这个信息不会进入模型上下文。

从 npm registry 安装:
npm install dsh-subagent-default-model
或通过 DSH 插件命令(等价,内部同样走 npm):
dsh plugin --profile desktop add dsh-subagent-default-model
发布到 npm registry。完整权威流程见仓库根目录 RELEASING.md(含 2FA 确认、tag 修正、代理、验证步骤、GitHub Release)。
要点速览:
# 1. 测试:npm --prefix plugin test
# 2. 更新版本号(plugin/package.json 的 version 字段)和 CHANGELOG.md
# 3. 提交并打标签
git add plugin/package.json plugin/CHANGELOG.md
git commit -m "chore: 版本升级至 X.Y.Z"
git tag -a vX.Y.Z -m "vX.Y.Z: <说明>"
git push origin main
git push origin vX.Y.Z
# 4. 发布到 npm(账号若开启 2FA,需在浏览器确认一步)
cd plugin
npm publish
# 5. 创建 GitHub Release(易漏!npm 发布成功不会自动建 Release)
cd ..
export PATH="/opt/homebrew/bin:$PATH" # 本机 gh 不在默认 PATH 上
gh release create vX.Y.Z \
--repo dingminhua/dsh-subagent-default-model \
--title "vX.Y.Z — <一句话>" \
--notes-file /tmp/rel-body.md \
--verify-tag
⚠️ 发布前先跑一遍测试:
npm --prefix plugin test。package.json的files字段已限定只发布lib/、icons/、cordis.patch.yml、LICENSE、README.md、README.en.md、CHANGELOG.md,test/和node_modules/不会进入发布包。⚠️ 第 5 步别漏:npm 发布与 GitHub Release 是两条独立链路,
npm publish成功不会自动建 Release。历史上有版本(v2.0.2、v2.0.7)就是在这里漏掉的。补救办法与批量核对脚本见RELEASING.md的「忘了创建 GitHub Release」一节。
本地安装(DSH Desktop / desktop profile):
# 在 ~/.dsh/profiles/desktop 下执行(或使用 dsh plugin 命令)
npm install dsh-subagent-default-model
# 或本地开发:dsh plugin --profile desktop add /路径/plugin(link: 安装,改码即时生效)
说明:
link: 安装:dsh plugin --profile desktop add /Users/dmh2002/DshProject/dsh-subagent-default-model/plugin,node_modules 里是源码软链,改代码后重启 DSH Desktop 生效全部 8 个 @deepseek-ai/* peer 声明为 >=0.1.7-rc.1 <0.3.0-0:支持 0.1.7 线及其后的整个 0.2.x 线(prerelease 与正式版都放行),0.3.0 起不再声明支持。
要理解这个区间为什么长这样,得先知道 DSH 怎么校验它。@deepseek-ai/dsh-app-boot 对每个 @deepseek-ai/dsh / dsh-* peer 执行:
semver.satisfies(runtimeVersion, range, { includePrerelease: true })
includePrerelease: true 关闭了 semver 的 prerelease 元组规则——预发布版本不再「缺少同元组载体就被拒」,而是直接按常规序比较。两个后果都是反直觉的:
| 上界写法 | 0.2.0-rc.1 | 0.2.0(正式版) | 说明 |
|---|---|---|---|
<0.2.0 | ✅ 放进 | ❌ 拒绝 | 最坏组合:预发布能装,正式版一发布就把 bundle 摘掉 |
<0.3.0 | ✅ | ✅ | 但会一并放进 0.3.0-rc.1,超出已验证范围 |
<0.3.0-0 | ✅ | ✅ | 推荐:0.2.x 全放行,0.3.0-rc.1 也挡住 |
上界写错时宿主不会降级运行:loadProfileDirectory() 对不兼容 bundle 直接抛错,该 bundle 落入 skippedBundles,启动时 stderr 输出 skipping profile bundle "dsh-subagent-default-model"——插件本体与设置卡片一起消失。
plugin/test/peer-range.test.mjs 是这条契约的回归护栏:它调用宿主同款的 semver.satisfies(..., { includePrerelease: true }),并逐条断言上表的结果。
优先用 Web 设置卡片(设置 → 插件 → dsh-subagent-default-model)。
也可以直接编辑 profile 的 patch 文件 ~/.dsh/profiles/<profile>/cordis.patch.yml:DSH 0.1.7 起设置就存在这里,段名是本插件的 Loader 条目 id dsh-subagent-default-model:
- id: dsh-subagent-default-model
name: dsh-subagent-default-model
config:
# 单模型
provider: deepseek-official
model: deepseek-v4-pro
# 或多模型:功能一(分配策略)+ 功能二(跨供应商故障转移)
provider: deepseek-official
models:
- model: deepseek-v4-pro
reasoningEffort: high
- provider: other-provider # 换一个供应商的模型
model: gpt-5.6
reasoningEffort: max
strategy: round-robin # round-robin(顺序) | random(随机)
failoverEnabled: true # 连接类失败时跨供应商切换
injectRouteContext: true # 把当前 provider/model 写进子代理上下文(默认开)
从 0.1.6 及更早版本升级:旧版把配置写在
~/.dsh/settings.yaml的subagent-default-model段。0.1.7 会在启动时把该文件一次性导入并改名为settings.yaml.imported,改名后不再回读。导入按段名直接当条目 id 用,而本插件的条目 id 是dsh-subagent-default-model,因此旧段不会被导入(宿主日志留一条section subagent-default-model … was not imported into entry subagent-default-model),旧值只留在改名后的文件里——需要手工搬到上面的config:里。
Windows / macOS / Linux 均受支持,且不需要任何平台专用配置。本插件的运行时代码是纯 JavaScript:lib/index.js(宿主半边)与 lib/client.js(客户端半边)不读取文件系统、不拼接路径、不派生进程、也不判断 process.platform——它只消费 DSH 宿主暴露的服务与事件,因此平台差异完全由 DSH 宿主承担。
已被检查并纳入持续验证的平台相关面:
.dsh/profiles/<profile>/cordis.patch.yml。Windows 上是 %USERPROFILE%\.dsh\profiles\<profile>\cordis.patch.yml(通常是 C:\Users\<你>\.dsh\...),与 macOS/Linux 的 ~/.dsh/... 指向同一处约定。package-lock.json 同时锁定 Windows 三套可选原生构建(win32-x64-msvc、win32-arm64-msvc、win32-ia32-msvc),npm 只安装与当前平台匹配的那一个;本插件的直接依赖 @deepseek-ai/schemastery 是纯 JS。core.autocrlf,Windows 检出可能得到 CRLF 源码。全部测试已在该形态下验证通过——解析源码的断言都基于子串而非行尾,因此 CRLF/LF 不影响结果。fileURLToPath 而非 URL.pathname。后者在 Windows 上会得到 /C:/... 并被 path.join 折成不存在的 \C:\...,属于只会在 Windows 上暴露的硬故障。npm test 直接调用 node --test(不带 glob),由 Node 测试运行器自行发现用例,不依赖 shell 展开——test/*.test.mjs 这类 glob 在 POSIX sh 下会展开、在 cmd/PowerShell 下会原样传入,行为不一致。CI 在 ubuntu-latest、windows-latest、macos-latest 三个平台上同时运行同一套测试,因此上述约定有持续验证而非一次性声明。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
provider | string | — | 字符串类型模型条目的 provider。 |
model | string | — | 单模型 id(向后兼容)。 |
models | array | [] | 模型条目列表(string 或 {provider, model, reasoningEffort?} 对)。≥2 项时功能一、二才有意义。 |
strategy | string | round-robin | 功能一的分配策略:round-robin(顺序轮换)或 random(随机)。 |
failoverEnabled | boolean | true | 功能二:子代理连接类失败时在 models 列表内跨供应商切换模型(仅 subagent)。 |
injectRouteContext | boolean | true | 功能三通路二:向子代理自己的上下文注入一行「当前 provider/model」的真实提示词(仅 subagent)。 |
reasoningEffort | string | — | 可选推理强度(如 high、max)。 |
开启 failoverEnabled(默认开启)后,子代理自身的循环遇到连接类失败时,插件会在 models 列表内按 strategy 自动切换模型并重试。完整说明见上文「功能二:跨供应商故障转移」,要点复述:
models 列表,可以切到另一个 provider 的模型,不限于同一家换型号。RATE_LIMIT、QUOTA、SERVER、TIMEOUT、TRANSPORT、EMPTY_RESPONSE;认证类:AUTH、INVALID_CREDENTIAL(密钥无效/过期,会切换并打 warn 日志)。其余码不切换。round-robin:按列表顺序切到下一个模型(队列)。random:随机挑一个模型(不判断之前是否用过)。models 少于 2 项时本功能不生效。reasoningEffort —— 换到新 provider/model 后按默认推理强度请求,避免把主模型的强度强加给不支持它的 provider。该机制基于官方 agent/request-error + agent/request 瀑布,且仅对 subagent 生效——主代理循环不会被切换。
功能三有两条独立通路,完整说明见上文「功能三」:
| 视图 | 呈现内容 | 依据帧 |
|---|---|---|
| 轨迹视图 | 一行「当前供应商/模型:provider/model」 | 官方 request/context |
| 对话视图 | 「当前供应商/模型」/「已切换到」/「继续使用」三类文案行 | 官方 request/header(按 reason 区分 initial / change / resume) |
两个视图都在 ctx.effect 内注册,且节点 kind 使用插件自有值(轨迹侧 trajectory-subagent-model,对话侧 chat-subagent-model-notice),不占用宿主内置 context kind —— 后者会被宿主的可见性规则过滤掉。
见上文的完整说明与样例文本。实现要点:
| 方面 | 做法 |
|---|---|
| 取值来源 | agent/request 瀑布结算后返回的 {provider, model}(含故障转移切换结果) |
| 注入时机 | 下一步的 agent/pre-step,此时该步消息列表仍可修改 |
| 去重 | 路由不变则不重复注入;路由变化则替换旧行 |
| 作用域 | 仅 origin === "subagent";主代理不碰 |
| 开关 | injectRouteContext,默认开启 |
| 消息来源 | plugin:dsh-subagent-default-model + form: "route-context"(v4 会话格式要求生产者自有 source.kind) |
两条通路互不替代:界面行不会进入模型上下文;提示词注入也不会显示在你的界面上。
请求携带显式 agentOptions
→ subagent-default-model 设置
→ 继承父会话路由
插件包装宿主 ctx.subagents 服务(start / startContinuable),覆盖所有派发路径 —— 内置的 subagent / subagent_fork 工具,以及任何调用该服务但未提供 agentOptions 的自定义工具。
本项目采用 MIT 许可证 开源发布,版权归属:Copyright (c) 2026 LaoDing。
MIT 许可证授予任何人免费处理本软件(包括使用、复制、修改、合并、发布、分发、再许可及出售副本)的权利,前提是所有副本或实质性部分均保留上述版权声明与本许可声明;软件按“原样”提供,不附带任何明示或暗示的担保。完整条款见 LICENSE。
FAQs
为 DeepSeek Harness 子代理配置默认模型:多模型顺序/随机分配、跨供应商连接失败故障转移,并在轨迹/对话视图显示当前供应商与模型,同时以一行真实提示词把当前路由注入子代理上下文。
The npm package dsh-subagent-default-model receives a total of 308 weekly downloads. As such, dsh-subagent-default-model popularity was classified as not popular.
We found that dsh-subagent-default-model demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
Cloudflare is acquiring Deno’s team, which will provide another year of bug fixes and security updates before ending support for the runtime.

Security News
Anthropic’s free OSS Scanner uses Mythos and other Claude models to find open source vulnerabilities and send maintainers reports with proposed fixes.

Security News
On Front Lines’ Early Adopters: CISO podcast, Andrew Becherer shares lessons from Datadog, weighs the long-term costs of AI-built tools, and explains how founders can actually gain a CISO’s trust.