Java中的通用商务协议(UCP):构建支持智能体的商务工作流
随着AI智能体和自主商务日益普及,对标准化互操作性的需求变得空前重要。本综合指南演示了如何使用tools4ai框架在Java中实现UCP(通用商务协议),提供理论理解和实际实现模式。

什么是UCP?
UCP(通用商务协议)是一种新兴的智能体间互操作性协议,旨在让不同供应商构建的AI智能体能够以标准化方式进行通信、发现能力、交换上下文和调用操作。它专注于能力发现、身份认证、安全性和结构化消息交换,使智能体能够在无需紧密耦合或专有集成的情况下协作。
实际上,UCP充当智能体之间的中立”语言”,使工具、智能体和服务能够跨平台协作——其理念类似于HTTP标准化了Web通信,但UCP专门用于自主和半自主的AI智能体。
核心库
此实现使用三个核心库:
tools4ai- AI智能体工具的核心框架a2ajava- 智能体间通信ucpjava- UCP协议实现
为什么UCP很重要?
如今,商务生态系统、平台、企业、支付提供商和凭证提供商在不同系统上运行,造成了集成复杂性和交易失败。UCP通过提供以下功能来解决这种碎片化问题:
- 标准化通用语言:所有商务实体进行通信的统一方式
- 功能原语:实现无缝交互的核心构建块
- 降低集成复杂性:无需为每个平台进行定制集成
- 面向未来的架构:支持有人参与和自主AI智能体商务流程
核心概念
UCP协议架构
UCP通过三个关键功能提供标准化的交互模式,以解决碎片化商务问题:
- 发现:平台通过
/.well-known/ucp处的配置文件动态发现商务能力 - 传输无关:适用于REST、MCP(模型上下文协议)和A2A协议
- 模块化设计:可组合的能力和扩展,支持灵活实现
UCP商家
UCP商家是销售商品或服务的实体,作为记录商户(MoR)保留财务责任和所有权。在代码中,这由 @UCPBusiness注解表示。
关键约束:UCP强制规定每个主机恰好代表一个商家,以保持明确的责任和所有权。
@UCPBusiness(name = "AutoGroup North", version = "2026-01-19")
public class ShoppingService implements UCPAware {
// 商家实现
}
UCP能力
UCP能力是企业支持的独立核心功能——UCP的基本”动词”。这些使用 @UCPCapability注解声明,并遵循反向域名命名约定。
能力命名空间模式
| 命名空间模式 | 权威机构 | 示例 |
|---|---|---|
dev.ucp.* | UCP管理机构 | dev.ucp.shopping.checkout |
com.vendor.* | 供应商组织 | com.example.payments.installments |
io.github.* | 自定义实现 | io.github.vishalmysore.car_booking |
标准UCP能力
UCP定义了几种标准能力:
- Checkout:购物车管理和结账会话
- Identity Linking:OAuth 2.0授权
- Order:生命周期事件Webhook
能力结构
所有能力必须包含:
- Name:反向域名格式(例如,
dev.ucp.shopping.checkout) - Version:YYYY-MM-DD格式
- Spec URL:规范文档链接
- Schema URL:JSON Schema定义链接
@UCPCapability(
name = "dev.ucp.shopping.checkout",
version = "2026-01-11",
spec = "https://ucp.dev/specification/checkout",
schema = "https://ucp.dev/schemas/shopping/checkout.json"
)
public Object createCheckout(Map<String, Object> checkoutRequest);
实现架构
本指南涵盖的内容
本实现指南将引导您构建一个完整的UCP兼容Java应用程序,演示:
- 核心UCP概念:理解协议架构,包括平台、商家、凭证提供商和支付服务提供商的角色
- 传输协议:实现对REST API和模型上下文协议(MCP)的双重支持,用于AI智能体集成
- 能力发现:构建动态发现配置文件,使平台能够自主检测商务能力
- 标准与自定义能力:实现标准UCP能力和自定义业务特定功能
- 安全模式:利用OAuth 2.0进行身份链接和AP2授权,确保自主交易安全
实现方法
本指南采用实用的、代码优先的方法,使用Spring Boot和tools4ai框架,演示如何:
- 使用
UCPAware接口构建支持UCP的服务以实现标准能力 - 通过适当的注解模式创建自定义能力
- 为标准结账操作实现所需的REST端点
- 为AI智能体集成配置MCP传输
- 为能力协商生成合规的发现配置文件
标准UCP能力
UCPAware接口
UCPAware接口定义了核心商务操作必须实现的标准UCP能力:
public interface UCPAware {
@UCPCapability(
name = "dev.ucp.shopping.checkout",
version = "2026-01-11",
spec = "https://ucp.dev/specification/checkout",
schema = "https://ucp.dev/schemas/shopping/checkout.json"
)
Object createCheckout(Map<String, Object> checkoutRequest);
@UCPCapability(
name = "dev.ucp.shopping.order",
version = "2026-01-11",
spec = "https://ucp.dev/specification/order",
schema = "https://ucp.dev/schemas/shopping/order.json"
)
Object getOrder(String orderId);
@UCPCapability(
name = "dev.ucp.common.identity_linking",
version = "2026-01-11",
spec = "https://ucp.dev/specification/identity-linking",
schema = "https://ucp.dev/schemas/common/identity_linking.json"
)
Object linkIdentity(Map<String, Object> identityRequest);
}
关键要求
- 标准能力需要精确的REST端点实现
- 所有能力必须使用YYYY-MM-DD版本控制
- 必须包含规范(spec)和模式(schema)URL
- 通过注解扫描自动发现能力
自定义能力
实现示例:汽车预订
自定义能力允许企业使用特定领域功能扩展UCP,同时保持协议合规性。
package io.github.vishalmysore.controllers;
import com.t4a.annotations.Action;
import com.t4a.annotations.Agent;
import com.t4a.processor.ProcessorAware;
import io.github.vishalmysore.a2ui.A2UIAware;
import io.github.vishalmysore.ucp.annotation.UCPCapability;
import io.github.vishalmysore.ucp.domain.SimpleUCPResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
/**
* UCP汽车预订业务
*
* 重要约束:
* - 在我们的Spring Boot应用程序中,只能有一个智能体带有 @UCPBusiness 标签
* - UCP能力只能存在于REST控制器中(不在服务中)
* - 这是必需的,因为UCP要求支持REST和MCP两种传输方式
* - 如果是REST控制器,UCP清单会添加"rest"作为传输方式
*/
@Agent(
groupName = "carbooking",
groupDescription = "汽车预订服务",
prompt = "您是一个汽车预订助手。根据用户的偏好和需求帮助他们预订汽车。"
)
@RestController(value = "/carbooking")
public class CarbookingController implements ProcessorAware, A2UIAware {
@Action(description = "根据用户偏好预订汽车")
@UCPCapability(
name = "io.github.vishalmysore.car_booking",
version = "2026-01-19",
spec = "https://autogroup-north.com/specs/car-booking",
schema = "https://autogroup-north.com/schemas/booking.json"
)
@PostMapping("/bookCar")
public SimpleUCPResult bookCar(
String carType,
String pickupLocation,
String dropoffLocation,
String pickupDate,
String dropoffDate) {
// 预订逻辑
Map<String, String> bookingDetails = new HashMap<>();
bookingDetails.put("carType", carType);
bookingDetails.put("pickupLocation", pickupLocation);
bookingDetails.put("dropoffLocation", dropoffLocation);
bookingDetails.put("pickupDate", pickupDate);
bookingDetails.put("dropoffDate", dropoffDate);
bookingDetails.put("confirmationNumber", "ABC123XYZ");
return new SimpleUCPResult(bookingDetails);
}
}
自定义能力分析
✅ 正确结构
- 控制器要求:控制器正确遵循UCP模式,其中能力必须位于REST控制器中以支持REST传输
- 能力注解:使用正确的自定义命名空间和基于日期的版本控制:
@UCPCapability(
name = "io.github.vishalmysore.car_booking",
version = "2026-01-19",
spec = "https://autogroup-north.com/specs/car-booking",
schema = "https://autogroup-north.com/schemas/booking.json"
)
- REST端点:使用
@PostMapping("/bookCar")正确映射预订操作 - 返回类型:使用
SimpleUCPResult,当与MCP传输一起使用时,它包含UCP元数据
📝 发现配置文件影响
此控制器将被自动发现并添加到发现配置文件中:
{
"name": "io.github.vishalmysore.car_booking",
"version": "2026-01-19",
"spec": "https://autogroup-north.com/specs/car-booking",
"schema": "https://autogroup-north.com/schemas/booking.json"
}
重要注意事项
@Agent注解使此能力可通过MCP和A2A传输以及REST访问- 自定义能力可以定义自己的端点模式(与标准UCP能力不同)
SimpleUCPResult返回类型在用于MCP传输时应包含UCP元数据UCPController将在扫描带注解的方法时自动注册此能力
服务类型和模式
服务类型比较
| 服务类型 | 注解 | 传输 | 用例 |
|---|---|---|---|
| UCP商家 | @UCPBusiness + @RestController | REST + MCP | 标准商务能力 |
| 智能体服务 | @Agent | MCP + A2A | AI智能体交互 |
智能体服务示例:汽车销售
不是UCP能力但可用于AI智能体交互的服务:
package io.github.vishalmysore.service;
import com.t4a.annotations.Action;
import com.t4a.annotations.Agent;
import com.t4a.processor.ProcessorAware;
import io.github.vishalmysore.a2ui.A2UIAware;
/**
* 汽车销售的MCP服务
*
* 重要约束:
* - 这不是UCP商家或UCP能力
* - 仅通过MCP和A2A协议公开
* - 不需要REST端点
* - 不能使用@UCPCapability注解(启动时会抛出错误)
*/
@Agent(
groupName = "carbooking",
groupDescription = "汽车预订服务",
prompt = "您是一个汽车预订助手。根据用户的偏好和需求帮助他们预订汽车。"
)
public class CarSellingService implements ProcessorAware, A2UIAware {
/**
* 这是一个仅通过MCP和A2A公开的智能体操作
* 它不是UCP业务或能力
*/
@Action(description = "根据用户偏好销售汽车")
// @UCPCapability(name = "io.github.vishalmysore.sell_car", ...)
// ⚠️ 不能取消上面的注释 - 将抛出错误:
// "UCP违规:智能体CarSellingService必须使用@RestController注解以支持REST传输"
public Object sellCar(
String carType,
String pickupLocation,
String dropoffLocation,
String pickupDate,
String dropoffDate) {
return "已售出汽车:" + carType + " 从 " + pickupLocation +
" 到 " + dropoffLocation + " 在 " + pickupDate +
" 和 " + dropoffDate + " 之间";
}
}
模式指南
-
对于CarSellingService(智能体模式):
- 使用
@Agent注解进行智能体发现 @Action方法仅通过MCP/A2A公开- 不需要REST端点
- 保持
@UCPCapability注释掉——这不是UCP业务 sellCar方法将通过MCP在/ucp/mcp和A2A协议中可用
- 使用
-
对于UCP标准能力:
- 使用实现
UCPAware接口的ShoppingService - 必须是
@RestController - 支持REST和MCP两种传输方式
- 使用实现
这种分离允许您在同一应用程序中同时支持标准UCP商务和自定义智能体功能。
发现和端点解析
生成的UCP清单
框架会在 /.well-known/ucp自动生成完整的UCP发现配置文件:
{
"ucp": {
"capabilities": [
{
"schema": "https://autogroup-north.com/schemas/inventory_search.json",
"name": "io.github.vishalmysore.inventory_search",
"version": "2026-01-19",
"spec": "https://autogroup-north.com/specs/inventory-search"
},
{
"schema": "https://ucp.dev/schemas/shopping/order.json",
"name": "dev.ucp.shopping.order",
"version": "2026-01-11",
"spec": "https://ucp.dev/specification/order"
},
{
"schema": "https://ucp.dev/schemas/shopping/checkout.json",
"name": "dev.ucp.shopping.checkout",
"version": "2026-01-11",
"spec": "https://ucp.dev/specification/checkout"
},
{
"schema": "https://autogroup-north.com/schemas/comparison.json",
"name": "io.github.vishalmysore.car_comparison",
"version": "2026-01-19",
"spec": "https://autogroup-north.com/specs/car-comparison"
},
{
"schema": "https://autogroup-north.com/schemas/booking.json",
"name": "io.github.vishalmysore.car_booking",
"version": "2026-01-19",
"spec": "https://autogroup-north.com/specs/car-booking"
},
{
"schema": "https://ucp.dev/schemas/common/identity_linking.json",
"name": "dev.ucp.common.identity_linking",
"version": "2026-01-11",
"spec": "https://ucp.dev/specification/identity-linking"
}
],
"services": {
"dev.ucp.shopping": {
"rest": {
"schema": "https://ucp.dev/services/shopping/openapi.json",
"endpoint": "http://localhost:7860/ucp/v1"
},
"mcp": {
"schema": "https://ucp.dev/services/shopping/mcp.openrpc.json",
"endpoint": "http://localhost:7860/ucp/mcp"
},
"version": "2026-01-11",
"spec": "https://ucp.dev/specification/overview"
}
},
"version": "2026-01-19"
}
}
客户端发现过程
为了发现预订汽车的具体REST调用,客户端遵循以下系统性的端点解析过程:
步骤1:识别垂直领域(服务)
客户端检查 services对象。“预订”或”结账”通常属于 dev.ucp.shopping服务。
- 服务名称:
dev.ucp.shopping - 基础端点:
http://localhost:7860/ucp/v1
步骤2:获取传输模式
客户端从 rest.schema字段检索OpenAPI规范:
https://ucp.dev/services/shopping/openapi.json
注意:此OpenAPI文件是”精简的”——它包含路径和方法名称(例如,/checkout-sessions),但内部不定义完整的负载结构。
步骤3:将能力与路径匹配
客户端看到广告了 io.github.vishalmysore.car_booking能力。通过查阅规范或shopping服务的标准映射,它识别出相关的REST路径。
对于预订/结账流程,标准路径通常是:
POST /checkout-sessions
步骤4:解析最终URL
客户端将OpenAPI路径附加到服务端点:
- 基础:
http://localhost:7860/ucp/v1 - 路径:
/checkout-sessions - 解析后的URL:
http://localhost:7860/ucp/v1/checkout-sessions
步骤5:构建负载(模式组合)
这是自定义能力最关键的步骤:
- 获取基础模式:从
https://ucp.dev/schemas/shopping/checkout.json下载标准结账模式 - 获取扩展模式:从
https://autogroup-north.com/schemas/booking.json下载自定义模式 - 组合:使用
allOf合并这些模式。请求体将包含标准结账字段加上汽车特定的预订字段
发现总结表
| 步骤 | 操作 | 结果 |
|---|---|---|
| 1 | 查找Shopping服务 | dev.ucp.shopping |
| 2 | 获取基础端点 | http://localhost:7860/ucp/v1 |
| 3 | 查找Booking路径 | POST /checkout-sessions |
| 4 | 获取负载模式 | https://autogroup-north.com/schemas/booking.json |
| 5 | 组合并发送请求 | 包含汽车预订数据的完整结账信息 |
模式组合
扩展模式模式
基于UCP规范的扩展模式模式,自定义模式充当增强基础商务类型的模块。它们使用 allOf来”插入”标准UCP模式。
自定义预订模式示例
遵循命名约定 {能力名称}.{类型名称}:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://autogroup-north.com/schemas/booking.json",
"title": "汽车预订扩展",
"description": "扩展UCP结账以支持汽车特定的预订数据。",
"$defs": {
"car_details": {
"type": "object",
"properties": {
"vin": {
"type": "string",
"pattern": "^[A-HJ-NPR-Z0-9]{17}$"
},
"make": { "type": "string" },
"model": { "type": "string" },
"year": { "type": "integer" },
"trim": { "type": "string" }
},
"required": ["vin", "make", "model"]
},
"booking_metadata": {
"type": "object",
"properties": {
"pickup_date": {
"type": "string",
"format": "date-time"
},
"dealership_id": { "type": "string" },
"test_drive_requested": {
"type": "boolean",
"default": false
}
}
},
"io.github.vishalmysore.car_booking.checkout": {
"description": "用于汽车预订的组合结账对象",
"allOf": [
{
"$ref": "https://ucp.dev/schemas/shopping/checkout.json"
},
{
"type": "object",
"properties": {
"car_info": {
"$ref": "#/$defs/car_details"
},
"booking_details": {
"$ref": "#/$defs/booking_metadata"
}
}
}
]
}
}
}
关键结构特性
- 命名空间对齐:主要组合类型名为
io.github.vishalmysore.car_booking.checkout,确保客户端知道哪个对象定义用于POST /checkout-sessions - 组合(allOf):明确引用官方UCP结账模式作为基础,要求支持标准字段,同时添加汽车特定字段
- 自描述性:按照UCP要求声明其引入的类型
最终请求结构
当平台合并这些模式时,发送到 http://localhost:7860/ucp/v1/checkout-sessions的JSON负载如下所示:
{
"ucp": {
"version": "2026-01-11",
"capabilities": [
{
"name": "dev.ucp.shopping.checkout",
"version": "2026-01-11"
},
{
"name": "io.github.vishalmysore.car_booking",
"version": "2026-01-19"
}
]
},
"cart": {
"line_items": [
{
"sku": "SERVICE-FEE",
"quantity": 1
}
]
},
"car_info": {
"vin": "1HGCM82635A000001",
"make": "Honda",
"model": "Accord"
},
"booking_details": {
"pickup_date": "2026-02-01T10:00:00Z",
"dealership_id": "NORTH-001"
}
}
在配置文件中链接模式
为了使模式可被发现,更新 /.well-known/ucp配置文件:
"services": {
"dev.ucp.shopping": {
"rest": {
"schema": "http://localhost:7860/v3/api-docs",
"endpoint": "http://localhost:7860/ucp/v1"
}
}
}
客户端使用模式进行发现
当用户说”我想在伦敦预订一辆SUV”时,客户端会:
- 读取配置文件:看到支持
io.github.vishalmysore.car_booking - 获取模式:从
http://localhost:7860/v3/api-docs下载JSON - 找到匹配项:在路径中搜索与”booking”相关的
operationId或标签 - 检查参数:识别必需参数:
carTypepickupLocationdropoffLocationpickupDatedropoffDate
- 执行:调用
POST http://localhost:7860/bookCar?carType=SUV&pickupLocation=London...
专业提示:请求体与查询参数
- 当前状态:参数在查询中定义:
POST http://localhost:7860/bookCar?carType=...&pickupLocation=... - UCP推荐:对于创建预订意图的POST操作,数据应放在请求体中而不是URL字符串中。这样更简洁,可以防止URL过长和混乱。
工具使用和API调用
MCP工具发现
使用MCP的 tools/list方法列出所有可用工具:
curl -H "Content-Type: application/json" -d '{
"jsonrpc": "2.0",
"method": "tools/list",
"params": {},
"id": 1
}' http://localhost:7860/
示例响应
{
"result": {
"_meta": {},
"tools": [
{
"parameters": null,
"inputSchema": {
"type": "object",
"properties": {
"provideAllValuesInPlainEnglish": {
"type": "string",
"description": "{\n \"parameters\": {\n \"carType\": \"\",\n \"pickupLocation\": \"\",\n \"dropoffLocation\": \"\",\n \"pickupDate\": \"\",\n \"dropoffDate\": \"\"\n }\n}"
}
},
"required": ["provideAllValuesInPlainEnglish"]
},
"annotations": {
"properties": {
"usage": "为特定时期和地点预订汽车。",
"name": "汽车预订工具",
"description": "此工具允许用户通过指定汽车类型、取车地点、还车地点以及取车和还车日期来预订汽车。",
"parameters": "carType, pickupLocation, dropoffLocation, pickupDate, dropoffDate"
}
},
"description": "根据用户偏好预订汽车",
"name": "bookCar",
"type": null
},
{
"description": "比较2辆汽车",
"name": "compareCar",
"annotations": {
"properties": {
"name": "汽车比较工具",
"description": "此工具根据各种参数比较两辆汽车,帮助用户做出明智的决定。"
}
}
}
]
},
"id": 1,
"jsonrpc": "2.0"
}
普通MCP工具调用
使用MCP的 tools/call方法执行工具:
curl -H "Content-Type: application/json" -d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "compareCar",
"arguments": {
"provideAllValuesInPlainEnglish": "{\"car1\": \"Tesla Model 3\", \"car2\": \"BMW i4\"}"
}
}
}' http://localhost:7860/
示例响应
{
"result": {
"content": [
{
"type": "text",
"annotations": null,
"text": "Tesla Model 3比BMW i4更好"
}
],
"text": "Tesla Model 3比BMW i4更好"
},
"id": 2,
"jsonrpc": "2.0"
}
通过MCP的UCP请求
对于UCP兼容的请求,使用能力名称作为方法:
curl -H "Content-Type: application/json" -d '{
"jsonrpc": "2.0",
"method": "io.github.vishalmysore.car_booking",
"params": {
"_meta": {
"ucp": {
"profile": "https://platform.example/profiles/v2026-01/shopping-agent.json"
}
},
"car_model": "Toyota Camry",
"booking_date": "2026-01-25",
"customer_info": {
"name": "John Doe",
"email": "[email protected]"
}
},
"id": 1
}' http://localhost:7860/ucp/mcp
示例响应
{
"result": {
"ucp": {
"capabilities": [
{
"name": "io.github.vishalmysore.car_booking",
"version": "2026-01-19"
}
],
"version": "2026-01-11"
},
"carType": "Toyota Camry",
"confirmationNumber": "ABC123XYZ",
"dropoffDate": null,
"dropoffLocation": null,
"pickupDate": "2026-01-25",
"pickupLocation": null
},
"id": 1,
"jsonrpc": "2.0"
}
实现说明
CarbookingController正确:
- 通过REST和MCP两种传输方式公开自定义能力
- 返回具有适当元数据的UCP兼容响应
- 处理预订参数并返回确认详细信息
注意:dropoffDate、dropoffLocation和 pickupLocation的 null值表明实现可能需要处理请求中的其他位置参数。
响应合规性
- MCP服务器根据UCP规范正确格式化响应
- 此响应结构是生产就绪的
- 预订能力将在
/.well-known/ucp的UCP配置文件中自动发现 - 对于自定义能力,REST和MCP传输都完全功能正常
设计考虑因素
注解驱动的方法
UCP实现中的注解驱动方法提供了自动能力发现、清晰的关注点分离和双重传输支持。
优势
- 自动发现:
UCPController自动扫描@UCPCapability注解并生成发现配置文件。这消除了手动配置,确保配置文件始终与代码同步。 - 清晰架构:在以下两者之间进行分离:
@Agent服务(仅MCP/A2A)@UCPBusiness控制器(REST + MCP)- 这强制执行了UCP的要求,即标准能力必须支持REST传输。
- 类型安全:注解提供编译时检查:
- 能力名称
- 版本格式
- 必需字段(规范和模式URL)
未来考虑因素
以下是我将在未来迭代中考虑进行潜在改进的领域:
- 验证复杂性:注解值(如YYYY-MM-DD版本格式)必须在运行时进行验证。控制器包含此逻辑,但它增加了复杂性。
- 框架耦合:该方法将业务逻辑紧密耦合到:
- UCP框架
- Spring的注解处理
- 这可能会使测试和移植更具挑战性。
- 运行时开销:启动时的注解扫描会增加初始化时间,尽管对于大多数应用程序来说这通常可以忽略不计。
实现质量和改进
当前实现通过以下方式很好地处理了复杂性:
- 强制执行单一商家:每个主机一个
UCPAware实现 - 命名空间验证:验证规范URL的命名空间权威性
- 自动配置文件生成:生成合规的发现配置文件
- 双重能力支持:支持标准和自定义能力
注解方法对于UCP特别有效,因为它自然地映射到协议的基于能力的设计,并实现了UCP所强调的动态发现。
未来方向
- 构建时验证:我将考虑添加更多的构建时验证,以便更早地捕获注解错误
- 解耦框架:探索将UCP逻辑与Spring解耦的方法,以提高可测试性
- 性能优化:研究具有许多能力的大型应用程序的缓存策略
- 增强工具:开发IDE插件以帮助注解使用和验证
- 模式生成:基于带注解的方法自动化扩展模式的生成
【注】本文译自:Universal Commerce Protocol (UCP) in Java: Building Agent-Enabled Commerce Workflows - DEV Community