跳到主内容

dsh-llm-fallbacks

13Star2Fork0Issue0Watching

当 LLM 请求持续失败(鉴权、配额、限流)时自动沿降级链切换 provider/model,让 DSH 代理任务不被模型问题中断。

机审证据5/5方法论数据来源安装命令持续维护DSH 版本风险扫描
机审证据安装命令仓库已核验dsh-plugin Topic许可证READMEAI 百科
语言
TypeScript
License
MIT
分支
main
deepseek-harnessdeepseek-harness-plugindshdsh-pluginfallbackssubagents

安装

命令web profile
$ dsh plugin --profile web add dsh-llm-fallbacks

在终端中运行以上命令,通过 dsh CLI 安装此插件。可在右上角切换 Profile。 第一次用 dsh?看这篇新手教程

对话式安装

帮我安装 DeepSeek Harness 插件 omdsh-dev/dsh-llm-fallbacks:先查看仓库 https://github.com/omdsh-dev/dsh-llm-fallbacks 确认安全性,然后执行安装命令并验证插件加载成功。

把这段指令粘贴给 DSH Web GUI 里的助手,由它代你完成安装与验证。

一句话定位

当 DSH 代理的 LLM 请求反复失败(鉴权错误、配额耗尽、429 限流)时,这个插件会自动沿降级链切换到下一个可用的 provider/model,让当前步骤直接在新模型上继续,不让模型问题打断整个任务;web 端与 dsh-tui 都共用同一套配置。

核心能力

  • 自动故障降级:在 agent/request-error 水龙头里监听到配置的失败码时,按角色解析出的降级链依次往下走,挑出当前可用且不在冷却里的下一个模型,自行恢复(不再走宿主默认重试)
  • 时间槽路由:按 fallbacks.tz(默认 Asia/Shanghai)的时钟窗口切换"有效的全天链",高峰低谷用不同模型,跨过窗口后下一次根请求自动换链(不算失败切换、不占冷却)
  • 虚拟 Auto 模型:插件启用后向宿主 LLM 适配器目录注入一行 FallbacksChain / Auto,把它当主模型选用就把整条当前有效降级链作为根代理的主模型
  • 三阶段角色解析:子代理首请求依次按 显式 agentPreset → 声明规则 → 可选的 LLM 自动匹配 解析角色,并把解析到的角色链头模型注入首请求
  • 冷却与回切:被切走或失败的模型在 cooldownMs 内不再被选中,到期后依据 revertPolicy 自动回到主模型;每步还有 maxSwitchesPerStep 安全阀防止链无限走
  • 零配置即空操作:enabled: false 且无任何 chain 时插件是完全 no-op,不会做任何拦截和切换

技术实现

  • 语言: TypeScript(host 端 ESM,client 端 React + TSX)
  • 关键依赖: @deepseek-ai/cordis(cordis 4 插件框架)/ @deepseek-ai/schemastery(设置 schema 与默认值)/ @deepseek-ai/dsh-settings(installSettingsSection 注册设置命名空间)/ react(web 端 FallbacksCard 与 ConversationFallbackSwitch)
  • 架构模式: 纯 mount 插件——通过 bundle/cordis.patch.yml 在 profile 的 bundle 栈里插一行(必须在 dsh-base 的 llm-retry 之后注册,这样插件的 agent/request-error 监听器在 llm-retry 重试预算耗尽后才接管);host 端 apply() 在 agent/request-error 与 agent/request 两个水龙头接链决策,client 端通过 dsh.client.inject 把设置卡片注入 web 设置侧栏;配置读写走插件自己的 /api/fallbacks/get|set|reset RPC 通道
  • 入口文件: src/index.ts(host 端:apply(ctx, config) 入口、FallbacksService 注册、gateway 注册、commands 注册)/ src/client/index.ts(client 端:设置卡片 FallbacksCard、会话切换徽章 ConversationFallbackSwitch)

适用场景

适合同时使用多家 provider 的 DSH 用户:单一 provider 偶发鉴权、配额、限流是长任务最常见的失败原因,启用后可以让代理在主模型短暂异常时静默切到备用模型继续工作;按时段切换有效链的特性也适合把便宜的模型放在高峰、旗舰模型放在低峰。需要注意的是,rootChain 末尾必须是 deepseek-official/deepseek-v4-flash 或 deepseek-official/deepseek-v4-pro 之一作为最后兜底,不支持其它模型作为整链终点。

前置依赖与兼容性

依赖最低版本说明
DSH^0.1.1-rc.1peerDependencies 声明的 @deepseek-ai/dsh-* 系列;运行时由 dsh 宿主以 bundle 形式提供,本机 npm 注册表按 autoInstallPeers 拉取(README 徽标 DSH-0.1.1--rc.1)
Node.js>= 22package.json 的 engines.node;构建脚本需要 pnpm ≥ 10(仅本地目录安装需要)
平台跨平台纯 TypeScript,无 OS / CPU 限制字段
原生模块无无 node-gyp 原生依赖,未使用 node:sqlite 等内置原生 API

安装方式

dsh plugin --profile web add github:omdsh-dev/dsh-llm-fallbacks

配置项

所有配置都在 DSH 共享设置文档的 fallbacks: 命名空间下,启用即代表放弃 dsh 的内置降级兜底:

配置类型说明默认值
enabled布尔总开关。false 时插件不拦截任何请求,行为与未安装完全一致false
triggerCodes字符串数组触发降级决策的失败码(AUTH / QUOTA / RATE_LIMIT),代码不在此列表的请求会被原样放行['AUTH', 'QUOTA', 'RATE_LIMIT']
rootChain字符串数组主代理的全天降级链;最后一项必须恰好是 deepseek-official/deepseek-v4-flash 或 deepseek-official/deepseek-v4-pro 二选一(兜底模型),前面才是按顺序走的降级模型[]
timeSlots数组时段行;预设行(kind: preset)使用冻结窗口(梁文峰 / 梁文谷 / GLM峰 / GLM谷,固定 UTC+8 不可调),自定义行(kind: custom)可设 start / end / days;首个窗口命中当前时刻的行作为下一次根请求的有效链[]
roles.list数组声明的角色集合;每项 id(唯一小写字母数字短横线 ≤32 字符,inherit 是保留字不能用作 id) + persona(人格描述,自由文本)+ 可选 chain(专用降级链)+ 可选 fallback('inherit-root' / 'none')[]
roles.rules数组子代理规则:按 provider / model 模式匹配首个命中规则的子代理,把它路由到 roles.list 里的某个角色或内置的 inherit。root 永远不匹配规则,直接走 rootChain[]
cooldownMs数字(毫秒)失败/被切走的模型在多少毫秒内不被重新选中;过期之后依据 revertPolicy 处理300000(5 分钟)
revertPolicy枚举冷却到期后的回切策略:'cooldown-expiry' 到期回到主模型,'never' 本会话一直停在最后一个 fallback'cooldown-expiry'
maxSwitchesPerStep数字单步内允许的最大降级切换次数;超过后停止切换,保留原始错误语义,防止降级链放大延迟8
alwaysModeRetryCap数字当 provider 是 retryPolicy.mode: 'always' 时,多少次重试后强制切走;0 表示禁用5
presets枚举是否在 apply 时自动声明 7 个内置预设角色(task / sonic / scout / designer / librarian / reviewer / security-reviewer)'bundled'
roleAutoMatch布尔子代理的角色三阶段解析里是否启用第三阶段 LLM 自动匹配;false 时只剩显式 agentPreset + 规则两条路径true
tz字符串 IANA 时区时段行匹配使用的时区;只要存在任意预设时段行就锁定为 Asia/Shanghai'Asia/Shanghai'

常见问题

Q: 装上之后代理行为没任何变化,是没生效吗?

A: 不是,是配置处于"零配置 no-op"状态。默认 enabled: false 且 rootChain 是空数组,插件会主动跳过对所有请求的干预。需要在 Fallbacks 设置卡或 YAML 里把 enabled 设为 true,再加上一条至少含 V4 官方模型作为末项的 rootChain。

Q: 配置改完之后什么时候生效?

A: 保存即生效。host 端通过 settings 的 onChange 钩子读取最新配置,热更新角色 id 集合、maxSwitchesPerStep 等所有设置;不需要重启 dsh 也不需要新建会话。

Q: rootChain 末尾必须用某个特定模型,是不是太死板?

A: 是故意设计的:rootChain 末尾是整个降级链的最终兜底,插件把它和虚拟 Auto 行绑定,期望它指向能兜住所有场景的官方旗舰/闪速模型。其它模型作为末项启动时只会告警、走老版本兼容路径,但 web 设置卡和 gateway 会拒绝保存带非官方末项的 chain。

Q: 模型选择器里那个新出来的 Auto 怎么用?

A: 它是注册到宿主 LLM 适配器目录的虚拟行(provider 是 FallbacksChain,模型 id 是 Auto),开启插件即出现。选中后根代理的主模型就用 rootChain 当前有效窗口里的第一项;选真实模型则保持"主模型 + 失败后才降级"的传统行为。Auto 出现的条件只有 enabled: true,无论 chain 是否已配置都会显示,chain 不合规时仅拒绝接管、不会隐藏。

Q: 子代理会话也要配置降级链吗?

A: 不强制,但建议:未匹配任何规则的子代理默认走内置的 inherit 角色,等同于直接走 rootChain;想给特定子代理用特定链就在 roles.list 声明一个角色(含 chain),再用 roles.rules 按 provider / model 模式把它路由过去。LLM 自动匹配默认开启,配 roles.list 之后会自动为子代理挑最合适的角色。

Q: 怎么关掉某一类失败不触发降级?

A: 把对应的失败码从 triggerCodes 移除。默认只有 AUTH / QUOTA / RATE_LIMIT 三个,5xx 类的可重试错误由 dsh 自带的 llm-retry 先吃回退预算,超出后才进入这条降级链,无需额外声明。

Q: dsh-tui 终端用户怎么编辑配置?

A: 在 /settings 屏幕里找 fallbacks 段(需要 dsh-tui ≥ v0.8.5)。布尔(enabled、roleAutoMatch)渲染为开关,单选(presets、revertPolicy)渲染为选择器,数字渲染为数字输入,复杂结构(rootChain、timeSlots、roles.list、roles.rules)是 JSON 文本框。非法草稿(坏 JSON、不合规 chain、坏时段行)会阻止保存,不会写坏配置。

Q: 升级到新版会不会丢配置?

A: 不会,配置写在 DSH 共享设置文档里,插件只读写自己注册的 fallbacks 命名空间,不动其它字段。注意:升级后如果你的旧配置没有显式 enabled 字段,schema 解析默认到 false,插件会突然变成 no-op,请主动加上 enabled: true。

上手难度

进阶 — 需要理解降级链、cooldown、角色匹配等概念,并按要求写一段合理的 fallbacks: YAML(或用 web 卡片点点鼠标);只想"装上就有用"还不够,必须先配置至少一条 chain 才会从 no-op 模式脱离。

已知问题与限制

  • 从 <0.2.2 版本升级上来的会话可能无法加载:旧版本会持久化写 fallbacks/switch 会话事件,新版 dsh 的会话读取模块识别不了(插件和宿主解析的是不同模块实例),新插件已停止写入此类事件,但历史会话需要运行 pnpm repair:fallbacks-switch-logs -- --apply --backup(先停 dsh)把老事件标记为可忽略,会保留一份 .bak 备份
  • rootChain 末尾必须是官方 V4 模型(deepseek-official/deepseek-v4-flash 或 deepseek-official/deepseek-v4-pro 二选一),web 设置卡和 gateway 在保存时会拒收任何其它尾节点;想保留非官方末项只能在 YAML 里手写,startup 会有一次告警、运行时会按老版本兼容走完降级链路
  • 只要存在任意 kind: preset 时段行,tz 就被锁定为 Asia/Shanghai,预设时段窗口是写死的 UTC+8 常量,无法在 UI 里调整;自定义时段行不受此限制
  • 单步内的降级切换不能突破 maxSwitchesPerStep,超过后停止切换并保留原始错误语义;这是有意的安全阀,避免降级链死循环放大延迟
  • 没有 rootMode 这类配置字段:根请求到底走"chain 为主模型"还是"主模型失败再 chain"两种模式,由模型选择器里选了 Auto 还是真实模型决定,调用方不要在 YAML 里找这种配置
  • roleAutoMatch 默认开启会让插件在子代理首请求时多发一次受限 LLM 调用(超时 5 秒、32 token 上限;src/automatch.ts:52-55)来挑选角色,断网/超时/没声明角色都会自动回退到 inherit,不会抛错
  • roles.rules 不匹配根代理会话(PR #62 反馈):根请求只能走 rootChain;如要给根代理配特定链,只能改 rootChain 本身

查看使用指南 →

该插件的安装步骤、关键要点、FAQ 与兼容性说明(基于已收录字段派生)。

收录徽章

Listed on deepseek-plugin.org
[![Listed on deepseek-plugin.org](https://img.shields.io/badge/listed_on-deepseek--plugin.org-007EC6)](https://deepseek-plugin.org/plugins/omdsh-dev/dsh-llm-fallbacks)

把这段 markdown 粘贴到你的 GitHub README,链接回本插件详情页。徽章只声明已被本站收录,不代表安全认证。

返回插件目录