A2A 協定:打破 AI 溝通的高牆

A2A 協定:打破 AI 溝通的高牆

開了一間規模龐大的跨國企業,重金聘請全世界最頂尖的十位專家:精通量化分析的資料科學家、能寫出得獎文案的創意總監、執行力無可挑剔的專案經理。這個夢幻團隊理論上無堅不摧——但架構有個致命陷阱:這十位專家被分別關在十個完全隔音的獨立房間裡,而且每個人說著完全不同的語言。

當需要完成複雜的大型專案時,我們沒有辦法讓他們開會。只能自己跑去第一個房間要資料,再跑到第二個房間請人翻譯,翻完拿去分析,最後跑到第三個房間求人把結果寫成報告。夢幻團隊的潛力,全部被那堵無法溝通的無形高牆消耗殆盡。這正是目前企業級 AI 應用的殘酷現況。

單一 AI 的瓶頸

到了這個階段,為什麼我們會覺得單一超大型 AI 助理好像已經不夠用了?我們不是已經有參數動輒幾千億的大型語言模型了嗎?因為真實世界問題的複雜度正在指數級上升 – 一個單一的 AI 模型,無論參數多龐大,它的上下文空間、推理邏輯,甚至專業微調都有極限——它存在某種方向性。有的擅長寫文案,有的擅長分析數據。

當要求 AI 規劃一個完整的跨國供應鏈最佳化方案時,這已經不只是「幫我寫一段優美的文案」或「解析一段長程式碼」那麼簡單。它需要:

子任務 需要的專業
抓取即時全球天氣資料 氣象資料 API
分析航運競爭對手定價 市場情報
預估匯率波動的財務成本 財務分析
產出策略報告 策略規劃

單一模型處理這種跨領域多步驟任務,不只容易產生幻覺(開始胡說八道),運算效率也極度不合理——不可能讓一個超大型模型去處理所有雞毛蒜皮的小事。所以開發者開始走向多代理(Multi-Agent)架構。市場上出現各種 AI 框架,像是 LangGraph、CrewAI,或是 Google 提出的 ADK(Agent Development Kit),用不同框架打造出各種極度專業的 AI 專家。

問題又回到開場的比喻:它們聽不懂彼此的語言。用 LangGraph 寫出來的資料分析 AI,在底層邏輯和資料格式上,聽不懂用 CrewAI 寫出來的規劃 AI 在說什麼。這不只是兩段程式碼接不起來的問題,而是整個企業想擴充自動化流程時會撞上的高牆。

A2A 協定:AI 之間的共通語

Google 提出的 A2A(Agent-to-Agent)協定,是一個基於 HTTP 的開放標準(HTTP 就是我們上網用的網頁通訊協定)。它的目的就是打破孤島,成為所有 AI 代理之間的共通語。用開場的比喻來說:A2A 協定就像是在那些隔音房間之間牽起實體的網路線,並且發給每個 AI 一台完美的通用翻譯機與任務指派系統。

這絕對不是只在實驗室自嗨的小眾技術,它解決的是實實在在的企業痛點,而且已經獲得業界巨頭的廣泛支援:

公司 動態
Microsoft 計劃將 A2A 整合進 Azure AI Foundry 與 Copilot Studio
SAP 支援 A2A,並整合進自家平台與代理
Salesforce 支援 A2A
ServiceNow 支援 A2A
Atlassian 支援 A2A
Box 支援 A2A
LangChain 支援 A2A
MongoDB 支援 A2A
Auth0 正在將 A2A 支援整合進平台與代理

連 SAP、Salesforce、ServiceNow 這種商用軟體巨頭都進來了,代表未來的企業後台,可能真的就是一堆 AI 在背景互相開會、協商。整個科技產業都意識到:我們談論的不再是單一使用者的單一 AI,而是如何管理幾千幾萬個微型代理,讓它們同時運作,形成模組化、可擴充的 AI 生態系統。

代理卡(Agent Card):AI 的數位身份證

在一個擁有數千個服務的 AI 網路裡,甚至是在茫茫網際網路大海中,AI 要怎麼知道誰具備什麼技能?如果彼此之間沒有一本共同的「黃頁目錄」,那條籤起來的網路線就毫無意義——總得知道要打給誰。這就帶出 A2A 協定的第二個關鍵概念:代理卡(Agent Card),AI 的數位身份證。

A2A 架構下有三個核心參與者:

發出需求的使用者
    │
    ▼
客戶端代理 ──(A2A)──> 遠端代理(A2A 伺服器)

遠端代理對客戶端來說,是一個刻意設計成不透明(Black Box)的系統。客戶端代理在委派任務時,完全不需要知道遠端 AI 是用 Python 還是 Java 寫的,也不用管它背後跑的是 GPT-4 還是 Gemini。這就是系統解耦(Decoupling)的精髓——客戶端唯一需要解析的,就只有那張代理卡。

代理卡是一個標準化、結構化的 JSON 檔案,記錄了:

欄位 說明
端點 URL 遠端 AI 的位址
版本 代理卡的版本,方便相容性管理
通訊能力 例如能否進行即時事件串流傳輸、推送通知、狀態轉移歷史
技能 它會做什麼,含輸入/輸出格式
認證要求 存取這個代理需要哪種身份驗證(例如 API Key)

像資料提到的 weather 天氣代理,它的代理卡就會清楚標明:具備查詢天氣的技能,輸入地點(例如「巴黎的天氣如何?」),然後輸出對應的氣溫與降雨機率。

// 天氣代理的代理卡(agent-card.json)
type AgentCard = {
  name: string
  url: string
  version: string
  description: string
  skills: Array<{
    id: string
    name: string
    description: string
    inputModes: string[]
    outputModes: string[]
  }>
  capabilities: {
    streaming: boolean
    pushNotifications: boolean
    stateTransitionHistory: boolean
  }
  authentication: {
    schemes: string[]
  }
  defaultInputModes: string[]
  defaultOutputModes: string[]
}

const weatherAgentCard: AgentCard = {
  name: 'weather-agent',
  url: 'https://weather.example.com/a2a',
  version: '1.0.0',
  description: '查詢全球即時天氣與降雨機率',
  skills: [
    {
      id: 'check_weather',
      name: 'check_weather',
      description: '輸入地點,回傳氣溫與降雨機率',
      inputModes: ['text'],
      outputModes: ['text'],
    },
  ],
  capabilities: { streaming: true, pushNotifications: false, stateTransitionHistory: true },
  authentication: { schemes: ['apiKey'] },
  defaultInputModes: ['text'],
  defaultOutputModes: ['text'],
}

代理發現:三種找名片的方式

遠端代理是一張靜態的 JSON 名片,那客戶端代理要怎麼在浩瀚的網路上動態發現這張名片?A2A 定義了三種明確的代理發現策略:

  1. 眾所周知的 URL(Well-Known URL):遠端代理把代理卡放在一個標準化的路徑下,例如網站根目錄的 /.well-known/agent.json,讓其他系統可以自動化爬取和識別。就像直接走到大廳的公佈欄去看名單。這適合完全公開的基礎服務。但如果牽涉到企業機密的財務分析,總不能把名片直接貼在大廳,讓網路上所有的爬蟲程式都看得到。
  2. 精選登錄檔(Selective Registry):集中式的目錄服務,就像企業內部的 App Store 或受嚴格控管的目錄服務。所有代理卡都必須經過稽核,發布到集中的登錄檔裡。客戶端代理可以根據特定標準查詢,例如「幫我找一個擁有存取 Q3 財報權限、而且回應延遲保證在一秒內的財務 AI」。這種模式非常適合企業環境,因為可以透過登錄檔進行嚴格的存取控制、版本管理和流量監控——就像企業內部有門禁的 AI 人才庫。
  3. 直接設定(Direct Configuration):如果兩個系統根本是同一個開發團隊寫的,只是拆成兩個微服務,有更直接的做法:開發者把遠端代理卡的資訊直接寫進程式碼或環境變數裡,完全不透過任何外部目錄。它們早就認識彼此,不需要在外面拋頭露面被別人發現,只需要專注於彼此溝通就好。
發現策略 方式 適合場景
眾所周知的 URL /.well-known/agent.json 公開的基礎服務
精選登錄檔 集中式稽核目錄 企業受控環境
直接設定 環境變數 緊密耦合的私有系統

非同步任務通訊:不是粗暴的 HTTP POST

透過三種策略,客戶端代理找到了對的 AI 專家、拿到了數位名片、知道輸入輸出格式。接下來它們具體怎麼對話?A2A 的通訊嚴格圍繞非同步任務(Asynchronous Task)建構。所有通訊透過 HTTP/HTTPS,資料層使用 JSON-RPC 2.0 協定。但 HTTP 本身是無狀態的,不會記住過去的對話。為了解決這個問題,伺服器每次接受任務時都會產生一個 Context ID,就像任務的追蹤號碼,用來保留長任務的上下文連貫性——寄包裹的追蹤碼。

這也帶出一個實用的能力:多輪對話(Multi-turn)。當遠端代理發現資訊不足、需要客戶端補資料時,它可以把任務狀態設為 input-required,明確回覆「還缺什麼」;客戶端補上資訊後,再以同一個 Context ID 續問。這讓 A2A 的互動不是一次性的問與答,而是可以來回補齊資料的完整協作流程。

四種互動機制:依任務輕重緩急選擇通訊方式

A2A 定義了四種互動機制,代理可以根據任務性質選擇最有效率的溝通方式。用點餐的經驗來比喻最容易理解:

機制 點餐比喻 技術 適合任務
同步請求/回應 得來速點餐 阻塞式 HTTP 極快、立刻要結果的簡單任務
非同步輪詢 美食街叫號機 Polling + Context ID 中等耗時任務
串流更新 回轉壽司 SSE(Server-Sent Events) 生成式 AI、長文件輸出
推送通知 外燴送餐 Callback URL 跨天、資源密集型任務

同步請求與回應(得來速點餐)

在得來速點一份漢堡,把車停在窗口、引擎不熄火,什麼事都不做,死死盯著店員直到他把漢堡遞過來。技術上這就是阻塞型操作:客戶端發出 HTTP 請求後連線保持開啟,一直等到收到遠端代理完整的結果回應。

const response = await fetch('https://calculator-agent.example.com/', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: 'req-001',
    method: 'tasks/send',
    params: {
      id: 'task-001',
      message: { role: 'user', parts: [{ text: '計算 2 + 2' }] },
    },
  }),
})

const result = await response.json() // 阻塞等待完整結果

很卡,但適合那些運算極快、立刻就要有結果的簡單任務。

非同步輪詢(美食街叫號機)

去百貨公司的美食街點餐,店員給一個會震動的叫號機。點完餐可以先去旁邊逛街,只是得偶爾低頭看叫號機亮了沒。客戶端可以先去執行其他工作,然後定期拿 Context ID 問伺服器「任務標記為完成了嗎?」。

但輪詢有致命傷:擴充性很差。在一個有一萬個微型代理的企業系統裡,每個客戶端代理每秒都去問伺服器「好了沒」,會產生巨大的無效網路流量,甚至造成伺服器崩潰。這就是 A2A 提供第三、四種更優雅機制的原因。

串流更新(回轉壽司)

坐在日式回轉壽司店的吧檯,師傅在裡面做壽司,做完一盤就直接推到軌道上送到面前,完全不需要一直開口問「好了沒」。只要軌道連線著,好料就會源源不絕主動送過來。

SSE 建立了一個持久的單向連線,這對生成式 AI 特別有用。遠端代理正在生成一份長達五十頁的報告時,不需要等全部寫完才回傳,而是寫完一段就透過 SSE 推送一段,客戶端代理就能即時處理這些增量結果。

const response = await fetch('https://report-agent.example.com/', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: 'req-002',
    method: 'tasks/sendSubscribe',
    params: {
      id: 'task-002',
      message: {
        role: 'user',
        parts: [{ text: '生成一份 50 頁的市場分析報告' }],
      },
    },
  }),
})

// 透過 SSE 串流接收增量結果,寫完一段處理一段
const reader = response.body?.getReader()
const decoder = new TextDecoder()

while (true) {
  const { value, done } = await reader!.read()
  if (done) break
  processChunk(decoder.decode(value))
}

實務上,tasks/sendSubscribe 回傳的是標準 SSE 格式(event:/data: 欄位),不建議手刻解析器。用現成的 eventsource-parser(或 Node 端的 EventSource client)來拆解串流,既能正確處理多行 data,也少踩邊界案例的坑——上面的 getReader() 迴圈是示意「逐段處理」的思維,實作時換成解析器更穩。

推送通知(外燴送餐)

舉辦一場派對,請外燴公司。給他們地址和電話,告訴他們「菜全部做好再主動聯絡送到這個地址」,中間完全不用管他們怎麼煮,也不用開著連線等。

對於極耗時、甚至需要跨越多個日曆執行好幾天的資源密集型任務,保持連線或一直輪詢都太浪費網路資源。客戶端可以提供一個回覆網址(Callback URL),當遠端伺服器任務狀態發生重大改變或完成時,它會主動發送一個 HTTP POST 到那個網址來通知客戶端。

await fetch('https://research-agent.example.com/', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: 'req-003',
    method: 'tasks/send',
    params: {
      id: 'task-003',
      message: { role: 'user', parts: [{ text: '模擬供應鏈風險分析' }] },
      pushNotificationConfig: {
        url: 'https://client.example.com/callback',
        token: 'secret-token',
      },
    },
  }),
})

跨模態的工件傳遞

A2A 協定有一個關鍵技術亮點:與模態無關(Modality Agnostic)。這代表 A2A 不只是用來傳遞程式碼指令或純文字結果。代理執行任務時產生的輸出,在 A2A 規範裡被統稱為 Artifact(工件)。這些工件不只是結構化的 JSON 資料——如果遠端代理是影像生成模型,它可以直接把高畫質圖片檔或音訊檔作為工件回傳。這大大省去人類在不同軟體間轉換格式的時間。

資料分析 AI 可以直接產出一支包含動態圖表的影片,直接作為工件交給簡報 AI 排版。這就是 A2A 跨模態的威力。

MCP vs A2A:向外看 vs 向內看

前陣子才大力推廣的 MCP(Model Context Protocol),跟 A2A 是不是在做同一件事?A2A 會不會是多餘的?

很多人會把兩者搞混,因為它們看起來都在解決 AI 溝通的問題。但實際上它們不僅不衝突,反而是完美的互補。簡單來說:MCP 的焦點是向外看,A2A 的焦點是向內看。可參考這裡-MCP:讓 AI 從只會聊天到真正做事

  MCP A2A
核心問題 單一 AI 如何存取外部系統 AI 與 AI 如何協調委派
方向 向外看(代理 → 工具) 向內看(代理 → 代理)
比喻 AI 拿工具的手 AI 之間的橋樑
互動對象 非 AI 的外部系統、資料、工具 其他 AI 代理

MCP 專注於讓單一 AI 代理能與非 AI 的外部系統互動,為代理建立上下文——讀取本地端電腦的檔案、查詢第三方 SQL 資料庫。沒有 MCP,AI 就缺乏現實世界的資料。但當這個代理拿到 SQL 資料庫的資料後,如果需要把它交給另一個專門生成互動式圖表的 AI,MCP 就無能為力了。這時需要 A2A 登場——它專注代理與代理之間的協調與任務委派。沒有 A2A,AI 就永遠只能孤軍奮戰。

MCP:授權代理查詢企業內部 SQL 資料庫
     ↓ 撈出第一季銷售資料
A2A:使用 JSON-RPC 把原始資料打包
     ↓ 跨網路移交給託管在 Google Cloud 的視覺化代理
     ↓ 產出圖表 Artifact

兩者結合,才是企業級多代理生態系統的完整藍圖。

實作:日曆代理

Google 的 a2a-samples 儲存庫展示了具體的實踐範例——用 Python 和 Google ADK 建立的日曆代理(calendar agent),專門處理行程的微服務。我們改寫為 TypeScript:

import { LlmAgent } from '@google/adk'

// 官方 a2a-samples 是 Python 範例:
//   from google.adk.tools.google_api_tool import CalendarToolset
//   toolset = CalendarToolset(client_id=..., client_secret=...)
//   tools = await toolset.get_tools()
// 此處以 TypeScript 示意對應的代理結構,
// getCalendarTools() 代表取得行事曆工具集的步驟
const calendarTools = await getCalendarTools()

// 建立配備 Gemini 模型的 LLM 代理
const calendarAgent = new LlmAgent({
  name: 'calendar_agent',
  model: 'gemini-2.0-flash-001',
  instruction: '行事曆助理,負責查詢與安排行程。',
  tools: calendarTools,
})

// 3. 代理卡中明確定義「檢查可用性」技能
const calendarAgentCard = {
  name: 'Calendar Agent',
  url: 'http://localhost:8000/',
  version: '1.0.0',
  description: '管理行事曆行程',
  skills: [
    {
      id: 'check_availability',
      name: 'check_availability',
      description: '檢查指定時間是否可預約',
      inputModes: ['text'],
      outputModes: ['text'],
    },
  ],
  capabilities: { streaming: true, pushNotifications: false },
}

其他客戶端 AI 就可以透過 A2A 發現這個日曆代理,送出 JSON-RPC 請求呼叫 check_availability,問「下週二下午三點有空嗎?」:

const response = await fetch('http://localhost:8000/', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: 'req-010',
    method: 'tasks/send',
    params: {
      id: 'task-010',
      message: {
        role: 'user',
        parts: [{ text: '下週二下午三點有空嗎?' }],
      },
    },
  }),
})

開發者還推薦使用 Trickle AI 工具。當多個代理透過非同步 JSON-RPC 互相丟訊息時,出錯會變成一場惡夢,根本不知道誰丟給誰。Trickle AI 可以將底層的 A2A 通訊視覺化,清楚看到哪個代理呼叫了誰、帶了什麼參數。

企業級安全防線

任何代理都可以透過 HTTP 呼叫另一個代理的 API,如果未經授權的外部 AI 代理突然呼叫了日曆代理,甚至利用漏洞修改行程怎麼辦?機器與機器之間的信任機制是核心問題。A2A 沒有把安全當做事後補充的選項,而是把它放在架構的核心位置——它不是一個門戶洞開的 API 系統。有四道防線:

防線一:mTLS 雙向驗證
  ┌──────────┐         憑證          ┌──────────┐
  │ 客戶端AI │ ◄──────────────────► │ 日曆代理 │
  │ 出示憑證 │                      │ 出示憑證 │
  └──────────┘                      └──────────┘
  通訊雙方都必須證明真實身份

防線二:全面的稽核日誌
  所有代理間通訊:哪個 Context ID、幾毫秒、傳了什麼任務、
  帶了什麼工件,通通鉅細靡遺記錄

防線三:代理卡聲明認證要求
  代理卡上明確列出存取需要的身份驗證方式,集中管理

防線四:憑證只放 HTTP Header
  OAuth token 只能透過 Header 傳遞,禁止放 URL 或 Body

第一道防線:mTLS(相互傳輸層安全性)。一般瀏覽網頁看到的鎖頭是 TLS,只有伺服器向客戶端證明身份。但在 mTLS 中,通訊的雙方都必須出示由受信任的憑證機構頒發的加密憑證——不只伺服器要自證清白,客戶端也要。這就像一種只有授權 AI 才擁有的秘密握手,徹底防堵偽造身份的流氓代理。雙向驗證是微服務架構的黃金標準。

第二道防線:全面的稽核日誌。A2A 規範了所有代理間通訊——哪一個 Context ID、在什麼毫秒傳送了什麼任務、帶了什麼工件,全部都要記錄下來。反走過必留下痕跡。發生越權存取時,資安團隊就可以沿著 JSON-RPC 的呼叫鏈,一路追蹤回最原始的發起者。

第三道防線:代理卡聲明認證要求。前面介紹代理卡時提到它記錄了身份驗證方式(authentication 欄位)——這不是擺好看的。把認證要求集中寫在代理卡上,等於每一張代理卡都內建了「要進這扇門得先出示哪種鑰匙」的門禁清單,客戶端不用猜、也不用私相授受,身份驗證的管理因此集中且可稽核。

第四道防線:憑證只放 HTTP Header。A2A 嚴格禁止把密碼或 token 放在 URL 或訊息 Body 裡。為什麼差很多?因為企業 IT 架構中,應用程式防火牆和負載平衡器通常會記錄 HTTP 的 URL 和訊息正文來除錯。如果把金鑰放在 Body,很容易在系統日誌中以明文暴露——任何 IT 人員看 log 就把密碼看光了。把憑證隔離在 HTTP Header,底層網路裝置記錄日誌時就能輕易遮蔽過濾,確保機密授權資料不會外流。

何時該用 A2A:經驗法則

看完這些能力,什麼情況才需要把 A2A 請出來?基本判斷很簡單:當需要協調兩個或兩個以上、而且很可能用不同框架打造的 AI 代理一起協作時,就用 A2A。具體來說,它特別適合:

但要注意的是,只有單一代理、或代理之間關係固定不會變動時,A2A 就是殺雞用牛刀。A2A 的價值在於「跨框架、動態發現、可擴充」——如果這些都不是我們的痛點,用程式直接呼叫彼此的方法還更快更簡單。就像開場的比喻,只有當夢幻團隊真的需要互相開會時,才值得牽起那些網路線。

對 UI/UX 的影響:讓多代理協作看得見

多代理在背景互相開會、委派任務,但人類使用者最怕的就是「不知道它到底在幹嘛」。A2A 系統的 UI/UX 核心是透明度與信任

代理網路視覺化

Trickle AI 這種工具讓開發者看到 A2A 通訊,企業使用者也需要看到任務被怎麼探討與委派。以供應鏈分析儀表板為例:

┌─────────────────────────────────────────────────────────┐
│  🔗 多代理協作視圖                                       │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  使用者請求:分析跨國供應鏈最佳化方案                 │
│                                                         │
│  主控代理 ──┬── 委派 → 天氣代理(即時天氣)   ✓ 完成    │
│             │                                           │
│             ├── 委派 → 航運分析代理(對手定價)✓ 完成   │
│             │                                           │
│             ├── 委派 → 財務代理(匯率波動)  ✓ 完成     │
│             │                                           │
│             └── 彙整 → 策略報告              ⏳ 生成中  │
│                                                         │
│  ┌─ 委派鏈追蹤 ────────────────────────────────────┐   │
│  │ 主控 → 財務代理  [Context: ctx-001, 0.8s]       │   │
│  │ 財務 → 匯率API   [Context: ctx-002, 1.2s]       │   │
│  │ 憑證:mTLS ✓ | 稽核日誌已啟用 ✓                 │   │
│  └──────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────┘

委派決策的可解釋性

當主控代理自主動態發現並委派任務時,UI 應該呈現「為什麼選這個代理」。以企業登錄檔搜尋為例:

┌─────────────────────────────────────────────────────────┐
│  🔍 代理委派決策                                        │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  需求:需要一個能存取 Q3 財報的財務分析 AI             │
│                                                         │
│  ┌─────────────────────────────────────────────────┐   │
│  │  [1] finance-analyst-v2        ★ 已稽核        │   │
│  │      存取權限:Q3 財報 ✓ | 延遲保證:0.8s      │   │
│  │      信任分數:98  | 上次稽核:2026-07-28      │   │
│  │                                                 │   │
│  │  [2] quick-math-agent          未稽核          │   │
│  │      存取權限:Q3 財報 ✓ | 延遲保證:0.3s      │   │
│  │      信任分數:32  | 無稽核紀錄                │   │
│  └─────────────────────────────────────────────────┘   │
│                                                         │
│  🤖 已自動選擇 [1] finance-analyst-v2                   │
│     (較慢但已稽核,符合企業安全政策)                  │
│                                                         │
│  ┌──────────────┐  ┌────────────────────┐              │
│  │  改用 [2]    │  │  查看稽核日誌      │              │
│  └──────────────┘  └────────────────────┘              │
└─────────────────────────────────────────────────────────┘

安全事件的可見性

mTLS、稽核日誌這些安全機制,也應該轉化為使用者能理解的介面,而不是只存在於後台 log 裡:

┌─────────────────────────────────────────────────────────┐
│  🛡 代理間信任狀態                                      │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  ┌──────────┐   mTLS 雙向驗證   ┌──────────┐           │
│  │ 主控代理 │ ◄───────────────► │ 財務代理 │           │
│  │  憑證✓   │   加密通道已建立   │  憑證✓   │           │
│  └──────────┘                    └──────────┘           │
│                                                         │
│  本日代理間通訊:1,284 筆                               │
│  ✓ 已稽核通訊:1,284 筆(100%)                        │
│  ⚠ 異常嘗試:0 筆                                       │
│                                                         │
│  ┌──────────────────────────────────────┐              │
│  │  查看完整稽核日誌(1,284 筆)        │              │
│  └──────────────────────────────────────┘              │
└─────────────────────────────────────────────────────────┘

前後端技術怎麼落地:讓代理網路看得見

前面幾個 UI 設計決策把「透明度與信任」講得很美,但實際要怎麼做出來?多代理通訊不像一般 API 呼叫——它橫跨多個伺服器、有非同步委派、有憑證與稽核,這些資料天生就分散在各個代理身上。要讓前端畫得出來,後端必須先把「分散的通訊軌跡」彙整成一條可以串流的事件流。

後端:把分散的通訊軌跡彙整成事件流

A2A 的 UI/UX 影響有一個核心難題:代理通訊資料不在一台機器上。主控代理在 A 伺服器,財務代理在 B 伺服器,匯率 API 在 C 伺服器——每個節點只知道自己的那一段。如果每個代理各回各的 log,前端根本拼不出「主控 → 財務 → 匯率API」這條完整委派鏈。

解法是讓後端把每個代理的執行階段當作事件,統一彙整後透過 SSE(Server-Sent Events) 推送:

// 後端:委派鏈追蹤服務,彙整各代理的階段事件
import { createServer } from 'node:http'

const agents = new Map<string, { name: string; status: string }>()

createServer(async (req, res) => {
  res.writeHead(200, {
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    Connection: 'keep-alive',
  })

  const send = (event: string, data: unknown) => {
    res.write(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`)
  }

  // 每個代理執行時回報自己的狀態,由後端統一彙整
  send('agent-status', {
    chain: [
      { id: 'ctx-001', from: '主控代理', to: '財務代理', durationMs: 800, status: 'done' },
      { id: 'ctx-002', from: '財務代理', to: '匯率API', durationMs: 1200, status: 'done' },
      { id: 'ctx-003', from: '主控代理', to: '策略報告', status: 'running' },
    ],
    security: { mTLS: true, audited: 1284 },
  })

  // 代理完成時即時更新
  agents.set('strategy-report', { name: '策略報告', status: 'done' })
  send('agent-status', {
    chain: [{ id: 'ctx-003', from: '主控代理', to: '策略報告', status: 'done' }],
    security: { mTLS: true, audited: 1285 },
  })

  send('done', {})
})

關鍵不是用了什麼協定,而是後端把分散在 A、B、C 三台伺服器的執行階段,彙整成一條有先後順序的委派鏈——前端才畫得出「主控 → 財務 → 匯率API」這張網。如果沒有這層彙整,每個代理各自為政,介面就只能顯示「任務處理中」這個空泛的狀態。

前端:把事件流畫成代理網路

後端把事件送出來了,前端的工作是把事件流渲染成看得懂的代理網路:

// 前端(React):把委派鏈事件渲染成節點圖
import { useEffect, useState } from 'react'

type AgentStep = { id: string; from: string; to: string; status: string }

function AgentNetwork() {
  const [chain, setChain] = useState<AgentStep[]>([])
  const [mTLS, setMTLS] = useState(false)

  useEffect(() => {
    const es = new EventSource('/api/delegation-chain')

    es.addEventListener('agent-status', (e) => {
      const data = JSON.parse(e.data)
      setChain((prev) => [...prev, ...data.chain])
      setMTLS(data.security.mTLS)
    })

    return () => es.close()
  }, [])

  return (
    <div className="agent-network">
      {chain.map((step) => (
        <div key={step.id} className={`step ${step.status}`}>
          {step.from}  {step.to}
          {step.status === 'done' ? '' : ''}
        </div>
      ))}
      <div className="security">
        {mTLS ? '🔒 mTLS 雙向驗證已建立' : '⚠ 加密通道未建立'}
      </div>
    </div>
  )
}

注意幾個設計決策:

前端手法 對應的 UI/UX 效果
EventSource 訂閱委派鏈事件 委派過程即時出現,而不是等全部完成才顯示
每步 / 狀態標記 使用者一眼看到「進行到哪一步」,等待變可預期
安全狀態獨立渲染 mTLS、稽核這些機制不只存在後台 log,而是變成介面上的視覺訊號
委派鏈依序堆疊 把分散的代理呼叫,拼回「主控 → 財務 → 匯率API」的因果順序

判斷在後端,呈現在前端

最後一個重點跟 RAG 那篇一樣:前端絕對不能自己決定「該選哪個代理」。前面 委派決策的可解釋性 說的「採用已稽核的 finance-analyst-v2」這種判斷,必須在後端用確定性規則(稽核狀態、信任分數、安全政策)算好,前端只負責把結果和理由畫出來。選代理的邏輯放在後端,才能跟 UI 分開測試、被其他系統(排程、報表)重複使用。

正確的分工是:

後端(資料與判斷)              前端(呈現與互動)
┌───────────────────────┐    ┌───────────────────────┐
│ 彙整代理通訊軌跡        │    │ 渲染委派鏈節點圖        │
│ 依安全政策挑選代理      │───▶│ 呈現信任分數與稽核狀態   │
│ 產生稽核日誌事件        │    │ 可展開的委派決策面板     │
│ 記錄憑證與 mTLS 狀態    │    │ 渲染安全事件警示         │
└───────────────────────┘    └───────────────────────┘
      只管「誰能做、做了沒」          只管「怎麼呈現」

多代理協作最容易失控的地方,就是「每個代理各講各的話,使用者聽不懂」。後端把分散的委派與安全事件彙整成結構化資料,前端再把這些資料畫成節點圖與狀態標記——兩邊各司其職,透明與信任才真的做出來,而不是停留在設計稿上。

總結

A2A 協定為下一個世代的超級自動化鋪平標準化道路:

在不遠的將來,數位助理不再是一個單打獨鬥的個體。當丟出一個極度複雜的商業需求,AI 助理會自動在背景解析任務、搜尋目錄、跨越不同的伺服器與平台,組建一個由各種專屬 AI 構成的臨時「超級專家大腦」,行雲流水地完成從資料分析到圖文產出的所有工作流程。

但這也留下一個值得深思的治理問題:當主控 AI 為了追求最高效率,自主動態發現並委派任務給一個登錄檔中完全未經人類事先審查、但透過 A2A 溝通無礙的陌生遠端 AI,會發生什麼事?回顧開場的比喻——如果這些專家為了完成專案,自己決定透過網路線引進外部未知的專家系統來處理機密資料呢?

技術標準給了 AI 建立無限橋樑的能力,但這張由機器自主編織出來的網路,最終拓撲結構可能遠超人類最初的設計。當 AI 開始繞過人類的管理層,建立起屬於它們自己的專家社交圈與信任網路時,我們還能完全掌握這個自動化工作流程的內部邏輯與邊界嗎?這值得我們在擁抱自動化的同時,持續保持警惕與思考。

參考資料


Agentic Design Pattern Agentic AI A2A Agent to Agent Multi-Agent AI Architecture Design Pattern MCP AI 幻覺

Summer Tang
Sponsored
Summer Tang 一對一諮詢
Summer|TSMC 主任工程師|擁有 15 年資深 Web 架構經驗,職涯歷經跨國頂尖企業與新創。專精於高流量企業級應用開發,核心技術涵蓋微前端、效能優化、測試自動化與 SEO。曾出版多本技術著作,並多次擔任 MOPCON、WebConf 等大型技術年會講者。
了解更多 →