Spotify 資深工程師 Pratik Rasam 在 QCon AI Boston 2026 的演講中,揭露了 Spotify Ads Manager 內部名為 Ads AI 的多代理平台如何運作。這不是研究原型,而是實際承接廣告業務的生產系統:上線至今超過七成廣告使用其中的 AI 工具,累積為七千多家廣告主生成約兩萬個廣告素材。廣告主只需要用自然語言描述想要的廣告,系統便能產出腳本、受眾建議與投放設定。Rasam 指出,整場分享的重點不只是架構長什麼樣子,還包括團隊在開發過程中犯過的錯,以及他們最後歸納出的設計準則。
為什麼需要多代理
Rasam 回顧,十八個月前要從模型拿到穩定可解析的 JSON 並不容易,輸出經常是「像 JSON 的字串」或包在 Markdown 標記裡。如今模型對 JSON 解析、schema 檢查與業務規則驗證的支援已明顯改善,開發者能在模型輸出之後補上確定性檢查。另一方面,LangChain4j、Google Cloud ADK、CrewAI 等框架開始提供平行執行與工作階段管理等基本元件,問題從「怎麼設計」變成「怎麼實作」。可觀測性也出現供給側的變化:OTel 的 GenAI 語意慣例讓追蹤格式標準化,團隊不再需要各自發明標註方式,並且能重播生產環境的追蹤紀錄來測試判斷模型,避免代理系統變成黑盒子。
需求側同樣升溫。多步驟流程在傳統軟體中一直存在,但現在每一步都牽涉可能有多個進入點的 LLM 互動:廣告主可能在手機 App 開始建立活動,再到 Ads Manager 或 Ads API 繼續,每個進入點的意圖與上下文都不同,必須靠多代理流程把上下文串起來。加上生成式廣告可以回頭量測成效,形成閉環,把表現資料餵回系統。Rasam 的結論是,多代理並非新發明,而是三項供給側條件與一項需求側條件在近兩年同時成熟,才讓它從研究展示變成可用的架構。
代理邊界與所有權模型
在傳統的活動建立流程中,廣告主依序設定目標、受眾、預算排程與素材,問題在於每一步各自獨立,到了素材階段上下文幾乎消失,系統只用品牌、訊息、目標與廣告類別等少數欄位生成腳本。改成代理式介面後,各步驟共享同一份工作階段狀態,上下文會在流程中累積,受眾解析結果、地區、語言、歷史成效、年齡性別組合等都能納入生成考量。
但並非所有事情都該交給代理。Rasam 提出的判準是:語意、意圖與判斷交給代理,規則、目錄與資料交給程式碼,需要事實查詢的則走工具層。他強調能在程式碼中計算、能用單元測試驗證的邏輯,就應該寫成程式碼。團隊一開始把所有職責塞進單一代理與一份龐大的指令,工具全掛在同一個代理上,運作雖然可行卻十分脆弱,指令一改行為就容易出現幻覺,出錯時也難以定位。後來他們拆成三個代理:負責解析地區、人口與興趣的受眾解析代理,以及平行執行的腳本生成代理與腳本守門代理,後者負責品牌安全檢查。
拆分方式也對應組織的所有權。Spotify 廣告團隊中,受眾管理團隊擁有受眾解析代理,素材管理團隊擁有腳本生成代理。平台以「一個代理、一個套件、一個負責團隊」強制執行這個原則,每個代理是獨立的 Bazel 套件,內含相依管理、所有權資訊、PR 審查歸屬、監控資訊與儀表板告警設定。跨代理的匯入權限在編譯期就以 Bazel 可見性擋下,未經允許無法引用其他團隊的代理,違反時直接建置失敗。這種做法讓代理在撰寫任何指令之前,就已經具備指標與告警。
平台整體是一個 gRPC 服務,客戶端呼叫時建立工作階段,進入代理層,再往下到模型與工具平台。安全與編排被刻意放在代理之外的獨立層,以確保所有代理共享一致的護欄與流程。LLM 閘道使用 Vertex AI 與內部 GCP 平台,共享層另外提供指標、追蹤與工具能力,工具多數圍繞 Spotify Ads 的開發者 API,另有一層名為 kutest 的審核機制管理護欄政策。平台設計圍繞三個支柱:安全內容、模組化代理平台與彈性整合。
工具設計即提示工程
Rasam 認為工具是代理的手腳,而工具 schema 是最被低估的一環。schema 中的描述不只是給開發者看的文件,而是直接送進模型、告訴模型如何呼叫工具的契約。他以地區投放為例:使用者若只說「美國南部與中西部」,南部涵蓋十三州、中西部涵蓋十二州,若工具沒有額外帶入國別代碼,喬治亞可能被解析成國家而非州。把這類資訊放進工具描述作為接地,能避免模型自行猜測。
工具不該只是 API 的包裝,而應該對應代理的意圖。同一個上游 API 可能被兩個不同工具以不同方式使用,因為代理的需求不同。工具呼叫本身也是 LLM 呼叫,會增加延遲與成本,因此團隊會評估哪些 API 呼叫該合併、哪些該拆分。工具失敗時必須優雅退場:與其回傳一個代理無法理解的內部伺服器錯誤,不如給出結構化錯誤,讓代理知道發生什麼事並據此調整。工具也能透過 ToolContext 讀寫工作階段狀態,例如把國別代碼帶進工具,作為解析地區時的額外護欄。
團隊也歸納出幾種可重複使用的代理模式:最單純的單代理加工具,零編排負擔但要注意工具數量,三到十個還行,接近八到十個就容易幻覺;循序管線以輸出鍵傳遞狀態、易於增減階段,代價是延遲累加且上游失敗會污染整條鏈;條件路由依分類結果分派到不同代理,但路由本身是單點故障,模型也可能過度分類意圖;平行扇出適合確定能同時執行的代理,缺點是代理之間看不到彼此上下文且 token 消耗上升;生成者與評論者迴圈可反覆精煉輸出,但每輪都是完整的 LLM 往返成本,需以最大迭代次數設下退出條件。
評估與可觀測性
團隊以單元測試與模擬 LLM 的整合測試驗證管線,但 LLM 呼叫本身不確定、容易產生幻覺。Rasam 強調評估的前提是追蹤:沒有追蹤的評估只是表演。追蹤不只記錄輸出,也記錄達成輸出的過程,包含各代理的耗時、工具呼叫、審核與延遲,以及自行加入、記錄原始輸入輸出的 GenAI span。這些遙測資料可匯出到 OTel 供 Grafana 儀表板使用,或送到 Braintrust 觀察代理呼叫的樣貌。
評估分三層:工具軌跡確認代理走了正確步驟;確定性斷言檢查 schema、地區 ID 結構與年齡分桶等;LLM 作為評審則負責語調、品牌契合度與語意連貫性。此外還有即時評估,直接在生產流量上跑評估器,但不建議對全部流量執行,比例依使用情境調整,新代理可先拉高,穩定後再調降。團隊刻意不把評估掛在合併建置上,因為每次合併都會產生 LLM 呼叫成本,改為開發者離線迭代、夜間批次跑完整套件。Rasam 也提醒評審的功能是偵測而非預防,每當偵測到異常,就補上一條新的斷言,斷言越多,評審的負擔就越輕。
限制與教訓
Rasam 以幾個實際錯誤說明代理的侷限。有次輸入「納許維爾二十一歲以上女性」,代理直接輸出二十一至九十九歲,被下游系統拒絕,因為不符合既有的年齡分桶,解法是明確列舉七個支援的年齡區間。另一例是「十三到十七歲青少年的父母」,代理卻推薦十三到十七歲,問題出在把人口屬性誤當成人物設定。這些案例顯示即使採用最新模型,仍會出現出乎意料的行為,需要靠確定性護欄補強。
成本控制也是重點。團隊早期讓守門機制不分情況都執行,生成失敗時仍消耗 token 卻沒有產出。後來改為先呼叫內部的審核分類器,未通過就提早返回,確定要繼續才呼叫 LLM。Rasam 建議,若組織內已有不需 LLM 就能給出結果的方案,就應該先跑它。
回顧整體設計,他提出幾項會想改變的做法:不要打造單一巨型代理、不要讓工具設計與可觀測性被忽略、不要依賴全域系統提示。核心結論是,代理負責推理,確定性邏輯回到程式碼,工具對應意圖並優雅處理失敗,而不同團隊各自擁有並維護自己的代理,讓推理在編排層流動,再從成效回饋回到系統,這正是目前多代理架構的樣貌。
本文由 Agent Donma 當麻代理人根據公開資料進行中文技術改寫與觀點整理,並非原文逐字翻譯。