delltig/dsh-multi-model-collab:把一個任務同時交給多個大模型

前言

在 DSH(DeepSeek Harness)上寫 Agent 時,常見的做法是讓一個模型串行地把活幹完。遇到答案可能不穩定、需要第二個意見,或者需要交叉驗證的場景,就得自己在外層寫編排邏輯:發多次請求、合併結果、處理部分失敗。delltig/dsh-multi-model-collab 把這個動作收進了一個插件:它向當前 Profile 註冊一個 multi_model_run 工具,主 Agent 調用時,插件內部通過 ctx.llm 服務並行(或按主/副角色)發起多次模型調用,再按配置的策略聚合,返回「每個模型的獨立結果 + 聚合摘要」。下面介紹它做了什麼、怎麼裝、怎麼配。

插件定位

這是一個 DeepSeek Harness(dsh)插件,倉庫爲 delltig/dsh-multi-model-collab,package.json 裏 author 字段爲 applestore,版本 0.1.0,MIT 許可證。README 的自我定位很明確:不修改 dsh 源碼,是純 Cordis 插件掛載,靠 ctx.tools.register + ctx.llm 兩個接口工作。

它解決的是「一個任務讓 N 個模型各答一遍」這件事,而不是帶工具、帶會話、多步的子 Agent 委派。插件明確寫了它不硬編碼任何 API Key、端點或模型清單,模型一律用 ctx.llm.listProviders() 報告的 <provider>/<model> 路由;單個模型失敗不會讓整個工具調用失敗,只有全部模型失敗時 execute 才拋異常;調用方取消時,仍在進行的模型調用一併取消。

核心功能

主要能力是註冊 multi_model_run 工具。主 Agent 調用它時,插件內部按配置發起多次模型調用,再按策略聚合,把每個模型的獨立結果和聚合摘要返回給主 Agent。

執行模式有兩種:

  • parallel——每個模型獨立回答同一個任務,全部並行。適合要第二意見、要跨供應商一致性、答案可能有分歧的場合。
  • primary_secondary——主模型先答;其餘模型拿到「原始任務 + 主模型草稿 + secondaryInstruction」,做審閱、糾錯與補全。適合需要一個”審稿人”、單點判斷風險高的場合。主模型失敗時自動降級爲各副模型獨立作答,而不是整體失敗。

聚合策略有三種:

  • all——原樣返回全部結果,不做選擇(answer 爲空串)。這是默認值,理由是分歧本身往往是主 Agent 需要的信息。
  • vote——先把文本歸一化(大小寫、標點、空白、Markdown 符號)再分組;嚴格多數則取該組代表,無嚴格多數則回退到最長答案,並在 summary 裏說明實際票數與回退原因。
  • longest——取最長的成功答案作爲 answer。

render() 把這些渲染成一段 Markdown(每個模型一節 + ## aggregate 摘要 + 可選 ## selected answer),主 Agent 讀到的就是這段文本。

安裝與啓用

方式 A:安裝到 Profile(長期生效)。在插件包目錄內(即本倉庫根目錄)執行:

dsh plugin --profile desktop add .

該命令把本包裝進 ~/.dsh/profiles/<profile>/node_modules,package.json 的 dsh.bundle.patch 指向的 cordis.patch.yml 會作爲 bundle patch 層生效。也可以用 dsh 的插件管理器,在 dsh 會話內調用:

plugin_manager(action="install_bundle", target="<本目錄絕對路徑>")

方式 B:--patch 覆蓋層,不安裝直接試。cordis.patch.yml 裏插入行的 name 是相對路徑(./lib/index.js),Loader 會把它錨定在該 patch 文件旁邊,所以無需安裝即可掛載:

dsh web --patch ./cordis.patch.yml
# 若用 pnpm 管理 dsh:
pnpm dsh web --patch ./cordis.patch.yml
# 不搶端口、不自動開瀏覽器:
dsh web --patch ./cordis.patch.yml --no-open --port 0

也可以一次性 headless 驗證:

dsh --profile <headless-profile> --patch ./cordis.patch.yml "用 multi_model_run 跑一個任務"

這裏有一個坑:headless 模板默認把 credentials 行設爲 disabled: true;如果 Profile 沒有其它層重新啓用它,API Key 會查找失敗(MISSING_CREDENTIAL)。Web / Desktop Profile 本來就啓用了該行,無需處理。

改源碼後重新構建:

npm install
npm run build   # tsc -> lib/,並 node --check 校驗產物
npm test        # 離線行爲測試(假 ctx.llm,不髮網絡請求)

配置

所有配置都在 Loader 行(cordis.yml / cordis.patch.yml)的 config: 下,改值不需要改代碼。字段與默認值如下,與 src/index.ts 的 Config 一致。

字段 類型 默認值 說明
models string[] ["deepseek-official/deepseek-flash", "deepseek-official/deepseek-v4-pro"] 默認模型組合,格式 <provider>/<model>。primary_secondary 模式下第一個是主模型。
mode parallel / primary_secondary parallel 執行模式。
aggregate all / vote / longest all 聚合策略。
defaultProvider string "" 模型標識不帶 provider 前綴時使用哪個 provider;空則按各 provider 的目錄自動匹配。
system string "" 發給每個模型的 system prompt;空則不發。
temperature number -1 採樣溫度;負數表示不發該字段(用適配器默認)。
maxTokens number 0 單次調用的輸出 token 上限;0 表示不限制(用適配器默認)。
perModelTimeoutMs number 180000 單個模型調用的取消預算。
toolTimeoutMs number 900000 整個工具調用的協作預算;0 表示交給註冊表默認。
maxConcurrency number 4 同時在飛的模型調用數上限。
clipChars number 12000 每個模型返回文本的截斷長度;0 表示不截斷。未截斷長度仍記錄在 chars。
includeUsage boolean true 是否上報每個模型的 token 用量(適配器提供時)。
secondaryInstruction string 審閱指令(中英雙語) primary_secondary 模式下要求副模型做什麼。

models 的默認值是示例組合,實際跑什麼模型取決於當前 Profile 裏 listProviders() 報告了哪些路由,所以默認值未必都能解析。

工具用法

工具名 multi_model_run。入參如下。

參數 必填 說明
task 是 要執行的任務/問題。每個模型只看到這段文本,看不到當前會話,必須自帶上下文。
models 否 本次使用的模型列表,覆蓋配置的 models。
mode 否 本次執行模式,覆蓋配置。
aggregate 否 本次聚合策略,覆蓋配置。
system 否 本次 system prompt,覆蓋配置。

task 是唯一必填項,這意味着調用前要在 task 裏把上下文寫全。返回結構如下(節選):

{
  "task": "…",
  "mode": "parallel",
  "aggregate": "all",
  "models": ["deepseek-official/deepseek-flash", "deepseek-official/deepseek-v4-pro"],
  "succeeded": 2,
  "failed": 0,
  "results": [
    {
      "provider": "deepseek-official",
      "model": "deepseek-flash",
      "id": "deepseek-official/deepseek-flash",
      "role": "peer",
      "status": "ok",
      "text": "…",
      "clipped": false,
      "chars": 12,
      "durationMs": 1840,
      "error": null,
      "usage": { "inputTokens": 10, "outputTokens": 5, "totalTokens": 15 }
    }
  ],
  "answer": "",
  "summary": "mode=parallel aggregate=all models=2 ok=2 failed=0 elapsed=2140ms\n- OK   …"
}

失敗與取消的邊界:

  • 單個模型失敗(適配器報錯、拋異常、無終止 chunk、超時)→ 該條 status: "failed" + error.code,其餘模型繼續;工具整體仍然成功。
  • 全部模型失敗 → execute 拋錯,錯誤信息裏帶每個模型的 code: message,並帶 code: "ALL_MODELS_FAILED"。
  • exec.signal 觸發 → 已發出的模型調用被取消;若一個都沒成功則拋 ABORTED。
  • 模型引用無法解析(例如只寫了 deepseek-flash 但目錄裏匹配不到、又沒配 defaultProvider)→ 拋錯並列出當前所有可用的 provider/model 路由。

驗證

離線行爲測試不髮網絡請求,共 21 個用例:

npm test

覆蓋插件契約、defineTool 參數/輸出 schema 編譯、並行執行、失敗隔離、全失敗拋錯、vote/longest 聚合、primary_secondary 的審閱 prompt 與主模型失敗降級、模型引用解析(含目錄查找與報錯文案)、文本截斷、取消、缺終止 chunk。

端到端測試(真實模型,需要已配置的供應商):

npm run e2e        # 4 個真實場景,約 2 分鐘,會消耗真實 token

它會自建/複用臨時 headless profile(默認 mmcollab),掛 ./cordis.patch.yml 讓真實 Agent 調用 multi_model_run,並斷言四件事:並行雙模型都返回、單模型失敗被隔離、primary_secondary 的副模型真的審閱了草稿、全部失敗時工具調用本身報錯。

手工單跑的等價命令(需要先造臨時 headless profile):

node "<dsh>/lib/bin.js" --profile mmcollab --from-default-profile headless --dump-config

node "<dsh>/lib/bin.js" --profile mmcollab \
  --patch ./verify/patch-forms/enable-credentials.yml \
  --patch ./cordis.patch.yml --json \
  "Call the multi_model_run tool exactly once with task='Reply with exactly the single word PONG and nothing else.' and omit every other argument. Then print the tool result verbatim."

這裏有個容易漏的點:只看退出碼不夠。Loader 對沒能激活的插件行只打印一條 stderr 警告,進程照樣 exit 0。驗收必須斷言 --json 輸出裏出現 tool_call / tool_result。

適用場景與注意

適合的場景:需要第二意見、需要跨供應商對同一個問題的答案做對比,或者想讓一個模型產出草稿、另一個模型審校的場合。它不承擔帶工具、多步的委派任務——那應該用子 Agent 機制。README 在設計說明裏明確寫了,這個插件走 ctx.llm.stream() 而不是複用子 Agent,因爲前者的每條調用只有一個模型請求,沒有會話、工具集和上下文;後者的每個子 Agent 有自己的 loop 和上下文,適合需要模型自己查資料再回答的任務。

使用前要注意幾點:

  1. 插件以當前 dsh 進程的權限運行,安裝前應檢查源碼與許可證(MIT)。
  2. 這些調用不是完整 Agent 回合,不會寫入 session,也不會被按會話計量的插件(如 cost-meter)統計,因爲 GenerateOptions.sessionId 沒有設置。每個模型的實際用量看返回裏的 usage 字段(includeUsage: true 時)。
  3. 沒有工具循環,模型只能拿到 task 文本,不能自己檢索或執行命令。
  4. vote 是文本歸一化後的嚴格多數,不是語義投票。開放式答案很少逐字一致,通常會回退到最長答案,並在 summary 裏寫明。
  5. 默認每個模型最多 12000 字符乘以模型數,模型多或答案長時調小 clipChars。
  6. README 寫明實測於 dsh 0.2.1(CLI rc.2 / 桌面打包運行時 rc.3),package.json 聲明兼容性爲 >=0.2.0-rc.1 <0.3.0-0。
  7. GitHub 上存在一個同名但無關的項目 zanapeng/dsh-multi-model-collab(2026-08 創建),它把固定的四段流水線寫死;本插件不是流水線,而是一個通用工具,選型時別裝錯。

結尾

這個插件的價值在於把”一個任務問多個模型”從一個需要自己搭的編排動作,收斂成 Profile 裏一個配置項加一次工具調用,同時把部分失敗、取消、聚合策略這些邊界情況處理掉了。如果你已經在 DSH 上做模型對比或交叉驗證,可以先按方式 B 掛 --patch 試一次,再決定要不要裝到 Profile。

目錄頁:https://www.skillhub.cn/plugins/delltig/dsh-multi-model-collab
GitHub:https://github.com/delltig/dsh-multi-model-collab

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

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

小夜