상세 컨텐츠

본문 제목

NAT A2A

카테고리 없음

by state 2026. 7. 6. 15:01

본문

**제미나이로 번역하고 인간이 하나하나 수정했습니다.

Build Workflows > A2A

 

NVIDIA NeMo Agent Toolkit Workflow as an A2A Client — NVIDIA NeMo Agent Toolkit (1.8)

<!-- SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance w

docs.nvidia.com

 

 

 리눅스 재단(Linux Foundation)이 표준화를 주도하고 있는 A2A(Agent-to-Agent) 프로토콜은 서로 다른 환경의 AI 에이전트들이 멀티 에이전트 환경에서 능력을 탐색하고, 작업을 위임하며, 정보를 안전하게 교환할 수 있도록 돕는 오픈 표준 인터페이스입니다.

오늘 포스팅에서는 엔비디아의 에이전트 개발 프레임워크인 NVIDIA NeMo Agent Toolkit을 활용해 외부의 원격 A2A 에이전트와 연결하고 협업을 수행하는 A2A 클라이언트(Client) 워크플로우를 구축하는 방법을 자세히 알아보겠습니다.

 

NeMo Agent Toolkit에서 A2A 클라이언트는 사용자별 per-user Function Group(함수 그룹) 형태로 동작합니다. 

  • 시스템을 이용하는 각 사용자(User)는 고유하고 격리된 A2A 클라이언트 인스턴스를 부여받습니다. 사용자마다 별도의 연결 상태, 인증(Authentication), 세션 상태가 완벽히 분리되어 관리됩니다. 즉 한 사용자가 다른 사용자의 에이전트에 접근할 수 없습니다. 
  • 공용으로 공유되는 일반 워크플로우(react_agent 등)에서는 A2A 클라이언트를 직접 사용할 수 없습니다. 반드시 사용자별 격리를 지원하는 @register_per_user_function 데코레이터를 쓰거나 내장된 사용자 전용 워크플로우(per_user_react_agent)를 활용해야 합니다. 멀티 테넌트(Multi-tenant) 서비스 환경에서 보안과 프라이버시를 자동으로 보장해 주는 핵심 메커니즘입니다.
  • -> 3번의 '기본 설정 예시'에서 workflow의 type 선언에서 확인할 수 있습니다

2. 환경 구성 및 패키지 설치

A2A 클라이언트 기능을 사용하려면 nvidia-nat-a2a 확장 패키지가 필요합니다.

uv pip install "nvidia-nat[a2a]"

 

3. A2A 클라이언트 워크플로우 설정 (YAML Configuration)

NeMo Agent Toolkit은 선언적인 YAML 설정을 통해 외부 에이전트를 내 워크플로우의 '도구(Tool)'처럼 연결할 수 있게 지원합니다.

기본 설정 예시 (환율 에이전트 연결)

function_groups:
  currency_agent:
    _type: a2a_client
    url: http://localhost:11000
    task_timeout: 60

workflow:
  _type: per_user_react_agent  # A2A 클라이언트를 위해 사용자별 워크플로우 지정 필수
  tool_names:
    - currency_agent
  llm_name: nim_llm

 위 설정은 로컬 11000 포트에서 실행 중인 외부 환율 에이전트(currency_agent)를 지정한 것입니다. NeMo 클라이언트는 해당 에이전트의 에이전트 카드(Agent Card)를 읽어오고, 해당 에이전트가 가진 기술(Skills)들을 자동으로 탐색하여 자신이 호출할 수 있는 함수 인터페이스로 변환합니다. A2A 클라이언트가 per-user이므로 workflow도 per-user 단위로 나뉩니다. 

 

a2a_client function group은 다음과 같은 Configuration 옵션을 가집니다

Parameter Type Description Default
url string A2A 에이전트 URL 필수
agent_card_path string 에이전트 card endpoint 경로 /.well-known/agent-card.json
task_timeout int 작업 타임아웃 시간을 초단위로 기본값은 300
include_skills_in_description boolean 함수 설명에 내장된 스킬들 기본값은 true
auth_provider string authentication provider 레퍼  

 

# 전체 설정가능한 옵션과 스키마를 불러오기
nat info components -t function_group -q a2a_client

여러 에이전트 동시 연결 예시

여러개의 A2A 에이전트들을 같은 per-user workflow에 연결할 수 있습니다. 모든 A2A 클라이언트는 사용자 단위로 

function_groups:
  calculator_agent:
    _type: a2a_client
    url: http://localhost:10000
  currency_agent:
    _type: a2a_client
    url: http://localhost:11000

workflow:
  _type: per_user_react_agent
  tool_names:
    - calculator_agent
    - currency_agent

4. 3단계 API 아키텍처

NeMo A2A 클라이언트는 개발자의 요구사항에 맞추어 추상화 수준을 3개 계층(Level)으로 나누어 제공합니다. 프로젝트의 복잡도에 따라 적절한 수준의 API를 선택해 호출할 수 있습니다. 하위레벨로 갈 수록 추상화 수준이 감소하여 사용자가 지정할 수 있는 부분이 많아집니다.

API 레벨 인터페이스 및 메서드 주요 특징 및 설명
Level 1: High-level agent_name.call(query)  LLM 기반 에이전트 간 대화에 최적화된 형태이며, 쿼리를 던지면 원격 에이전트가 생각하고 처리한 최종 텍스트 결과를 받아옵니다.
Level 2:
Helper Functions
get_skills(), get_info(), get_task()  원격 에이전트가 어떤 기술을 가졌는지 메타데이터를 확인하거나 진행 중인 작업 상태를 모니터링할 때 사용합니다.
Level 3: 
Low-level
send_message(), send_message_streaming()  JSON-RPC 등 기저 프로토콜 메시지를 직접 제어하거나 실시간 스트리밍(Streaming) 이벤트를 한 땀 한 땀 받아 처리할 때 유용합니다.

 

어느정도로 A2A를 컨트롤하고 현재 상태를 가져올건지에 따라서 api 레벨을 선택하면 된다. 개인적으로 High-level에서는 CoT를 받아오기 어려우며 최소한 Level 2 정도를 사용하는 것이 좋아보인다. 

Level 1: 고수준 API (High-Level API) 

대부분의 LLM 기반 멀티 에이전트 시스템을 구축할 때 가장 먼저 선택해야 하는 표준 접근 방식입니다. 사람이 대화하듯 자연어 문장을 던지면 원격 에이전트가 최종 결과를 도출해 반환합니다.

핵심 함수: agent_name.call(query: str) -> str

  • 표준 LLM 기반 멀티 에이전트를 상호 연동할 때
  • 메인 에이전트가 다른 하위 에이전트에게 작업을 단순 위임할 때 -> 즉 두 개 이상의 에이전트가 동등하게 서로 호출하는 것이 아님
  • '에이전트를 하나의 도구처럼(Agent-as-a-tool)' 패턴으로 래핑할 때 -> 그냥 단순히 결과만 받아오기 때문에 복잡한 중간 과정을 호출한 master 에이전트의 입력으로 사용하지 않는다. 
  • 클라이언트가 별도로 스킬을 지정할 필요가 없습니다. 쿼리를 통째로 넘기면 원격 서버 에이전트가 스스로 판단하여 내부 스킬을 선택하고 실행합니다.

 워크플로우 설정 (YAML) 및 LLM 인지 구조

클라이언트 단에서 아래와 같이 외부 환율 에이전트(currency_agent)를 도구로 등록했다고 가정해 봅시다.

workflow:
  _type: react_agent
  tool_names:
    - currency_agent  # 내부적으로 고수준의 .call() 함수를 호출하도록 매핑됨

이렇게 등록하면 메인 에이전트의 LLM은 이 외부 에이전트를 단 하나의 파이썬 함수처럼 인지하게 됩니다. 실제 LLM 프롬프트 컨텍스트에 주입되는 함수의 형태는 다음과 같습니다.

# LLM이 실제로 바라보는 함수 명세 내부 구조
currency_agent(query: str) -> str
Description: Currency conversion agent with the following skills:
  - convert_currency: Convert between currencies
  - get_exchange_rate: Get current exchange rates

NeMo 서버가 제공한 에이전트 카드를 해석해서 외부의 convert_currency나 get_exchange_rate 같은 세부 스킬 정보들을 함수의 '설명(Description)' 란에 자동으로 임베딩해 줍니다. LLM은 이 설명을 읽고 자연어 쿼리를 어떻게 구성해 던질지 판단합니다.

Level 2: 헬퍼 함수 계층 (Helper Functions) — 태스크 관리 및 모니터링

원격 에이전트의 상태를 조회하거나, 비동기로 백그라운드에서 실행 중인 작업(Task)을 관리하고 취소할 수 있는 메타데이터 제어 기능들을 제공합니다.

  • 커스텀 오케스트레이션(Orchestration, 중앙 제어) 로직을 직접 코딩할 때
  • 현재 원격 에이전트가 어떤 스킬셋을 보유하고 있는지 동적으로 쿼리해야 할 때
  • 장시간 실행되는 작업의 상태를 모니터링하고 필요 시 취소(Cancel)해야 할 때

주요 지원 함수 예시 (비동기 처리 지원)

  • agent_name.get_skills() : 원격 에이전트가 제공하는 가용한 스킬 목록 전체를 리스트로 반환합니다.
  • agent_name.get_info() : 에이전트의 이름, 버전, 설명 등 메타데이터 정보를 가져옵니다.
  • agent_name.get_task(task_id) : 특정 태스크 ID의 실시간 진행 상황을 추적합니다.
  • agent_name.cancel_task(task_id) : 현재 원격지에서 열심히 돌고 있는 비동기 작업을 중단시킵니다.
# 가용한 원격 스킬 목록 동적 쿼리
skills = await agent.get_skills()

# 에이전트 메타데이터 조회
info = await agent.get_info()
print(f"연결된 에이전트 이름: {info.name}, 버전: {info.version}")

Level 3: 저수준 프로토콜 API (Low-Level Protocol API)

 메시지 전송 시 세션 식별자나 컨텍스트를 커스텀하게 조작할 수 있으며, 특히 응답이 생성되는 과정을 실시간 이벤트를 통해 가로챌 수 있습니다.

  • A2A 프로토콜 규격 자체를 커스텀하게 확장하거나 완전히 제어해야 하는 특수 에이전트를 만들 때
  • 고도화된 고급 태스크 관리 시스템이 필요할 때
  • 실시간 스트리밍(Streaming) 데이터 스트림이나 이벤트 로그에 직접 파이프라인을 연결해야 할 때
  • agent_name.send_message(query, task_id, context_id) : 메시지를 전송하고 해당 작업 흐름에서 발생하는 로우 이벤트를 수신합니다.
  • agent_name.send_message_streaming(query, task_id, context_id) : 원격 에이전트가 연산하는 과정에서 뱉어내는 데이터 스트림을 실시간으로 구독(Subscribe)합니다.
# JSON-RPC 규격상의 task_id와 대화의 맥락을 잡아줄 context_id를 직접 제어
events = await agent.send_message(
    query="Convert 100 USD to EUR",
    task_id="custom-task-uuid-1234",
    context_id="user-session-9999"
)

 

 

멀티 에이전트 아키텍처를 설계할 때 가장 번거로운 작업 중 하나는 "새로운 에이전트가 추가될 때마다 연결 코드를 새로 짜야 하는가?"입니다. 엔비디아 네모(NeMo)는 '에이전트 카드 탐색(Agent Card Discovery)' 메커니즘을 통해 이 문제를 완전히 해결했습니다.

연결 주소(URL) 하나만 찔러주면 알아서 명세를 분석하고 내 시스템의 '도구'로 빌드해 주는 이 편리한 기술의 내부 작동 원리와 관리 팁을 공유합니다.

 

  1. 클라이언트는 지정된 URL 뒤에 표준 경로인 /.well-known/agent-card.json을 붙여 에이전트 카드를 다운로드합니다.
  2. 대상 에이전트의 이름(name), 버전(version), 설명(description)을 읽어 들입니다.
  3. 에이전트가 가진 skill을 그들의 설명과 실제 사용 예시를 추출합니다.
  4. 추출한 skill들을 기반으로 앞서 배웠던 3가지 API 레벨을 갖춘 하나의 Function Group을  생성합니다.
  5. 상위 LLM이 이 도구를 알아보고 쓸 수 있도록 고수준 call() 함수의 Description 란에 세부 스킬 설명들을  집어넣어 줍니다.

2. 데이터 전송(Transport) 및 스트리밍(Streaming) 지원 현황

A2A 클라이언트는 에이전트 카드에 명시된 통신 규격을 파악하여 가장 알맞은 전송 계층을 자동으로 매핑합니다. 현재는 HTTP 상에서 JSON-RPC를 사용하는 것이 기본 표준입니다. (향후 업데이트를 통해 gRPC 및 순수 HTTP/REST 프로토콜을 명시적으로 설정할 수 있는 옵션이 추가될 예정입니다.)

  • 지능형 스트리밍 전환: 클라이언트가 원격 에이전트에 연결하면 시스템 내부적으로 스트리밍 기능이 자동으로 활성화됩니다. 기저 프로토콜 레벨에서 저수준 함수인 send_message_streaming()이 구동되어, 원격지에서 응답 이벤트가 도착하는 대로 실시간으로 데이터를 밀어줍니다. 개발자는 복잡한 스트림 파이프라인을 짤 필요 없이 고수준 call() 함수만 편하게 쓰면 됩니다.

코드를 한 줄도 작성하지 않고 터미널 명령행 인터페이스(CLI) 도구인 nat를 사용해 에이전트 상태를 검증하는 방법입니다.

① 에이전트 능력 탐색하기 (Discover)

일회성 질문을 던져 리스폰스 타임과 답변 정확도를 즉시 테스트합니다.

nat a2a client call --url http://localhost:10000 --message "What is 2 + 2?"
 

출력 예시

Query: What is 2 + 2?

The sum of 2 and 2 is 4.

(0.85s)

discover 명령어는 A2A 에이전트에 연결하여 에이전트 카드(capabilities, skills, configuration)를 출력합니다.

nat a2a client discover --url $A2A_SERVER_URL

출력 예시

 

 

 

Run Workflows > A2A server

NVIDIA NeMo Agent Toolkit을 사용하면 복잡한 네트워크 웹 서버 코딩 없이, 기존 워크플로우 설정 파일(YAML)에 간단한 명세를 추가하여  A2A 서버(Server)로 변환할 수 있습니다.

2. 필수 패키지 설치

A2A 클라이언트와 동일하게 서버 기능도 nvidia-nat-a2a 확장 패키지가 기반이 됩니다.

uv pip install "nvidia-nat[a2a]"

3. A2A 서버 구동 및 설정법

A2A 서버를 여는 방법은 크게 CLI 명령어를 이용하는 방법설정 파일(YAML)에 내장하는 방법 두 가지가 있습니다.

방법 A. CLI 명령어로 즉시 서빙하기 (가장 간단한 방법) - nat a2a serve

기존에 구현해 둔 워크플로우 파일(config.yml)이 있다면 다음과 같이 터미널 명령을 내려 서버를 띄울 수 있습니다.

nat a2a serve --config_file ./configs/config.yml 
	--host 0.0.0.0
    --port 11000 
    --name "Calculator Agent" 
    --description "수학적 연산을 수행하는 계산기 에이전트입니다."

명령어를 실행하면 workflow 설정을 불러와서

기본적으로 http://localhost:11000에 A2A서버가 열리며

에이전트 카드를 (http://localhost:11000/.well-known/agent-card.json)에 노출시킵니다.

방법 B. YAML 설정 파일에 선언하기 (프로덕션 추천)

워크플로우 환경 설정 파일의 general.front_end 섹션에 서버 명세를 직접 내장시키는 방식입니다. 코드가 깔끔하게 관리되므로 실제 서비스 배포 시 유리합니다.

general:
  front_end:
    _type: a2a
    name: "Calculator Agent"
    description: "수학적 연산을 처리하는 API 에이전트"
    host: localhost
    port: 10000
    public_base_url: "https://agents.example.com/calculator" # 인프라 외부 노출용 public URL
    version: "1.0.0"
    max_concurrency: 16 # 동시 처리 제어 (기본값: 8)

이렇게 설정을 마친 후에는 별도 파라미터 없이 서버만 구동해 주면 됩니다.

nat a2a serve --config_file ./configs/config.yml


대규모 배포 팁 :

general:
  front_end:
    _type: a2a
    name: "Calculator Agent"
    max_concurrency: 16  # Maximum concurrent workflow executions (default: 8)

 

  • max_concurrency: 서버가 동시에 처리할 수 있는 워크플로우 수행 개수를 제한합니다. 설정값을 넘어서는 무리한 요청이 들어오면 워크프로우 완료시 까지 큐(Queue)에서 대기하도록 하여 하드웨어 자원 고갈을 막아줍니다.
general:
  front_end:
    _type: a2a
    host: 0.0.0.0
    port: 10000
    public_base_url: ${NAT_PUBLIC_BASE_URL}
  • public_base_url: 쿠버네티스(K8s)나 인그레스(Ingress) 환경에서 내부 바인딩 주소(0.0.0.0:10000)와 실제 외부 사용자가 접근하는 도메인 주소가 다를 때 사용합니다. 이 값을 지정해야 생성되는 agent-card.json 내부에 올바른 외부 접속 경로가 광고됩니다.

4. 에이전트 카드(Agent Card) 자동 맵핑 예시

서버가 실행되면 NeMo가 내 파이썬 도구들을 분석해 아래와 같이 깔끔한 JSON 형태의 Agent Card 표준 규격을 발행합니다. 맵핑 예시

 

Workflow Configuration

function_groups:
  calculator:
    _type: calculator # 내부에 add, subtract, multiply, divide 함수 포함
workflow:
  _type: react_agent
  tool_names: [calculator]

A2A Agent card (generated)

{
  "name": "Calculator Agent",
  "skills": [
    {"id": "calculator__add", "name": "add", "description": "Add two or more numbers"},
    {"id": "calculator__subtract", "name": "subtract", "description": "Subtract numbers"},
    {"id": "calculator__multiply", "name": "multiply", "description": "Multiply numbers"},
    {"id": "calculator__divide", "name": "divide", "description": "Divide numbers"}
  ]
}

5. 서버 정상 작동 테스트 및 호출하기

서버를 띄웠다면 NeMo CLI 도구를 이용해 원격지 혹은 로컬 환경에서 정상 작동 여부를 즉시 검증할 수 있습니다.

export A2A_SERVER_URL=http://localhost:10000

# 1) 에이전트 카드가 규격대로 잘 나오는지 수동 확인
curl $A2A_SERVER_URL/.well-known/agent-card.json | jq

# 2) NeMo CLI로 호출 테스트
nat a2a client call --url $A2A_SERVER_URL --message "42와 67의 곱은 얼마인가요?"

 

CLI로 에이전트 호출하기 

# 에이전트 호출
nat a2a client call --url $A2A_SERVER_URL --message "What is product of 42 and 67?"

# 예시 응답
Query: What is product of 42 and 67?

The product of 42 and 67 is 2814.0

(0.85s)

 

A2A 서버 사용의 예시는 examples/A2A/math_assistant_a2a/README.md 에서 확인할 수 있습니다. A2A 서버는 공식 A2A Python SDK의 프로토콜 컴플라이언스를 준수합니다. 구체적인 프로토콜 상세는 A2A 프로토콜 공식 문서를 참조하세요

댓글 영역