A2A에서의 스트리밍 및 비동기 작업¶
Agent2Agent(A2A) 프로토콜은 즉시 완료되지 않을 수 있는 작업을 처리하도록 설계되었습니다. 많은 AI 기반 작업은 장기간 실행되거나, 여러 단계를 포함하거나, 증분적 결과를 생성하거나, 사람의 개입이 필요할 수 있습니다. A2A는 이러한 비동기적 상호 작용을 관리하기 위한 강력한 메커니즘을 제공하여, 클라이언트가 지속적으로 연결되어 있든 더 단절된 방식으로 작동하든 효과적으로 업데이트를 받을 수 있도록 보장합니다.
1. 서버 전송 이벤트(SSE)를 이용한 스트리밍¶
증분적 결과(긴 문서 생성 또는 미디어 스트리밍 등)를 생성하거나 지속적인 상태 업데이트를 제공하는 작업의 경우, A2A는 서버 전송 이벤트(SSE)를 사용하여 실시간 통신을 지원합니다. 이는 클라이언트가 A2A 서버와 활성 HTTP 연결을 유지할 수 있을 때 이상적입니다.
주요 특징:
- 시작: 클라이언트는
message/stream
RPC 메서드를 사용하여 초기 메시지(예: 프롬프트 또는 명령어)를 보내고 동시에 해당 작업에 대한 업데이트를 구독합니다. - 서버 기능: A2A 서버는 해당 에이전트 카드에서
capabilities.streaming: true
를 설정하여 스트리밍 지원을 표시해야 합니다. - 서버 응답 (연결): 구독이 성공하면 서버는 HTTP
200 OK
상태와Content-Type: text/event-stream
으로 응답합니다. 이 HTTP 연결은 서버가 이벤트를 푸시할 수 있도록 열린 상태로 유지됩니다. - 이벤트 구조: 서버는 이 스트림을 통해 이벤트를 보냅니다. 각 이벤트의
data
필드에는 JSON-RPC 2.0 응답 객체, 구체적으로SendStreamingMessageResponse
가 포함됩니다. 이 JSON-RPC 응답의id
는 클라이언트의 원래message/stream
요청의id
와 일치합니다. - 이벤트 유형 (
SendStreamingMessageResponse.result
내):Task
: A2A 클라이언트를 위해 A2A 서버에서 처리 중인 상태 저장 작업 단위를 나타냅니다.TaskStatusUpdateEvent
: 작업의 라이프사이클 상태 변경(예:working
에서input-required
또는completed
로)을 전달합니다. 또한 에이전트로부터 중간 메시지를 제공할 수도 있습니다(예: "현재 데이터를 분석 중입니다...").TaskArtifactUpdateEvent
: 작업에서 생성된 새롭거나 업데이트된 아티팩트를 전달합니다. 이는 큰 파일이나 데이터 구조를 청크 단위로 스트리밍하는 데 사용됩니다. 이 객체 자체에는 클라이언트가 전체 아티팩트를 재조립하는 데 도움이 되는append
및lastChunk
와 같은 필드가 포함됩니다.
- 스트림 종료: 서버는
TaskStatusUpdateEvent
에서final: true
를 설정하여 특정 상호 작용 주기(즉, 현재message/stream
요청)에 대한 업데이트 종료를 알립니다. 이는 일반적으로 작업이 최종 상태(completed
,failed
,canceled
) 또는input-required
상태(서버가 클라이언트로부터 추가 입력을 예상하는 경우)에 도달할 때 발생합니다.final: true
이벤트를 보낸 후 서버는 일반적으로 해당 특정 요청에 대한 SSE 연결을 닫습니다. - 재구독: 작업이 아직 활성 상태이고 서버가 해당 단계에 대해
final: true
이벤트를 보내지 않은 상태에서 클라이언트의 SSE 연결이 조기에 끊어지면, 클라이언트는tasks/resubscribe
RPC 메서드를 사용하여 스트림에 다시 연결하려고 시도할 수 있습니다. 연결 끊김 기간 동안 누락된 이벤트에 대한 서버의 동작(예: 백필하는지 또는 새 업데이트만 보내는지 여부)은 구현에 따라 다릅니다.
스트리밍 사용 시기:
- 장기 실행 작업의 실시간 진행 상황 모니터링.
- 큰 결과(아티팩트)를 증분적으로 수신하여 전체 결과를 사용할 수 있기 전에 처리를 시작할 수 있도록 허용.
- 즉각적인 피드백이나 부분적인 응답이 유익한 대화형 교환.
- 에이전트로부터 낮은 지연 시간의 업데이트가 필요한 애플리케이션.
자세한 구조는 프로토콜 사양을 참조하십시오:
2. 연결되지 않은 시나리오를 위한 푸시 알림¶
매우 장기간 실행되는 작업(예: 몇 분, 몇 시간 또는 며칠 동안 지속되는 작업)이나 클라이언트가 영구적인 연결(모바일 클라이언트 또는 서버리스 기능과 같은)을 유지할 수 없거나 선호하지 않는 경우, A2A는 푸시 알림을 통해 비동기 업데이트를 지원합니다. 이 메커니즘을 통해 A2A 서버는 중요한 작업 업데이트가 발생할 때 클라이언트가 제공한 웹훅에 능동적으로 알릴 수 있습니다.
주요 특징:
- 서버 기능: A2A 서버는 해당 에이전트 카드에서
capabilities.pushNotifications: true
를 설정하여 이 기능에 대한 지원을 표시해야 합니다. -
구성: 클라이언트는 서버에
PushNotificationConfig
를 제공합니다.-
이 구성은 다음을 통해 제공될 수 있습니다:
- 초기
message/send
또는message/stream
요청 내 (TaskSendParams
의 선택적pushNotification
매개변수를 통해). - 기존 작업에 대해
tasks/pushNotificationConfig/set
RPC 메서드를 사용하여 별도로.
- 초기
-
PushNotificationConfig
에는 다음이 포함됩니다:url
: A2A 서버가 작업 업데이트 알림을 보내야 하는(POST) 절대 HTTPS 웹훅 URL입니다.token
(선택 사항): 클라이언트가 생성한 불투명한 문자열(예: 비밀 또는 작업별 식별자). 서버는 클라이언트의 웹훅 수신자가 유효성을 검사할 수 있도록 알림 요청(예:X-A2A-Notification-Token
과 같은 사용자 지정 헤더)에 이 토큰을 포함해야 합니다(SHOULD).authentication
(선택 사항): A2A 서버가 _클라이언트의 웹훅 URL_에 자신을 인증하는 방법을 지정하는AuthenticationInfo
객체입니다. 클라이언트(웹훅 수신자)가 이러한 인증 요구 사항을 정의합니다.
-
-
알림 트리거: A2A 서버는 푸시 알림을 보낼 시기를 결정합니다. 일반적으로 작업이 최종 상태(
completed
,failed
,canceled
,rejected
) 또는input-required
또는auth-required
상태로 전환되는 등 중요한 상태 변경에 도달할 때, 특히 관련된 메시지와 아티팩트가 완전히 생성되고 안정화된 후에 발생합니다. - 알림 페이로드: A2A 프로토콜 자체는 서버가 클라이언트의 웹훅으로 보내는 푸시 알림의 HTTP 본문 페이로드를 엄격하게 정의하지 않습니다. 그러나 알림에는 클라이언트가
Task ID
를 식별하고 업데이트의 일반적인 특성(예: 새로운TaskState
)을 이해하기에 충분한 정보가 포함되어야 합니다(SHOULD). 서버는 최소한의 페이로드(단지Task ID
와 새 상태) 또는 더 포괄적인 페이로드(예: 요약 또는 전체Task
객체)를 보낼 수 있습니다. - 클라이언트 조치: 푸시 알림을 수신하고 (그 신뢰성과 관련성을 성공적으로 확인한 후) 클라이언트는 일반적으로 알림의
task ID
와 함께tasks/get
RPC 메서드를 사용하여 새로운 아티팩트나 상세 메시지를 포함한 완전하고 업데이트된Task
객체를 검색합니다.
푸시 알림 서비스 (클라이언트 측 웹훅 인프라):
PushNotificationConfig.url
에 지정된 대상url
은 푸시 알림 서비스를 가리킵니다. 이 서비스는 클라이언트 측의 구성 요소(또는 클라이언트가 구독하는 서비스)이며 A2A 서버로부터 HTTP POST 알림을 수신할 책임이 있습니다.- 그 책임은 다음과 같습니다:
- 수신 알림 인증 (즉, 합법적인 A2A 서버로부터 온 것인지 확인).
- 알림의 관련성 확인 (예:
token
확인). - 적절한 클라이언트 애플리케이션 로직 또는 시스템으로 알림 또는 해당 콘텐츠 전달.
- 간단한 시나리오(예: 로컬 개발)에서는 클라이언트 애플리케이션 자체가 직접 웹훅 엔드포인트를 노출할 수 있습니다.
- 엔터프라이즈 또는 프로덕션 환경에서는 종종 수신 웹훅을 처리하고, 호출자를 인증하며, 메시지를 라우팅하는(예: 메시지 큐, 내부 API, 모바일 푸시 알림 게이트웨이 또는 다른 이벤트 기반 시스템으로) 강력하고 안전한 서비스입니다.
푸시 알림에 대한 보안 고려 사항¶
푸시 알림은 비동기적이고 서버에서 시작하는 아웃바운드 특성으로 인해 보안이 가장 중요합니다. A2A 서버(알림 전송)와 클라이언트의 웹훅 수신기 모두 책임이 있습니다.
A2A 서버 보안 (클라이언트 웹훅으로 알림 전송 시)¶
-
웹훅 URL 유효성 검사:
- 서버는 클라이언트가
PushNotificationConfig
에 제공한 어떠한url
도 맹목적으로 신뢰하고 POST 요청을 보내서는 안 됩니다 (SHOULD NOT). 악의적인 클라이언트는 내부 서비스나 관련 없는 제3자 시스템을 가리키는 URL을 제공하여 해를 입히거나(서버 측 요청 위조 - SSRF 공격) 분산 서비스 거부(DDoS) 증폭기로 작동할 수 있습니다. - 완화 전략:
- 허용 목록: 가능한 경우 웹훅 URL에 대한 신뢰할 수 있는 도메인 또는 IP 범위의 허용 목록을 유지합니다.
- 소유권 확인 / 챌린지-응답: 실제 알림을 보내기 전에 서버는 확인 단계를 수행할 수 있으며 (이상적으로는 수행해야 함) 수행해야 합니다. 예를 들어, 고유한
validationToken
(쿼리 매개변수 또는 헤더로)을 사용하여 제안된 웹훅 URL에 HTTPGET
또는OPTIONS
요청을 실행할 수 있습니다. 웹훅 서비스는 소유권과 도달 가능성을 증명하기 위해 적절하게 응답해야 합니다(예: 토큰을 다시 에코하거나 준비 상태 확인). A2A Python 샘플은 간단한 유효성 검사 토큰 확인 메커니즘을 보여줍니다. - 네트워크 제어: 송신 방화벽 또는 네트워크 정책을 사용하여 A2A 서버가 아웃바운드 HTTP 요청을 보낼 수 있는 위치를 제한합니다.
- 서버는 클라이언트가
-
클라이언트 웹훅에 대한 인증:
- A2A 서버는
PushNotificationConfig.authentication
에 지정된 체계에 따라 클라이언트의 웹훅 URL에 자신을 인증해야 합니다(MUST). - 서버 간 웹훅에 대한 일반적인 인증 체계는 다음과 같습니다:
- 베어러 토큰 (OAuth 2.0): A2A 서버는 클라이언트의 웹훅을 나타내는 대상/범위에 대한 액세스 토큰(예: 웹훅 공급자가 지원하는 경우 OAuth 2.0 클라이언트 자격 증명 부여 흐름 사용)을 얻고, 알림 POST 요청의
Authorization: Bearer <token>
헤더에 포함합니다. - API 키: A2A 서버가 특정 HTTP 헤더(예:
X-Api-Key
)에 포함하는 미리 공유된 API 키입니다. - HMAC 서명: A2A 서버는 공유 비밀 키를 사용하여 HMAC으로 요청 페이로드(또는 요청의 일부)에 서명하고, 헤더(예:
X-Hub-Signature
)에 서명을 포함합니다. 그러면 웹훅 수신기가 이 서명을 확인합니다. - 상호 TLS (mTLS): 클라이언트의 웹훅 인프라에서 지원하는 경우, A2A 서버는 클라이언트 TLS 인증서를 제시할 수 있습니다.
- 베어러 토큰 (OAuth 2.0): A2A 서버는 클라이언트의 웹훅을 나타내는 대상/범위에 대한 액세스 토큰(예: 웹훅 공급자가 지원하는 경우 OAuth 2.0 클라이언트 자격 증명 부여 흐름 사용)을 얻고, 알림 POST 요청의
- A2A 서버는
클라이언트 웹훅 수신기 보안 (A2A 서버로부터 알림 수신 시)¶
-
A2A 서버 인증:
- 웹훅 엔드포인트는 수신 알림 요청의 신뢰성을 엄격하게 확인하여 합법적인 A2A 서버로부터 온 것이지 사칭자가 아닌지 확인해야 합니다(MUST).
- 서명/토큰 확인:
- JWT(예: 베어러 토큰)를 사용하는 경우, A2A 서버의 신뢰할 수 있는 공개 키(예: 해당되는 경우 A2A 서버에서 제공하는 JWKS 엔드포인트에서 가져온 키)에 대해 JWT의 서명을 확인합니다. 또한
iss
(발급자),aud
(대상 - 웹훅을 식별해야 함),iat
(발급 시각),exp
(만료 시각)와 같은 클레임을 확인합니다. - HMAC 서명을 사용하는 경우, 공유 비밀을 사용하여 수신된 페이로드에서 서명을 다시 계산하고 요청 헤더의 서명과 비교합니다.
- API 키를 사용하는 경우, 키가 유효하고 알려진 키인지 확인합니다.
- JWT(예: 베어러 토큰)를 사용하는 경우, A2A 서버의 신뢰할 수 있는 공개 키(예: 해당되는 경우 A2A 서버에서 제공하는 JWKS 엔드포인트에서 가져온 키)에 대해 JWT의 서명을 확인합니다. 또한
PushNotificationConfig.token
확인: 클라이언트가 작업에 대한 알림을 설정할 때PushNotificationConfig
에 불투명한token
을 제공한 경우, 웹훅은 수신 알림에 이 정확한 토큰이 포함되어 있는지 확인해야 합니다(예:X-A2A-Notification-Token
과 같은 사용자 지정 헤더). 이는 알림이 이 특정 클라이언트 컨텍스트 및 작업을 위한 것임을 보장하는 데 도움이 되며, 권한 부여 계층을 추가합니다.
-
재생 공격 방지:
- 타임스탬프: 알림에는 이상적으로 타임스탬프(예: JWT의
iat
- 발급 시각 - 클레임 또는 사용자 지정 타임스탬프 헤더)가 포함되어야 합니다. 웹훅은 공격자가 오래된 캡처된 알림을 재생하는 것을 방지하기 위해 너무 오래된 알림(예: 몇 분 이상 된 알림)을 거부해야 합니다. 타임스탬프는 무결성을 보장하기 위해 서명된 페이로드의 일부여야 합니다(서명을 사용하는 경우). - 논스/고유 ID: 중요한 알림의 경우, 각 알림에 대해 고유한 일회용 식별자(논스 또는 이벤트 ID)를 사용하는 것을 고려하십시오. 웹훅은 중복 알림 처리를 방지하기 위해 수신된 ID를 (합리적인 기간 동안) 추적해야 합니다. JWT의
jti
(JWT ID) 클레임이 이 목적을 수행할 수 있습니다.
- 타임스탬프: 알림에는 이상적으로 타임스탬프(예: JWT의
-
안전한 키 관리 및 순환:
- 암호화 키(HMAC용 대칭 비밀 또는 JWT 서명/mTLS용 비대칭 키 쌍)를 사용하는 경우, 정기적인 키 순환을 포함한 안전한 키 관리 관행을 구현합니다.
- A2A 서버가 서명하고 클라이언트 웹훅이 확인하는 비대칭 키의 경우, JWKS(JSON 웹 키 세트)와 같은 프로토콜을 사용하면 서버가 잘 알려진 엔드포인트에서 공개 키(순환 중 새 키 포함)를 게시할 수 있습니다. 그러면 클라이언트 웹훅은 서명 확인을 위해 올바른 공개 키를 동적으로 가져와 키 순환을 더 원활하게 할 수 있습니다.
예시 비대칭 키 흐름 (JWT + JWKS)¶
- 클라이언트는
PushNotificationConfig
를 설정하여authentication.schemes: ["Bearer"]
및 JWT에 대한 예상issuer
또는audience
를 지정합니다. - A2A 서버는 알림을 보낼 때:
- 개인 키로 서명한 JWT를 생성합니다. JWT에는
iss
(발급자),aud
(대상 - 웹훅),iat
(발급 시각),exp
(만료 시각),jti
(JWT ID),taskId
와 같은 클레임이 포함됩니다. - JWT 헤더(
alg
및kid
)는 서명 알고리즘과 키 ID를 나타냅니다. - A2A 서버는 JWKS 엔드포인트(이 엔드포인트의 URL은 웹훅 공급자에게 알려져 있거나 검색될 수 있음)를 통해 공개 키를 사용할 수 있도록 합니다.
- 개인 키로 서명한 JWT를 생성합니다. JWT에는
- 클라이언트 웹훅은 알림을 수신하면:
Authorization
헤더에서 JWT를 추출합니다.- JWT 헤더의
kid
를 검사합니다. - A2A 서버의 JWKS 엔드포인트에서 해당 공개 키를 가져옵니다(키 캐싱 권장).
- 공개 키를 사용하여 JWT 서명을 확인합니다.
- 클레임(
iss
,aud
,iat
,exp
,jti
)을 확인합니다. - 제공된 경우
PushNotificationConfig.token
을 확인합니다.
푸시 알림에 대한 이러한 포괄적이고 계층화된 보안 접근 방식은 메시지가 신뢰할 수 있고, 완전하며, 시기적절하도록 보장하여 전송 A2A 서버와 수신 클라이언트 웹훅 인프라 모두를 보호합니다.