Spring AI 智能体模式(第五部分):使用 Agent2Agent(A2A)协议构建可互操作的智能体

预估阅读时长:10分钟

Spring AI 智能体模式(第五部分):使用 Agent2Agent(A2A)协议构建可互操作的智能体

Agent2Agent(A2A)协议是一个用于 AI 智能体无缝通信的开放标准。它使智能体能够跨平台发现能力、交换消息并协调工作流——无论其具体实现如何。

Spring AI A2A 通过 Spring Boot 自动配置将 A2A Java SDK 与 Spring AI 集成在一起。它将 A2A 协议与 Spring AI 的 ChatClient 和工具无缝连接,让您能够将智能体暴露为 A2A 服务器。

本文是 Spring AI 智能体模式系列的一部分。前几篇文章讲述了如何让单个智能体变得更强大(Agent Skills、AskUserQuestionTool、TodoWriteTool、子智能体编排),而本文则通过实际示例展示 A2A 协议如何让智能体跨越系统边界进行协作。

Agent2Agent(A2A)协议

A2A 协议是一个用于 AI 智能体通信的开放标准,提供了厂商中立的基础,使智能体能够发现能力、交换消息和协调工作流。它基于 HTTP、SSE 和 JSON-RPC 标准构建。

智能体发现是 A2A 通信的基础。智能体通过 AgentCard——一个在 /.well-known/agent-card.json 处暴露的标准化 JSON 文档——来发现彼此的能力,该文档描述了智能体的身份、能力和技能。这遵循三步模式:发现 → 发起 → 完成。

该协议定义了两个角色:A2A 服务器智能体暴露用于发现和消息处理的端点,而 A2A 客户端智能体通过发现远程智能体并发送消息来发起通信。

A2A Java SDK 提供了一个 Java 实现,包含处理请求和管理任务的服务器端组件,以及调用远程智能体的客户端组件。它支持多种传输方式(HTTP、SSE、JSON-RPC),并处理底层协议细节。

Spring AI A2A 集成

A2A Java SDK 提供了协议实现,但要将其与 Spring AI 集成,还需要额外的连接工作。这就是 Spring AI A2A 项目的用武之地。

spring-ai-a2a 项目目前专注于服务器端集成,让您能够将 Spring AI 智能体暴露为符合 A2A 标准的服务器。

集成涵盖以下内容:

  • Spring Boot 自动配置:自动配置的 A2A 端点。
  • Spring AI 集成:直接集成 Spring AI 的 ChatClient 和工具。
  • 基于 REST 控制器的 JSON-RPC 传输:当前为智能体通信实现了 JSON-RPC 传输。控制器提供智能体卡片和消息处理的端点。
  • AgentExecutor 实现DefaultAgentExecutor 桥接了 A2A SDK 和 Spring AI。

以下是框架为您自动暴露的 A2A 端点(相对于您的上下文路径):

POST   /                                  // 处理 JSON-RPC sendMessage 请求
GET    /.well-known/agent-card.json       // AgentCard(标准 A2A 位置)
GET    /card                              // AgentCard(备用端点)

工作原理

逐步分解:

  1. 智能体发现:通信开始前,客户端从 /.well-known/agent-card.json 获取服务器的 AgentCard,以发现其能力、技能和协议细节。
  2. 请求接收MessageController 在根端点接收 A2A JSON-RPC sendMessage 请求。
  3. 执行:路由到您的 AgentExecutor Bean(Spring AI A2A 提供默认实现:DefaultAgentExecutor)。
  4. 处理器调用:使用 Spring AI ChatClient 和请求上下文调用 ChatClientExecutorHandler lambda 表达式。
  5. Spring AI ChatClient 响应:将 Spring AI ChatClient 的响应打包为 A2A JSON-RPC 消息。

快速开始

让我们用 Spring AI A2A 构建可互操作的智能体系统。我们将从先决条件和设置开始,然后通过实际示例:一个单智能体服务器和一个多智能体编排示例。

先决条件

  • Java 17 或更高版本
  • Spring Boot 4.0.1
  • Spring AI 2.0.0-M2
  • 一个 LLM 提供商(OpenAI、Anthropic 等)

依赖

将 Spring AI A2A 起步依赖添加到项目中,以将您的 Spring AI 智能体暴露为 A2A 服务器:

<dependency>
   <groupId>org.springaicommunity</groupId>
   <artifactId>spring-ai-a2a-server-autoconfigure</artifactId>
   <version>0.2.0</version>
</dependency>

此起步依赖包含 A2A Java SDK(v0.3.3.Final)作为传递依赖。

对于需要调用远程 A2A 智能体的应用程序,显式添加 A2A SDK 客户端:

<dependency>
   <groupId>io.github.a2asdk</groupId>
   <artifactId>a2a-java-sdk-client</artifactId>
   <version>0.3.3.Final</version>
</dependency>

配置

application.properties 中配置应用程序:

# 服务器配置
server.servlet.context-path=/weather

# LLM 配置(以 Anthropic Claude 为例)
spring.ai.anthropic.api-key=${ANTHROPIC_API_KEY}
spring.ai.anthropic.chat.options.model=claude-sonnet-4-5-20250929

# 对于多智能体编排(示例 2),配置远程智能体 URL:
# remote.agents.urls=http://localhost:10001/foo/,http://localhost:10002/bar/

示例 1:智能体服务器

将带有工具的 Spring AI 应用程序暴露为 A2A 服务器:

@Configuration
public class WeatherAgentConfiguration {

   @Bean
   public AgentCard agentCard(@Value("${server.port:8080}") int port,
           @Value("${server.servlet.context-path:/}") String contextPath) {
       // 此 AgentCard 自动暴露在 /.well-known/agent-card.json
       // 其他智能体通过此端点发现该智能体的能力
       return new AgentCard.Builder()
           .name("Weather Agent")
           .description("Provides weather information for cities")
           .url("http://localhost:" + port + contextPath + "/")
           .version("1.0.0")
           .capabilities(new AgentCapabilities.Builder().streaming(false).build())
           .defaultInputModes(List.of("text"))
           .defaultOutputModes(List.of("text"))
           .skills(List.of(new AgentSkill.Builder()
               .id("weather_search")
               .name("Search weather")
               .description("Get temperature for any city")
               .tags(List.of("weather"))
               .examples(List.of("What's the weather in London?"))
               .build()))
           .protocolVersion("0.3.0")
           .build();
   }

   @Bean
   public AgentExecutor agentExecutor(ChatClient.Builder chatClientBuilder, WeatherTools weatherTools) {

       ChatClient chatClient = chatClientBuilder.clone()
           .defaultSystem("你是一个天气助手。使用温度工具来回答问题。")
           .defaultTools(weatherTools)  // 注册 Spring AI 工具
           .build();

       return new DefaultAgentExecutor(chatClient, (chat, requestContext) -> {
           String userMessage = DefaultAgentExecutor.extractTextFromMessage(requestContext.getMessage());
           return chat.prompt().user(userMessage).call().content();
       });
   }
}

@Service
class WeatherTools {
    // ...
}

您的 Spring AI 智能体现在是一个符合 A2A 标准的服务器。其他智能体可以通过标准的 /.well-known/agent-card.json 端点发现其能力,然后通过 POST 请求到根端点发送天气查询。自动配置负责暴露 AgentCard 和消息端点。

示例 2:智能体客户端

下面是一个智能体客户端的实际示例:一个编排专业化智能体(Airbnb 住宿和天气信息)来完成旅行规划的主智能体。

@Service
public class RemoteAgentConnections {

   private final Map<String, AgentCard> agentCards = new HashMap<>();

   public RemoteAgentConnections(@Value("${remote.agents.urls}") List<String> agentUrls) {
       // 启动时发现远程智能体(参见上方"智能体发现"部分)
       for (String url : agentUrls) {
           String path = new URI(url).getPath();
           AgentCard card = A2A.getAgentCard(url, path + ".well-known/agent-card.json", null);
           this.agentCards.put(card.name(), card);
       }
   }

   @Tool(description = "向远程智能体发送任务。使用此工具将工作委托给专门的智能体。")
   public String sendMessage(
           @ToolParam(description = "智能体名称") String agentName,
           @ToolParam(description = "要发送的任务描述") String task) {

       AgentCard agentCard = this.agentCards.get(agentName);

       // 创建 A2A 消息
       Message message = new Message.Builder()
           .role(Message.Role.USER)
           .parts(List.of(new TextPart(task, null)))
           .build();

       // 使用 A2A Java SDK 客户端
       CompletableFuture<String> responseFuture = new CompletableFuture<>();

       Client client = Client.builder(agentCard)
           .clientConfig(new ClientConfig.Builder()
               .setAcceptedOutputModes(List.of("text"))
               .build())
           .withTransport(JSONRPCTransport.class, new JSONRPCTransportConfig())
           .addConsumers(List.of(consumer -> {
               if (consumer instanceof TextPart textPart) {
                   responseFuture.complete(textPart.getText());
               }
           }))
           .build();

       client.sendMessage(message);
       return responseFuture.get(60, TimeUnit.SECONDS);
   }

   public String getAgentDescriptions() {
       return agentCards.values().stream()
           .map(card -> card.name() + ": " + card.description())
           .collect(Collectors.joining("\n"));
   }
}

@Configuration
public class HostAgentConfiguration {

   @Bean
   public ChatClient routingChatClient(ChatClient.Builder chatClientBuilder,
           RemoteAgentConnections remoteAgentConnections) {

       String systemPrompt = """
           你负责跨专业化智能体协调任务。
           可用智能体:
           %s
           使用 sendMessage 工具将任务委托给合适的智能体。
           """.formatted(remoteAgentConnections.getAgentDescriptions());

       return chatClientBuilder
           .defaultSystem(systemPrompt)
           .defaultTools(remoteAgentConnections)  // 注册为 Spring AI 工具
           .build();
   }
}

这里发生了什么:

  • 主智能体(客户端)在启动时通过从标准的 .well-known/agent-card.json 端点获取 AgentCard 来发现远程智能体。
  • RemoteAgentConnections 被注册为 Spring AI 的 @Tool,并与 ChatClient 集成。
  • 当用户询问”规划一次伦敦之旅”时,LLM 通过 sendMessage 工具决定调用哪些智能体。
  • 该工具使用 A2A Java SDK 客户端与远程智能体通信。
  • 结果被聚合并返回给用户。

此模式实现了 LLM 驱动的路由——模型根据用户查询决定调用哪些专业化智能体。


未来展望

虽然当前版本专注于服务器端集成,Spring AI 社区正在探索增强 Spring AI 应用程序 A2A 客户端体验的机会。

潜在的未来增强功能:

  • 安全性:支持 A2A 认证和授权。
  • 智能体发现:用于发现和路由到 A2A 智能体的 Spring Boot 自动配置。
  • 客户端自动配置:自动配置的 A2A 客户端连接,提供对 Spring 友好的抽象。
  • 多传输支持:扩展当前 JSON-RPC 实现,支持用于实时流式响应的 SSE(服务器发送事件)。
  • 增强可观测性:集成 Spring Boot Actuator 以监控 A2A 交互。

这些增强将为构建作为 A2A 智能体客户端的 Spring AI 应用程序提供额外支持,为客户端和服务器实现提供一致的集成模式。

想要贡献? Spring AI A2A 项目欢迎社区贡献。请查看 GitHub 仓库参与其中。


总结

A2A 协议代表着迈向可互操作 AI 智能体生态系统的重要一步。通过标准化智能体的通信方式,它消除了构建复杂多智能体系统的障碍。

Spring AI A2A 社区项目提供了参与此生态系统所需的集成。通过 Spring Boot 自动配置,您可以暴露 Spring AI 智能体作为 A2A 服务器,与其他符合 A2A 标准的智能体集成,并构建利用 Spring Boot 约定的编排模式。

随着 A2A 生态系统的成长,更多智能体、工具和平台可能会采用这一标准,从而扩展智能体协作与组合的选项。

要开始将 A2A 协议支持与您的 Spring AI 智能体集成,请参阅下方资源。


资源

系列链接

相关 Spring AI 博客


【注】本文译自:Spring AI Agentic Patterns (Part 5): Building Interoperable Agents with the Agent2Agent (A2A) Protocol