A2A 簡介

2026-04-18

簡介

A2A (Agent2Agent) 通訊協定旨在將 AI Agent 之間的通訊標準化。

2025 年 3 月:IBM Research 推出 Agent Communication Protocol (ACP)

2025 年 4 月:Google 在 Google Cloud 平台上推出 A2A 協定。

2025 年 9 月:正式宣佈 ACP 併入 A2A。並將治理權完全移交給 Linux 基金會。

User 向負責處理互動的 Client Agent 提出需求,接著該 Client Agent 透過 A2A 作為溝通橋樑,將自身無法處理的任務委託給專門負責實際執行的 Remote Agent 來協助完成。

Quick Walk-through

一群 AI Agent 協作時,首先需要相互發現並了解彼此的功能,可使用 Agent Card 將 Agent 的描述標準化。

當 Client Agent 找到了 Remote Agent,雙方要如何對話?

Remote Agent 的 Agent card 中定義了 URI 及 Protocol binding (ex: JSON‑RPC、gRPC/protobuf),Client Agent 可以依此發出請求。

Agent 通訊有 4 種模式

  • Synchronous
  • Asynchronous
  • Streaming
  • Push Notification

Synchronous 模式

Client Agent 會先傳送一個 Message 物件,一個 Message 代表對話中的一個輪次。

Message 中包含 Role,及 Parts。

Part 是實際的內容,可以是純文字、檔案、multi-model data,或 structured JSON。

當 Remote Agent 接收到來自 Client Agent 的請求時,如果該請求非常簡單且能快速完成,Remote Agent 可以直接回覆 Client Agent 一個包含解答回應的 Message。

Asynchronous 模式

當任務需要花些時間,Remote Agent 可以不回覆訊息,而是回覆一個 Task 物件。這個任務具有 ID,以及 Status。

Status 指示了 Task 生命週期的當前階段:包含

  • submitted
  • working
  • input required (當 Remote Agent 需要 User 提供更多資訊時)
  • completed
  • failed

Client Agent 可以透過 polling 方法來得知 Task 的最新狀態。

由於是 Remote Agent 決定要回傳 message 還是 task,所以 Client Agent 必須這兩種情況都能處理。

最終,Task 完成後進入 completed 的狀態,而任務的輸出結果將會放在 artifacts 欄位中。

Artifacts 是類似於 Message 的結構,它們同樣具有一個 Artifact ID 以及 Parts 內容片段,其中包含了實際的回應內容。

Streaming 模式

polling task 在簡單的情況下運作良好,但如果想要快速獲得更新,這並不是非常有效率。

A2A 支援使用 SSE (Server-Sent Events) 進行 streaming。 如果 Remote Agent 的 Agent card 載明支援 streaming,Cient Agent 就可以使用 SSE 方法通訊,Server Agent 可以在更新發生時即時傳給 Client Agent。

這些更新可以是

  • task object
  • status update events 像是 處理中 或任務已完成等
  • artifact update events 產出物更新事件

如果 Artifact 結果資料較大,例如一份長篇摘要,Server Agent 可以將其進行串流傳送。

使用者可以看到即時的進度更新,或者在答案生成的同時看到它逐步呈現。

Push Notification 模式

若 Remote Agent 的 Agent card 載明支援 pushNotifications,

Client Agent 可以提供 callback URL,

Remote Agent 可以主動地通知 task 狀態變化,或 artifact 已準備完成.

Agent Card

在 A2A agent 執行任何操作之前,它需要定義自己能做什麼(Agent Skill),以及其他 agents 或 clients 如何得知這些 capabilities(Agent Card)。

Agent Skill: 描述了 Agent 能夠執行的特定 capability 或 function。它是構成 Agent 的基本 building block,用於告知 clients 該 Agent 擅長處理哪些類型的 tasks。

Agent Card: 一份由 A2A Server 提供的 JSON document,通常存放於 .well-known/agent-card.json endpoint。它就像是該 Agent 的數位名片。

{
  "capabilities": {
    "streaming": true
  },
  "defaultInputModes": [
    "text"
  ],
  "defaultOutputModes": [
    "text"
  ],
  "description": "Just a hello world agent",
  "name": "Hello World Agent",
  "preferredTransport": "JSONRPC",
  "protocolVersion": "0.3.0",
  "skills": [
    {
      "description": "just returns hello world",
      "examples": [
        "hi",
        "hello world"
      ],
      "id": "hello_world",
      "name": "Returns hello world",
      "tags": [
        "hello world"
      ]
    }
  ],
  "supportsAuthenticatedExtendedCard": true,
  "url": "http://localhost:9999/",
  "version": "1.0.0"
}

Multi-Turn Interactions

Turn(輪次)指的是什麼?

Turn 代表一次通訊:在 A2A 中,一個 Turn 指的是客戶端 Agent 與遠端 Agent 之間的一次單向通訊(communication turn)。 由 Message 承載:這在底層資料模型中是透過 Message(訊息) 物件來具體代表的。舉例來說,當 Agent A 提出一個問題,這就是一個對話輪次。每個輪次都會清楚標示發送者的角色(user 或 agent),並在內部包含實際的資料內容(Parts)。

客戶端使用以下方式發送訊息message/send:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "message/send",
  "params": {
    "message": {
      "role": "user",
      "parts": [
        {
          "kind": "text",
          "text": "tell me a joke"
        }
      ],
      "messageId": "9229e770-767c-417b-a0b0-f0741243c589"
    },
    "metadata": {}
  }
}

伺服器處理請求,無需回應 Task,快速回應 Message。

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "messageId": "363422be-b0f9-4692-a24d-278670e7c7f1",
    "contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
    "parts": [
      {
        "kind": "text",
        "text": "A joke."
      }
    ],
    "kind": "message",
    "metadata": {}
  }
}

Multi-turn(多輪次)指的是什麼?

Multi-turn 代表連貫的對話與協作:它指的是 Agent 之間能夠跨越多次互動,持續維持對話的連貫性與 context。如果一個任務發生了多個輪次的互動,這些通訊紀錄會被保留並儲存在該任務的 history(歷史紀錄) 欄位中。

在 A2A 的實務應用中,Multi-turn 主要是透過以下機制和情境來實現的:

Context ID 的串聯:A2A 依賴 contextId 將多個相關的 Message 與 Task(任務)邏輯上分組在一起。只要帶有相同的 contextId,Agent 就會將這些互動視為同一個對話工作階段 session 的一部分,藉此繼承先前的 Context。

Input Required 狀態:這是一種最常見的多輪次情境。當 Agent 在處理任務的中途發現資訊不足時,可以將任務狀態標示為「input-required」。接著,客戶端必須傳送一則帶有相同 taskId 與 contextId 的新訊息來補充資訊,讓對話與任務能繼續推動。

Follow-up Messages:Client 可以主動發送後續訊息,並透過附帶 taskId(或使用 referenceTaskIds 欄位明確指定相關任務),來補充或延續現有任務的執行,完成多輪次的複雜指令。

Client 使用以下方式發送訊息message/send:

{
  "jsonrpc": "2.0",
  "id": "req-003",
  "method": "message/send",
  "params": {
    "message": {
      "role": "user",
      "parts": [{ "kind": "text", "text": "I'd like to book a flight." }]
    },
    "messageId": "c53ba666-3f97-433c-a87b-6084276babe2"
  }
}

伺服器回應,任務狀態為input-required:

{
  "jsonrpc": "2.0",
  "id": "req-003",
  "result": {
    "id": "3f36680c-7f37-4a5f-945e-d78981fafd36",
    "contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
    "status": {
      "state": "input-required",
      "message": {
        "role": "agent",
        "parts": [
          {
            "kind": "text",
            "text": "Sure, I can help with that! Where would you like to fly to, and from where? Also, what are your preferred travel dates?"
          }
        ],
        "messageId": "c2e1b2dd-f200-4b04-bc22-1b0c65a1aad2",
        "taskId": "3f36680c-7f37-4a5f-945e-d78981fafd36",
        "contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4"
      },
      "timestamp": "2024-03-15T10:10:00Z"
    },
    "kind": "task"
  }
}

客戶端(使用相同的message/send任務 ID提供所要求的輸入):

{
  "jsonrpc": "2.0",
  "id": "req-004",
  "method": "message/send",
  "params": {
    "message": {
      "role": "user",
      "parts": [
        {
          "kind": "text",
          "text": "I want to fly from New York (JFK) to London (LHR) around October 10th, returning October 17th."
        }
      ],
      "contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
      "taskId": "3f36680c-7f37-4a5f-945e-d78981fafd36",
      "messageId": "0db1d6c4-3976-40ed-b9b8-0043ea7a03d3"
    },
    "configuration": {
      "blocking": true
    }
  }
}