> ## Content Index
> Fetch the complete content index at: https://www.hubwiz.com/blog/llms.txt
> Use this file to discover other available public pages before exploring further.

# a2ajava：A2UI协议的java实现
- URL: https://www.hubwiz.com/blog/a2ajava-a2ui-java-implementation/
- Published: 2026-04-23T10:55:03.000Z
- Updated: 2026-04-23T10:55:03.000Z
- Description: Angular和Java的A2UI完整工作演示：简单至极，零复杂度
- Author: admin
- Tags: LIBRARY, A2AJAVA, A2UI, #Import 2026-10-14 14:41

A2UI（Agent-to-User Interface，代理到用户界面）是Google开发的一种革命性协议，它使AI代理能够动态渲染丰富的交互式用户界面。与返回静态JSON数据的传统REST API不同，A2UI允许AI代理即时生成完整的UI体验，在智能后端服务和现代前端应用之间架起无缝的桥梁。

完整的演示部署在 [https://vishalmysore.github.io/simplea2ui/](https://vishalmysore.github.io/simplea2ui/?ref=hubwiz.com)

你可以使用以下查询：

- Compare Honda and Toyota for me?
- What Food does Vishal like to eat?
- Can you book a restaruant for me? I need to eat food I am very hungry

## 1、什么是A2UI协议？

A2UI v0.8是一个规范，定义了AI代理如何将结构化UI组件传递给客户端应用程序。代理无需在前端硬编码UI逻辑，而是可以根据上下文、用户输入和应用状态来决定呈现什么样的界面。

![None](https://www.hubwiz.com/blog/content/images/2026/04/0-qcdZOtPp22O0E-oh.png)

核心特性：

- **动态UI生成**：代理根据业务逻辑以编程方式创建UI组件
- **基于组件的架构**：使用标准UI组件（Text、TextField、Button、Column等）
- **数据模型绑定**：UI组件与后端数据模型之间的双向数据绑定
- **动作处理**：按钮通过上下文数据触发后端动作
- **协议灵活性**：同时支持富UI渲染和纯文本响应

## 2、服务端实现：A2AJava框架

本项目使用 **a2ajava**（Actions for AI Java）实现A2UI协议，这是一个强大的框架：

- 自动将Java方法暴露为AI可调用的动作
- 提供注解驱动的代理和动作定义
- 与Spring Boot集成，支持企业级应用
- 支持多种回调类型，包括A2UI、文本和自定义协议

## 3、核心组件

### 3.1 代理定义

代理使用 `@Agent` 注解定义，并带有描述性元数据：

```
@Service
@Agent(groupName = "compareCar", groupDescription = "compare 2 cars")
@Slf4j
public class CompareCarService implements A2UIDisplay {
    private ThreadLocal<ActionCallback> callback = new ThreadLocal<>();
    // ... implementation
}

```

### 3.2 动作方法

动作是使用 `@Action` 注解的Java方法，可由AI系统调用：

```
@Action(description = "compare 2 cars")
public Object compareCar(String car1, String car2) {
    log.info("Comparing cars: {} vs {}", car1, car2);
    String betterCar = determineBetterCar(car1, car2);
    // Dual-mode support: UI or text response
    if(isUICallback(callback)) {
        return createComparisonUI(car1, car2, betterCar, result);
    } else {
        return "Text-based response: " + betterCar + " is better";
    }
}

```

### 3.3 双模式协议支持

该框架通过智能回调检测支持**文本和UI两种协议**：

- **文本模式**：当直接调用或通过基于文本的AI系统调用时，返回纯字符串响应
- **UI模式**：当使用A2UI回调调用时，返回结构化的组件树

```
// Detection logic
if(isUICallback(callback)) {
    // Return A2UI component structure
    return buildA2UIMessage(surfaceId, rootId, components);
} else {
    // Return plain text
    return "Simple text response";
}

```

## 4、A2UI组件结构

### 4.1 组件目录

该协议定义了标准组件：

- **Text**：显示静态或动态文本内容
- **TextField**：带有数据模型绑定的输入字段
- **Button**：带有动作回调的交互式按钮
- **Column**：用于垂直排列的布局容器

### 4.2 数据模型格式（A2UI v0.8规范）

数据模型使用**邻接表格式**进行高效状态管理：

```
{
  "dataModelUpdate": {
    "contents": [
      {
        "key": "form",
        "valueMap": [
          {
            "key": "name",
            "valueString": ""
          },
          {
            "key": "email",
            "valueString": ""
          }
        ]
      }
    ],
    "surfaceId": "user_form"
  }
}

```

### 4.3 TextField组件

TextField使用 `text` 属性绑定到数据模型路径：

```
{
  "component": {
    "TextField": {
      "label": { "literalString": "Person's Name" },
      "text": { "path": "/form/name" }
    }
  },
  "id": "name_input"
}

```

### 4.4 带上下文的按钮

按钮通过 `context` 数组指定要发送的数据：

```
{
  "component": {
    "Button": {
      "action": {
        "name": "whatThisPersonFavFood",
        "context": [
          {
            "key": "name",
            "value": { "path": "/form/name" }
          }
        ]
      },
      "child": "submit_button_text"
    }
  },
  "id": "submit_button"
}

```

## 5、实现示例

### 5.1 带表单提交的简单服务

```
@Service
@Agent(groupName = "whatThisPersonFavFood", 
       groupDescription = "Provide persons name and find what they like")
public class SimpleService implements A2UIDisplay {
@Action(description = "Get the favourite food of a person")
    public Object whatThisPersonFavFood(String name) {
        String favFood = lookupFavoriteFood(name);
        if(callback != null && callback.getType().equals(CallBackType.A2UI.name())) {
            return createFavoriteFoodUI(name, favFood);
        } else {
            return favFood;
        }
    }
    private Map<String, Object> createFavoriteFoodUI(String name, String favFood) {
        // Create UI components
        List<Map<String, Object>> components = new ArrayList<>();
        // Add title
        components.add(createTextComponent("title", "Favorite Food Finder", "h2"));
        // Add result display
        components.add(createTextComponent("result", 
            name + "'s favorite food is: " + favFood));
        // Add form for next query
        components.add(createTextFieldComponent("name_input", 
            "Person's Name", "/form/name"));
        // Add submit button with context binding
        Map<String, String> contextBindings = new HashMap<>();
        contextBindings.put("name", "/form/name");
        components.add(createButtonComponent("submit_button", 
            "Find Favorite Food", "whatThisPersonFavFood", contextBindings));
        // Initialize data model
        Map<String, Object> dataModel = new HashMap<>();
        dataModel.put("/form/name", "");
        return buildA2UIMessageWithData(surfaceId, rootId, components, dataModel);
    }
}

```

### 5.2 多步骤工作流：餐厅预订

具有多个动作方法的复杂工作流：

```
@Service
@Agent(groupName = "restaurantBooking", 
       groupDescription = "Book restaurant reservations with menu selection")
public class RestaurantBookingService implements A2UIDisplay {
@Action(description = "Book a restaurant reservation - shows form")
    public Object bookRestaurantReservation(String restaurantName) {
        if(isUICallback(callbackThreadLocal)) {
            return createReservationFormUI(restaurantName);
        }
        return "Please provide reservation details...";
    }
    @Action(description = "Confirm restaurant reservation with all details")
    public Object confirmReservation(String restaurantName, String date, 
                                     String time, int numberOfPeople, 
                                     String menuType, String specialRequests) {
        String confirmationNumber = generateConfirmationNumber();
        if(isUICallback(callbackThreadLocal)) {
            return createConfirmationUI(restaurantName, date, time, 
                                       numberOfPeople, menuType, 
                                       specialRequests, confirmationNumber);
        }
        return "Reservation confirmed! Confirmation #" + confirmationNumber;
    }
}

```

## 6、技术优势

### 6.1 关注点分离

- 后端控制UI逻辑和工作流
- 前端专注于渲染和用户交互
- 清晰的API边界和强类型支持

### 6.2 动态适应

- UI可以根据业务规则自适应，无需重新部署前端
- 在协议层面进行A/B测试
- 基于用户上下文的个性化体验

### 6.3 类型安全

- Java类型系统确保正确的数据结构
- 编译时验证组件层次结构
- IDE支持自动补全和重构

### 6.4 向后兼容

- 同一代码库支持传统的基于文本的客户端
- 对不支持的客户端进行优雅降级
- 对现代界面进行渐进增强

## 7、A2UIDisplay工具接口

该项目提供了一个带有辅助方法的工具接口：

```
public interface A2UIDisplay {
    // Create text components
    Map<String, Object> createTextComponent(String id, String text, String usageHint);
// Create input fields with data binding
    Map<String, Object> createTextFieldComponent(String id, String label, String dataPath);
    // Create buttons with action callbacks and context
    Map<String, Object> createButtonComponent(String id, String buttonText, 
                                               String actionName, 
                                               Map<String, String> contextBindings);
    // Create layout containers
    Map<String, Object> createRootColumn(String rootId, List<String> childIds);
    // Build complete A2UI messages
    Map<String, Object> buildA2UIMessageWithData(String surfaceId, String rootId,
                                                  List<Map<String, Object>> components,
                                                  Map<String, Object> dataModelValues);
}

```

## 8、数据流架构

### 请求-响应周期

1. **AI请求**：AI系统使用参数调用动作方法
2. **回调检测**：服务检查回调类型（A2UI还是文本）
3. **业务逻辑**：执行核心功能
4. **响应生成**：
- A2UI：构建带有数据模型的组件树
- 文本：返回简单字符串
1. **客户端渲染**：前端处理A2UI消息并渲染UI
2. **用户交互**：用户填写表单并点击按钮
3. **上下文提交**：按钮动作将绑定数据发送回后端
4. **下一步动作**：使用新的动作方法重复循环

### 数据模型生命周期

```
1. Backend initializes data model with empty values
   └─> dataModelUpdate.contents = [{ key: "form", valueMap: [...] }]
2. Frontend binds TextField.text to data model paths
   └─> { "text": { "path": "/form/name" } }
3. User types input → Frontend updates data model in real-time
4. User clicks button → Frontend extracts context values
   └─> Button.action.context specifies which paths to send
5. Backend receives action call with populated parameters
   └─> confirmReservation(restaurantName="Joe's Diner", date="2026-01-15", ...)

```

## 9、最佳实践

### 1\. 一致的命名

- 使用与按钮动作匹配的描述性动作名称
- 数据模型路径遵循类似REST的约定：`/resource/field`

### 2\. 错误处理

- 在动作方法中验证输入
- 在UI模式下返回用户友好的错误消息

### 3\. 状态管理

- 在多线程环境中使用ThreadLocal存储回调
- 使用合理的默认值初始化数据模型

### 4\. 组件层次结构

- 保持组件树扁平以提高性能
- 使用语义化的组件ID便于调试

### 5\. 上下文绑定

- 仅将必要的数据绑定到按钮上下文
- 使用与动作方法签名匹配的显式参数名称

## 10、与Spring Boot集成

该框架与Spring Boot无缝集成：

```
@Service  // Spring managed bean
@Agent(groupName = "myAgent", groupDescription = "Agent description")
public class MyService implements A2UIDisplay {
@Autowired
    private SomeDependency dependency;  // Spring dependency injection works
    private ActionCallback callback;  // Autowired by tools4ai framework
    private AIProcessor processor;    // Autowired by tools4ai framework
    @Action(description = "Action description")
    public Object myAction(String param) {
        // Use injected dependencies
        // Access callback and processor
    }
}

```

## 11、结束语

A2UI协议代表了AI代理与用户交互方式的范式转变。通过将智能后端服务的强大功能与动态UI生成相结合，开发者可以构建高度自适应的应用程序，实时响应用户需求。

a2ajava框架使A2UI的实现变得简单直接，通过以下特性：

- 注解驱动的开发方式
- 双模式协议支持（文本和UI）
- Spring Boot集成
- 类型安全的组件生成
- 可复用的工具接口

这种架构使团队能够构建复杂的对话式UI、多步骤工作流和上下文感知应用程序，同时在业务逻辑和展示层之间保持清晰的分离。

---

原文链接: [A2UI Protocol Guide: Build Dynamic AI Agent Interfaces with Java](https://freedium-mirror.cfd/https://medium.com/@visrow/a2ui-protocol-guide-build-dynamic-ai-agent-interfaces-with-java-e87ab1a52e5a?ref=hubwiz.com)

汇智网翻译整理，转载请标明出处