news 2026/5/5 19:49:58

Spring AI A2A实战:用开放协议打通你的多Agent系统

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring AI A2A实战:用开放协议打通你的多Agent系统

如果你在用Spring AI构建Agent应用,现在有了一个社区项目Spring AI A2A,可以让你的Agent轻松接入A2A生态。这篇文章是Spring AI官方Agentic Patterns系列的第五篇,我们来看看具体怎么用。

当你的AI应用里有多个Agent需要协作时,麻烦就来了——天气查询Agent、酒店推荐Agent、行程规划Agent,每个都用不同的框架实现,彼此之间怎么通信?自己写一套RPC?维护成本太高。用消息队列?又太重了。

Google在2025年4月发布的A2A(Agent2Agent)协议就是为了解决这个问题。这是一个开放标准,让不同平台、不同框架的AI Agent能够相互发现、通信和协作。Salesforce、ServiceNow、MongoDB等超过50家技术公司参与了这个协议的制定。

如果你在用Spring AI构建Agent应用,现在有了一个社区项目Spring AI A2A,可以让你的Agent轻松接入A2A生态。这篇文章是Spring AI官方Agentic Patterns系列的第五篇,我们来看看具体怎么用。

先搞清楚A2A协议在干什么

A2A协议的核心思路很简单:给每个Agent一张"名片",让其他Agent能找到它、知道它能干什么、然后按标准格式发消息。

这张名片叫做AgentCard,是一个JSON文档,放在固定路径 /.well-known/agent-card.json 下。其他Agent访问这个地址就能知道:这个Agent叫什么名字、能提供什么技能、支持什么输入输出格式。

协议定义了两种角色:

A2A Server- 暴露端点,处理请求,提供服务的Agent

A2A Client- 发现远程Agent、发送消息、发起协作的Agent

通信流程是:发现 → 发起 → 完成。底层用的是HTTP、SSE和JSON-RPC这些成熟的标准,不用学什么新协议。

A2A和MCP(Model Context Protocol)是互补的关系。MCP解决的是LLM与工具、数据的连接问题,A2A解决的是Agent与Agent之间的协作问题,两者在不同层面工作。

Spring AI A2A做了什么

A2A有一个官方的Java SDK,但要把它和Spring AI整合起来还需要写不少胶水代码。Spring AI A2A这个社区项目就是帮你省掉这些麻烦的。

目前它主要做服务端集成,具体包括:

Spring Boot自动配置- 自动暴露A2A端点

Spring AI集成- 直接对接ChatClient和Tools

JSON-RPC传输- 通过REST Controller提供Agent Card和消息处理端点

AgentExecutor实现- 用DefaultAgentExecutor桥接A2A SDK和Spring AI

加上依赖后,框架会自动暴露这些端点:

• POST / - 处理sendMessage请求

• GET /.well-known/agent-card.json - 暴露Agent Card

• GET /card - Agent Card的备用端点

环境准备

开始之前,确认你的环境:

• Java 17及以上

• Spring Boot 4.0.1

• Spring AI 2.0.0-M2

• 一个LLM提供商(OpenAI、Anthropic等)

添加Maven依赖:

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

这个starter会自动引入A2A Java SDK(v0.3.3.Final)作为传递依赖。

如果你的应用需要调用远程A2A Agent,还要显式添加SDK客户端:

<dependency> <groupId>io.github.a2asdk</groupId> <artifactId>a2a-java-sdk-client</artifactId> <version>0.3.3.Final</version> </dependency>
实战一:把你的Agent变成A2A Server

假设你有一个天气查询Agent,带着一些工具方法,现在要把它暴露成A2A服务。

首先在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

然后写配置类,定义AgentCard:

@Configuration public class WeatherAgentConfiguration { @Bean public AgentCard agentCard( @Value("${server.port:8080}") int port, @Value("${server.servlet.context-path:/}") String contextPath) { 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(); } }

再定义AgentExecutor,桥接Spring AI的ChatClient:

@Bean public AgentExecutor agentExecutor( ChatClient.Builder chatClientBuilder, WeatherTools weatherTools) { ChatClient chatClient = chatClientBuilder.clone() .defaultSystem("You are a weather assistant. " + "Use the temperature tool to answer questions.") .defaultTools(weatherTools) .build(); return new DefaultAgentExecutor(chatClient, (chat, requestContext) -> { String userMessage = DefaultAgentExecutor .extractTextFromMessage(requestContext.getMessage()); return chat.prompt().user(userMessage).call().content(); }); }

就这么多代码。启动应用后,你的天气Agent就是一个A2A Server了。其他Agent可以通过 /.well-known/agent-card.json 发现它,然后向根端点发送天气查询请求。

实战二:构建多Agent编排系统

更有意思的场景是让一个主控Agent调度多个专业Agent。比如做一个旅行规划助手,背后有Airbnb住宿Agent和天气查询Agent配合工作。

先在配置里指定远程Agent的地址:

remote.agents.urls=http://localhost:10001/airbnb/,http://localhost:10002/weather/

然后实现远程Agent连接管理,关键是把sendMessage方法标记为@Tool:

@Service public class RemoteAgentConnections { private final Map<String, AgentCard> agentCards = new HashMap<>(); public RemoteAgentConnections( @Value("${remote.agents.urls}") List<String> agentUrls) { // 启动时发现远程Agent 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 = "Sends a task to a remote agent.") public String sendMessage( @ToolParam(description = "The agent name") String agentName, @ToolParam(description = "The task to send") String task) { AgentCard agentCard = this.agentCards.get(agentName); Message message = new Message.Builder() .role(Message.Role.USER) .parts(List.of(new TextPart(task, null))) .build(); 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); } }

主控Agent的配置,把RemoteAgentConnections注册为Tool:

@Configuration public class HostAgentConfiguration { @Bean public ChatClient routingChatClient( ChatClient.Builder chatClientBuilder, RemoteAgentConnections remoteAgentConnections) { String systemPrompt = """ You coordinate tasks across specialized agents. Available agents: %s Use the sendMessage tool to delegate tasks. """.formatted( remoteAgentConnections.getAgentDescriptions()); return chatClientBuilder .defaultSystem(systemPrompt) .defaultTools(remoteAgentConnections) .build(); } }

这里的关键是:RemoteAgentConnections被注册为Spring AI的Tool。当用户问"帮我规划一次伦敦之旅"时,LLM会自动决定调用哪些远程Agent——先查天气、再找住宿,最后汇总结果。这就是LLM驱动的路由,模型根据用户意图自主决定调用哪些专业Agent。

未来可能的增强

Spring AI A2A目前主要做服务端集成,社区正在探索更多可能:

安全- 支持A2A认证和授权机制

Agent发现- Spring Boot自动配置发现和路由A2A Agent

客户端自动配置- 提供更友好的Spring风格抽象

多传输支持- SSE实时流式响应,不只是JSON-RPC

可观测性- 集成Spring Boot Actuator监控A2A交互

小结

A2A协议给多Agent系统提供了一个标准化的通信方式。有了它,你不用再为不同Agent之间的通信格式发愁,也不用担心被某个厂商锁定。Spring AI A2A这个社区项目则让Java开发者能够用熟悉的Spring Boot风格来接入这个生态。

随着更多Agent、工具和平台采用A2A标准,跨系统的Agent协作会变得越来越容易。如果你正在用Spring AI构建Agent应用,现在就可以尝试把它暴露成A2A Server了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/2 11:11:58

4步打造专业级抽奖工具:Magpie-LuckyDraw全方位应用指南

4步打造专业级抽奖工具&#xff1a;Magpie-LuckyDraw全方位应用指南 【免费下载链接】Magpie-LuckyDraw &#x1f3c5;A fancy lucky-draw tool supporting multiple platforms&#x1f4bb;(Mac/Linux/Windows/Web/Docker) 项目地址: https://gitcode.com/gh_mirrors/ma/Mag…

作者头像 李华
网站建设 2026/5/3 4:35:37

XHS-Downloader:让小红书内容收集像打包快递一样简单的开源工具

XHS-Downloader&#xff1a;让小红书内容收集像打包快递一样简单的开源工具 【免费下载链接】XHS-Downloader 免费&#xff1b;轻量&#xff1b;开源&#xff0c;基于 AIOHTTP 模块实现的小红书图文/视频作品采集工具 项目地址: https://gitcode.com/gh_mirrors/xh/XHS-Downl…

作者头像 李华
网站建设 2026/4/25 19:33:58

单片机上的微型翻译器:Hunyuan-MT 7B极限压缩方案

单片机上的微型翻译器&#xff1a;Hunyuan-MT 7B极限压缩方案 1. 当翻译模型第一次在单片机上“开口说话” 你见过能装进指甲盖大小芯片里的翻译器吗&#xff1f;不是手机App&#xff0c;不是云端服务&#xff0c;而是真正运行在一块几块钱的单片机上&#xff0c;插上电池就能…

作者头像 李华
网站建设 2026/5/4 17:00:15

Pi0具身智能嵌入式开发:STM32CubeMX外设配置实战

Pi0具身智能嵌入式开发&#xff1a;STM32CubeMX外设配置实战 1. 为什么具身智能硬件开发需要重新思考外设配置 具身智能设备不是传统单片机项目&#xff0c;它对实时性、功耗控制和多传感器协同的要求远超常规应用。当一个机器人需要同时处理电机驱动、视觉识别、力觉反馈和环…

作者头像 李华
网站建设 2026/5/5 3:36:23

深求·墨鉴新手教程:3步完成学术论文数字化

深求墨鉴新手教程&#xff1a;3步完成学术论文数字化 1. 你不需要懂OCR&#xff0c;也能把论文变成可编辑文档 你有没有过这样的经历&#xff1a;导师发来一份PDF格式的会议论文&#xff0c;里面嵌着三张关键图表和两个手写批注&#xff1b;你翻遍全文想复制公式&#xff0c;…

作者头像 李华
网站建设 2026/4/18 7:24:10

Qwen3-ASR-0.6B多场景落地:科研组会记录→发言归因+待办事项自动提取

Qwen3-ASR-0.6B多场景落地&#xff1a;科研组会记录→发言归因待办事项自动提取 1. 项目背景与价值 科研组会记录一直是学术团队的重要工作内容&#xff0c;传统的人工记录方式存在效率低下、信息遗漏等问题。基于Qwen3-ASR-0.6B语音识别模型开发的本地智能语音转文字工具&am…

作者头像 李华