# dsh-auto-model-router **Repository Path**: bm999/dsh-auto-model-router ## Basic Information - **Project Name**: dsh-auto-model-router - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-15 - **Last Updated**: 2026-08-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # dsh-auto-model-router DSH(DeepSeek Harness)cordis 插件:按任务复杂度在 `deepseek-v4-flash`(基线)与 `deepseek-v4-pro`(升级)之间**自动路由**,只升不降,绝不回合中途切换模型。 ## 效果 - 简单问题(寒暄/单点问答/短消息)→ **flash**(便宜、快) - 复杂任务(代码/架构/重构/长任务/关键词命中)→ **自动升 pro**(不干砸重活) - 拿不准的"中间态"消息 → 让 flash 分类器确认一次(3s 超时兜底,失败=不升级) - 你手动 `/model` 选 pro → **永远终局**,插件绝不覆盖 - 路由决策全自动,回合内锁定,重启/恢复后可重放 ## 安装 ```bash # 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` 段,热更新) ```yaml 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/.jsonl`(`withFileLock` 串行写 + 原子替换)。**绝不写 session 日志**——DSH 的事件类型是封闭白名单,写未知类型会让会话重启后无法加载。 - **可重放**:决策按 (sessionId, turn) 幂等重算,HMR/重启后回合内决策不变。 - **失败安全**:插件任何异常 → 透传原配置,主请求照常;下游异常原样传播。 ## 已知边界(文档化) 1. `agentDefaultModel` 服务缺失的 profile(理论上)→ 只升级不回落。 2. 手动 `/model` 选 pro 时若"保存为默认"失败(低概率)→ 下一回合可能被回落覆盖;重启后此边界消失。 3. 分类器调用是**真实计费**但不进界面 token 统计(meter 只统计会话事件);分类调用账本 = sidecar 中 `source: classifier` 的记录。 4. subagent/后台任务同样按各自消息自动路由(重活自动上 pro)。 5. 启发式是**强信号优先**:消息里带代码块(```)或命中强关键词就会判 pro,哪怕正文只是一句查询——这是有意为之(重活宁上 pro,不干砸),规则见 `lib/classify.js`。 ## 验证与审计 ```bash 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 # 全自动 web 端到端(需测试实例) node scripts/e2e-restart.mjs prepare|verify … # 跨重启回落验收 ``` **路由审计**:sidecar 每条记录含 `{sessionId, turn, decision, source}`——对照 `inspect-session.mjs` 的每回合实际模型,即可人工复核每一次自动路由是否正确;误判的规则可随时在 settings 里调整(改完热更新生效)。 ## 开发 ```bash pnpm install # 本机需 NODE_OPTIONS=--use-system-ca node --test ``` 提交信息遵循项目仓库规范(中文、单变更集)。插件以 `link:` 方式装进 profile,改代码后重启 `dsh web` 即生效。