第15章 A2A 协议

第15章 A2A 协议

本章目标

  • 理解 A2A(Agent-to-Agent)协议的设计理念
  • 了解 A2A 的架构:客户端与服务端
  • 掌握 A2aAgent 的使用方法
  • 学会部署和调用远程智能体服务

15.1 A2A 协议概述

15.1.1 什么是 A2A?

A2A(Agent-to-Agent)协议 是一种标准化的智能体间通信协议,允许不同系统、不同语言实现的智能体相互调用。它定义了智能体的发现、描述和调用规范。

┌─────────────────────────────────────────────────────────────┐
│                      A2A 协议架构                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   ┌─────────────────────┐       ┌─────────────────────┐    │
│   │    客户端应用        │       │    A2A 服务端        │    │
│   │  ┌───────────────┐  │       │  ┌───────────────┐  │    │
│   │  │   A2aAgent    │──┼──────▶│  │ AgentScope    │  │    │
│   │  │  (远程代理)    │  │ A2A   │  │   Server     │  │    │
│   │  └───────────────┘  │协议    │  └───────────────┘  │    │
│   └─────────────────────┘       └─────────────────────┘    │
│                                                             │
│   A2A 协议定义:                                             │
│   ┌─────────────────────────────────────────────────────┐   │
│   │ AgentCard(智能体名片)                               │   │
│   │ - name: 智能体名称                                    │   │
│   │ - description: 功能描述                               │   │
│   │ - url: 服务端点                                       │   │
│   │ - capabilities: 能力列表                              │   │
│   │ - inputModes: 支持的输入模式                          │   │
│   │ - outputModes: 支持的输出模式                         │   │
│   └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

15.1.2 核心概念

概念说明
AgentCard智能体名片,描述智能体的元信息和能力
A2A Server暴露智能体服务的服务端
A2aAgent调用远程智能体的客户端代理
Transport通信传输层(HTTP、JSON-RPC 等)
TaskA2A 中的任务单元

15.1.3 与其他模式的对比

特性A2AAgent-as-ToolMsgHub
部署方式分布式/远程本地进程内本地进程内
通信协议HTTP/JSON-RPC方法调用内存消息
发现机制AgentCard代码注册手动配置
适用场景微服务、跨语言同进程协作多方对话

15.2 A2A 服务端

15.2.1 服务端架构

┌─────────────────────────────────────────────────────────────┐
│                    A2A 服务端                                │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   ┌─────────────────────────────────────────────────────┐   │
│   │                 AgentScopeA2aServer                  │   │
│   │  ┌──────────────────────────────────────────────┐   │   │
│   │  │              HTTP/JSON-RPC 端点               │   │   │
│   │  │  - /.well-known/agent-card.json (AgentCard)  │   │   │
│   │  │  - /a2a (任务处理端点)                        │   │   │
│   │  └──────────────────────────────────────────────┘   │   │
│   │                        │                             │   │
│   │                        ▼                             │   │
│   │  ┌──────────────────────────────────────────────┐   │   │
│   │  │              RequestHandler                   │   │   │
│   │  │  - sendMessage: 处理消息发送                  │   │   │
│   │  │  - getTask: 获取任务状态                      │   │   │
│   │  │  - cancelTask: 取消任务                       │   │   │
│   │  └──────────────────────────────────────────────┘   │   │
│   │                        │                             │   │
│   │                        ▼                             │   │
│   │  ┌──────────────────────────────────────────────┐   │   │
│   │  │               ReActAgent                      │   │   │
│   │  │          (实际执行任务的智能体)                │   │   │
│   │  └──────────────────────────────────────────────┘   │   │
│   └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

15.2.2 Spring Boot 集成

AgentScope-Java 提供了 Spring Boot Starter 来快速搭建 A2A 服务:

添加依赖:

<dependency>
    <groupId>io.agentscope</groupId>
    <artifactId>agentscope-a2a-spring-boot-starter</artifactId>
    <version>${agentscope.version}</version>
</dependency>

配置文件:

# application.yml
agentscope:
  a2a:
    enabled: true
    agent-card:
      name: "MyAssistant"
      description: "一个智能助手,可以回答问题和执行任务"
      url: "http://localhost:8080"
      version: "1.0.0"
      capabilities:
        - streaming
        - pushNotifications

创建智能体 Bean:

import io.agentscope.core.ReActAgent;
import io.agentscope.core.model.DashScopeChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AgentConfiguration {

    @Bean
    public ReActAgent a2aAgent() {
        return ReActAgent.builder()
            .name("MyAssistant")
            .sysPrompt("你是一个有帮助的 AI 助手。")
            .model(DashScopeChatModel.builder()
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .modelName("qwen-plus")
                .stream(true)
                .build())
            .build();
    }
}

15.2.3 独立服务端

不使用 Spring Boot 时,可以直接使用 AgentScopeA2aServer

import io.agentscope.core.a2a.server.AgentScopeA2aServer;
import io.agentscope.core.ReActAgent;
import io.a2a.spec.AgentCard;

// 创建智能体
ReActAgent agent = ReActAgent.builder()
    .name("Assistant")
    .sysPrompt("你是一个 AI 助手。")
    .model(model)
    .build();

// 创建 AgentCard
AgentCard agentCard = new AgentCard(
    "Assistant",                        // name
    "http://localhost:8080",           // url
    "1.0.0",                           // version
    "智能助手服务",                     // description
    null,                              // iconUrl
    null,                              // provider
    null,                              // documentationUrl
    List.of("streaming"),              // capabilities
    null,                              // authentication
    List.of("text"),                   // defaultInputModes
    List.of("text"),                   // defaultOutputModes
    null                               // skills
);

// 创建并启动服务器
AgentScopeA2aServer server = AgentScopeA2aServer.builder()
    .agentCard(agentCard)
    .agent(agent)
    .port(8080)
    .build();

server.start();
System.out.println("A2A 服务启动在 http://localhost:8080");

// 保持运行
Thread.currentThread().join();

15.3 A2A 客户端

15.3.1 A2aAgent 简介

A2aAgent 是 A2A 协议的客户端实现,它作为远程智能体的本地代理,提供与本地智能体相同的接口。

import io.agentscope.core.a2a.agent.A2aAgent;
import io.a2a.spec.AgentCard;

// 方式一:直接提供 AgentCard
AgentCard remoteAgentCard = new AgentCard(
    "RemoteAssistant",
    "http://remote-server:8080",
    "1.0.0",
    "远程智能助手",
    // ... 其他字段
);

A2aAgent remoteAgent = A2aAgent.builder()
    .name("RemoteAssistant")
    .agentCard(remoteAgentCard)
    .build();

// 方式二:使用 AgentCardResolver(自动获取)
A2aAgent remoteAgent = A2aAgent.builder()
    .name("RemoteAssistant")
    .agentCardResolver(new WellKnownAgentCardResolver(
        "http://remote-server:8080",
        "/.well-known/agent-card.json"
    ))
    .build();

15.3.2 基本使用

import io.agentscope.core.a2a.agent.A2aAgent;
import io.agentscope.core.message.Msg;
import io.agentscope.core.message.MsgRole;
import io.agentscope.core.message.TextBlock;

// 创建远程智能体代理
A2aAgent remoteAgent = A2aAgent.builder()
    .name("RemoteExpert")
    .agentCard(agentCard)
    .build();

// 调用远程智能体(与本地智能体用法相同)
Msg response = remoteAgent.call(
    Msg.builder()
        .role(MsgRole.USER)
        .content(TextBlock.builder()
            .text("请帮我分析这份数据")
            .build())
        .build()
).block();

System.out.println("远程响应: " + response.getTextContent());

15.3.3 A2aAgentConfig 配置

import io.agentscope.core.a2a.agent.A2aAgentConfig;
import io.a2a.client.ClientConfig;

// 配置 A2aAgent
A2aAgentConfig config = A2aAgentConfig.builder()
    // 客户端配置
    .clientConfig(ClientConfig.builder()
        .timeout(30000)  // 超时时间(毫秒)
        .build())
    
    // 传输层配置(可选)
    // .clientTransports(...)
    
    .build();

A2aAgent remoteAgent = A2aAgent.builder()
    .name("RemoteAgent")
    .agentCard(agentCard)
    .a2aAgentConfig(config)
    .build();

15.4 完整示例

15.4.1 服务端示例

import io.agentscope.core.ReActAgent;
import io.agentscope.core.a2a.server.AgentScopeA2aServer;
import io.agentscope.core.memory.InMemoryMemory;
import io.agentscope.core.model.DashScopeChatModel;
import io.agentscope.core.tool.Toolkit;
import io.a2a.spec.AgentCard;
import java.util.List;

/**
 * A2A 服务端示例
 * 启动一个可被远程调用的智能体服务
 */
public class A2aServerExample {

    public static void main(String[] args) throws Exception {
        String apiKey = System.getenv("DASHSCOPE_API_KEY");
        int port = 8080;

        // ========================================
        // 创建智能体
        // ========================================
        ReActAgent expertAgent = ReActAgent.builder()
            .name("DataExpert")
            .sysPrompt("""
                你是一位数据分析专家。
                
                你的能力:
                1. 数据清洗和预处理
                2. 统计分析和建模
                3. 数据可视化建议
                4. 洞察报告撰写
                
                请基于用户提供的数据或问题,给出专业的分析和建议。
                """)
            .model(DashScopeChatModel.builder()
                .apiKey(apiKey)
                .modelName("qwen-plus")
                .stream(true)
                .build())
            .memory(new InMemoryMemory())
            .toolkit(new Toolkit())
            .build();

        // ========================================
        // 创建 AgentCard
        // ========================================
        AgentCard agentCard = new AgentCard(
            "DataExpert",                              // name
            "http://localhost:" + port,               // url
            "1.0.0",                                  // version
            "专业的数据分析智能体,提供数据分析和洞察服务", // description
            null,                                     // iconUrl
            null,                                     // provider
            null,                                     // documentationUrl
            List.of("streaming", "pushNotifications"),// capabilities
            null,                                     // authentication
            List.of("text"),                          // defaultInputModes
            List.of("text"),                          // defaultOutputModes
            null                                      // skills
        );

        // ========================================
        // 启动 A2A 服务器
        // ========================================
        AgentScopeA2aServer server = AgentScopeA2aServer.builder()
            .agentCard(agentCard)
            .agent(expertAgent)
            .port(port)
            .build();

        server.start();

        System.out.println("=".repeat(50));
        System.out.println("A2A 服务已启动!");
        System.out.println("=".repeat(50));
        System.out.println("服务地址: http://localhost:" + port);
        System.out.println("AgentCard: http://localhost:" + port + "/.well-known/agent-card.json");
        System.out.println("=".repeat(50));
        System.out.println("按 Ctrl+C 停止服务");

        // 保持服务运行
        Thread.currentThread().join();
    }
}

15.4.2 客户端示例

import io.agentscope.core.a2a.agent.A2aAgent;
import io.agentscope.core.a2a.agent.card.WellKnownAgentCardResolver;
import io.agentscope.core.memory.InMemoryMemory;
import io.agentscope.core.message.Msg;
import io.agentscope.core.message.MsgRole;
import io.agentscope.core.message.TextBlock;
import java.util.Scanner;

/**
 * A2A 客户端示例
 * 调用远程智能体服务
 */
public class A2aClientExample {

    public static void main(String[] args) {
        String remoteUrl = "http://localhost:8080";

        // ========================================
        // 创建远程智能体代理
        // ========================================
        A2aAgent remoteExpert = A2aAgent.builder()
            .name("DataExpert")
            // 使用 WellKnown 方式自动获取 AgentCard
            .agentCardResolver(new WellKnownAgentCardResolver(
                remoteUrl,
                "/.well-known/agent-card.json",
                null  // 额外的 HTTP headers
            ))
            .memory(new InMemoryMemory())
            .build();

        System.out.println("已连接到远程智能体: " + remoteUrl);
        System.out.println("智能体描述: " + remoteExpert.getDescription());
        System.out.println("=".repeat(50));

        // ========================================
        // 交互式对话
        // ========================================
        Scanner scanner = new Scanner(System.in);

        while (true) {
            System.out.print("\n你: ");
            String input = scanner.nextLine().trim();

            if ("exit".equalsIgnoreCase(input)) {
                System.out.println("已断开连接");
                break;
            }

            if (input.isEmpty()) continue;

            try {
                System.out.print("远程专家: ");
                
                Msg response = remoteExpert.call(
                    Msg.builder()
                        .role(MsgRole.USER)
                        .content(TextBlock.builder().text(input).build())
                        .build()
                ).block();

                System.out.println(response.getTextContent());
                
            } catch (Exception e) {
                System.err.println("调用失败: " + e.getMessage());
            }
        }

        scanner.close();
    }
}

15.5 服务发现与注册

15.5.1 Nacos 集成

AgentScope-Java 支持使用 Nacos 进行服务注册和发现:

添加依赖:

<dependency>
    <groupId>io.agentscope</groupId>
    <artifactId>agentscope-nacos-spring-boot-starter</artifactId>
    <version>${agentscope.version}</version>
</dependency>

配置:

agentscope:
  a2a:
    nacos:
      enabled: true
      server-addr: localhost:8848
      namespace: public
      group: DEFAULT_GROUP
      
      # 注册配置
      registry:
        enabled: true
        service-name: my-agent-service
        
      # 发现配置
      discovery:
        enabled: true

使用 Nacos 发现的智能体:

import io.agentscope.core.nacos.a2a.discovery.NacosAgentCardResolver;

// 使用 Nacos 发现远程智能体
NacosAgentCardResolver nacosResolver = NacosAgentCardResolver.builder()
    .serverAddr("localhost:8848")
    .namespace("public")
    .group("DEFAULT_GROUP")
    .build();

A2aAgent remoteAgent = A2aAgent.builder()
    .name("DataExpert")
    .agentCardResolver(nacosResolver)
    .build();

15.6 A2A 在多智能体系统中的应用

15.6.1 分布式智能体协作

/**
 * 分布式研究系统
 * 多个远程智能体协作完成研究任务
 */
public class DistributedResearchSystem {

    public static void main(String[] args) {
        // 连接到不同的远程智能体服务
        A2aAgent literatureAgent = connectToRemote("http://literature-service:8080");
        A2aAgent analysisAgent = connectToRemote("http://analysis-service:8080");
        A2aAgent writingAgent = connectToRemote("http://writing-service:8080");

        // 使用 Pipeline 协调远程智能体
        SequentialPipeline researchPipeline = SequentialPipeline.builder()
            .addAgent(literatureAgent)  // 文献研究
            .addAgent(analysisAgent)    // 数据分析
            .addAgent(writingAgent)     // 报告撰写
            .build();

        // 执行研究任务
        Msg result = researchPipeline.execute(
            Msg.builder()
                .role(MsgRole.USER)
                .content(TextBlock.builder()
                    .text("研究人工智能在教育领域的应用")
                    .build())
                .build()
        ).block();

        System.out.println("研究报告:\n" + result.getTextContent());
    }

    private static A2aAgent connectToRemote(String url) {
        return A2aAgent.builder()
            .name(extractName(url))
            .agentCardResolver(new WellKnownAgentCardResolver(url))
            .build();
    }
}

15.6.2 混合本地与远程智能体

/**
 * 混合系统:本地智能体 + 远程智能体
 */
public class HybridAgentSystem {

    public static void main(String[] args) {
        String apiKey = System.getenv("DASHSCOPE_API_KEY");

        // 本地智能体
        ReActAgent localCoordinator = ReActAgent.builder()
            .name("Coordinator")
            .sysPrompt("你是任务协调者...")
            .model(createModel(apiKey))
            .toolkit(createToolkit())
            .build();

        // 远程智能体(通过 A2A 调用)
        A2aAgent remoteExpert = A2aAgent.builder()
            .name("RemoteExpert")
            .agentCardResolver(new WellKnownAgentCardResolver(
                "http://expert-service:8080"))
            .build();

        // 将远程智能体封装为本地工具
        SubAgentTool remoteTool = new SubAgentTool(
            () -> remoteExpert,
            SubAgentConfig.builder()
                .toolName("call_remote_expert")
                .description("调用远程专家智能体")
                .build()
        );

        // 注册到本地协调者的工具包
        localCoordinator.getToolkit().registerAgentTool(remoteTool);

        // 现在本地协调者可以调用远程智能体了
        localCoordinator.call("请让远程专家分析这个问题...").block();
    }
}

15.7 最佳实践

15.7.1 部署建议

建议说明
服务健康检查配置健康检查端点,确保服务可用性
负载均衡多实例部署时使用负载均衡
超时配置根据任务复杂度合理设置超时时间
错误重试配置合理的重试策略
日志监控记录调用日志,监控服务状态

15.7.2 安全建议

// 配置认证
AgentCard agentCard = new AgentCard(
    "SecureAgent",
    "https://secure-service:8443",  // 使用 HTTPS
    "1.0.0",
    "安全的智能体服务",
    null, null, null,
    List.of("streaming"),
    new AuthenticationInfo(            // 配置认证
        List.of("bearer"),             // 支持的认证方案
        null
    ),
    List.of("text"),
    List.of("text"),
    null
);

15.8 本章小结

本章介绍了 A2A(Agent-to-Agent)协议:

  1. 协议概念:标准化的智能体间通信协议
  2. AgentCard:智能体的元信息描述
  3. 服务端:使用 AgentScopeA2aServer 或 Spring Boot Starter
  4. 客户端:使用 A2aAgent 作为远程代理
  5. 服务发现:支持 Nacos 等服务注册中心
  6. 混合架构:本地与远程智能体协作

A2A 协议是构建分布式多智能体系统的基础,适用于微服务架构和跨语言调用场景。


练习

  1. 部署一个 A2A 服务端,并使用客户端调用
  2. 使用 Nacos 注册和发现智能体服务
  3. 构建一个混合系统:本地协调者 + 多个远程专家
  4. 比较 A2A 和 Agent-as-Tool 在相同场景下的性能差异

上一章:第14章-Agent-as-Tool | 下一章:第16章-Hook系统

← 返回目录