什么是 A2A?从协议原理到 AgentScope Java 最小实践

什么是 A2A?从协议原理到 AgentScope Java 最小实践

摘要:A2A 让不同团队、不同框架构建的智能体通过统一协议协作。本文介绍 Agent Card、Message、Task 等核心对象,解释服务发现、任务跟踪与流式通信,并结合 AgentScope Java 样例演示服务端、客户端和 SSE 调用。

一个智能体擅长理解用户需求,另一个智能体掌握订单系统,第三个智能体负责生成报告。它们可能由不同团队开发,用不同框架运行。如何让第一个智能体发现另外两个、交付任务、等待结果,并在任务需要补充信息时继续对话?A2A 解决的就是这类协作问题。

本文先解释 A2A 的定义、使用场景和通信流程,再以 agentscope-a2a 项目的真实代码展示服务端、客户端和流式调用。文中的协议概念参考 A2A 官方核心概念;样例项目使用 AgentScope Java 2.0.0。

一、A2A 是什么?

A2A(Agent2Agent)是智能体之间通信与协作的开放协议。 它约定一个智能体如何公开自己的能力,另一个智能体如何发送消息、跟踪任务、接收结果。协议不规定智能体内部必须使用什么模型、提示词、工具或编排框架,因此服务端可以保留自己的实现细节。A2A 官方介绍

可以把它理解成智能体之间的"服务接口契约":

text 复制代码
用户 → 主智能体(A2A 客户端) → 专业智能体(A2A 服务端)
                                ↳ 返回消息、任务状态或交付物

它与普通 HTTP API 的区别在于,接口围绕智能体能力、会话消息和长任务生命周期设计,而不是只围绕固定的业务动作。与 MCP 的关注点也不同:MCP 常用于智能体连接工具和数据源;A2A 主要用于一个智能体调用另一个独立运行的智能体。二者可以同时存在,例如远端智能体通过 A2A 接单,再通过 MCP 查询数据库。

二、什么时候用 A2A?

场景 A2A 带来的能力
跨团队专业智能体协作 主智能体根据能力说明找到订单、财务、法务等专业智能体,无须了解其内部实现。
长时间任务 提交任务后通过轮询、流式事件或回调跟踪进度。
人工补充信息 服务端将任务置为需要输入的状态,客户端补充资料后继续同一任务。
跨语言、跨框架集成 双方只需支持共同的 A2A 协议版本和传输绑定。

例如,"分析本周退款异常并写报告"可以拆给两个智能体:数据分析智能体负责统计退款数据,报告智能体负责解释指标并产出文档。若只是调用一个确定的 queryRefunds() 函数,普通 API 或工具调用通常更简单;当远端有自己的规划、工具、状态和交付过程时,A2A 更有价值。

三、协议里有哪些对象?

对象 作用
Agent Card 智能体的"名片",说明名称、能力、服务地址、支持的传输方式和认证要求。
Message 双方的一轮通信,包含发送方与内容。
Part Message 或 Artifact 的内容单元,可承载文本、文件或结构化数据。
Task 有 ID 和状态的工作单元,用于跟踪需要持续处理的请求。
Artifact 任务产出的文档、图片、结构化数据等交付物。

这些对象及其关系见 A2A 官方核心概念。Message 不一定创建 Task:简单请求可以直接返回一条消息;需要跟踪进度的工作会返回 Task。Task 的状态可能从工作中进入完成、失败、取消,或进入需要更多输入的状态。不要把一次 HTTP 请求等同于整个任务生命周期。

四、底层协议与工作原理

A2A 先解决发现 ,再解决通信 。服务端可以在 /.well-known/agent-card.json 暴露 Agent Card;客户端读取能力、端点、传输协议和认证信息,判断能否调用。Agent Card 也可以通过私有注册中心发现,不要求所有服务都公开在互联网。官方发现机制

sequenceDiagram participant C as 主智能体 / A2A Client participant S as 专业智能体 / A2A Server C->>S: GET /.well-known/agent-card.json S-->>C: Agent Card(能力、端点、认证) C->>S: 发送 Message S-->>C: Message 或 Task(含 taskId) alt 长任务 C->>S: 查询任务 / 订阅流式事件 S-->>C: 状态变化、消息、Artifact end

在传输层,A2A 定义了 JSON-RPC、gRPC、HTTP+JSON 等标准绑定。JSON-RPC 方式通过 HTTP 发送请求;实时更新可用 SSE,长时间离线任务也可使用推送通知。具体可用能力以 Agent Card 中的声明和双方支持的协议版本为准。A2A 1.0.1 规范、异步与流式通信

一个容易踩的坑是混用协议版本 。截至本文编写时,A2A 官方文档已有 1.0 系列;但样例使用的 AgentScope Java 2.0.0 A2A 扩展依赖 a2a-java-sdk 0.3.3.Final,其 Agent Card 声明 protocolVersion: "0.3.0"。因此下面的样例演示的是 AgentScope 2.0.0 与同版本客户端之间的调用,不能据此断言它能直接与只接受 A2A 1.0 的服务互通。部署时应读取实际 Agent Card,再核对协议版本与传输绑定。

五、用 agentscope-a2a 项目跑通一次调用

下面直接使用 study-docs/agentscope-a2a 的实现。它将 ReActAgent 暴露为 A2A 服务端,在同一项目中提供命令行客户端和 HTTP 流式测试接口。项目使用 JDK 17+、Spring Boot 4.0.3、AgentScope Java 2.0.0,监听 127.0.0.1:8082。代码分别位于 config/AgentConfiguration.java、client/A2aClient.java 和 controller/A2aTestController.java。

1. 依赖与配置

项目的 pom.xml 使用 agentscope-a2a-spring-boot-starter 暴露服务,使用 agentscope-extensions-model-openai 接入 OpenAI 兼容模型,并引入 WebFlux 支持 SSE。关键依赖如下:

xml 复制代码
<properties>
    <java.version>17</java.version>
    <agentscope.version>2.0.0</agentscope.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
    <dependency>
        <groupId>io.agentscope</groupId>
        <artifactId>agentscope-a2a-spring-boot-starter</artifactId>
        <version>${agentscope.version}</version>
    </dependency>
    <dependency>
        <groupId>io.agentscope</groupId>
        <artifactId>agentscope-extensions-model-openai</artifactId>
        <version>${agentscope.version}</version>
    </dependency>
</dependencies>

实际项目还使用 AspectJ 记录 A2A 请求和 SSE 事件,并通过 Maven Exec 插件运行命令行客户端。以下配置只保留讲解所需字段,密钥必须由环境变量提供:

yaml 复制代码
server:
  address: ${A2A_HOST:127.0.0.1}
  port: 8082

agentscope:
  a2a:
    server:
      enabled: true
      card:
        name: A2A Assistant
        description: AgentScope Java A2A 问答样例
        version: 1.0.0

demo:
  a2a:
    server-url: ${A2A_SERVER_URL:http://127.0.0.1:8082}
  model:
    base-url: ${MODEL_BASE_URL}
    api-key: ${MODEL_API_KEY}
    name: ${MODEL_NAME}

这段配置为保护凭证,省略了样例文件中的模型默认值;运行前需要设置 MODEL_BASE_URL、MODEL_API_KEY 和 MODEL_NAME。card.version 是智能体服务自身的版本 ,不是 A2A 协议版本;协议版本应从实际返回的 Agent Card 的 protocolVersion 字段读取。

2. 服务端:把 ReActAgent 暴露为 A2A 服务

项目的 AgentConfiguration 创建模型和 Agent Builder。下面是其中的核心代码:

java 复制代码
@Bean
Model chatModel(
        @Value("${demo.model.base-url}") String baseUrl,
        @Value("${demo.model.api-key}") String apiKey,
        @Value("${demo.model.name}") String modelName) {
    if (apiKey.isBlank()) {
        throw new IllegalStateException("请先设置 MODEL_API_KEY");
    }
    return OpenAIChatModel.builder()
            .baseUrl(baseUrl)
            .apiKey(apiKey)
            .modelName(modelName)
            .endpointPath("/chat/completions")
            .stream(true)
            .build();
}

@Bean
ReActAgent.Builder agentBuilder(Model chatModel) {
    return ReActAgent.builder()
            .name("a2a-assistant")
            .description("通过 A2A 协议提供中文问答")
            .sysPrompt("你是一个简洁、准确的中文助手。")
            .model(chatModel);
}

A2A Starter 接收这个 Builder,提供 Agent Card 和 JSON-RPC 端点。先启动服务,再查看名片:

bash 复制代码
export MODEL_BASE_URL=https://your-openai-compatible-endpoint/v1
export MODEL_API_KEY=your-api-key
export MODEL_NAME=your-model-name
mvn spring-boot:run
curl http://127.0.0.1:8082/.well-known/agent-card.json

名片中的服务地址、传输绑定和协议版本决定了客户端如何连接。这里的模型调用需要真实可用的密钥;仅查看 Agent Card 通常不需要发起模型请求。

3. 客户端:读取 Agent Card 并发送问题

项目的 A2aClient.ask() 通过 WellKnownAgentCardResolver 获取名片,再用 A2aAgent 调用远端服务:

java 复制代码
public String ask(String question) {
    A2aAgent agent = A2aAgent.builder()
            .name("remote-assistant")
            .agentCardResolver(WellKnownAgentCardResolver.builder()
                    .baseUrl(serverUrl)
                    .relativeCardPath("/.well-known/agent-card.json")
                    .authHeaders(Map.of())
                    .build())
            .build();
    Msg reply = agent.call(new UserMessage(question)).block();
    if (reply == null) {
        throw new IllegalStateException("A2A 服务未返回消息");
    }
    return reply.getTextContent();
}

项目提供的命令行入口 A2aClientMain 调用的就是这个方法。服务端启动后,在另一个终端运行:

bash 复制代码
mvn -q exec:java \
  -Dexec.mainClass=com.jianjang.agentscope.a2a.client.A2aClientMain \
  -Dexec.args="用一句话介绍 A2A 协议"

调用路径是 A2aClientMain → A2aClient → Agent Card → A2A JSON-RPC → ReActAgent → 模型。A2aAgent 帮客户端完成 A2A 消息转换;调用方只处理 AgentScope 的 Msg。

4. 流式接口:观察协议事件

同一项目还提供 /api/a2a/test。它接收问题,调用 A2aClient.stream(),将远端的 message/stream SSE 事件转发给浏览器或 curl。客户端组装的请求主体如下:

java 复制代码
Map<String, Object> message = Map.of(
        "kind", "message",
        "role", "user",
        "messageId", UUID.randomUUID().toString(),
        "parts", List.of(Map.of("kind", "text", "text", question)));
Map<String, Object> request = Map.of(
        "jsonrpc", "2.0",
        "id", UUID.randomUUID().toString(),
        "method", "message/stream",
        "params", Map.of("message", message));

这段是本项目依赖的 A2A 0.3 风格 JSON-RPC 消息,不能直接当作 A2A 1.0 的通用模板。运行测试接口:

bash 复制代码
curl -N -X POST http://127.0.0.1:8082/api/a2a/test \
  -H 'Content-Type: application/json' \
  -H 'Accept: text/event-stream' \
  -d '{"message":"用一句话介绍 A2A 协议"}'

返回的多条 data: 事件可以展示任务状态与内容。若要直接观察 A2A 端点,可向服务根路径 / 发送同样的 message/stream JSON-RPC 请求;测试接口只是方便调用和转发。

六、从样例走向真实协作

这个项目演示了三件事:Agent Card 让客户端发现远端能力;A2aAgent 把远端服务包装成可调用的 Agent;message/stream 把执行过程作为事件持续送回。项目中的 A2aProtocolLoggingAspect 还能记录请求与 SSE 事件,方便理解协议流转。

接入业务系统时,还需补齐认证、访问控制、超时、任务状态存储和失败恢复。尤其要注意模型密钥与日志:请求正文和 SSE 事件可能包含用户输入或业务数据,不能不加筛选地写入生产日志。若要把本样例的 Starter 接入另一个 Spring Boot 项目,应先核对 Spring Boot 与 AgentScope 的依赖版本,再进行启动和协议互通验证。

结语

A2A 的核心价值是让独立智能体通过统一的能力描述、消息结构与任务生命周期协作。理解它时,抓住四步即可:发现 Agent Card → 发送 Message → 跟踪 Task → 接收 Message 或 Artifact。真正接入时,还要检查协议版本、传输方式、认证与任务状态管理;这些条件决定两个智能体能否可靠互通。

参考资料

相关推荐
wshzd1 小时前
LLM之Agent(114)|DeepSeek-Harness(二十一)内置工具全解析
人工智能
木圭的AI时代指南1 小时前
MiniCPM-V 4.7 35B-A3B 本地部署实录:RTX 3070 8GB 显存跑多模态,36 token/s
人工智能·ai·本地部署·openbmb·端侧大模型·minicpm-v 4.7
温迪的AI分享1 小时前
2026实测AI图片翻译工具:3款工具横向效果对比
人工智能
xianghongtao01161 小时前
arxiv_agents_review_2026-10-16
人工智能·深度学习·机器学习
wflynn1 小时前
Google Gemini 4 Argon:用一个模型完成机器人训练全流程
人工智能·ai
熊猫钓鱼>_>1 小时前
开源鸿蒙平台 KMP 三方库 kotlin-csv 适配全流程:从编码假设到沙箱真机互通验证
开发语言·人工智能·华为·kotlin·harmonyos·鸿蒙
金融小师妹1 小时前
多因子时间序列分析:美元与美债收益率变化对黄金价格+1.6%的影响
c语言·人工智能·git·决策树·pyqt
acrel71 小时前
浅谈碳中和背景下企业绿色低碳转型
人工智能·物联网·microsoft
什么嘻嘻果冻2 小时前
无代码开发平台中的自然语言生成:恐象AI实现路径
大数据·人工智能·低代码