Skip to main content
Summary

왜 명세를 계층으로 나누는가

A2A를 구현하려고 하면 곧바로 이런 질문을 만나게 된다. "JSON-RPC로 호출해야 하는가, gRPC로 만들어야 하는가, 아니면 REST API로 노출해야 하는가?" 이 질문은 중요하지만, 가장 먼저 답할 질문은 아니다. 더 근본적인 질문은 "어떤 전송 방식을 쓰더라도 같은 작업을 같은 의미로 이해할 수 있는가?"이다.

A2A 1.0.0 명세는 이 문제를 풀기 위해 세 계층 구조를 택한다. 첫째는 정식 데이터 모델(Canonical Data Model), 둘째는 추상 작업(Abstract Operations), 셋째는 프로토콜 바인딩(Protocol Bindings)이다. 데이터 모델은 무엇을 주고받는지 정의하고, 추상 작업은 무엇을 할 수 있는지 정의하며, 프로토콜 바인딩은 그것을 실제 네트워크에서 어떻게 호출하는지 정의한다.1

이 구조를 이해하면 A2A를 특정 API 스타일로 오해하지 않게 된다. A2A의 핵심은 "JSON-RPC를 쓰는 에이전트 프로토콜"도 아니고 "gRPC 전용 인터페이스"도 아니다. 핵심은 Task, Message, Artifact 같은 공통 의미론을 유지한 채 여러 전송 방식으로 같은 협업을 수행할 수 있게 하는 데 있다.

프로토콜 명세의 세 계층 구조AI 생성 이미지

1계층: 정식 데이터 모델

첫 번째 계층은 A2A에서 사용하는 공통 명사들을 정의한다. 여기에는 Task, Message, AgentCard, Part, Artifact, Extension이 포함된다. 이 객체들은 특정 전송 방식에 묶이지 않는다. JSON-RPC로 보내든, gRPC 메시지로 보내든, REST의 JSON 본문으로 보내든 같은 개념을 가리켜야 한다.

예를 들어 Task는 단순한 요청 번호가 아니다. 이전 장에서 살펴본 것처럼 Task는 하나의 업무가 접수되고, 진행되고, 입력을 기다리고, 완료되거나 실패하는 전체 실행 맥락이다. 따라서 어떤 바인딩을 쓰더라도 Task에는 고유 식별자, 상태, 관련 메시지, 산출물, 메타데이터가 같은 의미로 표현되어야 한다.

Message는 에이전트 간 의사소통의 한 턴이다. 사람이 입력한 요청일 수도 있고, 원격 에이전트가 돌려주는 응답일 수도 있다. Message 안에는 하나 이상의 Part가 들어간다. Part는 실제 콘텐츠 조각이다. 텍스트일 수도 있고, 구조화 데이터일 수도 있으며, 파일 참조일 수도 있다.

Artifact는 Task 수행의 결과로 남는 산출물이다. 보고서, 표, JSON 데이터, 파일 링크처럼 이후 단계에서 다시 사용할 수 있는 결과가 여기에 해당한다. AgentCard는 원격 에이전트의 신원, 기능, 엔드포인트, 인증 요구사항을 설명하는 소개서다. Extension은 핵심 명세만으로 표현하기 어려운 추가 기능이나 데이터를 확장하기 위한 장치다.

이 데이터 모델이 먼저 있어야 하는 이유는 간단하다. 같은 단어를 다르게 이해하면 협업은 쉽게 깨진다. 어떤 구현체는 completed를 "처리가 멈춘 상태" 정도로만 이해하고, 다른 구현체는 "최종 산출물까지 확정되어 더 이상 입력을 받을 수 없는 상태"로 이해한다면 자동화 흐름은 불안정해진다. 정식 데이터 모델은 이런 차이를 줄이는 공통 어휘 역할을 한다.

2계층: 추상 작업

두 번째 계층은 A2A 에이전트가 지원해야 하는 기본 행동을 정의한다. 여기서 중요한 점은 "추상"이라는 단어다. 추상 작업은 아직 HTTP 경로나 gRPC 메서드 이름을 말하지 않는다. 대신 클라이언트가 원격 에이전트에게 어떤 종류의 요청을 할 수 있고, 그 결과로 무엇을 기대할 수 있는지를 설명한다.

대표적인 작업은 Send Message다. 클라이언트는 Message를 보내고, 원격 에이전트는 단순한 응답 Message를 돌려주거나 장기 처리를 위한 Task를 생성한다. 간단한 질의라면 즉시 답이 올 수 있다. 반대로 분석, 승인, 외부 시스템 조회가 필요한 업무라면 Task가 만들어지고 이후 상태를 추적하게 된다.

여기에 가까운 작업으로 Send Streaming Message가 있다. 이름 그대로 메시지를 보내되, 처리 중 상태 변화나 중간 산출물을 스트리밍으로 받을 수 있는 방식이다. 단순 응답이면 하나의 Message만 받고 연결이 끝날 수 있고, Task가 만들어지는 경우에는 Task 상태 업데이트나 Artifact 업데이트가 이어질 수 있다. 즉시 끝나는 대화와 오래 걸리는 업무 사이의 차이를 프로토콜 차원에서 표현해주는 작업이라고 보면 된다.

Get Task는 이미 시작된 Task의 현재 상태를 조회한다. 스트리밍 연결이 끊겼거나, 웹훅 알림을 받은 뒤 최종 상태를 확인해야 하거나, 일정 주기로 진행 상황을 점검할 때 사용한다. List Tasks는 여러 Task를 조건에 따라 나열한다. 운영 도구, 관리자 콘솔, 배치 모니터링에서 유용하다. Cancel Task는 진행 중인 Task에 취소를 요청한다. 다만 취소 요청이 항상 성공한다는 뜻은 아니다. 이미 완료되었거나 취소할 수 없는 단계라면 실패하거나 현재 상태가 반환될 수 있다.

Get Agent Card는 협업 시작 전 원격 에이전트의 정보를 확인하는 작업이다. 어떤 기능을 제공하는지, 어떤 입력 형식을 받는지, 스트리밍을 지원하는지, 어떤 인증이 필요한지를 파악해야 안전하게 호출할 수 있다. 발견과 실행이 분리되어야 클라이언트는 무작정 요청을 던지는 대신, 상대의 능력과 제약을 확인한 뒤 적절한 상호작용 방식을 선택할 수 있다.

실제 명세에는 이 밖에도 진행 중인 Task에 다시 구독하거나, 장기 작업을 위해 푸시 알림 구성을 다루는 작업들이 이어진다. 하지만 이 장에서 먼저 기억해야 할 핵심은 작업 이름 자체가 아니다. 중요한 것은 Send Message든 Get Task든 Cancel Task든, 이 행동들이 특정 URL이나 특정 RPC 메서드보다 한 단계 위에서 정의된다는 점이다.

이 계층은 구현자에게 중요한 기준을 제공한다. "우리 서비스는 REST로만 노출할 예정인데 A2A의 Task 의미를 그대로 지키고 있는가?", "gRPC 스트리밍을 쓰지만 Send Streaming Message의 종료 조건을 올바르게 따르는가?" 같은 질문에 답할 수 있게 해준다.

3계층: 프로토콜 바인딩

세 번째 계층은 앞의 추상 작업을 실제 프로토콜로 노출하는 방법을 다룬다. A2A 1.0.0 명세는 JSON-RPC, gRPC, HTTP+JSON/REST 바인딩을 제시한다. 여기에 필요한 메서드 이름, 엔드포인트 패턴, 요청·응답 형태, 스트리밍 방식 같은 세부 사항이 들어간다.

같은 Send Message라도 바인딩에 따라 모습은 달라진다. JSON-RPC에서는 메서드 호출처럼 보일 수 있다. gRPC에서는 서비스의 RPC 메서드로 표현된다. REST에서는 특정 HTTP 엔드포인트에 JSON 본문을 보내는 형태가 된다. 그러나 이 셋은 모두 같은 추상 작업을 노출해야 한다. 입력 Message의 의미, Task를 반환할 수 있다는 점, terminal 상태의 Task에 새 메시지를 붙일 수 없다는 제약은 바인딩이 달라도 유지되어야 한다.

간단히 정리하면 다음과 같다.

계층다루는 질문예시
데이터 모델무엇을 주고받는가Task, Message, Part, Artifact, AgentCard
추상 작업무엇을 할 수 있는가Send Message, Send Streaming Message, Get Task, List Tasks, Cancel Task, Get Agent Card
프로토콜 바인딩어떻게 호출하는가JSON-RPC 메서드, gRPC RPC, REST 엔드포인트

이 분리는 실무에서 매우 중요하다. 한 조직 안에서도 백엔드 간 통신은 gRPC를 선호하고, 외부 파트너 연동은 REST를 선호하며, 기존 에이전트 런타임은 JSON-RPC와 잘 맞을 수 있다. 바인딩이 다르다는 이유만으로 Task 상태나 Artifact 구조가 달라진다면 A2A의 상호운용성은 무너진다. 반대로 세 계층을 지키면 각 팀은 자신에게 맞는 전송 방식을 선택하면서도 같은 업무 의미를 공유할 수 있다.

Protocol Buffers가 기준점이 되는 이유

A2A 1.0.0 명세에서 특히 눈여겨볼 부분은 spec/a2a.proto 파일의 역할이다. 이 proto 파일은 프로토콜 데이터 객체와 요청·응답 메시지의 단일하고 권위 있는 규범적 정의로 취급된다. 생성된 JSON 산출물이나 SDK, 스키마는 편의를 위한 파생물이며, 수동으로 따로 관리하는 기준점이 아니다.1

이 선택에는 실용적인 이유가 있다. 첫째, 데이터 구조가 여러 문서와 코드에 흩어지면 시간이 지나면서 서로 어긋난다. 이를 명세 드리프트(specification drift)라고 부를 수 있다. proto를 기준으로 삼으면 언어별 SDK, JSON 스키마, 문서가 같은 원천에서 생성되므로 불일치를 줄일 수 있다.

둘째, Protocol Buffers는 특정 전송 방식에 종속되지 않는다. gRPC와 잘 맞지만 gRPC만을 위한 형식은 아니다. 중요한 것은 "Task라는 객체가 어떤 필드를 가지며, 그 필드가 어떤 타입과 의미를 갖는가"를 명확히 정의하는 것이다. JSON-RPC나 REST 구현체도 이 정의를 기준으로 직렬화 방식을 맞출 수 있다.

셋째, 생태계가 커질수록 변경 관리가 중요해진다. 필드를 추가하거나 이름을 바꾸거나 더 이상 권장하지 않는 값을 표시할 때, 기준 파일이 있어야 호환성 정책을 일관되게 적용할 수 있다. 에이전트 프로토콜은 한 회사의 내부 API보다 더 넓은 범위에서 사용되므로, 이런 결정적 기준점이 필요하다.

새 바인딩을 추가해도 의미는 바뀌지 않는다

A2A의 계층 구조는 미래의 확장을 전제로 한다. 오늘은 JSON-RPC, gRPC, REST가 중심일 수 있지만, 내일은 다른 메시징 시스템이나 내부 서비스 메시, 이벤트 기반 전송 방식이 필요할 수 있다. 이때 새 바인딩을 추가한다고 해서 Task의 의미나 Send Message의 동작이 바뀌어서는 안 된다.

새 바인딩이 해야 할 일은 세 가지다. 첫째, 정식 데이터 모델을 그대로 표현해야 한다. 둘째, 추상 작업의 입력, 출력, 오류, 상태 전이를 보존해야 한다. 셋째, 해당 전송 방식에서만 필요한 세부 규칙을 명확히 문서화해야 한다. 예를 들어 인증 헤더를 어디에 넣는지, 스트리밍을 어떤 메커니즘으로 제공하는지, 오류 코드를 어떻게 매핑하는지는 바인딩의 책임이다. 하지만 "완료된 Task에는 새 메시지를 보낼 수 없다" 같은 규칙은 바인딩이 마음대로 바꿀 수 없다.

Extension도 같은 관점에서 보아야 한다. Extension은 핵심 모델을 깨뜨리지 않고 추가 기능을 표현하기 위한 장치다. 특정 산업, 특정 기업, 특정 런타임에 필요한 부가 정보를 담을 수 있지만, 기본 Task와 Message의 의미를 대체해서는 안 된다.

구현자가 가져야 할 관점

A2A 명세를 읽을 때는 API 문서의 경로 목록부터 외우려 하지 않는 편이 좋다. 먼저 데이터 모델을 보고, 그다음 추상 작업을 이해한 뒤, 마지막으로 자신이 사용할 바인딩을 선택해야 한다. 이 순서를 따르면 구현 결정이 더 단단해진다.

예를 들어 Google Cloud 기반으로 에이전트 서비스를 운영한다고 해도, A2A 자체는 특정 클라우드에 묶이지 않는다. 내부 서비스 간에는 gRPC를 쓰고, 외부 고객에게는 REST 게이트웨이를 제공하며, 일부 에이전트 플랫폼과는 JSON-RPC로 연동할 수 있다. 중요한 것은 세 경우 모두 같은 AgentCard로 능력을 설명하고, 같은 Task 생명주기를 따르며, 같은 Artifact 의미를 유지하는 것이다.

결국 A2A 1.0.0 명세의 세 계층은 구현 자유와 상호운용성 사이의 균형 장치다. 데이터 모델은 공통 어휘를 제공하고, 추상 작업은 공통 행동을 정의하며, 프로토콜 바인딩은 각 환경에 맞는 호출 방식을 제공한다. 이 구조를 이해하면 A2A를 단순한 API 형식이 아니라, 여러 에이전트가 같은 업무 언어로 협업하기 위한 표준으로 볼 수 있다.

참고

1A2A Protocol Specification 1.0.0

책 목록

구글이 주도한 A2A(Agent-to-Agent): 다중 AI 에이전트 협업을 위한 개방형 프로토콜

전체 목차 보기

이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.

틸노트는 사용자가 AI를 활용해 노트를 쉽게 작성하거나 편집할 수 있는 서비스입니다.

AI 스퀘어 단톡방에 함께해요

AI 활용과 틸노트 사용 팁을 나누는 오픈채팅방입니다. 입장 비밀번호는 tilnote입니다.

참여하기