CSlawyer1985/dsh-jev-router ↗★ 0
dsh-jev-router
提供思考强度调节与自动模型路由功能 适合需要根据任务复杂度自动或手动控制模型思考深度以平衡成本的用户。
安装
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:CSlawyer1985/dsh-jev-router说明文档
阅读完整 README ↗配置项
全部配置都在「设置 → 插件 → Jev 路由」里,DSH 由 Config schema 自动生成表单。带 .volatile() 的字段改动即时生效,不需要重启。
Tier A · 思考强度
| 字段 | 默认 | 说明 |
|---|---|---|
enabled | true | 总开关 |
effort | auto | 手动钉死档位:auto/off/low/high/max。手动值永远压过自动判定 |
confidenceFloor | 0.5 | 低于此置信度弃权,沿用 harness 默认档 |
fallbackEffort | high | Jev 不可用时的关键词回退默认档 |
hysteresisRounds | 2 | 迟滞窗口(轮) |
downgradeStreak | 2 | 降档需连续确认轮数。只作用于高错误代价的降档;低代价与关键词回退立即生效 |
riskCeiling | 0.6 | 「低错误代价」上界(Jev 的 risk 分 0–3)。risk 不超过此值的降档立即生效 |
offFloorChars | 280 | off 地板的字符阈值:消息不短于此长度时不允许降到 off(0 = 关闭)。off 的语义是"琐碎到不需要思考",需要"短消息"这个正面证据;Jev 对中文准确率官方说明较低 |
syncSessionEffort | true | 把生效档位同步进会话配置(写 model/selection),让 DSH 原生的「模型后面的思考程度」跟随。关掉则原生界面永远停在会话设置上 |
全部可调项都在插件的设置页上(设置 → 插件 → Jev 路由),不必去 DSH 的通用设置里找。
status.config会公开全部可调字段的已解析值,所以新增配置项会自动出现在页面上。 |timeoutMs|4000| 单次判定超时;超时即回退,绝不阻塞用户请求。不要按热调用中位数设——实测冷启动 1367–1463ms、热调用 358–548ms,卡在中间会导致重启后首次判定必然超时 | |blockOnDecision|true| 首步是否等待判定结果;关闭后用上一轮判定,延迟更低 |
Tier B · 自动模型路由
| 字段 | 默认 | 说明 |
|---|---|---|
modelRouting | false | 自动模型路由总开关 |
acknowledgeCacheRisk | false | 硬门禁:不勾选则策略层拒绝一切模型切换 |
modelSwitchMode | turn-boundary | 只支持回合起点切换 |
modelAllowlist | [] | 候选模型。裸 id = 当前 provider;provider::model = 跨 provider(用双冒号,因为真实模型 id 里就有斜杠与冒号) |
modelNotes | [] | "模型id: 说明",作为 Jev 的 criteria 描述 |
customPricing | [] | 非 DeepSeek 模型的自备价目:"provider::model=命中,未命中,输出"(USD/1M) |
stickyRounds | 3 | 候选需连续胜出轮数 |
switchCooldown | 2 | 两次切换最小间隔轮数 |
maxSwitchesPerSession | 2 | 单会话切换上限 |
hitRateAlert | 0.8 | 窗口命中率告警阈值 |
Tier C · 预留
| 字段 | 默认 | 说明 |
|---|---|---|
skillRouting | false | 首版未实现,仅占位 |
凭据与价格
| 字段 | 默认 | 说明 |
|---|---|---|
apiKeyRef | TYPESAFE_API_KEY | 存放 Key 的凭据名。密钥本体进 DSH 凭据存储,不写进 profile 配置 |
pricingAutoRefreshHours | 24 | 价目刷新间隔(0 = 只在启动与手动触发时获取)。改动需重启 |
pricingCachePath | '' | 默认 ~/.dsh/jev-router/pricing.json。改动需重启 |
holidays | [] | 中国法定节假日(YYYY-MM-DD),用于 peak/off-peak 判定 |
界面
| 字段 | 默认 | 说明 |
|---|---|---|
showBadge | true | 输入框工具行的档位徽章。建议关闭:原生「模型后面的思考程度」是唯一真相,两个指示器重复(见下方说明) |
namespace | jev-router | 设置 namespace(= loader entry id)。改动需重启 |
Key 的解析顺序(DSH 原生分层):
继承的进程环境变量(只读,最高)>$DSH_HOME/.credentials.yaml(可写,设置页输入框写这里)>/.env>$DSH_HOME/.env。 如果解析到的来源是进程环境变量,设置页的写入会被拒绝(只读层遮蔽可写层),此时会返回明确错误。
方式 B:作为 bundle 安装(推荐用于使用)
## 使用
1. **配 Key**:设置 → 插件 → Jev 路由 → 「Jev API Key」粘贴 TypeSafe API Key → **保存**。保存后下一次对话即生效,不需要重启。密钥只写入 DSH 凭据存储,不会回显,也不进配置文件。
2. **测连通**:点**连通**——插件会用一句固定的探针消息真的打一次 Jev,然后告诉你结果。成功会显示版本号、判定档位、置信度与耗时:
已接通 · jev-1.13.0 · off(置信度 1.00) · 430ms
失败会明确说原因(未配置 / 请求失败 / 响应无法解析),**不会假装成功**。这个按钮让你不必靠"用一次看看"来判断是否配好。
> **两个指示器,该信哪个?**
>
> | 指示器 | 数据源 | 是否准 |
> |---|---|---|
> | DSH 原生「模型后面的思考程度」 | 会话配置(`model/selection`) | **准**(同步不变量保证它等于实际请求档位) |
> | 本插件的输入框徽章(`showBadge`) | 请求侧状态 | 准,但**与原生重复** |
>
> 两者现在由同一条不变量保证一致。**建议关掉插件徽章**(设置页 → 输入框档位徽章 → 关),
> 让原生指示器成为唯一真相——它在模型名后面,更显眼,也不会多一个需要维护的一致性问题。
3. **确认生效**:发 `/jev status` 或 `/jev why`,看判定的**来源**——`jev(jev-1.13.0)` 表示走真 Jev;`heuristic` 表示没配 Key 或调用失败(超时/限流)。
3. **日常使用**:什么都不用做。Tier A 默认开启,Jev 会按每条消息的难度自动升降档位。
4. **手动干预**:点徽章循环切档,或 `/jev effort high` 钉死;想交回自动用 `/jev effort auto`。
5. **开 Tier B(可选)**:设置页打开「自动模型路由」→ 三步确认 → 第二步会拿你自己的实测命中率与前缀长度算出盈亏平衡点,勾选风险确认后才能保存。
---
# 拿真实消息测 Jev 的判定质量(需要已配置 Key)
node scripts/try-jev.mjs # 内置样例集
node scripts/try-jev.mjs "你的消息" ... # 自己的消息
node scripts/try-jev.mjs --json # 输出 JSON
try-jev.mjs 会把同一批消息同时喂给 Jev 与关键词表,把差异直接摆出来。实测样例(8 条,实际版本 jev-1.13.0,中位耗时 426ms):
| 消息 | Jev | 关键词表 |
|---|---|---|
| 你好 | off (1.00) | off |
| 今天几号? | off (0.67) | high |
| 把这段 JSON 格式化成两空格缩进 | low (0.84) | high |
| 帮我彻底重构这个模块的架构… | high (0.65) | high |
| 这段代码线上偶发超时…帮我定位根因 | high (0.99) | high |
| ultrathink 一下这个一致性协议有没有漏洞 | max (0.64) | max |
| 不要完整全量思考,简单说就行 | low (0.99) | max |
| 别 ultrathink,我只要一个是或否 | low (0.76) | max |
不一致 4/8,且每一条都是 Jev 对、关键词表错。最后两条是否定句——关键词表看到「完整全量思考」「ultrathink」就判最高档,而用户的意思正好相反。这就是「语义判定」与「关键词匹配」的差别。
测试分层
| 层 | 文件 | 覆盖 |
|---|---|---|
| 单元 | policy / pricing / classify / metrics / routes | 盈亏平衡数学、迟滞与降档确认、五道闸(含硬门禁)、价目解析(含 rowspan 错位与结构不识别)、peak 时段判定、同源校验 |
| 能力适配 | model-caps | 强度轴对齐、夹取规则(上下界/等距/无元数据)、provider::model 解析(含 ollama 那种带斜杠冒号的 id)、能力缓存的正/负 TTL |
| 配置解析 | config | volatile 引用拆包、缺省回退、整份配置都是引用时 resolveConfig 必须给出裸布尔/数字/字符串 |
| 会话生命周期 | session-store | 同一会话只创建一次、TTL 过期回收、LRU 容量淘汰、disposal 只计数不删状态、create() 返回值不得被额外包装 |
| 前端半 | client | 用桩 React + 仿真语义的槽位桩(未声明就抛、inject 挂起等待)真正渲染设置页与徽章;覆盖"槽位未声明时 apply 绝不能抛"这条事故回归 |
| 集成 | integration | 假 Cordis 上下文把插件真正 apply() 起来,端到端跑 inbox → Jev → request 改写、同轮多 step 复用、llm/stream 计量、四条路由、命令族、Tier B 硬门禁与放行、跨 provider 路由 |
| 契约 | contract | 禁止改写 messages、禁止注册 systemPrompt、只允许改 reasoningEffort/model/provider、provider 与 model 成对切换、volatile 字段约定、默认值单一真源 |
隔离实例验证(不碰在用的实例)
不必重启正在使用的 DSH 也能做完整实机验证: