A2A Java 示例
克隆代码
git clone https://github.com/google-a2a/a2a-samples
cd a2a-samples/samples/java
本项目是 Agent-to-Agent (A2A) 协议的 Java 实现示例,提供完整的客户端和服务端 SDK,以及一个 AI 驱动的翻译服务演示应用程序。
项目架构
本项目采用 Maven 多模块架构,包含以下三个核心模块:
samples/java/
├── model/ # A2A 协议数据模型
├── server/ # A2A 服务端 SDK 和翻译服务
├── client/ # A2A 客户端 SDK 和示例代码
└── pom.xml # 父级 Maven 配置文件
模块详情
Model 模块 (model/)
A2A 协议的核心数据模型,为 JSON-RPC 2.0 和 A2A 协议提供完整的数据结构:
- 消息模型:
Message,Part,TextPart,Artifact - 任务模型:
Task,TaskStatus,TaskState - 代理模型:
AgentCard,AgentCapabilities,AgentSkill - JSON-RPC 模型:
JSONRPCRequest,JSONRPCResponse,JSONRPCError - 事件模型:
TaskStatusUpdateEvent,TaskArtifactUpdateEvent
Server 模块 (server/)
基于 Spring Boot 的 A2A 服务端 SDK,集成 Spring AI 框架:
核心组件:
A2AServer: 管理代理行为的主服务器类A2AController: 实现 A2A 协议端点的 REST 控制器TaskHandler: 任务处理接口A2AServerConfiguration: AI 翻译机器人配置
主要特性:
- 完整的 JSON-RPC 2.0 支持
- 代理卡片发布 (
/.well-known/agent-card) - 任务管理(发送、查询、取消)
- 流式响应支持(Server-Sent Events)
- Spring AI 集成,支持 OpenAI 和其他模型
Client 模块 (client/)
纯 Java A2A 客户端 SDK,包含翻译客户端示例:
核心组件:
A2AClient: 处理所有 A2A 操作的主客户端类StreamingEventListener: 流式事件监听器接口A2AClientException: A2A 特定异常处理A2AClientExample: 完整的翻译客户端示例
主要特性:
- JSON-RPC 2.0 客户端实现
- 代理发现和能力查询
- 同步/异步任务操作
- 流式响应处理
- 连接池和错误恢复
核心功能实现
AI 翻译服务
项目实现了一个智能翻译代理,支持多语言翻译:
翻译逻辑:
- 中文 → 英文
- 英文 → 中文
- 其他语言 → 英文
技术特性:
- 基于 Spring AI ChatClient
- 支持 OpenAI、Azure OpenAI 和其他模型
- 上下文感知的自然语言翻译
- 实时流式响应
A2A 协议实现
完整实现 A2A 协议规范:
核心操作:
tasks/send: 发送任务消息tasks/get: 查询任务状态tasks/cancel: 取消任务执行
协议特性:
- JSON-RPC 2.0 通信
- 代理能力发现
- 任务状态跟踪
- 流式事件推送
- 标准化错误代码
通信机制
同步通信:
- HTTP POST
/a2a- 标准 JSON-RPC 请求 - HTTP GET
/.well-known/agent-card- 代理信息检索
流式通信:
- HTTP POST
/a2a/stream- Server-Sent Events - 实时任务状态更新
- 自动重连和错误恢复
如何运行
要求
- Java: 17 或更高版本
步骤 1: 编译项目
在项目根目录执行编译:
cd samples/java
./mvnw clean install -DskipTests
步骤 2: 配置环境变量
设置 AI 模型相关的环境变量(翻译功能必需):
# OpenAI 配置
export OPENAI_API_KEY="your-openai-api-key"
export OPENAI_BASE_URL="https://api.openai.com"
export OPENAI_CHAT_MODEL="gpt-4o"
# 或 GCP OpenAI 配置
export OPENAI_API_KEY="your-gcp-api-key"
export OPENAI_BASE_URL="https://{location}-aiplatform.googleapis.com/v1/projects/{project_id}/locations/{location}/endpoints/openapi"
export OPENAI_CHAT_MODEL="gemini-2.5-pro-preview-05-06"
OpenRouter 配置
export OPENAI_API_KEY="sk-or-v1-"
export OPENAI_BASE_URL="https://openrouter.ai/api"
export OPENAI_CHAT_MODEL="openai/gpt-4o-2024-11-20"
注意 OPENAI_BASE_URL,URL 中没有 /v1。
步骤 3: 启动翻译服务器
启动 A2A 翻译服务器:
cd server
../mvnw spring-boot:run
服务器将在 http://localhost:8080 启动,提供以下端点:
http://localhost:8080/.well-known/agent-card- 代理信息http://localhost:8080/a2a- A2A 协议端点http://localhost:8080/a2a/stream- 流式端点
验证代理卡片:
- A2A 协议验证器
- 指南: 如何验证您的代理卡片
步骤 4: 运行翻译客户端
在新的终端窗口中,运行客户端示例:
cd client
../mvnw exec:java -Dexec.mainClass="com.google.a2a.client.A2AClientExample"
时序图
以下时序图展示了基于 A2AClientExample.java 的 A2A Java 示例应用程序的完整交互流程:
participant Example as A2AClientExample
participant Client as A2AClient
participant Server as A2A Server<br/>(localhost:8080)
Note over Example,Server: A2A Java 示例时序图
%% 1. 初始化客户端
Example->>Client: new A2AClient("http://localhost:8080")
activate Client
%% 2. 获取代理卡片
Example->>Client: getAgentCard()
Client->>Server: GET /.well-known/agent-card
Server-->>Client: AgentCard (name, description, version, skills)
Client-->>Example: AgentCard
Note over Example: 打印代理信息
%% 3. 法语到中文翻译
Example->>Client: sendTask(frenchToChineseParams)
Note right of Example: TextPart: "Bonjour le monde!<br/>Comment allez-vous?"
Client->>Server: POST /a2a<br/>JSON-RPC: tasks/send
Server-->>Client: Task (id, status, history)
Client-->>Example: JSONRPCResponse<Task>
Note over Example: 打印翻译结果
%% 4. 中文到英文翻译
Example->>Client: sendTask(chineseParams)
Note right of Example: TextPart: "你好,世界!<br/>欢迎使用AI翻译机器人。"
Client->>Server: POST /a2a<br/>JSON-RPC: tasks/send
Server-->>Client: Task (id, status, history)
Client-->>Example: JSONRPCResponse<Task>
Note over Example: 打印翻译结果
%% 5. 流式翻译
Example->>Client: sendTaskStreaming(frenchParams, StreamingEventListener)
Note right of Example: TextPart: "Bonjour le monde!<br/>Comment allez-vous?"
Client->>Server: POST /a2a/stream<br/>Server-Sent Events
activate Server
loop 流式响应
Server-->>Client: SSE Event (翻译进度)
Client-->>Example: onEvent(event)
Note over Example: 打印实时翻译事件
end
Server-->>Client: SSE Complete
deactivate Server
Client-->>Example: onComplete()
Note over Example: 流式翻译完成
%% 6. 查询任务状态
Example->>Client: getTask(queryParams)
Note right of Example: 查询法语翻译任务状态
Client->>Server: POST /a2a<br/>JSON-RPC: tasks/get
Server-->>Client: Task (更新状态)
Client-->>Example: JSONRPCResponse<Task>
Note over Example: 打印任务状态
%% 7. 发送要取消的任务
Example->>Client: sendTask(cancelParams)
Note right of Example: TextPart: "Diese Übersetzung<br/>wird abgebrochen." (德语)
Client->>Server: POST /a2a<br/>JSON-RPC: tasks/send
Server-->>Client: Task (id, status)
Client-->>Example: JSONRPCResponse<Task>
%% 8. 取消任务
Example->>Client: cancelTask(cancelTaskParams)
Client->>Server: POST /a2a<br/>JSON-RPC: tasks/cancel
Server-->>Client: Task (已取消状态)
Client-->>Example: JSONRPCResponse<Task>
Note over Example: 打印取消结果
deactivate Client
Note over Example,Server: 示例程序执行完成
关键交互模式
时序图展示了以下核心交互模式:
- 客户端初始化: 创建连接到本地服务器的
A2AClient实例 - 代理发现: 通过
/.well-known/agent-card端点检索代理信息 - 多语言翻译示例:
- 法语 → 中文翻译
- 中文 → 英文翻译
- 德语 → 英文流式翻译
- 任务管理:
- 查询任务状态
- 取消任务执行
通信机制
- 同步翻译: 使用
POST /a2a端点和 JSON-RPC 请求 - 流式翻译: 使用
POST /a2a/stream端点和 Server-Sent Events (SSE) - 状态查询: 使用
tasks/get方法检查任务执行状态 - 任务取消: 使用
tasks/cancel方法取消运行中的任务
API 使用示例
获取代理信息
curl -X GET http://localhost:8080/.well-known/agent-card \
-H "Accept: application/json"
发送翻译任务
curl -X POST http://localhost:8080/a2a \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": "request-1",
"method": "tasks/send",
"params": {
"id": "translation-task-1",
"message": {
"messageId": "msg-1",
"kind": "message",
"role": "user",
"parts": [
{
"kind": "text",
"text": "Hello, world!"
}
]
}
}
}'
流式翻译
curl -X POST http://localhost:8080/a2a/stream \
-H "Content-Type: application/json" \
-H "Accept: text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": "stream-request-1",
"method": "tasks/send",
"params": {
"id": "streaming-translation-task",
"message": {
"messageId": "stream-msg-1",
"kind": "message",
"role": "user",
"parts": [
{
"kind": "text",
"text": "Hello world!"
}
]
}
}
}'
A2A Java 示例的更多相关文章
- 课程作业01:模仿JavaAppArguments.java示例,编写一个程序,此程序从命令行接收多个数字,求和之后输出结果。
1.设计思想: 首先是从JavaAppArguments.java示例开始,此示例已打印参数,定义数字 之和和作为存储单位的整型,然后将输入参数的字符串转化为整型,之后求和即可. 2.程序流程图: 3 ...
- 左右JAVA示例代码事件分发和监督机制来实现-绝对原创有用
文章标题:左右JAVA示例代码事件分发和监督机制来实现 文章地址: http://blog.csdn.net/5iasp/article/details/37054171 作者: javaboy201 ...
- Spark 用户自定义函数 Java 示例
Spark UDF Java 示例 在这篇文章中提到了用Spark做用户昵称文本聚类分析,聚类需要选定K个中心点,然后迭代计算其他样本点到中心点的距离.由于中文文字分词之后(n-gram)再加上昵称允 ...
- thrift java示例
thrift java示例 使用IntelliJ IDEA作为开发工具: 增加proto文件夹,里面写上sayHello.proto syntax = "proto3"; opti ...
- & 和 && 的区别,与(&)运算符、位移运算符(<< 、>>、>>>)的含义及使用(Java示例)
& 和 && 的区别,与(&)运算符.位移运算符(<< .>>.>>>)的含义及使用(Java示例) 1. & 和 & ...
- HTTP基本认证(Basic Authentication)的JAVA示例
大家在登录网站的时候,大部分时候是通过一个表单提交登录信息.但是有时候浏览器会弹出一个登录验证的对话框,如下图,这就是使用HTTP基本认证.下面来看看一看这个认证的工作过程:第一步: 客户端发送ht ...
- CentOS安装卸载memcache及JAVA示例
原文地址:http://www.cnblogs.com/zhongshengzhen/ 先安装libevent,memcached依赖libevent的lib [root@VM_64_81_c ...
- hbase 0.96 java 示例
import java.util.ArrayList; import java.util.List; import org.apache.hadoop.conf.Configuration; impo ...
- epub、ocf等常用电子书格式浅析----附JAVA示例程序
一. 电子书介绍 转载请注明http://www.cnblogs.com/xckk/p/6020324.html Epub(Electronic Publication)是一个完全开放和免费的电子书标 ...
- 国际快递查询接口JAVA示例-trackingmore
国际快递查询接口 国际快递查询接口的需求量很大,例如一些跨境电商B2C网站.快递查询APP.快递柜.跨境物流公司等都会需要用到国际快递接口. 目前市面上的快递接口,以国内快递居多,有些虽然号称支持多家 ...
随机推荐
- 【P2】MARS使用/MIPS汇编
课上 T1 在n位数中删除N个数使剩下的(n-N)位数最大 写得似乎过于谨慎而慢了,没出现寄存器打错的问题,一遍过了 T2 拆分数字 将输入整数N拆分为几个数相加的形式,按拆分项数降序排列,每项按数字 ...
- @ComponentScan @MapperScan 拆分项目的时候,这两个注解很重要
今天,在做项目拆分的时候遇到了个问题,就是将service和dao层拆完之后,项目启动不起开了,如图: 最终解决办法,在启动类上增加两个注解搞定: @ComponentScan(basePackage ...
- Ubuntu下如何管理多个ssh密钥
Ubuntu下如何管理多个ssh密钥 前言 我一直在逃避这个问题,误以为我能够单纯地用一个 ssh 走天下. 好吧,现实是我不得不管理多个 ssh 做,那就写个博客总结一下吧. 查阅后发现前人已经 ...
- ModuleNotFoundError: No module named '_bz2'
前言 运行 python 报错:ModuleNotFoundError: No module named '_bz2' when building python 解决 安装在 Ubuntu/Debia ...
- nginx服务和uwsgi服务如何设置开机自启动
上次学到了在云服务器下如何部署Django项目,用到了nginx服务和uwsgi服务,需要手工启动这2个服务的命令. 现在考虑如何设置开机自启动,为什么要这样考虑?因为服务器万一出问题,意外重启了,那 ...
- 解决VuePress中的”Error from chokidar : Error: EBUSY“问题
.title { padding: 10px; background-color: rgba(3, 169, 244, 1); font-size: 16px; color: rgba(255, 25 ...
- Redis 是什么?
Redis 的定义? 百度百科: Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.K ...
- Fetch 别名查找
if (PlanClass.Attributes.Contains("new_excelcolor_avg")) ...
- CompletableFuture原理及应用场景详解
1.应用场景 现在我们打开各个APP上的一个页面,可能就需要涉及后端几十个服务的API调用,比如某宝.某个外卖APP上,下面是某个外卖APP的首页.首页上的页面展示会关联很多服务的API调用,如果使用 ...
- Redis使用IO多路复用进行事件处理机制
一.epoll多路复用 这里重点要说的就是redis的IO编程模型,首先了解下 为什么要有多路复用呢 ? 案例 引用知乎上一个高赞的回答来解释什么是I/O多路复用.假设你是一个老师,让30个学生解答一 ...