前言¶
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 一起做¶
大多數「給所有會話換模型」的嘗試停在模型層面,因爲思考強度看起來像另一個層。實際不是:
sessionController.selectModel()接受{ provider, model, reasoningEffort? }。- 提交的選擇會以
model/selection事件追加到會話日誌,該事件的 schema 帶reasoningEffort。 modelSelectionprojection 重新讀取它,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。