dsh-group-chat:在 DSH 裏開一個多 AI 羣聊

前言

DSH 的理念是「一切皆插件」,WebUI 上的不少能力都由插件注入。做智能體開發時常會遇到這樣一個需求:讓幾個模型圍繞同一份上下文輪流討論——一個出方案、一個挑毛病、一個做總結。在沒有專門工具時,通常只能在多個會話之間手動搬運上下文,發言順序也要自己盯着。

下面介紹的 dsh-group-chat 把這件事做成了羣聊形態:你在 DSH WebUI 裏當「羣主」,管理一組可配置的 AI 角色,讓它們圍繞共享上下文進行多模型輪流發言。插件由 Qx002 維護,當前版本 0.1.0。

這是什麼

dsh-group-chat 是一個 DSH 原生多 AI 羣聊插件,核心設定有三點:

  1. 用戶是「羣主」,AI 角色是羣成員,可以配置角色卡、模型、發言模式,也能隨時禁言;
  2. 羣聊是獨立頁面,與工作區原生對話完全隔離——插件不接管原生輸入框(不註冊 agent/pre-step 攔截),原生對話區域的輸入框、模型選擇、讀寫權限繼續爲原有工作流服務;
  3. 純 Node.js / Cordis 實現,不使用 Tauri / Rust。

核心功能

獨立羣聊頁面

插件通過 WebUI slot 注入兩個入口:

  • conversation.input.left:輸入卡工具欄左端的羣聊開關,點擊開啓或關閉獨立羣聊頁面,狀態持久化到 enabledSessions,全局開關自動聯動;
  • settings.section(id group-chat):設置面板中的「羣聊設置」頁。

羣聊頁面約覆蓋原生對話區域 2/3、居中顯示,右上 ✕ 關閉、左上 ⚙ 打開設置。聊天視圖是微信式佈局:AI 成員消息在左、用戶在右,獨立輸入框支持 Enter 發送、Shift+Enter 換行,也可以發送圖片(PNG/JPEG/WebP/GIF,經 DSH attachment 服務持久化後作爲 image block 進入模型請求並在氣泡內顯示)。頁面打開期間輪詢消息視圖。

AI 角色管理

先在設置頁添加成員,再逐個配置。每個 AI 角色可以設置:

  • 角色卡 System Prompt 與初始上下文;
  • Provider / Model,由 ModelPicker 級聯選擇器選擇:點擊後先列出 DSH 已接入的提供方(ctx.llm.listProviders()),再列出該提供方通告的模型(listModels(provider)),數據與 DSH 模型目錄完全一致;沒有目錄時也可手動填寫 provider/model;
  • 發言模式(被動回覆 / 主動發言)與主動發言策略;
  • @ 別名、觸發詞;
  • 禁言/啓用權限,成員列表支持快捷禁言。

發言者選擇與羣主規則

每一輪誰發言按固定優先級決定:

mentioned(@名字/別名)→ triggered(觸發詞)→ active(主動發言成員)→ default(兜底)

候選池先過濾掉被禁言或已移除的成員;單輪發言者數量受 maxAgentsPerTurn 截斷;muteAll 開啓時不生成任何回覆,但用戶消息仍會落盤;無人觸發時由第一個可用成員兜底。

羣主規則集中在設置頁:禁言全體、主動發言總開關、單輪迴覆上限、單輪發言者上限、並行生成、超時、@ 語法。

共享上下文

所有發言者看到同一份轉寫。插件把統一的 Session Log 投影爲「[AI名稱]: <內容>」行,用戶行使用設置裏的「用戶名稱顯示」(默認「羣主」),按滾動窗口 maxMessages 截取;轉寫模板可配置,角色卡注入有獨立開關。順序模式下,後發言者能看到本輪先發言者的最新回覆——每一步都重新派生轉寫。

主動發言

被動成員等 @ 或觸發詞,active 模式的成員會自己開口。每個主動成員按 [minIntervalMs, maxIntervalMs] 內的隨機間隔掛一次性定時器,觸發前檢查一組條件:羣聊啓用、主動發言總開關開啓、未禁言全體、該成員未禁言、會話無進行中的輪次、距上次活動滿足間隔要求。條件臨時不滿足就 30 秒後重試。配置變更會即時重置全部主動定時器,策略改動馬上生效。

輪次事件與流式輸出

一輪羣聊的事件序列與官方 agent-loop 同構:

turn/start → user/message → 每發言者: step/start → assistant/chunk* → assistant/message → step/end → turn/end

爲避免與原生輪次編號衝突,羣聊 turn 編號使用 GROUP_TURN_BASE = 1_000_000 起的偏移空間,恢復會話時掃描日誌續號。流式方面,每個 chunk 先落盤 assistant/chunk,用官方 BlockAssembler 組裝後寫 assistant/message,消息帶 source: {provider, model} 溯源信息與 usage。

失敗語義比較剋制:單個發言者失敗只記錄自身,不影響其他人繼續發言;全部失敗才以 turn/end(error) 收尾;中途取消標記爲 aborted

配置持久化

配置存放在 group-chat 用戶設置命名空間:插件通過 installSettingsSection 註冊同一份 schema,解析優先級是 schema 默認值 → 入口 base → ~/.dsh/settings.yaml 用戶層。環境中沒有 settings 服務時,寫入路徑拋出 GroupChatError(碼 NO_SETTINGS),讀取降級爲入口配置。每次配置提交都會廣播 group-chat/config-updated 事件,編排器據此重置主動發言定時器。

安裝與構建

本次覈對的資料(README、package.json)中沒有給出官方安裝命令,這裏不自行拼接。安裝方式請以倉庫 README 爲準(README 中的倉庫主頁字段目前還是 TODO 佔位,以 GitHub 倉庫頁爲準):

https://github.com/Qx002/dsh-group-chat

從源碼構建時,插件聲明的 peer 依賴如下:

@deepseek-ai/cordis          ^4.0.1
@deepseek-ai/dsh-attachment  ^0.1.0-rc.6
@deepseek-ai/dsh-llm         ^0.1.0-rc.6
@deepseek-ai/dsh-session     ^0.1.0-rc.6
@deepseek-ai/dsh-settings    ^0.1.0-rc.6
@deepseek-ai/schemastery     ^3.18.1
react                        ^18.2.0

構建命令是 npm run build,等價於 tsc 編譯主機端 lib,加上 tsdown 打包瀏覽器端 client.js。

典型用法

從界面開始,流程大致是:

  1. 點擊輸入框旁的羣聊開關,打開獨立羣聊頁面;
  2. 左上 ⚙ 進入羣聊設置,添加 AI 成員,配置角色卡、模型、發言模式;
  3. 回到聊天頁輸入消息,@ 某個成員,或等主動發言成員自己開口;
  4. 需要叫停時點右上 ✕ 關閉頁面(開關同步回「關」,主動發言定時器停止),或在代碼裏調用 cancelSession

習慣寫代碼的話,也可以直接走 Service API:

// 持久化開啓某會話的羣聊
await ctx.groupChat.enableSession(sessionId);

// 添加 AI 角色
const agent = await ctx.groupChat.addAgent(input);

// 管理成員狀態
await ctx.groupChat.setMuted(agent.id, true);
await ctx.groupChat.setMode(agent.id, "active");

// 羣主控制
await ctx.groupChat.setMuteAll(true);
await ctx.groupChat.setActiveSpeakEnabled(false);

// 提交用戶消息並運行一輪羣聊(可攜帶圖片)
// 要求羣聊已啓用,且該會話在 enabledSessions 中
await ctx.groupChat.submitMessage(sessionId, text, images);

// 中止進行中的羣聊輪次
await ctx.groupChat.cancelSession(sessionId);

完整接口還包括 getConfig / getAgent / listAgents / getStatus / watchupdateAgent / removeAgent / setEnabledupdateHostRules / updateSharedContextsetGroupEnabled / setGroupNameisSessionEnabled / listEnabledSessionsgetEngine / listModelCatalog

開發者接口

除了 UI,插件留了三類接入點,供其他插件或腳本使用:

  • WebUI API 路由 /api/group-chat/*stateconfigmodelsmessagesattachmenttogglesubmitcancelagentshost。帶同源 POST 防護,錯誤統一爲 {ok:false, code, message}
  • Cordis 事件:group-chat/config-updatedagent-added/updated/removedturn-startagent-speakingagent-spokenturn-endorchestrator-attached/detached,可按需訂閱。
  • 客戶端 bundle 純度 gate:客戶端只允許引用平臺模塊(react、cordis、ui-slots 等)與內聯安全層,任何其他 @deepseek-ai 值導入會在 build 期被拒絕——想與它協作,必須走 cordis 服務而不是直接 import。

適用場景與注意

適合誰:

  • 想讓多個模型圍繞同一份上下文討論、互評、頭腦風暴的 DSH 用戶;
  • 想對比不同模型在同一角色設定下表現的人——每個成員獨立配置 Provider/Model;
  • 插件開發者:輪次事件與官方 agent-loop 同構,可以基於 Cordis 事件或 ctx.groupChat 做二次開發。

幾點注意:

  1. 插件以當前 dsh 進程權限運行,安裝前建議先閱讀源碼;
  2. package.json 的 files 裏包含 LICENSE 文件,但資料未標明具體許可證類型,使用前請到倉庫確認;
  3. 羣聊與原生工作區對話完全隔離,羣聊內容不會混入工作區對話;
  4. 版本爲 0.1.0,README 標註基礎設施、編排器引擎、WebUI 三個階段均已完成,但整體仍處於早期階段。

結尾

dsh-group-chat 把多模型協作放進了 DSH 原生界面:羣主控場、成員按規則輪流發言、共享一份上下文,同時給開發者留了完整的 Service API 與事件訂閱。如果你在 DSH 裏有多個 AI 角色協作的需求,可以按上面的步驟試一試。

  • 插件目錄頁:https://www.skillhub.cn/plugins/Qx002/dsh-group-chat
  • GitHub 倉庫:https://github.com/Qx002/dsh-group-chat
羽毛球分组比赛记分
小程序二维码

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

小夜