A2A Primeros pasos

Crea y ejecuta un agente de protocolo A2A (de agente a agente) en menos de 5 minutos.

Requisitos previos

  • Rust 1.95.0 o posterior (rustup update stable)
  • cargo-adk instalado (cargo install cargo-adk)
  • Una clave de Google API (obtén una aquí)

Crear un proyecto A2A

La forma más rápida de comenzar es usar la plantilla a2a:

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

Esto genera un proyecto completo con:

  • Cargo.tomladk-rust con features = ["standard"] (incluye compatibilidad con A2A)
  • src/main.rs — servidor A2A que utiliza el constructor API
  • .env.example — marcador de posición para la clave API

Añade tu clave API:

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

Ejecuta:

cargo run

Tu agente A2A ahora está disponible en http://localhost:8080.

Otros proveedores

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

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

API de conveniencia

ADK-Rust proporciona A2aServer para exponer cualquier agente mediante el protocolo A2A sin configurar rutas manualmente.

Sin configuración: quick_start

El enfoque más sencillo: una llamada de función con valores predeterminados adecuados:

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:

  • Servicio de sesiones en memoria
  • Tarjeta del agente en GET /.well-known/agent.json
  • Punto de conexión JSON-RPC en POST /a2a
  • Transmisión habilitada

Configuración personalizada: constructor

Usa el constructor cuando necesites controlar el puerto, los metadatos o el backend de sesiones:

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 del constructorPredeterminadoDescripción
.agent(agent)obligatorioEl agente que se expondrá
.bind_addr(addr)0.0.0.0:8080Dirección de enlace del servidor
.session_service(svc)En memoriaBackend de sesión
.agent_card_name(name)agent.name()Nombre para mostrar de la tarjeta del agente
.agent_card_description(desc)agent.description()Descripción de la tarjeta del agente
.agent_card_version(ver)"1.0.0"Versión de la tarjeta del agente
.agent_card_url(url)http://localhost:{port}URL pública para el agente
.streaming(bool)trueHabilitar respuestas en streaming
.push_notifications(bool)falseHabilitar notificaciones push

Pruebas con curl

Una vez que el agente esté en ejecución, verifíquelo con estos comandos.

Obtener la tarjeta del agente

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

Respuesta 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 un mensaje (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"
  }'

Respuesta esperada:

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

Transmitir una respuesta

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

Esto devuelve Server-Sent Events con actualizaciones incrementales del estado de la tarea.


Mantener diferenciados los límites entre MCP y A2A

MCP conecta una aplicación de agente con herramientas, recursos y otras capacidades publicadas. A2A conecta agentes implementados de forma independiente y transporta el ciclo de vida de su trabajo remoto. Un puente puede traducir entre los protocolos, pero ese puente es un componente implementado por separado, con su propia identidad, autorización, mapeo de esquemas, mapeo del estado de las tareas y comportamiento ante fallos.

ADK-Rust no incluye un binario llamado mcp-a2a-server. No coloque ese comando en la configuración de MCP a menos que su implementación proporcione y pruebe por separado dicho puente. Cuando ambos lados son agentes, utilice directamente el cliente A2A.

Conectarse desde otro agente ADK-Rust

Utilice RemoteA2aAgent para llamar a su agente A2A desde otra aplicación ADK-Rust:

use adk_rust::server::RemoteA2aAgent;

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

Esto crea un agente que reenvía las solicitudes a su servidor A2A a través de la red.


Referencia de endpoints

MétodoRutaDescripción
GET/.well-known/agent.jsonTarjeta del agente (capacidades, habilidades, metadatos)
POST/a2aPunto de conexión de JSON-RPC (message/send, message/get, etc.)
POST/a2a/streamStreaming JSON-RPC (message/stream)

Próximos pasos


Anterior: Inicio rápido | Siguiente: LlmAgent