A2A 시작하기
5분 이내에 A2A(에이전트 간) 프로토콜 에이전트를 생성하고 실행합니다.
사전 요구 사항
- Rust 1.95.0 이상(
rustup update stable) cargo-adk설치됨(cargo install cargo-adk)- Google API 키(여기에서 발급)
A2A 프로젝트 스캐폴딩
시작하는 가장 빠른 방법은 a2a 템플릿을 사용하는 것입니다.
cargo adk new my-a2a-agent --template a2a
cd my-a2a-agent
다음 항목이 포함된 완전한 프로젝트가 생성됩니다.
Cargo.toml— A2A을 지원하는adk-rust(features = ["standard"]포함)src/main.rs— 빌더 API를 사용하는 A2A 서버.env.example— API 키 자리 표시자
API 키를 추가합니다.
cp .env.example .env
# Edit .env and set GOOGLE_API_KEY=your-key-here
실행합니다.
cargo run
이제 A2A 에이전트가 http://localhost:8080에서 서비스를 제공합니다.
기타 제공자
# OpenAI
cargo adk new my-agent --template a2a --provider openai
# Anthropic
cargo adk new my-agent --template a2a --provider anthropic
간편한 API
ADK-Rust는 수동으로 경로를 구성하지 않고도 모든 에이전트를 A2A 프로토콜을 통해 노출할 수 있는 A2aServer를 제공합니다.
구성 없이 사용: quick_start
가장 간단한 방법으로, 한 번의 함수 호출과 합리적인 기본값만 사용합니다.
use adk_rust::prelude::*;
use adk_rust::server::A2aServer;
use std::sync::Arc;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
dotenvy::dotenv().ok();
let api_key = std::env::var("GOOGLE_API_KEY")?;
let model = GeminiModel::new(api_key, "gemini-3.7-flash")?;
let agent: Arc<dyn Agent> = Arc::new(
LlmAgentBuilder::new("my-agent")
.description("A helpful AI assistant")
.instruction("You are a helpful assistant exposed via A2A.")
.model(Arc::new(model))
.build()?,
);
let app = A2aServer::quick_start(agent);
let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await?;
axum::serve(listener, app).await?;
Ok(())
}
quick_start는 다음을 구성합니다.
- 메모리 내 세션 서비스
GET /.well-known/agent.json의 에이전트 카드POST /a2a의 JSON-RPC 엔드포인트- 스트리밍 활성화
사용자 지정 구성: Builder
포트, 메타데이터 또는 세션 백엔드를 직접 제어해야 하는 경우 builder를 사용합니다.
use adk_rust::prelude::*;
use adk_rust::server::A2aServer;
use std::sync::Arc;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
dotenvy::dotenv().ok();
let api_key = std::env::var("GOOGLE_API_KEY")?;
let model = GeminiModel::new(api_key, "gemini-3.7-flash")?;
let agent: Arc<dyn Agent> = Arc::new(
LlmAgentBuilder::new("my-agent")
.description("Production A2A agent")
.instruction("You are a helpful assistant.")
.model(Arc::new(model))
.build()?,
);
let server = A2aServer::builder()
.agent(agent)
.bind_addr("0.0.0.0:9090")
.agent_card_name("My Production Agent")
.agent_card_description("Handles customer queries via A2A")
.agent_card_version("2.0.0")
.streaming(true)
.push_notifications(false)
.build()?;
server.serve().await?;
Ok(())
}
| 빌더 메서드 | 기본값 | 설명 |
|---|---|---|
.agent(agent) | 필수 | 노출할 에이전트 |
.bind_addr(addr) | 0.0.0.0:8080 | 서버 바인드 주소 |
.session_service(svc) | 메모리 내 | 세션 백엔드 |
.agent_card_name(name) | agent.name() | 에이전트 카드 표시 이름 |
.agent_card_description(desc) | agent.description() | 에이전트 카드 설명 |
.agent_card_version(ver) | "1.0.0" | 에이전트 카드 버전 |
.agent_card_url(url) | http://localhost:{port} | 에이전트의 공개 URL |
.streaming(bool) | true | 스트리밍 응답 활성화 |
.push_notifications(bool) | false | 푸시 알림 활성화 |
curl을 사용한 테스트
에이전트가 실행되면 다음 명령으로 확인합니다.
에이전트 카드 가져오기
curl http://localhost:8080/.well-known/agent.json | jq .
예상 응답:
{
"name": "my-agent",
"description": "A helpful AI assistant",
"url": "http://localhost:8080",
"version": "1.0.0",
"capabilities": {
"streaming": true,
"pushNotifications": false,
"stateTransitionHistory": true
},
"skills": []
}
메시지 보내기(JSON-RPC)
curl -X POST http://localhost:8080/a2a \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "message/send",
"params": {
"message": {
"role": "user",
"parts": [{"kind": "text", "text": "What is the A2A protocol?"}],
"messageId": "msg-1"
}
},
"id": "req-1"
}'
예상 응답:
{
"jsonrpc": "2.0",
"id": "req-1",
"result": {
"id": "task-uuid",
"status": {"state": "completed"},
"artifacts": [
{
"parts": [{"kind": "text", "text": "The A2A protocol is..."}]
}
]
}
}
응답 스트리밍
curl -X POST http://localhost:8080/a2a/stream \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "message/stream",
"params": {
"message": {
"role": "user",
"parts": [{"kind": "text", "text": "Explain Rust in 3 sentences."}],
"messageId": "msg-2"
}
},
"id": "req-2"
}'
이는 증분 작업 상태 업데이트가 포함된 Server-Sent Events를 반환합니다.
MCP 및 A2A 경계를 명확히 구분하기
MCP은 에이전트 애플리케이션을 도구, 리소스 및 기타 게시된 기능에 연결합니다. A2A는 독립적으로 배포된 에이전트를 연결하고 원격 작업의 수명 주기를 전달합니다. 브리지는 두 프로토콜 간에 변환할 수 있지만, 해당 브리지는 자체 ID, 인증, 스키마 매핑, 작업 상태 매핑 및 오류 동작을 갖춘 별도로 배포되는 구성 요소입니다.
ADK-Rust에는 mcp-a2a-server이라는 바이너리가 포함되어 있지 않습니다. 배포 환경에서 이러한
브리지를 별도로 제공하고 테스트하지 않는 한 MCP 구성에 해당 명령을 넣지
마세요. 양쪽 모두 에이전트인 경우 A2A 클라이언트를 직접 사용하세요.
다른 ADK-Rust 에이전트에서 연결하기
RemoteA2aAgent를 사용하여 다른 ADK-Rust 애플리케이션에서 A2A 에이전트를 호출합니다.
use adk_rust::server::RemoteA2aAgent;
let remote = RemoteA2aAgent::new(
"my-remote-agent",
"http://localhost:8080",
);
이렇게 하면 네트워크를 통해 A2A 서버로 요청을 전달하는 에이전트가 생성됩니다.
엔드포인트 참조
| 메서드 | 경로 | 설명 |
|---|---|---|
| GET | /.well-known/agent.json | 에이전트 카드(기능, 스킬, 메타데이터) |
| POST | /a2a | JSON-RPC 엔드포인트(message/send, message/get 등) |
| 게시 | /a2a/stream | 스트리밍 JSON-RPC (message/stream) |
다음 단계
- A2A 빠른 시작 예제 — 최소 실행 가능 예제
- 도구 통합 — A2A 에이전트에 사용자 지정 도구 추가
- 세션 — 요청 간 대화 상태 유지
- 배포 — A2A 에이전트를 프로덕션에 배포