DeepSeek Super-agent 是什麼?拆解 Router 與 Worker 架構
本文目錄
- Super-agent 想解決什麼問題?
- Super-agent 的整體架構長什麼樣?
- 一則 bug 回報如何走完全程?
- Router 負責什麼?
- Worker 負責什麼?
- Worker 如何接收後續訊息?
- 文章與原型在這裡的差異
- Engine 裡的 Intake、Gate、Outbox 是什麼?
- Intake:統一的收件與分流
- Gate:呼叫 LLM 之前的規則過濾
- Outbox:對外發言的寄件匣
- Super-agent 團隊用了哪些 system design 手法優化 agent 系統?
- Batch:合併積壓的事件
- Async:避免 loop 卡在長指令
- 授權寫在程式,不依賴 prompt
- Super-agent 對 Harness Engineering 有什麼啟示?
Super-agent 是 DeepSeek Harness 團隊提出的多 agent 系統設計:由一個 Router 接收所有訊息,每項工作開一個 Worker 去執行,人只需要面對單一入口。它要處理的問題很實際,同時開多個 coding agent session 時,一個人能跟上的數量大約只有 3 到 5 個,超過之後,就得自己記住每個視窗在做什麼、哪個在等回覆、哪個已經偏離方向。Super-agent 把這份追蹤工作從人身上移到系統裡。
本文依據官方公開的研究原型 dsh-superagent-prototype,以及團隊文章〈Exploring Super-agent Design〉的內容轉述。原型建立在 DeepSeek Harness 之上(底層 runtime 可參考這個系列的第一篇),接一個 GitHub repo,可選擇再接 Feishu(Lark)。README 明確說明原型與文章描述的內部版本不同,部分設計只代表方向,文中遇到兩者有差異之處會另外標出。
讀完本文,你會理解:
- Super-agent 想解決什麼問題,以及它的三個設計目標
- Router、Worker、Engine 三種角色各自負責什麼
- Intake、Gate、Outbox 三個設計是什麼、為什麼需要
- Super-agent 團隊借用了哪些 system design 手法來優化 agent 系統
Super-agent 想解決什麼問題?
Super-agent 要解決的是「一個人同時監督多個 agent」的問題。最直覺的做法是開一個主 session,再由它派出 subagent,但訊息量一多,這個主 session 必須同時負責接收每則訊息、判斷歸屬、轉發後續、與人溝通、維護任務狀態,還要避免新輸入打斷手上的工作。
在這種結構下,閒聊、code review、CI 通知與程式碼全部混在同一個 context 裡,任務之間的隔離只能依賴模型遵守 prompt。團隊在實驗中觀察到,只修改一句「優先委派」的 prompt,任務完成時間與長尾就出現明顯差異。問題出在系統結構,單靠調整 prompt 無法穩定。

Super-agent 因此訂下三個設計目標:
- 人只面對一個入口,不必自己追蹤每個 session。
- 每個任務在各自的 agent loop 裡執行,彼此隔離。
- LLM 只處理需要理解語意的事,能以規則決定的部分一律寫成程式。
Super-agent 的整體架構長什麼樣?
Super-agent 由三種角色組成:常駐的 Router、每個 Ticket 一個的 Worker,以及負責過濾、記錄狀態與送出訊息的 Engine。agent loop 只存在於 Router 與 Worker;Engine 是 plugin 內的一般 TypeScript 程式,不呼叫 LLM。
在看架構圖之前,先認識系統中反覆出現的幾個名詞:
| 名詞 | 意思 |
|---|---|
| Source | 外部訊息來源的 plugin,原型有 GitHub 與 Feishu 兩種 |
| Trigger | 進入系統的一則事件,例如一則留言或一次 CI 結果 |
| Thread | Trigger 所屬的對話,例如同一個 Issue、PR 或聊天話題 |
| Ticket | Router 接下的一項工作,每個 Ticket 對應一個 Worker |
| Eval | 判斷新訊息是否成為工作的流程,Gate 是第一層,通過後再交給 Router |
| Mandate | 授權紀錄,決定誰能發起工作 |

| 角色 | 是否為 agent loop | 負責 | 刻意不做 |
|---|---|---|---|
| Router(主 session) | 是,常駐一個 | 判斷新訊息是否成為工作、分派、停止 | 不讀 code、不改寫需求、不做技術判斷 |
| Worker(每個 Ticket 一個) | 是,可並行多個(預設 3) | 實作、驗證、開 PR | 不決定新工作 |
| Engine(plugin 內的程式) | 否 | 過濾、儲存狀態、訂閱分流、授權紀錄、送出回覆 | 不呼叫 LLM |
一則 bug 回報如何走完全程?
以下用一個示意情境說明訊息在系統中的路徑。情境是為了說明而設計,並非原型的實際紀錄。
- 白名單上的成員在群組裡 @ agent,回報某個 API 回傳錯誤。這則 Feishu 事件進入 Intake,存成一筆 Trigger,掛到這個聊天話題的 Thread 上。
- 這個 Thread 還沒有 Worker 訂閱,訊息排進 Eval。Gate 看到發訊者在白名單上、而且直接 @ agent,判定為 explicit。同一時間,群組裡的其他閒聊被 Gate 歸為不收,直接丟棄,沒有花費任何 LLM 呼叫。
- Router 判斷這是一項新工作並接下,Engine 建立 Ticket、啟動 Worker,Worker 訂閱這個聊天話題。
- Worker 透過 Outbox 在原訊息下確認需求,接著修改程式、執行測試、開 PR,這個 PR 也成為它訂閱的 Thread。
- PR 的 CI 結果與 review 留言進入 Intake 後,因為 Thread 已有訂閱,直接送到這個 Worker,不經過 Gate 與 Router。
- 修正完成後,PR 連結與完成通知寫入 Outbox,依序送回群組。Worker 的報告同時轉給 Router,讓它掌握全局。
整個過程中,Router 只在第 3 步做了一次判斷,其餘訊息都由程式依規則或訂閱關係處理。
Router 負責什麼?
Router 是 Super-agent 的主 session,只負責任務之間的分派:判斷一則新訊息要不要成為工作、交給哪個 Worker、何時停止。它的定位接近 dispatcher,與常見的 agent team lead 不同。team lead 需要理解單一複雜任務的細節,Router 只處理任務之間的關係,不進入任務內部。
為了守住這個定位,Router 被刻意限制得很窄:
- 它只轉交 Trigger 原文與路由事實,不讀 code、不改寫需求,也不做技術決定。
- 路由備註最多 30 字。
- 程式直接封鎖 Router 的
sleep與長時間等待,避免它被卡住而漏接新訊息。
這些限制的目的,是讓 Router 保持輕量。文章建議 Router 搭配較輕的模型與較少的工具,Worker 則使用強模型。
Worker 負責什麼?
Worker 是每個 Ticket 專屬的 agent loop。每個 Worker 擁有自己的 session 與工作目錄,負責實作、驗證與開 PR,原型預設最多 3 個 Worker 並行。任務之間的隔離由結構保證:不同 Ticket 的 context 本來就分開,不需要靠 prompt 提醒模型「不要混在一起」。
Worker 拿到完整任務後,內部如何協作由它自己決定,可以再開 subagent,甚至組一個 agent team。步驟層級的分工留在 Worker 內,不會回到 Router。反過來,Worker 不決定新工作,收到超出範圍的訊息時,會交還給 Router 處理。
Worker 如何接收後續訊息?
Worker 建立後,會訂閱對應的 Thread,例如同一個 PR 的 CI 結果與 review 留言,或同一個 IM 話題。之後在這些對話上出現的訊息,會直接 fan-out 給訂閱的 Worker,不再經過 Router。
訂閱關係有兩個特性:
- 關係是多對多,一個 Thread 可以同時送給多個相關的 Worker。
- 訂閱只提供 context,不提供授權。Worker 若要開啟新工作,仍然必須經過 Router。
訂閱的目的是讓 Router 只需要為新任務做判斷。它節省的是重複路由的決策與 token,Worker 本身的執行時間不受影響。
文章與原型在這裡的差異
文章描述 Worker 不直接面對人,一律由 Router 統一回覆。原型中的 Worker 則會自己在原訊息下確認需求、在 PR 上回覆 review,只是這些訊息同樣經過 Outbox 送出,也受回覆長度規範限制。
Engine 裡的 Intake、Gate、Outbox 是什麼?
Intake、Gate、Outbox 是 Engine 中的三段程式,都不呼叫 LLM。Intake 與 Gate 位於 agent loop 的入口,Outbox 位於出口,它們的共同目的,是替 agent loop 處理掉不需要理解語意的工作。
| 設計 | 位置 | 是什麼 | 目的 |
|---|---|---|---|
| Intake | 入口 | 收件、去重、依訂閱分流 | 避免重複工作,後續留言不必再經過 Router |
| Gate | Router 之前 | 以規則判斷訊息的請求強度 | 擋掉噪音,並由程式決定誰能叫 agent 做事 |
| Outbox | 出口 | 對外訊息先存再送、依序重試 | 避免訊息遺失、重複或順序錯亂 |
Intake:統一的收件與分流
Intake 是所有外部事件的收件處。GitHub 與 Feishu 的事件進來後,Intake 依序完成四件事:把事件存成 Trigger,同一事件重複收到只計一次;把 Trigger 掛到所屬的 Thread,也就是同一個 Issue、PR 或聊天話題;查詢這個 Thread 有哪些 Ticket 訂閱,直接把訊息送給對應的 Worker;其餘訊息排進 Eval 佇列,等待判斷。
它的運作方式類似郵件分揀中心,已有負責人的信件直接送到對方桌上,新信件才放進「待判斷」的那一疊。
Intake 的目的有兩個。一是讓輪詢或重送不會產生重複工作;二是讓既有任務的後續留言直接抵達負責的 Worker,Router 不必每次重新判斷。
Gate:呼叫 LLM 之前的規則過濾
Gate 是 Eval 的第一層,只使用規則,不呼叫 LLM。它依每個 Source 各自的 admission table,看兩件事:發訊息的人是否在名單上,以及是否直接呼叫 agent。據此把訊息分成三種強度:
| 強度 | 適用情況 | 後續處理 |
|---|---|---|
| explicit(明確請求) | 白名單上的人直接找 agent,例如 @ 它 | 交給 Router 決定是否接下 |
| inferred(推斷的候選) | 沒有直接找 agent 但可能有用,例如群組裡未 @ 的 bug 回報、特定 bot 的訊息 | 依接單模式而定:off 丟棄、observe 只記錄「would accept」、auto 才可能真的接下 |
| 不收 | 其他 bot、閒聊、未設定接收的範圍 | 直接丟棄,不花費任何 LLM 呼叫 |
Gate 處理的是兩個風險:群組噪音耗盡 Router 的 context 與 token,Super-agent 主動加入群組聊天後,最先湧進來的一定是噪音;以及安全,「誰能叫 agent 做事」如果只靠 prompt 約束,擋不住 prompt injection,交給程式規則判斷才可靠,也方便稽核。
Outbox:對外發言的寄件匣
Outbox 負責 agent 對外說的每一句話,包括確認收到、提問、PR 連結與完成通知。它的運作分成四個部分:
- 「要送出這則訊息」與當下的狀態變更,寫進同一個 SQLite transaction。
- 背景程式從佇列取出訊息,透過 Source 送出;失敗就重試,間隔從 5 秒倍增,最長 5 分鐘。
- 同一個 Ticket 在同一個對話中,前一則尚未送出時,後一則會等待,避免「完成了」比「收到」更早出現。
- Source 關閉時,訊息會等到恢復再送;對話已不存在則直接丟棄。

這套做法就是 system design 中的 transactional outbox。它的目的是避免狀態已變更但訊息沒送出、重啟後重送、多則訊息順序錯亂等情況,同時讓 agent loop 不必等待網路 I/O。
Super-agent 團隊用了哪些 system design 手法優化 agent 系統?
Super-agent 團隊的每一個設計,都在回答同一個問題:這件事需要 LLM 嗎?不需要就寫成程式;需要的話,也不應該讓它阻塞 loop。團隊為此借用了七個傳統 system design 手法:
| 團隊的做法 | 對應的傳統手法 | 目的 |
|---|---|---|
| Gate 先以規則過濾,再交給 Router | API gateway、規則引擎 | 減少 LLM 呼叫次數 |
| Router 只分派,不碰任務內部 | Load balancer、dispatcher | 保持 Router 的 context 精簡 |
| 後續訊息直送已訂閱的 Worker | Pub/Sub、topic fan-out | 省下重複路由的決策與 token |
| 積壓的 Trigger 合併成一批處理 | Request coalescing | 撐住高負載下的 Router 吞吐量 |
| 長指令轉到背景,完成後以新事件送回 | Non-blocking I/O、job queue | 避免 loop 被卡住 |
| 對外動作先存再送,依 Ticket 保持順序 | Transactional outbox | 避免重啟後重複或遺失 |
| 授權由程式強制,不依賴 prompt | Policy enforcement point | 縮小 prompt injection 的風險面 |
過濾、分派、訂閱與 Outbox 已在前面各節說明,以下補充 Batch、Async 與授權三項。
Batch:合併積壓的事件
團隊在三個層次上做批次處理。每個 Thread 同一時間只跑一個判斷,判斷進行中又進來的 Trigger,併入下一批;Router 忙碌時,新進的轉送會在它的下一步一併送達;一次 orchestrator_route 呼叫可以對多個候選分別做出 accept、attach、stop 或 ignore,單筆失敗不影響其他筆。
這樣一來,事件速率上升時,Router 每次處理的筆數跟著增加,不會撞上單一 Router 的吞吐上限。
Async:避免 loop 卡在長指令
典型的 ReAct loop 呼叫同步的 run(),長指令執行期間,session 無法接收新訊息。團隊把耗時工具改成 start() 與 stop():start() 立即回傳 Started,執行結果完成後再以新事件送回 session。這段期間,人可以補充條件、要求停止,或開啟其他工作。

原型的做法是前景 shell 超過 5 秒就轉入背景,並替人的訊息額外保留一個 slot。文章提到非同步工具已在 Harness 中實作,但目前尚未預設啟用。
授權寫在程式,不依賴 prompt
誰能發起工作,由 Gate 與 Mandate(授權紀錄)在程式層強制執行。修改 prompt 只能影響行為指示,碰不到授權。
主動接單同樣由程式控制,分為三種模式:off、observe 與 auto。預設是 observe,只記錄「would accept」而不真的接下。回覆長度也有規範,聊天預設一句,上限 100 words,細節留在 Worker 與 PR 中。
這七個手法沒有一個是新發明。Filter 加上 Router 是 LLM 版本的 fast path 與 slow path 分流,Subscription 是 pub/sub,Batch 是 request coalescing,Outbox 是 transactional outbox。Super-agent 團隊做的,是把 event-driven 系統的既有做法套用在 agent loop 外圍,效益來自少做無用的工作,而非多加幾個角色。
Super-agent 對 Harness Engineering 有什麼啟示?
Super-agent 的設計裡,最關鍵的是它劃出的那條邊界。整個系統只有兩種位置需要 LLM:Router 判斷任務之間的關係,Worker 處理單一任務的內容;去重、過濾、分流、送出與授權,全部交給不呼叫 LLM 的程式。多個 agent 能並行而不互相干擾,靠的就是這條邊界。
邊界外側的這些工作,正是 Harness Engineering 的範圍。模型能力持續進步,但要讓多個 agent 穩定地一起運作,誰能叫 agent 做事、訊息如何分流、失敗如何重試,都必須由系統保證。Super-agent 團隊用到的訂閱、批次、非同步與 transactional outbox,都是傳統 system design 的既有機制,如今正逐步被放進 agent 系統。模型變強之後,系統工程的觀點反而更加重要。