第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 等) |
| Task | A2A 中的任务单元 |
15.1.3 与其他模式的对比
| 特性 | A2A | Agent-as-Tool | MsgHub |
|---|---|---|---|
| 部署方式 | 分布式/远程 | 本地进程内 | 本地进程内 |
| 通信协议 | 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)协议:
- 协议概念:标准化的智能体间通信协议
- AgentCard:智能体的元信息描述
- 服务端:使用
AgentScopeA2aServer或 Spring Boot Starter - 客户端:使用
A2aAgent作为远程代理 - 服务发现:支持 Nacos 等服务注册中心
- 混合架构:本地与远程智能体协作
A2A 协议是构建分布式多智能体系统的基础,适用于微服务架构和跨语言调用场景。
练习
- 部署一个 A2A 服务端,并使用客户端调用
- 使用 Nacos 注册和发现智能体服务
- 构建一个混合系统:本地协调者 + 多个远程专家
- 比较 A2A 和 Agent-as-Tool 在相同场景下的性能差异
上一章:第14章-Agent-as-Tool | 下一章:第16章-Hook系统