這星期 meta 和 alibaba 接續出了 Muse-Glimmer 和 qwen3.8:27B 兩個適合 local deployment 的 LLM model,網路上查起來,似乎各有所長,不知道怎麼選擇。就想說試試看能不能兩個模型都用,說不定能比線上模型更強(希望啦!)

不選了,兩顆一起上

既然各有所長,那與其二選一,不如讓它們分工。多模型協作(multi-agent ensemble)在概念上大致有三種模式,我把三種都實作出來了:

  1. Synthesizer(並行生成 + 融合大腦):兩顆模型同時作答(asyncio.gather 並行,只需等最慢的那顆),第三個「首席架構師」節點把兩份產出的優點融合成最終版。
  2. Critic & Refine(互相審查):一顆產初稿,另一顆以自己擅長的角度審查、抓漏,直接輸出修正後的完整版本——不需要第三次生成。還可以 --reverse 反過來跑,等於雙向審查。
  3. Specialized Pipeline(專長分工管線):一顆把任務拆解成結構化 JSON 規格(元件樹、狀態、事件、資料流),另一顆照規格實作——不讓兩顆模型做同一件事。

整個框架是一個約兩百行的 Python script(asyncio + openai 的非同步 client),打任何 OpenAI API 相容的本地伺服器(llama.cpp、LM Studio、vLLM、Ollama 都行),設定檔留給使用者自己填,不綁定任何預設端點。

測試環境

  • NVIDIA GB10,121GB 統一記憶體——兩顆 27B/30B 的量化模型(合計約 34–36GB)可以同時常駐,不用輪流載入。
  • llama.cpp llama-server 開兩顆:Muse-Glimmer-30B 在 port 8080,Qwen3.8-27B 在 port 8084。
  • 角色設定靠 system prompt:Qwen 定位為「UI/UX 與視覺工程師」,Muse 定位為「架構與資料流工程師」。

四輪實測與程式碼品質評估

四個模式各跑一個真實任務,逐一檢查最終輸出的程式碼品質(滿分 10):

模式任務耗時品質
synthesizeFlutter 計數器 + Riverpod + Logger942 秒8.5
critiquePython 增量備份 CLI 工具約十餘分鐘8.5
pipeline圖片上傳 + 離線佇列(Flutter Web)1020 秒7
critique —reverseFlutter TodoList912 秒9

synthesize:第一次被截斷,調大上限後完整且可跑

第一輪的融合結果其實是四份裡架構最漂亮的(DataLogger 抽象介面 + 依賴注入),但輸出在 max_tokens=4096 被截斷,程式碼停在一個 crossAxisAlignment: 中間,不能直接跑。把上限調到 16384、並在程式裡加了截斷偵測(finish_reason == "length" 就警告)之後重跑,這次完整了:9,954 字,含 pubspec.yaml 與一路到 void main() 的完整 main.dart,括號平衡、Provider 層層注入都檢查通過。

重跑版有幾個亮點:融合節點不只合併,還抓到並修正了初稿裡一個真实的字串插值 bug$DateTime.now());日誌採「記憶體 list 給 UI 即時顯示 + 檔案持久化」雙寫,比純記憶體版更貼近 Local Data Logger 的題意。小瑕疵是 Logger 這輪用了 singleton(可測試性不如第一輪的抽象介面設計),以及用了幾個已棄用的 Flutter API(會警告但可編譯)。

同一個任務跑兩次、融合節點交出兩種不同取向的正確解——這也說明融合結果有隨機性,不滿意可以再搖一次。

critique:保留架構、補上 UX,直接可跑

Muse 先產出 StateManager/Scanner/Engine 三層的備份工具初稿;Qwen 以介面視角審查,結論是「保留原架構,把黑盒操作改造成透明、即時的互動體驗」:加上 rich 進度條與摘要表格、stdout/stderr/記錄檔三流分離、狀態檔原子寫入、Ctrl-C 處理。整份完整可跑,小瑕疵只有兩處(對 stderr 用 print 印 rich 標記不會渲染顏色;datetime.utcnow() 已棄用)。

這一輪展示了審查模式最理想的分工:審查者沒有重寫一切,而是精準補上初稿缺的那一類東西。

pipeline:規格乾淨、骨架完整,但有 bug 要人修

Qwen 產出的 JSON 規格很乾淨(183 秒,元件樹、事件、資料流需求一應俱全);Muse 依規格實作出 Repository/Notifier/UI 分層、XHR 上傳進度、離線佇列與重試的完整程式碼(836 秒)。

但細看有幾個實際問題:cancelUpload 裡 abort 的 HttpRequest 不是實際上傳用的那個請求(兩處各建了一個物件);GestureDetector 用了不存在的 onDragEnteronDragEnd 回呼,編譯會失敗;「網路恢復自動續傳」的函式寫了但沒接上 online 監聽。骨架約八成可用,需要人工修一輪。

critique —reverse:四份裡最完善

反向審查(Qwen 產稿、Muse 審查)效果最好。Qwen 的初稿是純視覺取向:Material 3、動畫勾選、漸層卡片,但狀態全部藏在 StatefulWidget 裡、日誌呼叫散落各處。Muse 的審查一口氣點了五類問題(狀態未集中、Logger 無抽象層、元件耦合、邊界防呆不足、可維護性差),重構成 Riverpod StateNotifierProvider + 統一的 AppLogger 抽象層 + trim/空值/找不到項目的防禦,UI 部分則保持原樣。

這份是四份裡最完善、最接近直接可交付的:9/10。

三個發現

1. 分工是真的。 四輪下來模式一致:Muse 的強項是分層架構、狀態管理、Logger 抽象與錯誤處理;Qwen 的強項是 UI 細節、互動回饋、視覺打磨,以及抓出「狀態和畫面耦合」這類問題。兩顆模型的盲區幾乎互補。

2. 審查方向很重要。 誰產稿,另一顆就會抓到它那一類盲點:Muse 產稿缺 UX,Qwen 產稿缺架構治理。正反向各跑一次,就是一次完整的雙向審查。

3. 工程細節決定成敗。 第一輪 synthesize 就是敗在 max_tokens=4096 截斷——調到 16384 並加上截斷偵測後重跑就完整了;四種模式一輪都在 15–17 分鐘上下(synthesize 的並行只省了第一階段,融合本身仍是一次長生成);兩顆模型同時常駐要約 34–36GB 記憶體,不夠的話可以指向同一顆模型、只用不同 system prompt 分角色。

比線上模型強嗎?

老實說:單看一次產出,還打不過最強的線上模型——pipeline 版仍有要人修的 bug。但本地玩法的優勢不在單發火力:審查與修正可以免費無限跑、資料不出機器、離線可用,而且「分工 + 互審」確實能補掉單模型的盲點。這個 workflow 把兩顆 30B 級開源模型的可用性拉高了明顯一截。

「比線上模型更強」——希望啦!但至少現在已經是一個值得用的本地協作流程。

包成 LLM endpoint:讓 agent 直接載入

做到這裡,乾脆把整條流水線包成一個 OpenAI 相容的 API server(FastAPI + uvicorn,server.py)。對任何 agent 或 LLM 客戶端來說,它就是一顆普通模型:

base_url = http://localhost:8090/v1
model    = mas/synthesize | mas/critique | mas/critique-reverse | mas/pipeline

模式即模型名稱:要哪種協作就選哪個 model,最後一則 user 訊息就是任務。實測一輪完整的 streaming 請求:SSE 每 30 秒送一次 keepalive(避免 15–17 分鐘的長請求被中間層當死連線斷掉)、階段進度以註解行推送、最終 content 是括號平衡的完整程式碼,finish_reason: stop 正常收尾。

這樣一來,「雙模型協作」不再只是個 script,而是任何 OpenAI API 客戶端都能直接掛上的推理端點——agent 寫 code 寫到一半想要一份「架構與 UI 互審過」的實作,直接 call 這個 endpoint 就行。

開源了:multi-agent-synthesizer

整套框架已放上 GitHub:github.com/alanpaul1969/multi-agent-synthesizer

簡單來說:一個輕量的雙 LLM 協作框架(Python,asyncio + OpenAI client),三種協作模式——synthesize(並行生成 + 融合)、critique(互審,可 --reverse 反向)、pipeline(JSON 規格 → 實作)——外加 server 模式把整條流水線包成一個 OpenAI 相容 endpoint(model 名稱即模式:mas/synthesize 等),任何 agent 可直接掛上。模型端點完全由 config.toml 自填,本地(llama.cpp / Ollama / LM Studio / vLLM)與雲端 OpenAI 相容 API 可任意混搭,repo 裡不含任何預設端點,中英雙語 README。

想試的人:pip install -r requirements.txtcp config.example.toml config.toml 填自己的端點 → python3 synthesizer.py --mode critique "你的任務" 就能跑。

後續

  • 框架已開源(見上節)。
  • 已完成:max_tokens 預設調大到 16384、輸出達到上限時自動警告(finish_reason 偵測)、OpenAI 相容 endpoint(server.py)。
  • 待做:pipeline 加第三階段「融合節點總檢組裝」、輸出自動過一遍編譯檢查(flutter analyzepy_compile)再存檔。