跳至主要內容

A2A (Agent-to-Agent)

Mastra 支援 0.3.0 版 Agent-to-Agent (A2A) 協定,適用於跨平台多 Agent 系統。使用 A2A,可將 Mastra Agent 公開為遠端 Agent、將遠端 A2A Agent 作為 Mastra 子 Agent 使用,或透過 JavaScript 用戶端 SDK 呼叫 A2A 端點。

A2A 是一種開放協定,可跨網路、框架、廠商與程式語言邊界,將工作委派給 Agent。遠端 Agent 會將自己的 Tool、提示詞、記憶、Workflow 與基礎設施保密,同時公開可供其他系統探索及呼叫的協定端點。

何時使用 A2A
「何時使用 A2A」的直接連結

  • 父 Agent 應將工作委派給專門的遠端 Agent。
  • 遠端 Agent 由另一項服務、團隊、廠商或執行階段擁有。
  • 後端、瀏覽器應用程式或其他相容 A2A 的系統需要以程式存取 Mastra Agent。
  • 長時間執行的遠端工作需要任務 ID、狀態更新、成品、取消、重新訂閱或推播通知。

A2A 的運作方式
「A2A 的運作方式」的直接連結

A2A 使用 Agent 卡片進行探索。卡片是由眾所皆知 URL 提供的 JSON 文件,用來描述遠端 Agent,並包含接受 A2A JSON-RPC 請求的執行 URL。

使用 Mastra Server 的預設 apiPrefix /api 時,註冊為 weather-agent 的 Agent 會公開:

  • Agent 卡片:/api/.well-known/weather-agent/agent-card.json
  • 執行端點:/api/a2a/weather-agent

Agent 卡片包含 Agent 名稱、說明、端點 URL、Provider、功能、安全性中繼資料與 Skill 等欄位:

agent-card.json
{
"protocolVersion": "0.3.0",
"name": "Weather Agent",
"description": "Provides weather information.",
"url": "https://agent.example.com/api/a2a/weather-agent",
"version": "1.0",
"provider": {
"organization": "Acme",
"url": "https://acme.example.com"
},
"capabilities": {
"streaming": true,
"pushNotifications": true,
"stateTransitionHistory": false
},
"defaultInputModes": ["text/plain"],
"defaultOutputModes": ["text/plain"],
"skills": [
{
"id": "weather",
"name": "weather",
"description": "Gets weather conditions for a location.",
"tags": ["tool"]
}
]
}

A2A 以訊息與任務表示工作。訊息可攜帶文字、檔案或結構化資料部分。

任務是具有 ID 與生命週期狀態的有狀態工作單位。用戶端可追蹤長時間執行的工作並傳送後續回合,也可以取消工作,或在中斷連線後重新訂閱。

協定版本
「協定版本」的直接連結

Mastra 在相同 Agent 卡片與執行 URL 上支援 A2A Protocol v0.3 和 v1.0。A2A-Version 請求標頭會選擇線上協定:

  • 缺少、空白或 0.3:使用現有的 v0.3 API。
  • 1.0:使用 v1.0 API。
  • 任何其他值:傳回 VersionNotSupported 協定錯誤。

現有 A2AAgentMastraClient.getA2A() 整合會繼續使用 v0.3。若要發出 v1.0 請求,請使用 MastraClient.getA2AV1()。v1 用戶端會自動傳送 A2A-Version: 1.0,並新增 tasks/list 操作。

請從 @mastra/core/a2a/v1 匯入 v1.0 協定型別與編解碼器。現有的 @mastra/core/a2a/client 匯出仍維持 v0.3。

開始使用
「開始使用」的直接連結

A2A 在 Mastra 中有兩種常見用法:

  • 使用 A2AAgent,將遠端 A2A Agent 作為 Mastra 子 Agent 使用。
  • 使用 MastraClient.getA2A(),將請求傳送至 Mastra A2A 端點。

若另一個 Mastra Agent 應將工作委派給遠端 Agent,請使用 A2AAgent。若應用程式程式碼需要直接呼叫已啟用 A2A 的 Mastra 端點,請使用用戶端 SDK。

將 A2A Agent 作為子 Agent 使用
「將 A2A Agent 作為子 Agent 使用」的直接連結

使用 A2AAgent 包裝遠端 A2A Agent,再透過 Supervisor Agent 模式將它加入父 Agent。若遠端伺服器託管多個 Agent,或使用自訂的眾所皆知路徑,請傳入明確的 Agent 卡片 URL。

src/mastra/agents/support-agent.ts
import { Agent } from '@mastra/core/agent'
import { A2AAgent } from '@mastra/core/a2a'

const remoteWeatherAgent = new A2AAgent({
url: 'https://weather.example.com/api/.well-known/weather-agent/agent-card.json',
headers: {
Authorization: `Bearer ${process.env.WEATHER_AGENT_TOKEN}`,
},
})

export const supportAgent = new Agent({
id: 'support-agent',
name: 'Support Agent',
instructions: 'Answer user questions and delegate weather questions when needed.',
model: 'openai/gpt-5.6-sol',
agents: {
remoteWeatherAgent,
},
})

url 指向網域,A2AAgent 會從 /.well-known/agent-card.json 擷取 Agent 卡片。對於遵循此探索路徑的單一 Agent 伺服器,請使用網域 URL。對於多 Agent 伺服器,請傳入完整卡片 URL,例如 https://agent.example.com/api/.well-known/weather-agent/agent-card.json

執行期間,A2AAgent 會:

  • 擷取並快取遠端 Agent 卡片。
  • 從卡片讀取執行 URL 與功能。
  • 對非串流執行呼叫 message/send;支援串流時則呼叫 message/stream
  • 將遠端訊息、任務、成品與狀態更新轉換為 Mastra 子 Agent 結果。
  • 當遠端任務需要後續輸入或重新訂閱時,支援 resumeGenerate()resumeStream()

若遠端卡片未宣告支援串流,A2AAgent.stream() 會改用非串流產生路徑,並傳回緩衝的串流結果。

使用用戶端 SDK 傳送請求
「使用用戶端 SDK 傳送請求」的直接連結

若想讓應用程式程式碼呼叫已啟用 A2A 的 Mastra Agent,請使用 MastraClient.getA2A()。以伺服器來源設定 baseUrl;若伺服器未使用預設 /api 前綴,則設定 apiPrefix

src/a2a-client.ts
import { MastraClient } from '@mastra/client-js'

const client = new MastraClient({
baseUrl: 'https://agent.example.com',
headers: {
Authorization: `Bearer ${process.env.AGENT_API_TOKEN}`,
},
})

const a2a = client.getA2A('weather-agent')
const card = await a2a.getAgentCard()

console.log(card.name, card.capabilities)

使用 sendMessageStream() 傳送訊息,並透過 Server-Sent Events (SSE) 接收任務狀態與成品更新:

src/a2a-client.ts
const stream = a2a.sendMessageStream({
message: {
kind: 'message',
role: 'user',
messageId: crypto.randomUUID(),
parts: [{ kind: 'text', text: "What's the weather in Prague?" }],
},
})

for await (const event of stream) {
if (event.kind === 'artifact-update') {
console.log(event.artifact.parts)
}
}

若任務仍在執行時串流中斷連線,請使用 resubscribeTask() 接收進行中任務的即時更新:

src/a2a-client.ts
const updates = a2a.resubscribeTask({
id: 'task-123',
})

for await (const event of updates) {
console.log(event)
}

使用 v1.0 用戶端
「使用 v1.0 用戶端」的直接連結

使用 getA2AV1() 選用 A2A v1.0 線上協定。協定套件提供編解碼器,可從 JSON 形式的輸入建立 v1 請求值:

src/a2a-v1-client.ts
import { ListTasksRequest } from '@mastra/core/a2a/v1'
import { MastraClient } from '@mastra/client-js'

const client = new MastraClient({
baseUrl: 'https://agent.example.com',
})

const a2a = client.getA2AV1('weather-agent')
const response = await a2a.listTasks(
ListTasksRequest.fromJSON({
contextId: 'customer-support',
pageSize: 20,
}),
)

for (const task of response.tasks) {
console.log(task.id, task.status)
}

v1.0 用戶端支援 getAgentCard()sendMessage()sendMessageStream()getTask()listTasks()cancelTask()resubscribeTask()

設定子 Agent 呼叫
「設定子 Agent 呼叫」的直接連結

A2AAgent 接受適用於已驗證或受限環境的請求選項:

src/mastra/agents/support-agent.ts
import { A2AAgent } from '@mastra/core/a2a'

const remoteWeatherAgent = new A2AAgent({
url: 'https://weather.example.com/api/.well-known/weather-agent/agent-card.json',
headers: {
Authorization: `Bearer ${process.env.WEATHER_AGENT_TOKEN}`,
},
retries: 2,
backoffMs: 250,
maxBackoffMs: 1000,
timeoutMs: 30_000,
})

若執行階段需要自訂擷取行為或取消請求,也可以傳入 credentialsfetchabortSignal

人機協作
「人機協作」的直接連結

A2A 使用 input-required 任務狀態表示人機協作 (HITL) 工作。當任務暫停以等待輸入時,用戶端會使用相同 taskId 傳送後續訊息以提供缺少的輸入,伺服器接著繼續執行任務。

Mastra 會雙向將自身的 Agent 暫停模型對應至此狀態:

  • 作為伺服器:公開的 Agent 暫停時,任務會轉換為 input-required。這包括由 Tool 核准或呼叫 suspend() 的 Tool 所造成的暫停。任務狀態訊息包含文字提示,以及內含結構化 suspendPayloadresumeSchema 的資料部分。使用相同 taskId 發出的後續 message/sendmessage/stream 請求,會使用所提供的輸入繼續執行暫停的工作。
  • 作為用戶端:遠端任務到達 input-requiredauth-required 時,A2AAgent 會傳回包含 finishReason: 'suspended'suspendPayload 的暫停結果。呼叫 resumeGenerate()resumeStream(),會使用原始 taskId 將輸入或憑證傳回遠端任務。
src/a2a-hitl.ts
import { A2AAgent } from '@mastra/core/a2a'

const agent = new A2AAgent({
url: 'https://agent.example.com/api/.well-known/booking-agent/agent-card.json',
})

const result = await agent.generate('Book a flight to Paris', { runId: 'run-1' })

if (result.finishReason === 'suspended') {
// Inspect result.suspendPayload, collect input from a human,
// then resume the remote task.
const resumed = await agent.resumeGenerate({ approved: true }, { runId: 'run-1' })
console.log(resumed.text)
}

input-required 任務的後續訊息可將繼續執行資料放在結構化資料部分中,或以文字部分中的 JSON 或純文字形式攜帶。

當繼續執行的工作需要其他輸入時,任務會再次回到 input-required,並重複此流程。若要繼續執行暫停的工作,Mastra 伺服器必須設定儲存空間,才能跨請求還原暫停的執行狀態。

備註

A2A 任務記錄存放於記憶體內儲存區,因此只有暫停任務的同一個伺服器處理程序能繼續執行該任務。若伺服器重新啟動,或水平擴充部署未使用黏性路由,任務記錄便會遺失,後續訊息也會因找不到任務而失敗。

推播通知
「推播通知」的直接連結

Mastra 支援遠端 Agent 所宣告之 capabilities.pushNotifications A2A 推播通知。當用戶端無法維持串流連線,或長時間執行的任務應在原始請求結束後更新回呼 URL 時,請使用推播通知。

用戶端取得任務 ID 後,即可為該任務註冊回呼 URL:

src/a2a-client.ts
await a2a.setTaskPushNotificationConfig({
taskId: 'task-123',
pushNotificationConfig: {
url: 'https://app.example.com/a2a/tasks',
token: process.env.A2A_WEBHOOK_TOKEN,
},
})

當任務到達 completedfailedcanceledrejectedinput-requiredauth-required 時,Mastra Server 會將目前的任務快照傳送至已註冊的回呼。推播通知會盡力傳送,但不保證成功。請保護回呼 URL、驗證通知 token,並避免將內部網路目標公開為推播通知目的地。

推播通知設定儲存在記憶體中,伺服器重新啟動後必須再次註冊。

簽署及驗證 Agent 卡片
「簽署及驗證 Agent 卡片」的直接連結

Mastra 支援已簽署的 A2A Agent 卡片,讓用戶端能驗證探索到的卡片是否來自受信任的發布者,以及卡片是否在傳輸過程中遭到變更。請在公開遠端 Agent 的 Mastra 伺服器上設定簽署:

src/mastra/index.ts
import { Mastra } from '@mastra/core/mastra'

export const mastra = new Mastra({
server: {
a2a: {
agentCardSigning: {
privateKey: process.env.A2A_AGENT_CARD_PRIVATE_KEY!,
protectedHeader: {
alg: 'ES256',
kid: 'agent-card-key',
},
},
},
},
})

設定簽署後,Mastra 會在 Agent 卡片中加入 signatures 陣列。用戶端驗證是選用功能,未簽署的卡片仍會原樣傳回。

使用 MastraClient.getA2A() 驗證已簽署的卡片:

src/a2a-client.ts
const card = await a2a.getAgentCard({
verifySignature: {
algorithms: ['ES256'],
keyProvider: async ({ kid, jku }) => {
return fetchTrustedPublicJwk({ kid, jku })
},
},
})

if (!card.signatures?.length) {
throw new Error('Expected a signed A2A agent card.')
}

當用戶端必須在呼叫遠端 Agent 前強制使用受信任的金鑰時,請使用用戶端簽章驗證。

驗證子 Agent 卡片
「驗證子 Agent 卡片」的直接連結

當父 Agent 應在委派工作前驗證遠端 Agent 時,請使用 verifyAgentCard。驗證掛鉤會接收擷取到的 Agent 卡片,以及卡片擷取位置與時間的情境資訊。

src/mastra/agents/support-agent.ts
import { A2AAgent } from '@mastra/core/a2a'

const remoteWeatherAgent = new A2AAgent({
url: 'https://weather.example.com/api/.well-known/weather-agent/agent-card.json',
verifyAgentCard: {
verify: async (card, context) => {
if (card.provider?.organization !== 'Weather Inc') {
throw new Error(`Unexpected provider for ${context.cardUrl}`)
}
},
},
})

父 Agent 將工作委派給遠端 Agent 前,可使用此掛鉤強制檢查預期的 Provider、端點、憑證繫結身分、已簽署卡片或其他信任要求。