dsh-unified-model:一次把模型和思考强度应用到所有 DSH 会话

前言

DeepSeek Harness(DSH)把模型选择保存在单个会话里。自带的默认模型设置只影响还没选择过模型的会话,/model 也只改变当前这个会话。当你有成片的历史会话想整体切到同一个模型和思考强度时,没有内置入口。下面介绍的 elfgzp/dsh-unified-model 就是补这个位置的插件:在 composer 行加一个控件,批量写入所有可写会话,并且把 reasoningEffort 一起带上。

插件定位是模型推理助手,由 elfgzp 维护,当前星标 0,版本 0.1.0,许可证 MIT。

这控制在哪、怎么用

控件挂在 composer 行,和官方模型选择器并列,不替换它:

[⇉ All sessions]  [ deepseek-v4.1-flash ▾ ]
                   ^ 官方模型选择器,保持原样

窗口窄时按钮收成图标:

[⇉]  [ deepseek-v4.1-flash ▾ ]

完整名称仍写在按钮的 title 和 aria-label 里,不以按钮变图标就变成无标签控件。

打开面板后依次选 provider、model、thinking effort 和作用范围:

选项 效果
Every session 写入每一个能保存独立选择的会话
Every other session 同上,但不动当前正在看的会话
Also make this the default 额外写 deployment default,之后新建的会话从它开始

批量执行过程中有一个实时的 done/total 计数,结束后报告哪些改了、哪些本来就一致、哪些失败。

为什么连 effort 一起做

大多数「给所有会话换模型」的尝试停在模型层面,因为思考强度看起来像另一个层。实际不是:

  1. sessionController.selectModel() 接受 { provider, model, reasoningEffort? }。
  2. 提交的选择会以 model/selection 事件追加到会话日志,该事件的 schema 带 reasoningEffort。
  3. modelSelection projection 重新读取它,selectionFor() 在重启后恢复它,因此 effort 能存活。

README 里给出的实测日志片段:

{"type":"model/selection","seq":4,"data":{"provider":"tencent-intranet","model":"deepseek-v4.1-flash-ioa","reasoningEffort":"max"}}

所以插件判断会话是否已匹配时,比较的是 provider、model 和 reasoningEffort 三项。只比较前两项的实现会显示成功,却悄悄少写了 effort。

作用范围与失败处理

情况 行为
普通会话 更新,是该控件的目标
子代理会话 不动;它们跟随父级路由,host 拒绝给它们单独选择;结果里单独计数,不当作失败
已携带目标选择的会话 跳过,不写;对已统一的历史重复点击在毫秒级完成
日志损坏或被其他进程锁住 按失败上报,附 host 给出的原因,批次其余部分继续

批量任务跑在 Host 上,不在浏览器里,关掉标签页不会中断;客户端只负责启动和轮询进度。

实现方式与接口

插件不修补自带插件、不改会话日志、不编辑 projection 缓存,直接调用内置 /model 对话框所用的公开 host API:

sessionController.list({})                  → 全部会话及其当前选择
sessionController.selectModel({ sessionId, provider, model, reasoningEffort })
sessionController.modelCatalog()            → provider 分组和每个模型公开的 effort
agentDefaultModel.saveSelection({ … })      → 需要时写 deployment default

写入走的是官方路径,会话状态保持官方格式,卸载不留下改动,未来 Harness 改名这些方法也只损失这个插件。

路由有三个,都在 composition 的连接信任栅栏之后:

GET  /unified-model/state    → catalog、default、各会话选择、当前 run
POST /unified-model/apply    → { provider, model, reasoningEffort?, scope, excludeSessionId? } → { runId }
GET  /unified-model/status   → 当前或最近一次 run
POST /unified-model/default  → 写 deployment default

两个性能与安全上的处理

先读后写。selectModel 会恢复每个冷会话,这是全程最贵的部分,所以插件先用 list() 读出所有会话的选择,跳过已一致的。README 在 55 会话 profile 上测得:首次跑写入了 36 个会话,耗时 2.7 s;紧接着的重复跑跳过 53 个,56 ms 完成。

写之前做校验。模型名或 effort 不被该模型公开时,适配器会拒绝请求,两项都在碰第一个会话前对照 modelCatalog() 检查,拼错会让请求整体失败,而不是逐个失败 60 个会话:

400 model-unknown       catalog 没有列出这个 p/m
400 effort-unsupported  p/m 公开 low/medium/high/xhigh/max,ultra999 不是其中之一

客户端也只提供模型实际公开的档位,两边不会对不上。

安装与启用

官方安装命令如下,profile 换成你自己的:

dsh plugin --profile <your-profile> add dsh-unified-model

如果已有 checkout,也可以从本地链接安装:

dsh plugin --profile <your-profile> add link:/path/to/dsh-unified-model

装好后要重启应用:bundle patch layer 和 client bundle 都在启动时加载。

配置项为空,控件直接出现在 composer 行,没有需要设置的东西。

适用场景与注意

适合需要把成片历史会话统一到同一模型和 effort 档位的 DSH 使用者,尤其是会话数量较多、手动逐个切换成本高的场景。子代理会话不会被动,这一点要提前知晓。

几点提醒:

  • 插件以当前 dsh 进程的权限运行,安装前应检查源码和许可证(MIT)。
  • 要求 DeepSeek Harness 0.2.0 或更新版本,且需要 Web UI(控件在 composer slot 里)。
  • 目录页 https://www.skillhub.cn/plugins/elfgzp/dsh-unified-model 是社区站点,与 DeepSeek / 幻方无官方从属关系。

源码和文档见 https://github.com/elfgzp/dsh-unified-model。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜