A2A Primeiros passos

Crie e execute um agente de protocolo A2A (Agent-to-Agent) em menos de 5 minutos.

Pré-requisitos

  • Rust 1.95.0 ou posterior (rustup update stable)
  • cargo-adk instalado (cargo install cargo-adk)
  • Uma chave do Google API (obtenha uma aqui)

Estruture um projeto A2A

A maneira mais rápida de começar é usar o template a2a:

cargo adk new my-a2a-agent --template a2a
cd my-a2a-agent

Isso gera um projeto completo com:

  • Cargo.tomladk-rust com features = ["standard"] (inclui suporte a A2A)
  • src/main.rs — servidor A2A usando o builder API
  • .env.example — placeholder da chave API

Adicione sua chave API:

cp .env.example .env
# Edit .env and set GOOGLE_API_KEY=your-key-here

Execute:

cargo run

Seu agente A2A agora está sendo executado em http://localhost:8080.

Outros provedores

# OpenAI
cargo adk new my-agent --template a2a --provider openai

# Anthropic
cargo adk new my-agent --template a2a --provider anthropic

API de conveniência

ADK-Rust fornece A2aServer para expor qualquer agente por meio do protocolo A2A sem configuração manual de rotas.

Configuração zero: quick_start

A abordagem mais simples — uma chamada de função, com padrões sensatos:

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 configura:

  • Serviço de sessão em memória
  • Cartão do agente em GET /.well-known/agent.json
  • Endpoint JSON-RPC em POST /a2a
  • Streaming habilitado

Configuração personalizada: Builder

Use o builder quando precisar controlar a porta, os metadados ou o backend de sessão:

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(())
}
Método do construtorPadrãoDescrição
.agent(agent)obrigatórioO agente a ser exposto
.bind_addr(addr)0.0.0.0:8080Endereço de vinculação do servidor
.session_service(svc)Em memóriaBackend de sessão
.agent_card_name(name)agent.name()Nome de exibição do cartão do agente
.agent_card_description(desc)agent.description()Descrição do cartão do agente
.agent_card_version(ver)"1.0.0"Versão do cartão do agente
.agent_card_url(url)http://localhost:{port}Público URL para o agente
.streaming(bool)trueHabilitar respostas em streaming
.push_notifications(bool)falseHabilitar notificações push

Testando com curl

Depois que seu agente estiver em execução, verifique-o com estes comandos.

Buscar o Cartão do agente

curl http://localhost:8080/.well-known/agent.json | jq .

Resposta esperada:

{
  "name": "my-agent",
  "description": "A helpful AI assistant",
  "url": "http://localhost:8080",
  "version": "1.0.0",
  "capabilities": {
    "streaming": true,
    "pushNotifications": false,
    "stateTransitionHistory": true
  },
  "skills": []
}

Enviar uma mensagem (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"
  }'

Resposta esperada:

{
  "jsonrpc": "2.0",
  "id": "req-1",
  "result": {
    "id": "task-uuid",
    "status": {"state": "completed"},
    "artifacts": [
      {
        "parts": [{"kind": "text", "text": "The A2A protocol is..."}]
      }
    ]
  }
}

Transmitir uma resposta

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"
  }'

Isso retorna Server-Sent Events com atualizações incrementais do status da tarefa.


Mantenha distintos os limites de MCP e A2A

MCP conecta uma aplicação de agente a ferramentas, recursos e outros recursos publicados. A2A conecta agentes implantados de forma independente e transporta o ciclo de vida do trabalho remoto. Uma ponte pode fazer a tradução entre os protocolos, mas essa ponte é um componente implantado separadamente, com sua própria identidade, autorização, mapeamento de esquemas, mapeamento do estado da tarefa e comportamento em caso de falha.

ADK-Rust não fornece um binário chamado mcp-a2a-server. Não coloque esse comando na configuração de MCP, a menos que sua implantação forneça e teste separadamente uma ponte desse tipo. Quando ambos os lados são agentes, use diretamente o cliente A2A.

Conectando-se a partir de outro agente ADK-Rust

Use RemoteA2aAgent para chamar seu agente A2A a partir de outra aplicação ADK-Rust:

use adk_rust::server::RemoteA2aAgent;

let remote = RemoteA2aAgent::new(
    "my-remote-agent",
    "http://localhost:8080",
);

Isso cria um agente que encaminha solicitações ao seu servidor A2A pela rede.


Referência dos endpoints

MétodoCaminhoDescrição
GET/.well-known/agent.jsonCartão do agente (capacidades, habilidades, metadados)
POST/a2aendpoint JSON-RPC (message/send, message/get, etc.)
POST/a2a/streamStreaming JSON-RPC (message/stream)

Próximos passos


Anterior: Início rápido | Próximo: LlmAgent