Agent2Agent 프로토콜 · A2A v1.0

에이전트를 독립적으로 배포하자 함께 일하세요.

A2A는 AI 에이전트가 다른 에이전트에게 자신을 소개하고, 작업을 수락하고, 진행 상황을 보고하고, 추가 정보를 요청하고, 유용한 결과를 반환하는 표준 방법을 제공합니다. 다른 에이전트가 다른 AI 서비스에서 실행되거나, 다른 프로그래밍 언어 또는 에이전트 프레임워크를 사용하거나, 다른 클라우드에 배포되는 경우에도 마찬가지입니다. 두 에이전트 모두 다른 에이전트가 어떻게 구축되었는지 이해할 필요가 없습니다. 그들은 A2A 표준을 사용하여 함께 통신하고 작업합니다.

11 v1 작업에이전트 카드JSON-RPC + RESTSSE 스트리밍다중 회전 작업인증된 푸시RemoteA2aAgent

ADK-Rust A2A 참조 아키텍처

A2A 원격 에이전트의 아키텍처

The network contract stays separate from the agent's model, tools, memory, and internal orchestration.

01

호출 시스템

다른 에이전트에게 작업을 요청하는 에이전트 또는 애플리케이션입니다.

코디네이터 에이전트

어떤 원격 전문가가 작업을 받아야 하는지 결정합니다.

A2A 클라이언트

카드를 검색하고 스트리밍을 선택하고 프로토콜 메시지를 보냅니다.

HTTPS

02

A2A 서비스 경계

호환되는 모든 클라이언트가 이해할 수 있는 공개 계약입니다.

대리인 카드

이름, 기술, 엔드포인트, 프로토콜 버전, 보안 및 선언된 기능입니다.

수표 요청

버전, 콘텐츠 유형, ID, 메시지 부분, 메타데이터, ID 및 제한.

요청 핸들러

하나의 공유 구현을 통해 JSON-RPC 또는 REST 작업을 디스패치합니다.

타이핑된 전화

03

ADK-Rust 런타임

프레임워크는 작업을 실행하고 형식화된 진행 상황을 생성합니다.

Runner

호출 컨텍스트를 생성하고 에이전트 이벤트를 스트리밍합니다.

에이전트 시스템

LLM, 워크플로, 그래프, 사용자 정의 또는 다중 에이전트 논리.

도구

Rust 도구 및 MCP

상태

세션 및 메모리

에이전트가 작동하는 동안 작업 상태 및 이벤트가 기록됩니다.

04

작업 수명주기

검증된 상태 머신은 장기 실행 작업을 검사 가능하게 만듭니다.

작업 저장소

상태, 컨텍스트, 기록, 아티팩트, 메타데이터 및 푸시 구성입니다.

상태 머신

유효한 전환만 허용됩니다. 터미널 작업은 터미널을 유지합니다.

05

진행상황 전달

발신자는 변경 사항을 수신할 방법을 선택합니다.

직접적인 반응

전체 작업과 해당 아티팩트를 반환합니다.

SSE 스트림

작업을 먼저 수행한 다음 상태 및 아티팩트를 업데이트합니다.

06

요청 후 작업

긴 작업은 하나의 연결을 열어두지 않고도 나중에 보고할 수 있습니다.

구독

클라이언트는 기존 작업에 대한 업데이트를 수신합니다.

웹훅 푸시

재시도 및 SSRF 확인을 통해 인증된 배달.

ADK-Rust는 A2A 와이어 계약, 작업 수명 주기, 에이전트 실행 및 전달 채널을 별도의 조각으로 유지하므로 각각 독립적으로 보안, 테스트 및 교체가 가능합니다.

아이디어부터 시작하세요

외부 호스팅 AI 에이전트로 작업하려면 어떻게 해야 하나요?

하나의 ADK-Rust 프로세스 내에서 에이전트는 Rust 유형, 세션, 도구 및 직접 함수 호출을 공유할 수 있습니다. 에이전트가 다른 서비스 또는 다른 조직에 속하게 되면 해당 개인 구현 세부 사항은 더 이상 안전한 계약이 아닙니다.

A2A는 해당 경계에서 공유 언어를 정의합니다. 호출자는 엔드포인트 뒤에서 어떤 모델, 프레임워크 또는 도구가 실행되는지 알 필요 없이 원격 에이전트가 제공하는 것을 발견하고, 구조화된 메시지를 보내고, 알려진 상태를 통해 작업을 따르고, 아티팩트를 수신합니다.

ADK-Rust는 adk-server에 A2A v1을 구현하고 프로토콜을 Runner에 직접 연결합니다. 로컬에서 테스트하는 동일한 에이전트는 네트워크 서비스가 될 수 있으며, RemoteA2aAgent를 사용하면 다른 ADK-Rust 시스템이 일반 에이전트 인터페이스를 통해 이를 사용할 수 있습니다.

대리인 카드

에이전트의 서비스 프로필

작은 공개 문서는 호출자에게 에이전트의 이름, 엔드포인트, 기술, 프로토콜 버전, 보안 요구 사항 및 스트리밍 또는 알림 지원 여부를 알려줍니다.

메시지

한 상담원이 다른 상담원에게 말하는 내용

메시지는 역할, 고유 ID 및 텍스트나 구조화된 데이터와 같은 하나 이상의 부분을 전달합니다. 고유 ID를 사용하면 안전한 재시도가 가능합니다.

작업

두 시스템 모두 수행할 수 있는 작업

작업은 원격 작업에 ID, 대화 컨텍스트, 상태, 메시지 기록, 메타데이터 및 그 과정에서 생성된 모든 아티팩트를 제공합니다.

유물

작업의 유용한 결과

아티팩트는 보고서, 결정, 계획, 생성된 파일 또는 다른 시스템에서 사용할 수 있는 기타 구조화된 출력 등 작업에 첨부된 명명된 결과입니다.

하나의 직업을 팔로우하세요

프로토콜은 작업의 요청과 수명을 모두 전달합니다.

호출자는 하나의 응답을 기다리거나, 라이브 이벤트 스트림을 열거나, 기존 작업을 구독하거나, 향후 업데이트를 위해 웹후크를 등록할 수 있습니다. 작업 ID와 컨텍스트는 모든 전달 모드를 동일한 작업에 연결합니다.

작업 상태 머신

원격 근무에는 따라갈 수 있는 삶이 있습니다.

A2A는 텍스트를 반환하는 것 이상의 기능을 수행합니다. 이는 작업에 정체성, 대화 컨텍스트, 현재 상태, 역사 및 인공물을 제공합니다. ADK-Rust는 모든 전환을 저장하기 전에 유효성을 검사합니다.

SUBMITTED

서버가 작업을 수락했습니다.

WORKING

에이전트가 실행 중입니다.

INPUT REQUIRED

상담원에게 추가 정보가 필요합니다.

AUTH REQUIRED

발신자는 승인을 제공해야 합니다.

COMPLETED

작품과 유물이 준비되었습니다.

FAILED

오류가 발생하여 실행이 종료되었습니다.

CANCELED

허용된 취소로 인해 작업이 종료되었습니다.

REJECTED

서버가 작업을 거부했습니다.

다중 회전 작업: 작업이 도달하면 INPUT_REQUIRED, 발신자는 동일한 내용의 다른 메시지를 보냅니다. contextId. ADK-Rust는 작업을 찾아서 다음으로 반환합니다. WORKING, 메시지를 추가하고 동일한 작업을 계속합니다.

실제 논리 흐름

Case Study: Resolve a customer's damaged order across two distinct agent services.

A customer tells the company's support agent that an order arrived damaged. The support agent remains responsible for the conversation: it understands the request, keeps the customer informed, collects any missing evidence, and presents the final decision. It does not have direct access to warehouse stock, delivery records, or replacement policy.

해당 운영 정보는 별도로 배포된 이행 에이전트에 속합니다. A2A를 통해 지원 에이전트는 이행 에이전트가 수행하는 작업을 검색하고, 조사를 작업으로 보내고, 진행 상황을 추적하고, 추가 정보 요청에 응답하고, 최종 교체 결정을 받을 수 있습니다. 각 서비스는 자체 코드, 데이터, 도구, 모델 공급자 및 보안 제어를 유지합니다. A2A 계약에 정의된 메시지, 작업 상태 및 아티팩트만 공유합니다.

01

전문가를 찾아보세요

지원 코디네이터는 주문 처리 담당자의 카드를 읽고 주문 조사를 처리하고 진행 상황을 스트리밍하는지 확인합니다.

02

명확한 작업 하나 보내기

주문 번호, 고객 요청, 고유 messageId 및 새 대화 컨텍스트를 보냅니다.

03

서비스 내부 경로

원격 ADK-Rust 상담원은 내부 정보를 발신자에게 노출시키지 않고 주문 도구, 재고, 배송 내역 및 회사 정책을 확인합니다.

04

무엇이 부족한지 물어보세요

손상 증명이 필요한 경우 작업은 추측하거나 자동으로 실패하는 대신 INPUT_REQUIRED가 됩니다.

05

동일한 작업 재개

코디네이터는 동일한 contextId를 사용하여 승인된 증거를 제공합니다. 기록과 작업 정체성은 그대로 유지됩니다.

06

감사 가능한 결과 반환

작업은 상태 기록과 교체 결정 및 다음 단계가 포함된 아티팩트로 완료됩니다.

Sequence diagram

The task pauses and resumes without losing its identity.

Read from top to bottom. The A2A service owns the network contract and task record. The fulfilment agent owns its reasoning and private tools.

Support coordinator

Calling agent

A2A service

Protocol boundary

Fulfilment agent

ADK-Rust Runner

Business systems

Orders · inventory · policy

A2A를 통해 전화
Runner로 파견
승인된 도구를 사용합니다

GET /.well-known/agent-card.json

Discover skills and streaming

Agent Card

Fulfilment capability published

SendStreamingMessage

ORD-1042 · messageId msg-order-1042

Runner invocation

Create task and execute agent

order.lookup + policy.check

Use private business tools

Evidence required

Damage photo is missing

INPUT_REQUIRED

Persist state and context

SSE status update

Ask support for evidence

SendMessage · same contextId

Approved photo reference

Resume task

INPUT_REQUIRED → WORKING

inventory.reserve

Reserve replacement stock

Artifact + COMPLETED

Replacement decision

Final SSE events

Auditable result returned

The support coordinator never receives database credentials or fulfilment code. It receives only the Agent Card, protocol events, task state, and final artifact.

코드 및 연결 응답

양측이 무엇을 보내고 받는지 확인하세요.

이 예제에서는 ADK-Rust 구현과 동일한 v1 작업 이름, 메시지 필드, 작업 상태 및 SSE 응답 형태를 사용합니다. ID와 주문 세부정보가 고정되어 있어 전체 대화를 쉽게 따라갈 수 있습니다.

fulfilment.rs이행 서비스 · RUST
let fulfilment = LlmAgentBuilder::new("fulfilment")
      .description("Investigates orders and delivery")
      .model(model)
      .instruction(
          "Use the approved order, inventory, and policy tools.            Ask for evidence when the replacement policy requires it."
      )
      .build()?;

  A2aServer::builder()
      .agent(Arc::new(fulfilment))
      .agent_card_name("Fulfilment Agent")
      .streaming(true)
      .build()?
      .serve()
      .await?;
support.rs지원 코디네이터 · RUST
let fulfilment = RemoteA2aAgent::builder("fulfilment")
      .description("Investigates orders and delivery")
      .agent_url("https://agents.example.com/fulfilment")
      .streaming(true)
      .build()?;

  let support = LlmAgentBuilder::new("support")
      .model(model)
      .instruction("Own the customer conversation.")
      .sub_agent(Arc::new(fulfilment))
      .build()?;
SendStreamingMessage.json1 · 작업 보내기
{
    "jsonrpc": "2.0",
    "id": "replace-1",
    "method": "SendStreamingMessage",
    "params": {
      "message": {
        "messageId": "msg-order-1042",
        "role": "ROLE_USER",
        "parts": [{
          "text": "Investigate damaged order ORD-1042 and prepare a replacement decision."
        }]
      }
    }
  }
text/event-stream2 · 스트림 작업 진행
data: {
    "jsonrpc":"2.0", "id":"replace-1",
    "result":{"task":{
      "id":"task-order-1042",
      "contextId":"ctx-order-1042",
      "status":{"state":"TASK_STATE_SUBMITTED"}
    }}
  }

  data: {
    "jsonrpc":"2.0", "id":"replace-1",
    "result":{"statusUpdate":{
      "taskId":"task-order-1042",
      "contextId":"ctx-order-1042",
      "status":{"state":"TASK_STATE_WORKING"}
    }}
  }
input-required.event.json3 · 누락된 증거를 요청하세요
{
    "statusUpdate": {
      "taskId": "task-order-1042",
      "contextId": "ctx-order-1042",
      "status": {
        "state": "TASK_STATE_INPUT_REQUIRED",
        "message": {
          "role": "ROLE_AGENT",
          "parts": [{
            "text": "Please provide a photo showing the damaged item."
          }]
        }
      }
    }
  }
SendMessage.follow-up.json4 · 동일한 작업 재개
{
    "jsonrpc": "2.0",
    "id": "replace-2",
    "method": "SendMessage",
    "params": {
      "message": {
        "messageId": "msg-order-1042-photo",
        "contextId": "ctx-order-1042",
        "role": "ROLE_USER",
        "parts": [{
          "text": "Evidence received and approved: damage-photo-8841.jpg"
        }]
      }
    }
  }
final-events.json5 · 아티팩트 및 완료 받기
{
    "artifactUpdate": {
      "taskId": "task-order-1042",
      "contextId": "ctx-order-1042",
      "artifact": {
        "artifactId": "replacement-decision-1042",
        "name": "Replacement decision",
        "parts": [{
          "text": "Approved. Reserve SKU-RED-42 and dispatch with priority shipping."
        }]
      }
    }
  }

  {
    "statusUpdate": {
      "taskId": "task-order-1042",
      "contextId": "ctx-order-1042",
      "status": { "state": "TASK_STATE_COMPLETED" }
    }
  }

A2A v1 API

클라이언트가 원격 에이전트 작업을 시작하고, 따르고, 완료하는 데 필요한 모든 것입니다.

ADK-Rust는 A2A v1에서 11가지 작업을 모두 구현합니다. 짧은 작업의 경우 SendMessage를 호출하고 작업 결과를 기다립니다. 작업 시간이 더 오래 걸릴 수 있는 경우 SendStreamingMessage를 사용하여 작업을 먼저 수신한 다음 SSE를 통해 실시간 상태 및 아티팩트 이벤트를 수신합니다.

반환된 작업 ID를 사용하면 클라이언트가 작업을 다시 제출하지 않고도 다시 연결할 수 있습니다. 최신 상태를 가져오고, 관련 작업을 나열하고, 추가 업데이트를 구독하거나, 취소를 요청할 수 있습니다. 클라이언트가 연결을 계속 열어둘 수 없는 경우 인증된 웹후크를 등록하고 원격 에이전트가 나중에 변경 사항을 전달하도록 할 수 있습니다.

01

일을 시작하다

메시지를 보내고 전체 작업이나 실시간 스트림을 받으세요.

SendMessageSendStreamingMessage
02

검사 및 제어

현재 작업을 읽고, 일치하는 작업을 나열하거나, 상태가 허용하는 경우 작업을 취소하세요.

GetTaskListTasksCancelTask
03

진행 상황을 따르세요

이미 존재하는 작업의 업데이트를 위해 SSE 구독을 엽니다.

SubscribeToTask
04

최신 업데이트 받기

작업에 대해 인증된 웹훅 대상을 생성하고, 읽고, 나열하고, 제거합니다.

CreatePushConfigGetPushConfigListPushConfigsDeletePushConfig
05

더 알아보기

에이전트의 게시된 서비스 프로필의 확장 버전을 요청합니다.

GetExtendedAgentCard

두 개의 바인딩을 위한 하나의 핸들러

JSON-RPC 및 REST 경로는 동일한 RequestHandler로 전달되므로 작업 동작이 전송 간에 드리프트되지 않습니다.

Runner 지원 실행

수신되는 A2A 메시지는 ADK-Rust 콘텐츠가 됩니다. Runner는 선택한 에이전트를 실행하고 해당 이벤트를 작업 상태 및 아티팩트로 변환합니다.

안전한 재시도

반복되는 messageId는 동일한 작업을 두 번 실행하는 대신 기존 작업을 반환합니다. 프로덕션 배포는 다시 시작해도 이 매핑을 유지해야 합니다.

컨텍스트로 시작하는 스트리밍

첫 번째 SSE 이벤트는 전체 작업입니다. 이후 이벤트는 상태 및 아티팩트 업데이트를 전달하므로 클라이언트는 항상 스트림이 속한 항목을 알 수 있습니다.

원격 상담원이 현지 느낌을 받음

RemoteA2aAgent는 ADK-Rust 에이전트 특성을 구현합니다. 코디네이터는 에이전트 계층 구조에 네트워크 서비스를 포함하고 일반 프레임워크 이벤트를 수신할 수 있습니다.

경계에서의 보호

버전 협상, 메시지 유효성 검사, 전달자 인증, 속도 제한, 감사 인터셉터, 웹훅 인증 및 SSRF 검사를 통해 서비스를 보호할 수 있습니다.

올바른 경계를 선택하세요

로컬 하위 에이전트와 원격 A2A 에이전트

A2A는 네트워크, 공개 계약, 인증, 오류 처리 및 원격 작업 상태를 도입합니다. 이러한 비용은 진정한 독립성을 창출할 때 가치가 있습니다. 모든 에이전트가 이미 동일한 프로세스에 있으면 불필요합니다.

로컬 하위 에이전트

원격 A2A 에이전트

최적의 핏
하나의 애플리케이션이 소유한 에이전트
독립적으로 배포되거나 소유된 에이전트
커뮤니케이션
진행 중인 에이전트 호출 및 타입 안전 이벤트
HTTP, JSON-RPC 또는 REST 및 SSE
공유 상태
동일한 세션과 서비스를 사용할 수 있습니다.
선언된 메시지, 작업 및 아티팩트만 공유합니다.
실패 경계
단일 런타임 및 배포
네트워크, 시간 초과, 재시도 및 원격 서비스 오류
상호 운용성
ADK-Rust 구성 요소
모든 A2A 호환 언어 또는 프레임워크

Rust 에이전트에서 네트워크 서비스로

에이전트를 노출한 후 에이전트로 사용합니다.

편의점 서버는 에이전트 카드, 세션, A2A 경로 및 스트리밍이 활성화된 Axum 애플리케이션을 생성합니다. 원격 어댑터는 해당 서비스를 검색하고 해당 작업 업데이트를 다시 ADK-Rust 이벤트로 변환합니다.

serve.rs에이전트 노출
use adk_server::a2a::convenience::A2aServer;

  let app = A2aServer::quick_start(agent);
  let listener = tokio::net::TcpListener::bind(
      "0.0.0.0:8080"
  ).await?;

  axum::serve(listener, app).await?;
coordinator.rs다른 상담원에게 전화하세요.
use adk_server::a2a::RemoteA2aAgent;

  let fulfilment = RemoteA2aAgent::builder("fulfilment")
      .description("Investigates orders and delivery")
      .agent_url("https://agents.example.com/fulfilment")
      .build()?;

  let coordinator = LlmAgentBuilder::new("support")
      .model(model)
      .sub_agent(Arc::new(fulfilment))
      .build()?;
완전히 구성된 v1 서비스의 경우: 문서화된 것을 사용하라 RequestHandler::with_runner 작업 저장소, 푸시 발신자, 에이전트 카드, Runner 서비스, JSON-RPC 경로, REST 라우터 및 버전 협상 미들웨어를 명시적으로 선택하기 위한 경로입니다.

생산 전

A2A 에이전트 배포

ADK-Rust는 v1 유형, 핸들러, 라이프사이클, 클라이언트, 검증, 전달 기본 요소 및 Runner와의 통합을 제공합니다. 프로덕션 준비 상태는 여전히 서비스에 대해 선택한 스토리지, ID, 네트워크, 관측 가능성 및 운영 정책에 따라 달라집니다.

01

정직한 카드를 공개하세요

배포가 실제로 지원하는 기술, 바인딩, 스트리밍, 푸시 전달 및 보안 체계만 광고하십시오.

02

내구성 있는 상태 선택

포함된 InMemoryTaskStore 및 인메모리 멱등성 맵은 개발에 유용합니다. 장기간 실행되는 생산 작업에는 프로세스를 다시 시작해도 지속되는 스토리지가 필요합니다.

03

양방향 확보

인바운드 통화를 인증하고 아웃바운드 푸시 전달을 보호합니다. HTTP 푸시 발신자는 전달자 자격 증명, 알림 토큰, 재시도 및 개인 주소 거부를 지원합니다.

04

디자인 취소 및 시간 초과

원격 작업은 요청보다 오래 지속될 수 있습니다. 클라이언트 시간 초과, 취소 정책, 재시도 동작 및 두 서비스 중 하나를 사용할 수 없게 되면 어떻게 되는지 정의합니다.

에이전트 시스템 연결

표준 A2A 인터페이스를 통해 에이전트를 노출합니다.

하나의 정직한 요원 카드와 하나의 유용한 작업으로 시작하세요. 작업이 길어지고 서비스가 중요해짐에 따라 스트리밍, 다중 턴 입력, 작업 지속성, 구독, 인증된 푸시, 경계 제어를 추가하세요.