iT邦幫忙

2026 iThome 鐵人賽

DAY 28
0
AI 自動化

從單一 Agent 到 Supervisor 架構:用 n8n 實作會自己分工的 Multi-Agent AI 部門系列 第 28 篇

Day 28|正面對決:公平升級的單兵贏了 Supervisor,直到我改掉一行 prompt

  • 分享至 

  • xImage
  •  

今天把單兵 Agent 和 Supervisor 架構放在同一批信上跑。

結果是:公平升級過的單兵 Agent 贏了 Supervisor 架構,55 比 50。

我花了一段時間確認這不是測錯了。確認完之後找到原因,改了 W1 的 prompt 裡的一行,Supervisor 追回到 55 平手,而且危險錯誤比單兵少。這個過程比分數本身有意思,所以今天從頭講。

三個參賽者

拿 Day 04 那個單兵 Agent 來比是不公平的。它沒有檢索、沒有結構化輸出、沒有程式守門員——而這些東西跟「要不要拆成多個 Agent」是兩回事。前面 27 天我學到的大部分東西,單兵 Agent 也可以用。

所以我做了三個參賽者:

是什麼 有什麼
A Day 04 的單兵 Agent FAQ 塞在 prompt 裡、一個查訂單工具、輸出純文字
B 單兵 Agent v2 三個工具(查單、列單、FAQ 檢索)、Structured Output、程式守門員
C Supervisor 架構 主管+三位專員、Switch 派工、九道防線、審批分流

B 是今天真正的對手。 它拿到的東西跟 C 幾乎一模一樣:同一組 Data table 工具、同一個 bge-m3 向量庫、同一份結構化契約、同樣的「事實必須有來源」檢查、同樣的合規檢查。

唯一的差別是沒有拆開:一個 Agent 做完分類、查詢、寫信三件事。

B 的守門員就是把 C 散在三個地方的程式檢查搬到同一個 Code 節點:

// 1. 事實要有來源,沒有的丟掉(Day 11)
const facts = allFacts.filter(f => f && String(f.source ?? '').trim());
// 2. 該轉人工就不寄(Day 17)
const escalate = ['complaint', 'promo_coupon', 'other'].includes(intent);
// 3. 合規檢查(Day 13)
if (!draft.includes(SIGNATURE)) violations.push('缺少署名');

B 的 prompt 是今天一口氣寫的,裡面有 Day 17 的決策表、Day 12 的「檢索工具總是會回東西,你要自己判斷」、Day 13 的語氣規範、Day 11 的來源規則。它沒有針對這 62 封信逐案調過,而 C 被我調了 27 天。這一點後面會再提。

測試集是 Day 27 整理好的 62 封,外加 12 封從來沒用來調過任何東西的 holdout。

結果

三個系統跑同一批信的結果如下圖。

https://ithelp.ithome.com.tw/upload/images/20261012/20183868ObQs3bsN0O.png

62 封 A 單兵 v1 B 單兵 v2 C Supervisor
完全通過 30 55 50
部分通過 21 3 7
失敗 11 2 5
整個失敗、沒產出東西 0 2 0
危險錯誤 11 2 5
每封 token 中位數 946 4,312 6,073
延遲 p50 865ms 1,996ms 4,379ms

12 封沒調過的 holdout:A 4/12、B 10/12、C 10/12。

按難度拆開,差距的來源很清楚:

A B C
E 簡單(14 封) 11 13 14
M 中等(27 封) 11 24 23
H 困難(21 封) 8 18 13

所有差距都在困難那一欄。 而且方向跟我預期的相反——我以為拆分的價值就在困難案例上。

先講 A:27 天的工作確實有用

A 是 30/62,11 個危險錯誤,其中 10 個是同一種:該轉人工卻自己回了。

Day 04 的做法是叫模型在回信開頭標註 [需人工處理]。17 封該轉人工的信,它只標對 7 封。客訴信、要折扣的信、看不懂的信,它都很熱心地回了。

holdout 上更慘,4/12。

所以從 A 到 B 的進步(30 → 55)是這 27 天真正的成果:檢索、結構化輸出、程式守門員。這些東西加起來把正確率拉高了 25 封。

但那 25 封裡,沒有一封是靠拆分換來的。

然後是 B 贏 C 的那六封

B 比 C 好的有六封,C 比 B 好的有三封。

C 比 B 好的三封:

  • EV01 B 漏講物流單號。
  • EV07 和 EV60,B 整個失敗了。 這兩封各呼叫了 24 次模型、燒掉約 49,000 個 prompt token,最後什麼都沒產出,webhook 回 500。代理層看到的是同一個工具被反覆呼叫:
list_orders_by_email({"customer_email":"..."})
list_orders_by_email({"customer_email":"..."})
list_orders_by_email({"customer_email":"..."})
...連續八次,然後重跑三次

這就是 Day 26 砍掉 W1 工具時看過的同一種死法:工具回了一個它用不上的結果,模型不會放棄,它會再呼叫一次同樣的工具,直到迭代上限用完。

B 比 C 好的六封裡,有三封是同一類,而且都是 C 的危險錯誤:

客人寫的 C 的回答 B 的回答
EV12 我的濾杯什麼時候寄? 列出兩筆,請客人確認 A10294 備貨中,9/17 送達
EV56 那個淺焙的豆子到了嗎? 列出兩筆,請客人確認 A10293 已出貨,單號 8891234567
EV59 那支日曬的寄了嗎? 列出兩筆,請客人確認 A10307 已出貨,9/15 送達

還有一封 EV51,就是 Day 27 那封轉寄的髒信——C 回答了客人明說「這個我收到了」的那一筆,B 正確回答了另一筆。

四封同信箱多筆訂單的信,B 四封全對,C 四封全錯。

為什麼?不是因為上下文被丟掉了

我第一個猜測是 Day 22 的問題:主管把信壓成一句 clean_question,線索在這一步掉了。

去看才發現不是。C 的 clean_question 寫得很準:

EV12 客戶詢問濾杯的寄送時間。
EV56 詢問淺焙咖啡豆的到貨狀態。
EV59 詢問日曬咖啡豆是否已出貨

線索完整地傳下去了。W1 收到的工單上寫著「濾杯」「淺焙」「日曬」,W1 也確實用 email 查到了兩筆訂單,品項就在它手上。

它還是把兩筆都報了上來。

原因在 Day 11 寫給 W1 的查詢策略第 3 條:

3. 如果 list_orders_by_email 回傳多筆,全部回報,不要自己挑

這條規則是 Day 11 寫的,當時的問題剛好相反——W1 查到兩筆只報一筆,漏掉客人的訂單。所以我寫了一條「不要自己挑」把它堵住。

十七天後,這條規則變成另一個問題的原因。

而這件事只有在拆開的架構裡才會發生。W1 不知道客人為什麼問、不知道這封信的語氣、不知道後面要寫成什麼樣的回信。對一個只負責查資料的專員來說,「查到幾筆就報幾筆」是最安全的規則。真正能判斷「客人問的是濾杯那筆」的那個角色——也就是看過整封信的主管——手上沒有訂單清單。

資訊沒有丟,是判斷的位置和資料的位置被分在兩個地方。

單兵 Agent 沒有這個問題,因為信和訂單清單在同一個 context 裡,它直接比對就好了。

改一行,追回來

我把那條規則改成這樣(新檔 prompts/w1_v3.md):

3. 如果 list_orders_by_email 回傳多筆,先看工單的「要查什麼」裡有沒有足以指認的線索
   (品項名稱、下單時間、處理法、烘焙度等):
   - 剛好對得上其中一筆 → 只回報那一筆,並在 notes 寫下你是依據什麼判斷的
   - 對不上、或兩筆以上都符合 → 全部回報,用 subject 區分
   沒有線索的時候絕對不要自己挑一筆

先跑 Day 15 那份 20 題的 W1 考卷確認沒有退步——20/20,其中「多筆結果」那一類 3/3,跟改之前一樣。

然後重跑 62 封:

62 封 B 單兵 v2 C 原本 C 改一行之後
完全通過 55 50 55
失敗 2 5 1
整個失敗 2 0 0
危險錯誤 2 5 1
困難(21 封) 18 13 17
每封 token 中位數 4,312 6,073 6,382
延遲 p50 1,996ms 4,379ms 4,417ms

holdout 12 封:B 10/12、C 10/12,危險錯誤各 1。

正確率打平。危險錯誤 C 比 B 少一個。代價是每封多付 48% 的 token、兩倍多的延遲。

那拆分到底買到了什麼

把四欄放在一起看,我的結論是這樣。

第一,拆分本身沒有提高正確率。 55 比 55,holdout 10 比 10。真正把 30 拉到 55 的是檢索、結構化契約和程式守門員——那些單兵 Agent 一樣能用。

第二,拆分買到的是「不會整個垮掉」。 B 有兩封信整個失敗,各燒掉約 49,000 個 token 什麼都沒產出。C 一封都沒有。

原因是結構上的:C 的主管沒有工具可以呼叫(Day 18 選的 Switch 版把派工交給程式),所以它不可能在工具迴圈裡打轉;W1 的迴圈上限是 6 次而且只碰得到訂單工具。每一封信的工作量在架構上就有上界。 B 的單一 Agent 手上有三個工具和八次迭代,上界要靠模型自己收斂。

第三,拆分讓錯誤的位置變得明確。 C 剩下的那個危險錯誤是 EV16(該轉人工卻自己回),我知道它發生在分類那一步,改分類規則就好。B 的兩個危險錯誤也是分類問題,但那個分類是在同一次推理裡跟查詢、寫信一起做的——要改就得動那份什麼都管的 prompt,而動它會同時影響另外兩件事。

今天那個「改一行就追回五封」本身就是證據:在拆開的系統裡,我能把問題定位到一個 20 行的 prompt 的第 3 條。

第四,代價是真的。 每封信多付 48% 的 token、延遲從 2 秒變成 4.4 秒。如果你的量是一天 120 封,這些都是小錢;如果是一天 12,000 封,這是一個需要認真算的決定。

一個對 C 不利、但我必須講的事

B 的 prompt 是我今天一口氣寫完的,只跑過一次 smoke test 就上場。C 是我調了 27 天的東西,而且就是對著這 62 封信調的。

在這種不對等之下,B 還是贏了第一輪。

這說明兩件事。一是 27 天累積的知識大部分可以寫進一份 prompt,不需要靠架構來承載;二是我對這份評估集的 overfitting 可能比我以為的少——因為真正把分數撐起來的是那些可以用一句話寫清楚的規則,不是逐案的微調。

holdout 的結果支持第二點:兩邊都是 10/12,跟 62 封上的比例差不多。

小結

  • 三個系統、62 封信:A 單兵 v1 拿 30,B 公平升級的單兵拿 55,C Supervisor 拿 50。 第一輪是單兵贏。
  • A 到 B 的 25 封進步來自檢索、結構化輸出、程式守門員——沒有一封來自拆分。A 最嚴重的問題是 17 封該轉人工的信只標對 7 封。
  • B 贏 C 的六封裡,有四封是「同信箱多筆訂單」:B 四封全對,C 四封全錯。
  • 原因不是上下文被摘要丟掉——主管的 clean_question 把「濾杯」「淺焙」「日曬」都傳下去了。原因是 Day 11 寫給 W1 的一條規則「查到多筆全部回報,不要自己挑」,那條規則當初是為了堵住相反的問題。
  • 拆開的架構讓能判斷的角色(主管)和有資料的角色(W1)變成兩個人,而只有同時擁有兩邊的那個才有可能做對。單兵 Agent 天生同時擁有。
  • 把那條規則改成「有線索就挑,沒線索才全部回報」,W1 考卷維持 20/20,C 從 50 追到 55,危險錯誤從 5 降到 1。holdout 兩邊都是 10/12。
  • 最後的帳:正確率打平;危險錯誤 C 少一個;整個垮掉的次數 B 兩次、C 零次(B 那兩封各燒掉約 49,000 個 token 什麼都沒產出);代價是每封多 48% token、延遲兩倍。
  • 拆分真正買到的不是正確率,是工作量有上界和錯誤可以定位到一個小檔案。

明天最後一天,把這 30 天的結論收起來,包括「什麼時候不該用 Multi-Agent」。今天的數字已經先回答了一半。


上一篇
Day 27|評估集:先量雜訊再補洞,雜訊不是問題,同信箱兩筆才是
下一篇
Day 29|攻擊自己的系統:拆分擋住的不是工具權限,是「要查誰的資料」
系列文
從單一 Agent 到 Supervisor 架構:用 n8n 實作會自己分工的 Multi-Agent AI 部門 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言