JianTG
dsh-auto-model-router
根据问题复杂度自动切换模型
- Stars
- 0
- Language
- JavaScript
- Created
- Aug 16, 2026
- Updated
- Aug 16, 2026
Introduction
dsh-auto-model-router
DSH(DeepSeek Harness)cordis 插件:按任务复杂度在 deepseek-v4-flash(基线)与 deepseek-v4-pro(升级)之间自动路由,只升不降,绝不回合中途切换模型。
效果
- 简单问题(寒暄/单点问答/短消息)→ flash(便宜、快)
- 复杂任务(代码/架构/重构/长任务/关键词命中)→ 自动升 pro(不干砸重活)
- 拿不准的"中间态"消息 → 让 flash 分类器确认一次(3s 超时兜底,失败=不升级)
- 你手动
/model选 pro → 永远终局,插件绝不覆盖 - 路由决策全自动,回合内锁定,重启/恢复后可重放
安装
# 1. 装进 web profile(自动注册,无需改任何配置文件)
dsh plugin --profile web add <本目录路径或 git 地址>
# 2. 激活前置:把默认模型改成 flash(任选其一)
# a) 界面上用 /model 选一次 DeepSeek-V4-Flash
# b) 或编辑 ~/.dsh/settings.yaml:
agent-default-model:
provider: deepseek-official
model: deepseek-v4-flash
reasoningEffort: off
# 3. 重启 dsh web
卸载/更新:dsh plugin --profile web remove|update dsh-auto-model-router。
本机注意:npm/pnpm 联网需
NODE_OPTIONS=--use-system-ca(本机 Node 自带 CA 证书过旧)。
配置(~/.dsh/settings.yaml 的 auto-model-router 段,热更新)
auto-model-router:
enabled: true # 总开关
baseProvider: deepseek-official
baseModel: deepseek-v4-flash # 基线模型(插件只管理这一对的升级/回落)
proModel: deepseek-v4-pro # 升级目标
upgradeReasoningEffort: high # 升级到 pro 时的推理强度(off/high/max)
classifierEnabled: true # 中间态是否调用 flash 分类器
classifierTimeoutMs: 3000
lengthStrong: 400 # 去空白长度 ≥ 此值 → pro
lengthWeak: 40 # 去空白长度 ≤ 此值 → flash
keywordsStrong: [重构, 架构, 设计, 排查, 分析, 审计, 优化, 测试, 实现, 开发, 修复, bug, 多文件, 批量, review, 迁移, 方案, implement, debug, refactor, migrate, migration, optimize, architecture, deploy, plugin]
原理(摘要)
两个 prepend 瀑布监听器 + 自有 sidecar(完整设计见 DESIGN.md,红队评审留痕见 docs/red-team-review.md):
agent/pre-step(每回合第一步)→ 启发式分类 → 中间态问 flash → 决策落盘 sidecar
agent/request(prepend 最外层)→ 读决策:pro 且基线 flash → 升级;flash 且上回合系插件升级 → 回落
关键语义:
- 排序:插件以
{ prepend: true }注册在最外层;内置模型选择层(installModelSelection)恒在内层——插件返回值生效,且绝不覆盖你的手动选择(只认"默认模型=flash"时回落)。 - 痕迹 sidecar:
~/.dsh/plugins/auto-model-router/<sessionId>.jsonl(withFileLock串行写 + 原子替换)。绝不写 session 日志——DSH 的事件类型是封闭白名单,写未知类型会让会话重启后无法加载。 - 可重放:决策按 (sessionId, turn) 幂等重算,HMR/重启后回合内决策不变。
- 失败安全:插件任何异常 → 透传原配置,主请求照常;下游异常原样传播。
已知边界(文档化)
agentDefaultModel服务缺失的 profile(理论上)→ 只升级不回落。- 手动
/model选 pro 时若"保存为默认"失败(低概率)→ 下一回合可能被回落覆盖;重启后此边界消失。 - 分类器调用是真实计费但不进界面 token 统计(meter 只统计会话事件);分类调用账本 = sidecar 中
source: classifier的记录。 - subagent/后台任务同样按各自消息自动路由(重活自动上 pro)。
- 启发式是强信号优先:消息里带代码块(```)或命中强关键词就会判 pro,哪怕正文只是一句查询——这是有意为之(重活宁上 pro,不干砸),规则见
lib/classify.js。
验证与审计
node --test # 单元测试(28 条)
node scripts/experiment.mjs <会话日志> # 用真实消息评估启发式命中率
node scripts/inspect-session.mjs <日志> # 解码会话日志,按回合打印实际模型
node scripts/summarize.mjs [sidecar目录] # 汇总 sidecar:pro/flash 占比、分类器调用次数
node scripts/e2e-web.mjs <url> <cwd> # 全自动 web 端到端(需测试实例)
node scripts/e2e-restart.mjs prepare|verify … # 跨重启回落验收
路由审计:sidecar 每条记录含 {sessionId, turn, decision, source}——对照 inspect-session.mjs 的每回合实际模型,即可人工复核每一次自动路由是否正确;误判的规则可随时在 settings 里调整(改完热更新生效)。
开发
pnpm install # 本机需 NODE_OPTIONS=--use-system-ca
node --test
提交信息遵循项目仓库规范(中文、单变更集)。插件以 link: 方式装进 profile,改代码后重启 dsh web 即生效。