iT邦幫忙

2026 iThome 鐵人賽

DAY 16
1

Day 16 | Multi-Agent 的最基礎形式:Template Workflow Agents

主張:graph 跟 dynamic workflow 給的是精細控制,但 multi-agent 編排真正的起點,是三個更基礎的固定積木——SequentialAgentParallelAgentLoopAgent。九成的多步驟需求,這三個積木就夠用,也是目前跨語言支援最完整的編排手段(Python/TypeScript/Go/Java 四種語言都有)。
讀完能做到:判斷一個多 agent 任務該用哪個模板,並知道 LoopAgent 為什麼不會自己停下來。

先講一件可能讓你意外的事

如果把 multi-agent 編排想成一個光譜,graph 跟 dynamic workflow 站在最有彈性、也最需要自己動手設計的一端。白話講:graph 是你自己畫節點(node)跟邊(edge),指定資料怎麼在 agent 之間流動、什麼條件下走哪條分支;dynamic workflow 則乾脆放棄畫圖,改用你熟悉的 if/for 這類程式語言控制流去決定要跑哪個 agent——這兩者 Day 13、Day 14 已經各自拆開講過。

今天要認識的,是站在另一端、最基礎的形式——Template workflow agents。基礎不代表次要:多數多步驟任務根本用不到 graph 的節點與邊,這三個積木就是你會第一個伸手拿的工具。

Template workflow agents 是 ADK 1.0 時代就存在的東西,繼承自 BaseAgent,執行邏輯完全確定性(deterministic),不受任何 AI 模型控制——子 agent 本身可以是不是 LLM 驅動都行,但「怎麼跑」這件事,是模板物件的固定邏輯決定的,不是推理決定的。三個積木分別是:

  • SequentialAgent:依序執行,固定順序,靠 output key 在 sub-agent 之間傳資料。
  • LoopAgent:反覆執行整組 sub-agent,但終止條件要自己實作,不然就是無窮迴圈。
  • ParallelAgent:同時執行所有 sub-agent,分支之間互不相通,適合彼此獨立的任務。

官方文件開頭就講明白它跟後起編排方式的關係:從 ADK 2.0 開始,Python 與 Go 版的模板工作流已經被更彈性的 graph-based workflows 與 dynamic workflows 取代。

graph 與 dynamic workflow 是官方認定的「進階版」,而模板這三個積木,才是理解 multi-agent 編排概念最基礎的起點——不需要學節點、邊、條件路由這些額外概念,三行程式碼就能組出一條可靠的多 agent 流程。而且別忘了——graph 跟 dynamic workflow 目前只有 Python 跟 Go 支援,如果你的專案是 TypeScript 或 Java,模板還是你唯一的多 agent 編排選項。

https://ithelp.ithome.com.tw/upload/images/20260910/20183762rmpCvbRmhq.png

SequentialAgent:固定順序,靠 Output Key 傳資料

運作方式:呼叫 run_async() 時,依 sub_agents 清單指定的順序,逐一呼叫每個 sub-agent 的 run_async()。所有 sub-agent 共享同一個 InvocationContext(可以先理解成「這次呼叫的執行環境」,裡面帶著 session state 與服務參照),代表它們共享同一份 session state(包含 temp: 這個臨時命名空間),跨步驟傳資料因此變得直接。

https://ithelp.ithome.com.tw/upload/images/20260910/20183762rVDwAg1wsA.png

最典型的用法是有明確先後依賴的任務——先抓網頁內容、再摘要,這種順序不能顛倒的流程。官方給的完整範例是一條三段式的程式碼開發管線:Code Writer 依規格寫程式碼 → Code Reviewer 審查並給意見 → Code Refactorer 依審查意見重構:

from google.adk.agents import LlmAgent, SequentialAgent

GEMINI_MODEL = "gemini-2.5-flash"

code_writer_agent = LlmAgent(
    name="CodeWriterAgent",
    model=GEMINI_MODEL,
    instruction="""
    You are a Python Code Generator.
    Based *only* on the user's request, write Python code that fulfills the requirement.
    Output *only* the complete Python code block, enclosed in triple backticks (```python ... ```).
    """,
    description="Writes initial Python code based on a specification.",
    output_key="generated_code"
)

code_reviewer_agent = LlmAgent(
    name="CodeReviewerAgent",
    model=GEMINI_MODEL,
    instruction="""
    You are an expert Python Code Reviewer.
    **Code to Review:**
    ```python
    {generated_code}
    ```
    ...
    """,
    description="Reviews code and provides feedback.",
    output_key="review_comments"
)

code_refactorer_agent = LlmAgent(
    name="CodeRefactorerAgent",
    model=GEMINI_MODEL,
    instruction="""
    You are a Python Code Refactoring AI.
    **Original Code:**
    ```python
    {generated_code}
    ```
    **Review Comments:**
    {review_comments}
    ...
    """,
    description="Refactors code based on review comments.",
    output_key="refactored_code"
)

code_pipeline_agent = SequentialAgent(
    name="CodePipelineAgent",
    sub_agents=[code_writer_agent, code_reviewer_agent, code_refactorer_agent],
    description="Executes a sequence of code writing, reviewing, and refactoring.",
)

這裡的資料流機制值得看清楚:每個 agent 用 output_key 把自己的回應寫進 state,下一個 agent 直接在 instruction 裡用 {key} 模板讀出來——code_reviewer_agent{generated_code}code_refactorer_agent 同時讀 {generated_code}{review_comments}。三個 output_keygenerated_codereview_commentsrefactored_code)串成一條完整的資料鏈,不需要額外寫任何膠水程式碼。

這正是 Day 14 提到的兩套資料流機制裡的第二套:graph 建議用 Event.Output,prebuilt workflow agents 走的是 OutputKey + state 這條路。同一個框架、兩套機制並存,寫程式碼時要清楚自己現在站在哪一邊。

LoopAgent:反覆執行,但停止不是它的責任

運作方式:依順序呼叫 sub-agent 清單裡每一個的 run_async(),跑完一輪再重來。官方文件特別用粗體強調一件事必須記住:LoopAgent 本身不會自己決定何時停止。你不寫終止機制,它就是一個無窮迴圈——這正好呼應這系列 Day 1 提過的「無窮迴圈」症狀之一,只是這次的成因不是 prompt 設計,而是模板本身的行為預期。

兩種常見的終止策略:

  • Max Iterations:在 LoopAgent 上設定最大迭代次數,跑滿次數強制停下。
  • 來自 sub-agent 的 escalation:設計一個專責評估某個條件的 sub-agent(例如「文件品質夠好了嗎?」),條件成立就發出終止訊號。

https://ithelp.ithome.com.tw/upload/images/20260910/20183762Rowm3izsyx.png

官方的完整範例是迭代式文件改善——Writer Agent 生成/修訂草稿,Critic Agent 給批評意見,兩者循環運作。以下這行是官方文件的示意片段,WriterAgentCriticAgent 只是佔位名字,不是可以直接執行的完整程式:

from google.adk.agents import LoopAgent

refinement_loop = LoopAgent(
    name="RefinementLoop",
    sub_agents=[WriterAgent, CriticAgent],
    max_iterations=5
)

CriticAgent 可以被設計成在品質達標時回傳一個「STOP」訊號提前結束整個迴圈;max_iterations=5 則是最後一道防線——即使沒有任何 agent 主動喊停,最多也只會跑五輪,不會無限燒 token。這兩種策略不是互斥的,實務上通常兩個一起用:優先靠 escalation 提前結束,max_iterations 當保底。

「STOP 訊號」具體怎麼發?官方範例是給負責評估的 sub-agent 掛一個 exit_loop 工具,呼叫它就把 escalate 設成 True

from google.adk.tools.tool_context import ToolContext

def exit_loop(tool_context: ToolContext):
    """Call this function ONLY when the critique indicates no further changes are needed, signaling the iterative process should end."""
    print(f"  [Tool Call] exit_loop triggered by {tool_context.agent_name}")
    tool_context.actions.escalate = True
    tool_context.actions.skip_summarization = True
    # Return empty dict as tools should typically return JSON-serializable output
    return {}

把這個函式塞進 CriticAgenttools=[exit_loop],agent 判斷品質已經達標就呼叫它,LoopAgent 讀到 escalate=True 就會提前跳出迴圈,不用等到 max_iterations 耗盡。

ParallelAgent:同時跑,但分支之間互不相通

運作方式sub_agents 清單裡的每一個 agent 幾乎同時啟動,各自在獨立的執行分支裡運作。執行期間分支之間不會自動共享對話歷史或 state;全部完成後,ParallelAgent 提供存取每個結果的方式,但結果的順序不保證是確定的

適用情境是多來源資料檢索、重運算量的獨立任務——只要子任務彼此沒有相依關係,平行化能大幅縮短總處理時間。關鍵前提是每個 sub-agent 必須能在不依賴其他 sub-agent 的情況下獨立運作。

官方用「crucial」這個詞強調一件事:ParallelAgent 裡的 sub-agent 是獨立運作的。如果你需要它們之間溝通或共享資料,必須自己明確實作,三種可能做法:

  • 共享 InvocationContext:當成資料存放區傳給每個 sub-agent,但要小心管理併發存取(例如用鎖)避免 race condition
  • 外部狀態管理:用外部資料庫、訊息佇列等機制促成 agent 之間溝通
  • 後處理(Post-Processing):先各自收集每個分支的結果,事後再寫邏輯統整資料

https://ithelp.ithome.com.tw/upload/images/20260910/20183762DFpS60ETlp.png

一個常見的組合技是把 ParallelAgent 巢狀放進 SequentialAgent——先平行 Fan-Out,SequentialAgent 確保接下來的彙整步驟一定等平行分支全部完成才開始:

# Conceptual Code: Parallel Information Gathering
from google.adk.agents import LlmAgent, ParallelAgent, SequentialAgent

fetch_api1 = LlmAgent(name="API1Fetcher", instruction="Fetch data from API 1.", output_key="api1_data")
fetch_api2 = LlmAgent(name="API2Fetcher", instruction="Fetch data from API 2.", output_key="api2_data")

gather_concurrently = ParallelAgent(
    name="ConcurrentFetch",
    sub_agents=[fetch_api1, fetch_api2]
)

synthesizer = LlmAgent(
    name="Synthesizer",
    instruction="Combine results from {api1_data} and {api2_data}."
)

overall_workflow = SequentialAgent(
    name="FetchAndSynthesize",
    sub_agents=[gather_concurrently, synthesizer] # Run parallel fetch, then synthesize
)
# fetch_api1 and fetch_api2 run concurrently, saving to state.
# synthesizer runs afterwards, reading state['api1_data'] and state['api2_data'].

這個模式在 Day 17 講七個多 agent 模式時還會再遇到——它就是 Parallel Fan-Out and Gather Pattern 的具體實作。

三種模板的選用心法

模板 特性 何時用
SequentialAgent 固定順序,共享 context,靠 output_key 傳資料 任務有明確先後依賴,例如「先查資料再摘要」
LoopAgent 反覆執行,自己必須實作終止條件 需要迭代改善的任務,例如反覆修訂文件或程式碼
ParallelAgent 同時執行,分支間互不相通 子任務彼此獨立,追求速度(多來源檢索、重運算)

三個模板都不夠用時:自己繼承 BaseAgent

如果連 LoopAgent 的條件式終止都滿足不了你的需求——例如「執行完三個子 agent 後,依某個 sub-agent 寫進 state 的結果決定要不要重跑第一步」這種跨步驟的條件分支——三種模板都天生做不到,因為它們的編排邏輯是寫死的,不接受你插入任意 if/else。這時候的最後一條路是自己繼承 BaseAgent,實作核心非同步方法(Python 是 _run_async_impl)寫你自己的編排邏輯,細節見官方文件(Custom agents)。

⚠️ 這是 ADK 2.0 之前的做法,2.0 之後你應該先評估 Day 13 的 Graph Workflows 或 Day 14 的 Dynamic Workflows 能不能做到你要的事,做不到才回頭寫 Custom Agent

Template 跟 Graph 的關係

把這三天的內容串起來看:graph 給你精細的節點與邊控制,dynamic workflow 給你程式語言原生的控制流,而模板給你三個現成、免接線的常見模式。實務上的判斷邏輯很簡單——能用模板解決的就別自己拉graph;等你真的需要條件分支、fan-out/join、巢狀流程這些更精細的控制時,再降到 graph 那一層自己動手。

三者不是三選一的競賽,是同一組編排思維在不同抽象層級的落地方式,而且可以混用:一個 SequentialAgent 裡的某個步驟完全可以是一整張 graph。

銜接

模板積木講完了,接下來要往「多 agent 怎麼分工」這個更大的主題走。Day 17 會攤開官方文件裡完整的七個多 agent 設計模式——包括這篇提到的 Sequential Pipeline 跟 Parallel Fan-Out/Gather 在內——並提醒你 Agent Routing 這個功能目前只有 TypeScript 能用。


Google ADK 官方網站
GitHub - Agent Development Kit (ADK) 2.0

GitHub 開源實作:https://github.com/SeanLinH/adk_tutor


上一篇
Day 15 - 讓人類插一腳:Human Input 與 Tool Confirmation
下一篇
Day 17 | 七種分工方式:Multi-Agent Workflow Patterns
系列文
Google ADK Agent 教戰:30 天從原型到可上線的 AI Agent 系統21
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言