> Discover all available pages from the documentation index: https://mastra.zisheng.pro/ko/llms.txt # A2A(Agent 대 Agent) Mastra는 버전 0.3.0을 지원합니다.[Agent-to-Agent (A2A) protocol](https://a2a-protocol.org/latest/)크로스 플랫폼 다중 Agent 시스템용. A2A를 사용하여 Mastra Agent를 원격 Agent로 노출하거나, 원격 A2A Agent를 Mastra 하위 Agent로 사용하거나, JavaScript 클라이언트 SDK를 사용하여 A2A 엔드포인트를 호출합니다. A2A는 네트워크, 프레임워크, 공급업체 및 언어 경계를 넘어 Agent에 작업을 위임하기 위한 개방형 프로토콜입니다. 원격 Agent는 자체 Tool, Prompt, Memory, Workflow 및 인프라를 비공개로 유지하면서 다른 시스템이 검색하고 호출할 수 있는 프로토콜 엔드포인트를 노출합니다. ## A2A를 사용해야 하는 경우 - 상위 Agent는 전문 원격 Agent에게 작업을 위임해야 합니다. - 원격 Agent는 다른 서비스, 팀, 공급업체 또는 런타임이 소유합니다. - 백엔드, 브라우저 앱 또는 다른 A2A 호환 시스템에는 프로그래밍 방식으로 Mastra Agent에 액세스해야 합니다. - 장기 실행 원격 작업에는 작업 ID, 상태 업데이트, 아티팩트, 취소, 재구독 또는 푸시 알림이 필요합니다. ## A2A 작동 방식 A2A는 검색을 위해 Agent 카드를 사용합니다. 카드는 잘 알려진 URL에서 제공되는 JSON 문서입니다. 원격 Agent를 설명하고 A2A JSON-RPC 요청을 수락하는 실행 URL을 포함합니다. 기본 Mastra Server를 사용하는 경우`apiPrefix` of `/api`, an agent registered as `weather-agent` exposes: - 대리인 카드:`/api/.well-known/weather-agent/agent-card.json` - 실행 끝점:`/api/a2a/weather-agent` Agent 카드에는 Agent 이름, 설명, 엔드포인트 URL, 공급자, 기능, 보안 메타데이터 및 기술과 같은 필드가 포함됩니다. ```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 프로토콜 v0.3 및 v1.0을 지원합니다. 그만큼`A2A-Version` request header selects the wire protocol: - 누락되었거나 비어 있거나`0.3`: Uses the existing v0.3 API. - `1.0`: v1.0 API를 사용합니다. - 기타 값: 다음을 반환합니다.`VersionNotSupported` protocol error. 기존의`A2AAgent` and `MastraClient.getA2A()` integrations continue to use v0.3. Use `MastraClient.getA2AV1()` for v1.0 requests. The v1 client sends `A2A-Version: 1.0` automatically and adds the `tasks/list` operation. v1.0 프로토콜 유형 및 코덱을 다음에서 가져옵니다.`@mastra/core/a2a/v1`. The existing `@mastra/core/a2a/client` export remains on v0.3. ## 시작하기 A2A에는 Mastra에 두 가지 공통 경로가 있습니다. - 원격 A2A Agent를 Mastra 하위 Agent로 사용합니다.`A2AAgent`. - 다음을 사용하여 Mastra A2A 엔드포인트에 요청을 보냅니다.`MastraClient.getA2A()`. 사용`A2AAgent` 다른 Mastra Agent가 원격 Agent에 작업을 위임해야 할 때 사용합니다. 애플리케이션 코드에서 A2A가 활성화된 Mastra 엔드포인트를 직접 호출해야 할 때는 클라이언트 SDK를 사용하세요. ## A2A Agent를 하위 Agent로 사용 사용`A2AAgent` 를 사용하여 원격 A2A Agent를 래핑한 다음, 이를 [supervisor agents](https://mastra.zisheng.pro/ko/docs/capabilities/subagents) 패턴으로 상위 Agent에 추가하세요. 원격 서버가 여러 Agent를 호스팅하거나 사용자 지정 well-known 경로를 사용하는 경우에는 Agent 카드 URL을 명시적으로 전달하세요. ```typescript 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` points to a domain, `A2AAgent` fetches the agent card from `/.well-known/agent-card.json`. 해당 검색 경로를 따르는 단일 Agent 서버에는 도메인 URL을 사용하세요. 다중 Agent 서버에는 다음과 같이 전체 카드 URL을 전달하세요: `https://agent.example.com/api/.well-known/weather-agent/agent-card.json`. 실행 중에는`A2AAgent`: - 원격 Agent 카드를 가져오고 캐시합니다. - 카드에서 실행 URL과 기능을 읽습니다. - 통화`message/send` for non-streaming runs or `message/stream` when streaming is supported. - 원격 메시지, 작업, 아티팩트 및 상태 업데이트를 Mastra 하위 Agent 결과로 변환합니다. - 지원`resumeGenerate()` and `resumeStream()` 원격 작업에 후속 입력이나 재구독이 필요할 때 사용합니다. 원격 카드가 스트리밍 지원을 광고하지 않는 경우`A2AAgent.stream()` 는 비스트리밍 생성 경로로 대체 처리하고 버퍼링된 스트림 결과를 반환합니다. ## 클라이언트 SDK를 사용하여 요청 보내기 사용`MastraClient.getA2A()` 애플리케이션 코드에서 A2A가 활성화된 Mastra Agent를 호출하려는 경우 사용합니다. `baseUrl` for the server origin and `apiPrefix` when the server doesn't use the default `/api` prefix. ```typescript 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)를 통해 작업 상태 및 아티팩트 업데이트를 수신하세요: ```typescript 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()` 를 사용하여 진행 중인 작업의 실시간 업데이트를 수신하세요: ```typescript const updates = a2a.resubscribeTask({ id: 'task-123', }) for await (const event of updates) { console.log(event) } ``` ### v1.0 클라이언트 사용 사용`getA2AV1()` 를 사용하여 A2A v1.0 유선 프로토콜을 사용하도록 설정하세요. 프로토콜 패키지는 JSON 형태의 입력으로부터 v1 요청 값을 생성하기 위한 코덱을 제공합니다: ```typescript 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()`, and `resubscribeTask()`. ## 하위 Agent 호출 구성 `A2AAgent`인증되거나 제한된 환경에 대한 요청 옵션을 허용합니다. ```typescript 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, }) ``` 합격하실 수도 있습니다`credentials`, `fetch`, and `abortSignal` 런타임에 사용자 지정 fetch 동작이나 요청 취소가 필요할 때 사용합니다. ## 인간 참여형 A2A Model HITL(Human-In-The-Loop)은 다음과 같이 작동합니다.`input-required` 작업 상태입니다. 입력을 기다리며 작업이 일시 중지되면 클라이언트는 동일한 `taskId`, and the server continues the task. Mastra는 Agent 정지 Model을 양방향으로 이 상태에 매핑합니다. - **서버로서**: 노출된 Agent가 일시 중지되면 작업이 다음으로 전환됩니다.`input-required`. This includes suspensions caused by [tool approval](https://mastra.zisheng.pro/ko/docs/agents/agent-approval) or a tool that calls `suspend()`. 작업 상태 메시지에는 텍스트 Prompt와 구조화된 `suspendPayload` and `resumeSchema`. A follow-up `message/send` or `message/stream` request with the same `taskId` 는 제공된 입력으로 일시 중단된 실행을 재개합니다. - **클라이언트로서**: 원격 작업이 도달했을 때`input-required` or `auth-required`, `A2AAgent` returns a suspended result with `finishReason: 'suspended'` and a `suspendPayload`. Calling `resumeGenerate()` or `resumeStream()` 는 원래의 `taskId`. ```typescript 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 작업 기록은 Memory 내 저장소에 있으므로 일시 중지된 작업은 해당 작업을 일시 중지한 동일한 서버 프로세스에 의해서만 재개될 수 있습니다. 고정 라우팅이 없는 서버 다시 시작 또는 수평 확장 배포에서는 작업 기록이 손실되고 작업을 찾을 수 없다는 오류로 인해 후속 메시지가 실패합니다. ::: ## 푸시 알림 Mastra는 광고하는 원격 Agent에 대한 A2A 푸시 알림을 지원합니다.`capabilities.pushNotifications`. 클라이언트가 스트림을 계속 열어 둘 수 없거나, 장기 실행 작업이 원래 요청 종료 후 콜백 URL에 업데이트를 전송해야 하는 경우 푸시 알림을 사용하세요. 클라이언트에 작업 ID가 있으면 해당 작업에 대한 콜백 URL을 등록할 수 있습니다. ```typescript await a2a.setTaskPushNotificationConfig({ taskId: 'task-123', pushNotificationConfig: { url: 'https://app.example.com/a2a/tasks', token: process.env.A2A_WEBHOOK_TOKEN, }, }) ``` Mastra 서버는 작업이 도달하면 현재 작업 스냅샷을 등록된 콜백으로 보냅니다.`completed`, `failed`, `canceled`, `rejected`, `input-required`, or `auth-required`. 푸시 알림 전송은 최선형 방식으로 이루어집니다. 콜백 URL을 보호하고 알림 토큰을 검증하며, 내부 네트워크 대상을 푸시 알림 목적지로 노출하지 마세요. 푸시 알림 구성은 Memory에 저장되며 서버를 다시 시작한 후 다시 등록해야 합니다. ## Agent 카드 서명 및 확인 Mastra는 서명된 A2A Agent 카드를 지원하므로 클라이언트는 발견된 카드가 신뢰할 수 있는 게시자로부터 왔으며 전송 중에 변경되지 않았는지 확인할 수 있습니다. 원격 Agent를 노출하는 Mastra 서버에서 서명을 구성합니다. ```typescript 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에는 다음이 포함됩니다.`signatures` 배열에 포함됩니다. 클라이언트 검증은 선택 사항이며, 서명되지 않은 카드도 변경 없이 반환됩니다. 서명된 카드를 확인하세요.`MastraClient.getA2A()`: ```typescript 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를 호출하기 전에 신뢰할 수 있는 키를 적용해야 하는 경우 클라이언트측 서명 확인을 사용합니다. ## 하위 대리인 카드 확인 사용`verifyAgentCard` 상위 Agent가 작업을 위임하기 전에 원격 Agent를 검증해야 할 때 사용합니다. 검증 훅은 가져온 Agent 카드와 해당 카드를 가져온 위치 및 시점에 관한 컨텍스트를 받습니다. ```typescript 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에 위임하기 전에 이 후크를 사용하여 예상 공급자, 예상 끝점, 인증서 바인딩 ID, 서명된 카드 또는 기타 신뢰 요구 사항을 적용합니다. ## 관련된 - [Agent 참조](https://mastra.zisheng.pro/ko/reference/agents/agent) - [JavaScript 클라이언트 Agent 참조](https://mastra.zisheng.pro/ko/reference/client-js/agents) - [A2A 핵심 개념](https://a2a-protocol.org/latest/topics/key-concepts/) - [A2A 검색 가이드](https://a2a-protocol.org/latest/topics/agent-discovery/) - 📹 [Agent-to-agent with Mastra workshop](https://www.youtube.com/watch?v=LQDzyNGm-aw)