Skip to content
目录

关键设计决策和原因

概述

本文档深入分析 UCP 的关键设计决策,解释每个决策背后的原因、权衡和依据。这些决策共同构成了 UCP 的核心架构,使其能够解决电商生态系统的互操作性问题。

1. 能力(Capabilities)与扩展(Extensions)分离

决策

将核心功能(Capabilities)与可选增强(Extensions)分离,使用 extends 字段声明扩展依赖。

原因

  1. 避免能力定义臃肿:如果所有功能都放在基础能力中,Schema 会变得庞大且难以维护
  2. 支持渐进式增强:商家可以根据需要逐步添加功能,而不必实现所有功能
  3. 保持核心简洁:核心能力保持简洁,专注于基本功能
  4. 灵活组合:通过扩展机制实现功能的灵活组合

权衡

优势

  • 模块化设计
  • 易于扩展
  • 向后兼容

挑战

  • 需要 Schema 组合逻辑
  • 扩展依赖管理
  • 文档复杂度增加

依据

  • JSON Schema 的 allOf 组合机制
  • 软件工程中的关注点分离原则
  • REST API 设计中的资源扩展模式

2. 动态能力发现与协商

决策

商家通过 Profile 声明能力,平台通过请求声明 Profile URI,双方通过算法协商确定共同支持的能力。

原因

  1. 无许可集成:无需预先注册即可集成,降低集成门槛
  2. 自动适配:平台可以自动发现和适配商家能力
  3. 减少集成复杂度:从 O(N×M) 降低到 O(N+M)
  4. 支持快速迭代:商家可以快速添加新能力,平台自动发现

权衡

优势

  • 降低集成成本
  • 支持快速集成
  • 灵活的生态系统

挑战

  • Profile 获取开销
  • 协商算法复杂度
  • 缓存和性能优化需求

依据

  • Web 标准中的 .well-known 机制
  • OAuth 2.0 的发现机制
  • 分布式系统中的服务发现模式

3. 反向域名命名空间

决策

使用反向域名格式({reverse-domain}.{service}.{capability})命名能力和服务,将治理权限编码到标识符中。

原因

  1. 无需中央注册表:通过域名所有权自然建立治理关系
  2. 避免命名冲突:反向域名确保全局唯一性
  3. 清晰的治理模型:从名称即可知道谁负责该能力
  4. 支持供应商扩展:供应商可以使用自己的命名空间定义自定义能力

权衡

优势

  • 去中心化
  • 避免单点故障
  • 清晰的治理关系

挑战

  • 名称较长
  • 需要域名所有权验证
  • 供应商需要管理自己的命名空间

依据

  • Java 包命名约定
  • Android 应用 ID 命名
  • DNS 系统的域名所有权模型

4. 传输无关设计

决策

协议设计独立于传输层,支持多种传输协议(REST、MCP、A2A、Embedded)。

原因

  1. 适应不同基础设施:不同商家和平台有不同的技术栈
  2. 支持多种用例:AI 代理偏好 MCP,Web 应用偏好 REST
  3. 未来扩展性:可以添加新的传输协议而不影响核心协议
  4. 统一操作语义:无论使用哪种传输,操作行为一致

权衡

优势

  • 灵活性
  • 广泛的适用性
  • 未来扩展性

挑战

  • 需要定义传输绑定
  • 实现复杂度增加
  • 需要统一的错误处理

依据

  • OSI 模型的层次化设计
  • HTTP 作为应用层协议的设计
  • 抽象与具体实现的分离原则

5. 支付处理器抽象

决策

将支付工具(接受什么)与支付处理器(如何处理)分离,通过 Payment Handler 规范定义处理流程。

原因

  1. 解决 N-to-N 复杂度:从 O(N×M×P) 降低到 O(N+M+P)
  2. 解耦支付逻辑:平台不需要了解每个支付提供商的细节
  3. 支持新支付方式:新支付方式只需定义新的 Handler
  4. 最小化 PCI 范围:平台不接触原始支付凭证

权衡

优势

  • 大幅降低复杂度
  • 灵活的支付方式支持
  • 安全优势

挑战

  • Handler 规范定义复杂度
  • 需要支付提供商合作
  • 实现复杂度增加

依据**

  • 设计模式中的策略模式
  • 插件架构模式
  • 支付行业的令牌化实践

6. 客户端 Schema 解析

决策

平台必须在客户端获取和组合 Schema,而不是服务器端预组合。

原因

  1. 瘦传输定义:传输定义只引用基础 Schema,保持简洁
  2. 支持动态扩展:扩展可以独立发布和版本化
  3. 类型安全:通过 JSON Schema 提供类型验证
  4. 自描述:Schema 明确声明依赖关系

权衡

优势

  • 模块化 Schema
  • 灵活的扩展机制
  • 类型安全

挑战

  • 客户端解析开销
  • 多次 Schema 获取
  • 需要缓存机制

依据

  • JSON Schema 的 $ref 机制
  • 客户端驱动的 API 设计
  • 微服务架构中的服务发现模式

7. HTTP Message Signatures

决策

使用 RFC 9421 HTTP Message Signatures 作为主要的身份认证机制。

原因

  1. 无许可集成:无需预先建立信任关系
  2. 基于标准:使用成熟的 IETF 标准
  3. 不可否认性:提供加密签名保证
  4. 密钥发现:通过 Profile 自动发现公钥

权衡

优势

  • 支持无许可集成
  • 强大的安全性
  • 基于标准

挑战

  • 实现复杂度
  • 性能开销
  • 密钥管理需求

依据

  • RFC 9421 HTTP Message Signatures
  • 公钥基础设施(PKI)模型
  • OAuth 2.0 的密钥发现机制

8. 日期格式版本控制

决策

使用日期格式(YYYY-MM-DD)而非语义版本(如 1.2.3)进行版本控制。

原因

  1. 清晰的顺序:日期格式提供明确的 chronological ordering
  2. 避免歧义:语义版本号可能产生歧义(如 1.2.3 vs 1.2.4
  3. 易于理解:日期格式直观易懂
  4. 独立组件版本化:支持协议和能力独立版本化

权衡

优势

  • 清晰的版本语义
  • 易于版本比较
  • 支持独立版本化

挑战

  • 不能表达破坏性更改的程度
  • 版本号较长
  • 需要明确的兼容性规则

依据

  • API 版本控制最佳实践
  • 日期格式的清晰性
  • 独立组件版本化的需求

9. 服务器选择(Server-Selects)架构

决策

能力协商采用服务器选择架构,商家(服务器)决定激活的能力集合。

原因

  1. 商家控制:商家对自己的能力有最终决定权
  2. 简化客户端:平台不需要复杂的协商逻辑
  3. 安全性:商家可以基于安全策略选择能力
  4. 性能:协商在服务器端完成,可以利用缓存

权衡

优势

  • 商家控制
  • 简化客户端
  • 安全性

挑战

  • 平台需要信任商家
  • 协商结果可能不符合平台期望
  • 需要明确的错误处理

依据

  • REST API 设计中的服务器驱动协商
  • OAuth 2.0 的服务器选择模式
  • 安全最佳实践

10. Profile 缓存策略

决策

要求 Profile 支持公共缓存,最小 TTL 60 秒,不允许 privateno-storeno-cache

原因

  1. 性能优化:减少 Profile 获取开销
  2. 稳定性:Profile 代表稳定的身份和能力
  3. 防止滥用:防止恶意请求导致大量 Profile 获取
  4. 支持 CDN:允许使用 CDN 缓存 Profile

权衡

优势

  • 性能提升
  • 减少服务器负载
  • 支持 CDN 缓存

挑战

  • 更新延迟
  • 需要版本控制
  • 缓存失效策略

依据

  • HTTP 缓存标准(RFC 7234)
  • Web 性能最佳实践
  • CDN 缓存策略

11. 单向凭证流

决策

支付凭证只从平台流向商家,商家不得在响应中回显凭证。

原因

  1. 最小化 PCI 范围:减少接触支付凭证的系统
  2. 安全最佳实践:避免凭证在响应中暴露
  3. 防止重放攻击:单向流减少攻击面
  4. 合规性:符合 PCI-DSS 要求

权衡

优势

  • 安全性提升
  • 合规性优势
  • 减少攻击面

挑战

  • 错误处理复杂度
  • 需要不透明令牌
  • 调试困难

依据

  • PCI-DSS 合规要求
  • 安全最佳实践
  • 支付行业的令牌化实践

12. 扩展的 requires 字段

决策

扩展 Schema 可以声明 requires 字段来指示所需的协议和能力版本。

原因

  1. 版本依赖管理:明确声明版本依赖关系
  2. 兼容性验证:在运行时验证版本兼容性
  3. 防止错误使用:防止在不兼容的版本中使用扩展
  4. 文档化:Schema 本身文档化版本要求

权衡

优势

  • 明确的版本依赖
  • 自动兼容性验证
  • 防止错误使用

挑战

  • Schema 复杂度增加
  • 需要版本比较逻辑
  • 文档维护成本

依据

  • 软件包管理的版本依赖模型
  • API 版本控制最佳实践
  • 类型系统的版本约束

总结

UCP 的关键设计决策共同实现了:

  1. 模块化:通过能力和扩展分离实现模块化设计
  2. 灵活性:通过动态发现和传输无关设计实现灵活性
  3. 安全性:通过 HTTP Message Signatures 和单向凭证流实现安全性
  4. 可扩展性:通过命名空间和扩展机制实现可扩展性
  5. 性能:通过缓存策略和客户端解析实现性能优化

这些决策基于:

  • 成熟的 Web 标准和最佳实践
  • 软件工程的设计原则
  • 支付行业的安全要求
  • 分布式系统的架构模式

通过仔细权衡各种因素,UCP 实现了一个既灵活又安全、既强大又易用的协议。

MIT License.