前言¶
在 DSH 里跑 Agent 时,模型接口会因为限流、5xx、鉴权或适配器缺失而失败。若只依赖同一 provider 上反复重试,整体挂掉时仍会在坏模型上空转;若手改配置换模型,又容易打断会话节奏。dsh-plugin-model-failover(仓库 Gpan666/dsh-plugin)面向「跨轮、跨步」的模型可用性:当前候选不健康时,在下一次 preStep 之前通过 agent.model.select() 换到下一个健康候选,并对失败模型做冷却与可选后台探活。维护者为 Gpan666;npm 包名为 dsh-plugin-model-failover,版本 1.0.0(见仓库 package.json),许可证 MIT。
下文按「能力边界 → 机制 → 安装配置 → 运行时接口 → 注意点」说明,事实以仓库 README 与 package.json 为准。
这是什么¶
一句话:DSH 的模型故障转移插件——当前模型变得不可用时,下一步(或下一条消息)自动换到下一个健康的候选模型。
依赖 Cordis 的 agents 服务(DSH 默认提供),peer 依赖 @deepseek-ai/cordis(>=4.1.0-0 <5.0.0-0)。插件加载后向上下文注册 modelFailover 服务。
能力边界:能做与不能做的¶
README 结合 dsh-agent-loop 源码说明了架构约束,避免错误预期。
不能:同一 step() 内失败后换模型继续¶
在 step() 的重试循环里,decision.selection 在整个 step() 生命周期内固定;prepareRequest() 禁止在 agent/request 中直接改 provider/model(会要求先 agent.model.select())。step() 抛错后本轮以 error 结束。agent.model.select() 只对下一次 preStep() 生效,对已在 step() 内的 retry 无效。因此「本步失败立刻换模型接着写」需要改 agent loop 本身,不属于本插件范围。
能:跨轮/跨步故障转移与配套能力¶
| 能力 | 机制 |
|---|---|
| 跨轮/跨步故障转移 | agent/pre-step 中若当前模型处于冷却,调用 agent.model.select() 换到下一个健康候选 |
| 失败即时降级 | 监听 agent/request-error 记账,该模型立刻进入冷却,下一步不再选它 |
| 配置类错误直判 | AUTH / NO_ADAPTER / MISSING_CREDENTIAL / INVALID_MODEL_INFO 重试无意义,直接冷到上限 |
| 后台探活 | 定期打 1 token 请求,提前发现掉线模型 |
| 粘滞(sticky) | 当前模型健康就不换,减轻风格跳变,保留 KV 缓存 |
| 指数退避 | 首次冷却 60s,逐次翻倍,由 maxCooldownSec 截断 |
与 @deepseek-ai/dsh-llm-retry 互补:retry 负责同一模型在 step() 内的重试(限流、5xx、超时等);本插件负责模型整体不可用时的换代,让下一条/下一步用健康模型。本插件默认不抢 retry(claimRetry 默认为 false),先 next() 交给下游,用尽 retry 预算失败后才终止本轮。
安装与启用¶
在 profile 目录安装依赖:
pnpm add dsh-plugin-model-failover
在 profile 的 cordis.patch.yml 中插入插件声明:
- insert:
- id: model-failover
name: 'dsh-plugin-model-failover'
安装前应自行查阅仓库源码与 MIT 许可证;插件以当前 DSH 进程权限运行,探活与正常推理一样走你已配置的 llm 服务。
配置项¶
| 键 | 默认 | 说明 |
|---|---|---|
enabled |
true |
总开关 |
candidates |
两个 deepseek 模型 | 候选表,一行一个 provider/model,# 后为注释 |
failureThreshold |
1 |
连续失败几次判坏 |
cooldownSec |
60 |
初始冷却,逐次翻倍 |
maxCooldownSec |
600 |
冷却上限 |
sticky |
true |
健康就不换 |
probeTimeoutSec |
8 |
单次探活超时 |
probeIntervalSec |
120 |
探活周期 |
claimRetry |
false |
为 true 时本插件接管 request-error 的重试(仍是同一模型重发) |
restoreOnStart |
true |
预留:启动恢复历史健康记录 |
候选写法(三种等价):
deepseek-official/deepseek-v4-flash
deepseek-official|deepseek-v4-flash
deepseek-official deepseek-v4-flash
若单条回复不能丢,可同时安装 dsh-llm-retry,与本插件分工如上。
典型用法:modelFailover 服务¶
插件加载后可通过 Cordis 上下文获取服务并查询或干预状态:
const svc = ctx.get('modelFailover')
svc.status() // { enabled, candidates: [{provider, model, ok, coolingDown, ...}], lastSwitch }
svc.probe() // 立刻探活一遍
svc.reset() // 清空健康记录
svc.updateSettings({ candidates: '...' }) // 运行中改配置,不重启
日常无需调用上述 API 时,只要在 candidates 中列出备用 provider/model,插件会在 pre-step 与 request-error 路径上自动维护健康状态与切换。
网络与隐私¶
- 探活请求走 DSH 自带的
llm服务(你已配置的模型接口),不连接 README 未列出的第三方。 - 插件不写盘、不读 Cookie、不处理消息正文(健康状态目前主要在内存,重启后重置;
restoreOnStart为后续持久化预留)。
适用场景与注意¶
适合:多模型候选、希望某条线路整体故障时自动让后续步骤落到备用模型,并愿意接受「切换仅在 step 边界生效」的 DSH 架构。
注意:
- 探活消耗 token:每次 1 token;默认 120 秒周期与 2 个候选时,README 估算约一天 1440 次调用。可调长
probeIntervalSec或减少候选。 claimRetry只改变谁处理重试次数,不会在单步内换模型。- 社区目录页 skillhub.cn/plugins/Gpan666/dsh-plugin 与 GitHub 仓库便于检索;DSH 生态强调「一切皆插件」,该目录为社区站点,与 DeepSeek / 幻方无 README 所载的官方从属关系。
结尾¶
dsh-plugin-model-failover 把「坏模型冷却 + 下一步选健康候选」做成可配置插件,并与 dsh-llm-retry 在同一轮内的重试分工明确。使用前请确认你接受 step 边界切换与探活 token 成本,并在 profile 中按 README 完成 pnpm add 与 cordis.patch.yml 配置。
- 目录页:https://www.skillhub.cn/plugins/Gpan666/dsh-plugin
- 源码与文档:https://github.com/Gpan666/dsh-plugin