克隆代码

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 - 流式端点

验证代理卡片:

步骤 4: 运行翻译客户端

在新的终端窗口中,运行客户端示例:

cd client
../mvnw exec:java -Dexec.mainClass="com.google.a2a.client.A2AClientExample"

时序图

以下时序图展示了基于 A2AClientExample.java 的 A2A Java 示例应用程序的完整交互流程:

sequenceDiagram
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: 示例程序执行完成

关键交互模式

时序图展示了以下核心交互模式:

  1. 客户端初始化: 创建连接到本地服务器的 A2AClient 实例
  2. 代理发现: 通过 /.well-known/agent-card 端点检索代理信息
  3. 多语言翻译示例:
    • 法语 → 中文翻译
    • 中文 → 英文翻译
    • 德语 → 英文流式翻译
  4. 任务管理:
    • 查询任务状态
    • 取消任务执行

通信机制

  • 同步翻译: 使用 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

A2A Java 示例的更多相关文章

  1. 课程作业01:模仿JavaAppArguments.java示例,编写一个程序,此程序从命令行接收多个数字,求和之后输出结果。

    1.设计思想: 首先是从JavaAppArguments.java示例开始,此示例已打印参数,定义数字 之和和作为存储单位的整型,然后将输入参数的字符串转化为整型,之后求和即可. 2.程序流程图: 3 ...

  2. 左右JAVA示例代码事件分发和监督机制来实现-绝对原创有用

    文章标题:左右JAVA示例代码事件分发和监督机制来实现 文章地址: http://blog.csdn.net/5iasp/article/details/37054171 作者: javaboy201 ...

  3. Spark 用户自定义函数 Java 示例

    Spark UDF Java 示例 在这篇文章中提到了用Spark做用户昵称文本聚类分析,聚类需要选定K个中心点,然后迭代计算其他样本点到中心点的距离.由于中文文字分词之后(n-gram)再加上昵称允 ...

  4. thrift java示例

    thrift java示例 使用IntelliJ IDEA作为开发工具: 增加proto文件夹,里面写上sayHello.proto syntax = "proto3"; opti ...

  5. & 和 && 的区别,与(&)运算符、位移运算符(<< 、>>、>>>)的含义及使用(Java示例)

    & 和 && 的区别,与(&)运算符.位移运算符(<< .>>.>>>)的含义及使用(Java示例) 1. & 和 & ...

  6. HTTP基本认证(Basic Authentication)的JAVA示例

    大家在登录网站的时候,大部分时候是通过一个表单提交登录信息.但是有时候浏览器会弹出一个登录验证的对话框,如下图,这就是使用HTTP基本认证.下面来看看一看这个认证的工作过程:第一步:  客户端发送ht ...

  7. CentOS安装卸载memcache及JAVA示例

      原文地址:http://www.cnblogs.com/zhongshengzhen/   先安装libevent,memcached依赖libevent的lib [root@VM_64_81_c ...

  8. hbase 0.96 java 示例

    import java.util.ArrayList; import java.util.List; import org.apache.hadoop.conf.Configuration; impo ...

  9. epub、ocf等常用电子书格式浅析----附JAVA示例程序

    一. 电子书介绍 转载请注明http://www.cnblogs.com/xckk/p/6020324.html Epub(Electronic Publication)是一个完全开放和免费的电子书标 ...

  10. 国际快递查询接口JAVA示例-trackingmore

    国际快递查询接口 国际快递查询接口的需求量很大,例如一些跨境电商B2C网站.快递查询APP.快递柜.跨境物流公司等都会需要用到国际快递接口. 目前市面上的快递接口,以国内快递居多,有些虽然号称支持多家 ...

随机推荐

  1. 【Bug记录】[@vue/compiler-sfc] `defineProps` is a compiler macro and no longer needs to be imported.

    [Bug记录][@vue/compiler-sfc] defineProps is a compiler macro and no longer needs to be imported. Vue3项 ...

  2. 查看、安装python指定版本的包、安装卸载第三方模块

    python安装/卸载第三方包 (1)安装第三方包: 安装指令pip install xxx (xxx,需安装的包名) 安装特定版本的package:通过使用==, >=, <=, > ...

  3. Joker 可视化开发平台全局方法使用指南

    在 Joker 可视化开发平台中,全局方法是实现公共业务逻辑的有力工具,它能跨越组件和页面文件的界限,让开发者快速调用,显著提升开发效率.下面将详细介绍全局方法在平台中的使用方式. 一.全局方法的定义 ...

  4. google_hacking_study

    简单了解一下Google Hacking语法. 这是goolehacking十个基本语法. ""完全匹配 据说匹配比较精准,但是我不加引号好像也没什么区别耶 *模糊匹配.?表示单个 ...

  5. 使用PIO自定义每一个格子的属性和值,完全DIY--Excel,不整齐也可以实现

    常规表格样式的Excel导出, 有一种不是常规表格样式的Excel导出, 比如如下这种怎么办 快速的excel框架API肯定不支持这种 所以我们需要自定义格子的内容 private CellStyle ...

  6. 资料推荐-一个神奇的网站educative.io

    前言 算法和数据结构一直是笔者心中的痛,笔者曾经阅读过两个材料,但都收效不好,尝试总结下这两个材料: 极客时间的数据结构和算法的课程 优点:适合用于去理解数据结构和算法的基本概念 缺点:不包含题目(这 ...

  7. Git Bash 无法输入中文

    场景重现 有个小伙伴的电脑上 Git Bash 里死活无法输入中文, 导致 git 提交信息没法用中文写... git commit -m "无法输入中文" 解决办法 在 Git ...

  8. CoreOS 发行版本介绍

    大多数的软件通常都有什么内测版.公测版什么的. CoreOS 发行版本 而在 CoreOS 中, 有以下3个版本: alpha - α版,音译:阿尔法,俗称尝鲜版,是最新的版本,但是容易出现bug,最 ...

  9. javascript 字符串截取

    <script> //字符截取(需要的字符长度) function cut_str(need_str_length){     var bag_set = document.getElem ...

  10. TDXSpreadSheet中自定义公式函数三大步骤

    看其demo:CustomFunctionDemo. 在报表系统中,特别是财务等报表系统中.需要对固定格式的报表中cell定义取数公式. 如新中大中: 公式 返回值 gs_dwmc(预算单位代码/名称 ...