A2A 入门

在 5 分钟内创建并运行一个 A2A(Agent-to-Agent)协议代理。

先决条件

  • Rust 1.95.0 或更高版本(rustup update stable
  • 已安装 cargo-adkcargo install cargo-adk
  • 一个 Google API 密钥(在此获取

搭建 A2A 项目

最快的入门方式是使用 a2a 模板:

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

此命令会生成一个完整项目,其中包括:

  • Cargo.toml — 使用 features = ["standard"]adk-rust(包含 A2A 支持)
  • 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 提供 A2aServer,无需手动配置路由即可通过 A2A 协议公开任意代理。

零配置: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 端点
  • 已启用流式传输

自定义配置:构建器

当你需要控制端口、元数据或会话后端时,请使用构建器:

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 进行测试

启动 agent 后,使用以下命令进行验证。

获取 Agent Card

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 的边界 distinct

MCP 将 agent 应用连接到工具、资源和其他已发布的能力。A2A 连接独立部署的 agent,并承载其远程工作的生命周期。桥接器可以在这些协议之间进行转换,但该桥接器是一个单独部署的组件,具有自己的身份验证、授权、模式映射、任务状态映射和故障行为。

ADK-Rust 不会提供名为 mcp-a2a-server 的二进制文件。除非你的部署单独提供并测试了此类桥接器,否则不要将该命令放入 MCP 配置中。当两端都是 agent 时,直接使用 A2A 客户端。

从另一个 ADK-Rust Agent 进行连接

使用 RemoteA2aAgent 从另一个 ADK-Rust 应用调用你的 A2A agent:

use adk_rust::server::RemoteA2aAgent;

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

这会创建一个通过网络将请求转发到你的 A2A 服务器的 agent。


端点参考

方法路径描述
GET/.well-known/agent.jsonAgent 卡片(能力、技能、元数据)
POST/a2aJSON-RPC 端点(message/sendmessage/get 等)
POST/a2a/stream流式 JSON-RPC(message/stream

后续步骤


上一页快速入门 | 下一页LlmAgent

A2A 入门 - ADK-Rust 文档 | ADK-Rust