前言¶
在 DSH 裏做多會話協作時,常見做法是在一個長會話裏手動記錄「張三幹 A、李四幹 B」,回頭看誰回覆了什麼。這種做法在會話多、上下文長時很容易出錯:把別人的輸出誤當成自己的結果,或者重啓後根本想不起某張工單投出去沒有。
下面介紹的 dsh-supergroup 就是針對這個痛點的一個插件。它不改變 DSH 的會話機制,而是加一層編排:一個主會話帶若干執行會話,按 sessionId 派工、按 rpcId 回收結果、重啓後自動對賬。維護者是 LXS652,分類爲工作流,許可證 MIT,項目版本 1.0.1。
這是什麼¶
一句話定位:dsh-supergroup 是 DeepSeek Harness 的一組會話編排插件,把一個主會話和若干執行會話組成一個「整體」,主會話負責拆解與派工,執行會話各幹各的,結果按投遞時生成的 rpcId 精確回到主會話。
它要解決的問題很具體:
- 派工不靠標題、暱稱或當前選中會話,而是按確定的
sessionId投遞,避免「派給誰」的歧義。 - 結果回收不靠「猜下一條回覆」,而是按投遞時生成的
requestId(即rpcId)錨定,該 id 會隨消息進入會話歷史。 - 宿主重啓後,賬本先恢復,再對「投遞了但沒等到結算」的工單做歷史對賬,能自動證明完成的才收斂,證明不了的留給人裁決。
- 對賬只做只讀歷史和改狀態,絕不自動重發——因爲外部副作用可能已經發生。
安裝只需要往 DSH profile 里加一個 insert 條目,無外部依賴。
核心能力¶
下面列出的是 README 中明確寫出的能力,按功能分述。
編排模型¶
一個 DSH profile 裏可以同時存在多個「整體」,每個整體有獨立的主會話(lead)、成員名單和工單賬本視圖。成員最多 8 個,lead 不能出現在成員裏。
派工通過 ms2_dispatch 完成,消息進入成員會話,賬本寫 dispatch,工單進入 delivered 狀態。回收有兩條路:一是 session/event 快路徑,收到帶同一 rpcId 的 user/message 後跟隨該回合到 turn/end;二是歷史對賬,在啓動、ms2_status、/ms2 panel 三個時機讀取會話歷史,按 rpcId 精確錨定。
重啓自愈¶
宿主重啓時,delivered 先轉成 uncertain(不知道結果是否已經產生)。啓動對賬繼續查歷史:
- 找到
turn/end且completed,結算爲completed,保留reason: "restart"作爲證據,source標爲history-reconcile-after-restart; - 找不到證據,保持
uncertain,原因寫進observeStats; uncertain也可以由主會話用ms2_resolve人工accept/fail。
需要強調的是:插件從不爲了「催結果」重投工單。
側欄面板¶
- 左欄按工作區分組列出會話,「摺疊批量會話」「摺疊空白會話」兩個勾選互相獨立;
- 點「創建一個整體」進入三步向導:選主會話 → 選執行會話(可多選,空白會話也可選)→ 填整體名;
- 每張整體卡片顯示主會話、成員、工單數與在途數,卡片內可改名、全量替換成員、解散整體;
- 有在途工單(
delivered/uncertain)時,解散或移除對應成員會被拒絕,並返回具體requestId。
權限隔離¶
成員不能調用 ms2_* 協調工具,也不能用跨會話工具,業務工具照常可用。派工、裁決、改名、改成員、解散權限只在整體 lead 手上。
安裝與啓用¶
當前版本有兩條安裝路徑,新裝優先走路 A:直接改 profile 的 patch 文件,不依賴 bundle 機制。
路 A:往 cordis.patch.yml 追加 insert 條目¶
1、把插件目錄放到一個固定位置,確認入口文件存在:<你的工作區>/dsh-supergroup/src/plugin2.mjs。
2、打開 ~/.dsh/profiles/<profile>/cordis.patch.yml,在文件末尾追加:
- insert:
- id: dsh-supergroup
name: file:///<你的工作區>/dsh-supergroup/src/plugin2.mjs
config:
registryFile: '<你的 DSH_HOME>\data\registry.json'
groupsFile: '<你的 DSH_HOME>\data\groups.json'
ledgerFile: '<你的 DSH_HOME>\data\tasks.jsonl'
這裏要注意三點:name 必須是絕對路徑的 file:/// 形式且指向入口文件 src/plugin2.mjs(不是目錄);Windows 路徑把反斜槓寫成 /;條目必須包在 insert: 列表裏,不能用 plugin: 字段,也不要裸寫 - id: dsh-supergroup——沒有對應已有條目時會被當成覆蓋,宿主只記一條 patch: entry ... not found 然後靜默跳過。
3、重啓 DSH。側欄應出現「超級代理部署」圖標,ms2_status 應可用。
配置上,groupsFile 省略時會跟隨 registryFile 落到同目錄的 groups.json,eventsLogFile 省略時落在賬本同目錄的 session-events.log。可選配置:startupReconcileAttempts(默認 50,夾在 1..50)、startupReconcileIntervalMs(默認 200,夾在 1..200)、bootstrapGroups(首次啓動預置整體,數組項爲 {name, lead, members})、startupReport(默認 false)、selfTest(傳入對象時運行內置自檢)。
路 B:作爲 bundle 安裝¶
如果 profile 已經用 bundle 機制,則三件事必須同時成立,缺一不會加載:
1、profile 的 package.json 在 dependencies 裏登記本包,例如 "dsh-supergroup": "file:<你的工作區>/dsh-supergroup";
2、同一個 package.json 的 dsh.profile.bundles 數組包含 "dsh-supergroup";
3、在 profile 目錄執行 pnpm install,讓包真正進入 node_modules。
三者齊備後,bundle 會讀取包內的 cordis.patch.yml,其中 name 使用包名 dsh-supergroup,而不是 file:// 路徑。
裝完沒反應怎麼查¶
1、確認改的是當前 profile 的 cordis.patch.yml,條目追加在文件末尾、位於 insert: 列表內。
2、用 dsh --dump-config 看最終配置。Desktop 的 profile 可能被 Electron 獨佔,可以複製一份再對副本 dump:
cp -al ~/.dsh/profiles/<profile> ~/.dsh/profiles/<profile>-probe
3、grep dsh-supergroup 檢查 dump 輸出;若 stderr 出現 patch: entry ... not found,說明條目沒進入 insert:,或 id 寫錯。
4、仍無圖標時,再確認入口文件存在、name 是 file:/// 文件 URL,且 DSH 已完全重啓——客戶端 bundle 不熱更。
典型用法¶
工具層面,主會話通過以下 ms2_* 工具完成日常編排:
| 工具 | 參數 | 作用 |
|---|---|---|
ms2_status |
留空或 list |
查看當前調用者可見的整體、成員、工單、恢復項與對賬統計 |
ms2_group |
{"action":"create","name":"...","lead":"session-...","members":["session-..."]} |
創建整體;list 列出可見整體 |
ms2_members |
{"group":"整體名或 id","request":"list\|add <id>\|remove <id>\|lead <id>"} |
查看或增刪成員 |
ms2_dispatch |
{"group":"整體名或 id","memberId":"session-...","text":"..."} |
把一張工單投給成員 |
ms2_resolve |
{"requestId":"...","action":"accept\|fail"} |
主會話裁決一條等待人工的工單 |
一個可復現的最小流程:
1、主會話裏執行 ms2_group,創建整體 {"action":"create","name":"research","lead":"session-A","members":["session-B","session-C"]};
2、把任務拆成兩張工單,分別用 ms2_dispatch 投給 session-B、session-C,每張工單各自生成 requestId;
3、結果走 session/event 快路徑迴流,或在下次 ms2_status / /ms2 panel 時由歷史對賬補結算;
4、如果某張工單成了 uncertain,在主會話裏用 ms2_resolve 按證據 accept 或 fail。
命令層面,面板側欄還支持以下命令,命令後的內容是 rawInput(不含 /ms2 前綴):
/ms2 panel
/ms2 create {"name":"...","lead":"session-...","members":["session-..."]}
/ms2 dissolve <groupId>
/ms2 group rename {"group":"g-...","name":"..."}
/ms2 group members {"group":"g-...","members":["session-..."]}
這些命令由客戶端面板通過 ctx.remote.commands.execute 投到目標會話。只有整體 lead 能解散、改名、改成員;成員名單是全量覆蓋;被移除成員若有 delivered / uncertain 工單,整次修改拒絕。
適用場景與注意¶
適合誰:需要在單個 DSH profile 內管理多個執行會話、希望派工有明確歸屬、要求結果可追溯、並且看重重啓後狀態不丟失的用戶。它把「誰來做、做沒做完、重啓後賬本是否對得上」這三件事交給了工程化的賬本和對賬,而不是靠人工記憶。
需要注意的邊界,README 已逐條寫明,下面挑重點:
- 對賬時機固定:只有啓動、
ms2_status、/ms2 panel三個入口觸發,沒有後臺輪詢,不調用就不會主動結算。 - 不做隔離:插件只做會話編排,成員共享文件系統、網絡和
cwd,不提供進程、目錄或網絡隔離,需要注意成員之間的可見範圍。 - 沒有外部效果的 exactly-once:賬本保證工單狀態可恢復,但成員在完成前執行的副作用(發消息、改文件、調外部 API)無法由插件回滾;需要重試前請自行確認冪等性。
- 會話必須存在:派工只按
sessionId投遞,不探測會話是否仍有效,失效會話會在歷史對賬時表現爲找不到錨點。 - 暫不支持主會話轉移:lead 是整體創建時確定的會話。
另外,該插件以當前 dsh 進程權限運行,安裝前應檢查源碼與許可證(MIT)是否符合你的環境要求。插件在 SkillHub 社區目錄的分類是工作流,社區目錄是獨立站點,與 DeepSeek 無官方從屬關係。
結尾¶
dsh-supergroup 補的是這樣一塊:多會話編排裏最難的不是「發出去」,而是「發出去之後能不能對得上賬」。它用 sessionId 解決歸屬,用 rpcId 解決回收,用落盤賬本和歷史對賬解決重啓後的自愈。如果你在 DSH 裏已經跑起了多條執行會話,可以把它作爲一層輕量的協調骨架試試。
插件目錄頁:https://www.skillhub.cn/plugins/LXS652/dsh-supergroup
源碼與文檔:https://github.com/LXS652/dsh-supergroup