A2A 又是啥?和 MCP 的關係?個人理解和定義梳理
繼 Anthropic 推出 MCP 之後,Google 終於下場了,推出了新的 AI 協議:A2A。
這東西到底是幹啥的?和 MCP 有啥區別?具體咋用?下面我們詳細道來。
A2A 能幹啥?
A2A,全程 agent2agent,顧名思義,就是 agent 和 agent 之間的交流溝通的範式,詳細地說它可以實現 agent 和 agent 之間溝通、協作、委派、信息同步的同能,並將這個工作作爲一個標準協議用於所有類型的 agent 之間。
和 MCP 有啥區別?
A2A 實際上是可以覆蓋 MCP 的功能的,他只是 MCP 概念的進一步封裝和抽象
MCP 的缺陷:
1、無安全隔離機制
2、無任何授權認證機制
A2A 協議的核心特性:
1、具備企業級的安全策略, 包含監控、追蹤、認證等等
2、具備異步的特性, 支持長時間的任務運行且允許隨時進行人工干預
3、支持多模態處理能力
4、多個代理無需共享狀態
A2A 定義了哪些規矩?
A2A 定義的核心規則,就這 agent 之間溝通的模板。
Task 任務
任務是一個對象實體,它用於 agent 和 agent 之間的任務委派,比如 A agent 需要向 B agent 發出一個請求,讓 B agent 幫它做一個任務,就用到了它,具體定義的對象內容如下
interface Task {
id: string; // 任務的唯一標識符
sessionId: string; // 客戶端生成的會話ID,用於持有該任務
status: TaskStatus; // 任務的當前狀態
history?: Message[]; // 消息歷史記錄
artifacts?: Artifact[]; // 任務的最後結果,也成爲工件
metadata?: Record<string, any>; // 擴展元數據
}
// 任務狀態及附帶消息
interface TaskStatus {
state: TaskState; // 任務狀態
message?: Message; // 給客戶端的額外狀態更新
timestamp?: string; // ISO 格式時間戳
}
// 服務器在 sendSubscribe 或 subscribe 請求期間發送
interface TaskStatusUpdateEvent {
id: string; // 任務ID
status: TaskStatus; // 任務狀態
final: boolean; // 表示事件流的結束
metadata?: Record<string, any>; // 擴展元數據
}
// 服務器在 sendSubscribe 或 subscribe 請求期間發送
interface TaskArtifactUpdateEvent {
id: string; // 任務ID
artifact: Artifact; // 產物對象
metadata?: Record<string, any>; // 擴展元數據
}
// 客戶端發送給代理以創建、繼續或重啓任務
interface TaskSendParams {
id: string;
sessionId?: string; // 未設置時,服務器會爲新任務創建新的 sessionId
message: Message; // 消息內容
historyLength?: number; // 要檢索的最近消息數量
// 斷開連接時服務器應發送通知的目標配置
pushNotification?: PushNotificationConfig;
metadata?: Record<string, any>; // 擴展元數據
}
type TaskState =
| "submitted" // 已提交
| "working" // 處理中
| "input-required" // 需要輸入
| "completed" // 已完成
| "canceled" // 已取消
| "failed" // 已失敗
| "unknown"; // 未知狀態
Message 消息
消息是 agent 之間溝通發送的對象,包括代理思維、用戶上下文、指令、錯誤、狀態或元數據
interface Message {
role: "user" | "agent";
parts: Part[];
metadata?: Record<string, any>;
}
Artifact 工件
這是 agent 和 agent 之間委派任務後的最終結果,工件是不可變的,一個任務可以生成多個工件
interface Artifact {
name?: string; // 工件名稱
description?: string; // 工件描述
parts: Part[]; // 工件組成部分
metadata?: Record<string, any>; // 元數據
index: number; // 索引
append?: boolean;
lastChunk?: boolean;
}
Part 工件塊
一個工件可以由多個塊組成(多模態,包含文字、圖片、視頻等等),是結果的部分呈現,包含文本塊、文件塊、數據塊
interface TextPart {
type: "text";
text: string;
}
interface FilePart {
type: "file";
file: {
name?: string;
mimeType?: string;
// oneof {
bytes?: string; //base64 encoded content
uri?: string;
//}
};
}
interface DataPart {
type: "data";
data: Record<string, any>;
}
type Part = (TextPart | FilePart | DataPart) & {
metadata: Record<string, any>;
};
除了上述的定義的對象,下面介紹具體如何使用上面定義的對象來構建 agent 之間溝通的方法
Agent Card 代理卡
每個 agent 都有一個代理卡,其中記錄着這個 agent 的基礎信息,類似於自己的名片,讓別人指導這個 agent 是幹嘛的,有哪些能力和使用規範
{
"name": "Google Maps Agent", // agent名稱
"description": "Plan routes, remember places, and generate directions", // agent描述
"url": "https://maps-agent.google.com", // agent 服務url
"provider": { // 組織信息
"organization": "Google",
"url": "https://google.com"
},
"version": "1.0.0",
"authentication": {
"schemes": "OAuth2"
},
"defaultInputModes": ["text/plain"], // 默認輸入格式
"defaultOutputModes": ["text/plain", "application/html"], // 默認輸出格式
"capabilities": { // 能力,是否支持流式輸出或者通知能力
"streaming": true,
"pushNotifications": false
},
"skills": [ //agent的能力,可以有多個
{
"id": "route-planner",
"name": "Route planning",
"description": "Helps plan routing between two locations",
"tags": ["maps", "routing", "navigation"],
"examples": [
"plan my route from Sunnyvale to Mountain View",
"what's the commute time from Sunnyvale to San Francisco at 9AM",
"create turn by turn directions from Sunnyvale to Mountain View"
],
// can return a video of the route
"outputModes": ["application/html", "video/mp4"]
},
{
"id": "custom-map",
"name": "My Map",
"description": "Manage a custom map with your own saved places",
"tags": ["custom-map", "saved-places"],
"examples": [
"show me my favorite restaurants on the map",
"create a visual of all places I've visited in the past year"
],
"outputModes": ["application/html"]
}
]
}
Send a Task 發送任務
由一個 agent 發送消息到另一個 agent 的方法結構體,其中 params 就是上面的 TaskSendParams
//Request
{
"jsonrpc": "2.0",
"id": 1,
"method":"tasks/send",
"params": {
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
"message": {
"role":"user",
"parts": [{
"type":"text",
"text": "tell me a joke"
}]
},
"metadata": {}
}
}
//Response
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
"sessionId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"status": {
"state": "completed",
},
"artifacts": [{
"name":"joke",
"parts": [{
"type":"text",
"text":"Why did the chicken cross the road? To get to the other side!"
}]
}],
"metadata": {}
}
}
Get a Task 獲取任務
//Request
{
"jsonrpc": "2.0",
"id": 1,
"method":"tasks/get",
"params": {
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
"historyLength": 10,
"metadata": {}
}
}
//Response
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
"sessionId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"status": {
"state": "completed"
},
"artifacts": [{
"parts": [{
"type":"text",
"text":"Why did the chicken cross the road? To get to the other side!"
}]
}],
"history":[
{
"role": "user",
"parts": [
{
"type": "text",
"text": "tell me a joke"
}
]
}
],
"metadata": {}
}
}
Cancel a Task 取消任務
//Request
{
"jsonrpc": "2.0",
"id": 1,
"method":"tasks/cancel",
"params": {
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
"metadata": {}
}
}
//Response
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
"sessionId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"status": {
"state": "canceled"
},
"metadata": {}
}
}
以上就是 A2A 定義的核心的內容,當然還有一些別的方法和對象的定義,這裏只列舉了最核心的,有助於對 A2A 的內容有一個全覽概況
google 代碼示例結構粗講
google 這次提供的示例代碼質量一般,相當的 "示例",整體代碼結構如下
demo
是前端交互相關的代碼,它構建了一個聊天界面和 agent 配置相關交互和邏輯
sample:
1、有兩個庫,js 和 python,主要看 python,導入 python 就可以了。
2、common 是 A2A 的核心代碼,講述了 client 如何構建,server 如何構建,數據結構如何構建(type.py)。
3、最重要的 host,講了如何進行服務發現、服務註冊,由前端 UI 來進行調用。
4、agents 中講述 A2A 多 agent server 的搭建。
總結和個人理解
整體理解下來,A2A 的核心就是上面講到的 agent 和 agent 之間傳遞的對象結構和方法結構(這個是一定要遵守的),其他都是根據自己的應用自由開發。
主要流程:
發現:客戶端從 /.well-known/agent.json 獲取 Agent Card,瞭解智能體的能力。
啓動:客戶端發送
使用 tasks/send 處理即時任務,返回最終 Task 對象。
使用 tasks/sendSubscribe 處理長期任務,服務器通過 SSE 事件發送更新。
處理:服務器處理任務,可能涉及流式更新或直接返回結果。
交互(可選):若任務狀態爲 input-required,客戶端可發送更多消息,使用相同 Task ID 提供輸入。
完成:任務達到終端狀態(如 completed、failed 或 canceled)。
核心理解:
核心對象 / 方法 + web server + 服務發現 / 註冊。
如果要構建一個 A2A 框架:
step1:建立多個 agent,然後分別對每個 agent 封裝一套 web server,比如 fastapi,接下來,每個 agent 創建一個任務管理器,用於這個 agent 的啓動、取消、獲取
step2:構建一個服務註冊,可以通過前端或 cli 將 step1 創建的每個 agent 服務註冊到內存中
step3:構建一個服務發現邏輯,這裏需要創建一個父 LLM 或父 agent,通過 LLM 的能力判斷是否需要調用其他的 agent 完成任務
可能的 A2A 的架構設計:
第一種架構:
構建一個 agent(可以通過 Agent 框架實現,也可以通過 LLM 本身構建 prompt 實現),這個 agent 作爲父 agent,它裏面實現服務發現和服務註冊的邏輯,獲取子 agent 的 agent card 信息,然後拼接在自己的 agent 的 prompt 中,由父 agent 的 AI 自主的編排和任務規劃,1 對多結構,這個和 MCP 類似,可以覆蓋 MCP 的功能
第二種架構:
沒有父子 agent 的概念,每一個 agent 都有服務發現的功能,比如:一共 3 個 agent,三個 agent 可以通過協作完成一個目標任務,每一個 agent 都可以鏈式或委派方式調用別的 agent,最終有一個總體的狀態管理和消息彙總的 LLM(總管)
第三種架構:
父 agent 或 LLM,結合 MCP 中的(工具、prompt、資源等),再結合 A2A agent 實現一個通過自定義編程或 agent 框架,實現一個複雜的多 agent 應用
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/Gu9NQZrSghbF95Prm93YUw