DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

wanghaixu-hai /

wanghaixu-hai/dsh-effort-router

Verified

DSH 模型分流插件:按每一轮请求的难度自动选模型与思考强度——简单问题走便宜快模型,难题才叫强模型。零 token 规则判定,只在判不准的灰区问一次小模型。发送前把本轮计划同步到输入框的模型框,座位=实际;不改你的默认模型。

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@103c1551

🧭 dsh-effort-router

给 DeepSeek Harness 装一个"按题目难度自动换模型"的路由器。 简单问题走便宜快模型,难题才叫强模型;规则判定 零 token,只有判不准的灰区才问一次小模型。 发送前会把本轮计划同步到输入框那个模型框,所以座位显示的就是这一轮真正会用的模型。

English summary ↓ · 更新日志 · License: MIT


这是什么?

这是一个 DSH 插件(DeepSeek Harness plugin),包名 dsh-effort-router。DSH 的插件就是普通的 npm 包,通过 package.json 里的 dsh 字段向宿主声明自己:

{
  "name": "dsh-effort-router",
  "dsh": {
    "bundle": { "patch": "./cordis.patch.yml" },   // 往宿主插件树里插一行:{ id: model-router, name: dsh-effort-router }
    "client": { "platform": "web", "inject": [...] } // 另半个自己在浏览器里跑(输入框开关、设置面板)
  }
}

安装到某个 profile 之后,它会挂在 agent/request 这条请求水路上,在每次真正调用模型之前决定这一轮用哪个 provider / 模型 / 思考强度。


关于名字(重要)

这个插件叫 dsh-effort-router,中文名仍是「模型分流」。原因很直白:npm 上的 dsh-model-router 是别人的包(thedeveloper256,已发到 0.7.0,是「角色制路由」,与本项目无关)。npm 不允许重名发布,所以:

  • 不要执行 dsh plugin add dsh-model-router —— 那会装上别人的插件;
  • 用 tarball(dsh plugin add /path/to/dsh-effort-router-0.3.0.tgz)或从本仓库安装;
  • GitHub 仓库名保留 dsh-model-router(改名可选,不影响使用)。

本插件的内部标识保持原样:HTTP 前缀 /api/model-router、插件树 entry id model-router、设置页 tab id。只有包名变了。

它解决什么问题

你的痛点 手动做法 这个插件
问个「1+1」也烧着最贵的模型 每次手动切 自动判 simple → 便宜快模型 + 低思考强度
全程用便宜模型,难题质量掉 猜什么时候该切 自动判 hard → 强模型 + MAX 思考强度
贴一张报错截图,模型不会看图 先手动换 vision 模型 图片档独立成档,思考强度按难度给(low/high/max)
切来切去很烦,还怕改了自己的设置 — 每轮请求级覆盖:不动你的会话选择、不动你的全局默认模型

一句话:把"该用多贵的脑子"这件事自动化,且不留下副作用。


30 秒上手

# 从 tarball 安装(把路径换成你下载到的文件)
dsh plugin --profile web add /path/to/dsh-effort-router-0.3.0.tgz

# 或从源码目录安装
dsh plugin --profile web add /path/to/dsh-effort-router

然后 重启宿主(host 半边是 Node 进程加载的,必须重启;client 半边只需刷新页面)。

开机后你会看到:

  • 输入框右侧多了一个开关:🧭 分流:开 / 关 —— 点一下即时生效,不用进设置、不用找保存按钮;
  • 输入框下方多了一行读数带:🧭 本轮实际 deepseek-v4-flash@high · 档位 standard;
  • 设置 → 插件 → 🧭 模型分流 里有完整面板:分档映射、图片档强度、灰区判定、分类测试、最近决策。

工作原理

四个档位

档位 何时命中 默认目标(按你的模型目录自动选)
① simple 闲聊、单点问答、小改动 便宜快模型 @ low
② standard 常规问答(规则判不准时交给小模型裁定) 便宜快模型 @ high
③ hard 原理/机制/架构/多步/长文/代码块 强模型 @ max
④ vision 本轮带图 能收图的模型,强度按难度 low / high / max

档位映射可以完全手写覆盖(面板下拉选),留空即用"自动推荐"。

判定规则(零 token)

加分(越难越高)

信号 权重
为什么 / 原理 / 本质 / 深层 / 底层 / 机制 / 论证 / 证明 +2
架构 / 设计 / 重构 / 迁移 / 优化 / 调优 / 方案 / 对比 / 取舍 / 选型 +2
并发 / 分布式 / 一致性 / 事务 / 缓存 / 索引 / 性能 / 安全 / 漏洞 +2
代码块 ``` +2
帮我做 / 实现一个 / 开发一个 / 搭建 / 集成 / 部署一整套 +2
多个 / 分步 / 先…再…最后 / 步骤 / 流程 / 全流程 / 端到端 +1
文本 >800 字 → +2;>300 字 → +1 —

减分(越像小事越低):以 你好/在吗/谢谢/好的/ok/hi 开头 −3;是什么/多少/几/谁/哪里/哪年 −1;改一下/换成/删掉/加上/重命名 −1;短于 30 字 −1;≤16 字且非疑问句再 −1。

图片信号:带图 + 配文含 报错/日志/代码/修复/排查/定位/500 等 +2;多张图 +1;只有图没配文 +1(不会再被当成"小事")。

合计 ≥3 → hard,≤−2 → simple,其余 standard。

灰区判定(判不准时才花一次小调用)

规则落在 standard 这个最不可靠的中间带时,插件会把这一轮交给一个便宜模型判一次难度(maxTokens: 8、4 秒超时、失败即退回规则)。明显简单和明显困难的轮次一次调用都不花——所以像「为什么这段会内存泄漏?setInterval(()=>{},100)」这种"差 1 分"的句子,也能自己走到 MAX,不需要你维护任何关键词表。

每轮请求级覆盖

你发消息 ──> 客户端(开关 / 计划同步 / 读数带)
                 │
                 ▼
           宿主 agent/request 水路
                 │  ① 分类:规则 →(灰区)小模型
                 │  ② 记忆:手选?我们设过的?会话开局?
                 │  ③ 覆盖这一次请求的 provider/model/reasoningEffort
                 ▼
             实际模型调用(你的会话选择不变)

开关与取舍(重要,请先读这段)

开关 默认 作用 代价
启用自动分流 开 总开关。关掉后宿主直接放行,完全不碰任何东西 —
尊重手动选择 开 你手动在座位上选过的模型,插件让开(决策日志里记 skip:manual) —
记录决策日志 开 每次判定写一行 JSONL 极小磁盘
灰区判定 开 见上,让"不靠关键词"成为可能 standard 轮多一次小调用(约 8 token 输出)
座位同步 无开关,始终生效 发送前把本轮计划写进会话选择:座位框显示的就是本轮真正要用的模型,带图轮自动落到图片档(所以文本模型会话也能直接发图) 每轮一次会话选择写入——座位会跟着计划走,这正是设计目标;全局默认模型先读走再写回,不会被动

几个开关点一下立即生效(立即写盘 + 让宿主的计划缓存失效),不需要滚到面板底部再点保存。

座位 = 本轮实际(这是设计,不是巧合)

模型座位渲染的是会话选择,而分流是每轮请求级决定的。为了不让两者打架,插件在每次发送前多做一步:

你按下发送
   │
   ├─ POST /api/model-router/preview   本轮的文字 + 图片张数(与正式判定同一套代码路径)
   │     返回:目标模型@强度,以及"这是不是你自己手选过的"
   ├─ 你没手选过 → 把目标写进会话选择(座位随之刷新)
   │     写之前先读走你的全局默认模型,写之后立刻还回去
   └─ 真正发送(宿主的请求水路再确认一次同样的目标)

三条性质因此同时成立:

  1. 座位 = 本轮实际:输入框里显示什么模型,这一轮就真的用什么模型;
  2. 带图轮自动落到图片档:计划本身就是 vision 目标,harness 的图片准入检查自然通过(不再需要单独的"带图自动切"开关);
  3. 你手选的模型绝不会被覆盖:预览返回 manual 标志时客户端原地不动,宿主也在同一轮跳过它,并在决策日志里记 skip:manual。

输入框下方那行读数带保留——它额外显示档位(simple/standard/hard/vision),与座位同源,不会再互相矛盾。


面板一览

设置 → 插件 → 🧭 模型分流

  • 📡 最近一次实际请求:档位 / 难度 / 领域 / 实际模型 / 你的输入(每 5 秒刷新,只读)
  • 开关:启用 / 尊重手动选择 / 记录日志 / 带图自动切模型 / 灰区判定
  • 分档映射:四个档位分别用哪个厂商、哪个模型、什么思考强度(留空=自动推荐)
  • 图片档的思考强度:简单 / 常规 / 困难 三档分别给 low / high / max
  • 强制关键词(可选,默认空):命中即强制某档,完全绕开打分
  • 分类测试:输入一句话 + 选配图张数(0/1/2),立刻看到判定与目标模型——不用真传图
  • 最近决策:时间 / 档位 / 难度·领域 / 判定依据 / 路由(from → to)/ 你的输入

HTTP API(面板用的那几个,可脚本调用)

curl -s localhost:3080/api/model-router/state           # 配置 + 目录 + 上次决策 + 运行中代码指纹
curl -s -X POST localhost:3080/api/model-router/preview \
     -H 'content-type: application/json' \
     -d '{"text":"这个报错怎么解决","imageCount":1}'      # 只判定,不调用模型
curl -s localhost:3080/api/model-router/log?limit=30     # 最近决策
curl -s -X POST localhost:3080/api/model-router/config \
     -H 'content-type: application/json' -d '{"enabled":false}'   # 即时改配置

排查:这次改动到底要重启还是刷新?

插件分两半,规则完全不同:

改的地方 生效方式
lib/*.js(host 半边:路由、分类、API) 必须重启宿主(Node 进程内存里的旧代码)
lib/client.js(client 半边:开关、面板、读数带) 刷新浏览器页面即可(服务端每次从磁盘读、no-cache)
storages/dsh-effort-router/config.json(档位、开关) 都不用,点面板即存即生效

自带一个自检脚本,让运行中的宿主自己报出它加载的是哪份代码:

node tools/check-reload.mjs                 # 默认检查 web profile 的安装目录
node tools/check-reload.mjs --src .         # 顺便比一下源码与安装副本是否一致

退出码:0 什么都不用做 · 1 需要重启宿主 · 2 安装目录不对 · 3 连不上宿主 · 4 源码还没装进 profile。


开发

npm run build     # 用 esbuild 把 src/client/index.jsx 打成 lib/client.js(host 半边不需要构建)
npm test          # 27 个用例:判定规则 / 图片阶梯 / 灰区判定 / 开关与手选 / 图片守卫 / 座位同步 / HTTP API

目录:

lib/                host 半边(Node):index.js 挂水路,router.js 分档,classify.js 规则,
                    judge.js 灰区小模型,config.js 配置,api.js HTTP 面板接口
src/client/         client 半边源码(React 设置面板 + 输入框开关 + 读数带)
lib/client.js       上面这份的构建产物(浏览器加载)
tools/check-reload  「要不要重启」自检
cordis.patch.yml    往宿主插件树插入自己那一行

已知限制

  • 每轮只判一次:判定发生在该轮第一个请求上,之后同轮不会重判。
  • 只看本轮文本:不读历史,所以"接着上面那个问题"这类指代型追问可能只拿到 standard——补一句带信号的说明即可。
  • 带图自动切模型默认关,原因见上文取舍表。
  • 座位同步会让座位随每轮计划移动;若你希望座位固定在自己选的模型上,在座位上手动选一次即可——之后插件会让开(skip:manual)。

English summary

dsh-effort-router is a DeepSeek Harness plugin that routes each request (not the session) to the cheapest model that can still do the job:

  • Zero-token rule classifier with four tiers — simple / standard / hard / vision.
  • Gray-zone judge: only when the rules land on the ambiguous middle band, one 8-token call to a cheap model decides — no keyword whitelists to maintain.
  • Vision tier ladder: one image model, effort scaled by difficulty (low/high/max), so a holiday photo and a stack-trace screenshot stop sharing one level.
  • The composer seat equals reality: before every send the client applies the turn plan to the session selection — reading and restoring your global default model around it — so the model box shows what the turn will really use, and image turns reach the vision model without a separate guard. A model you picked by hand is never overridden (logged as skip:manual).
  • Instant switches: an on/off button right in the composer, applied on the very next turn.

Install: dsh plugin --profile web add dsh-effort-router-0.3.0.tgz, then restart the host. MIT licensed.

—/ 5

No ratings yet

Verified DSH bundle

Commit 103c15511687

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout