S44:设计 v1 / v2 Tool Contract 与 Event Envelope
版本化契约把输入、输出、错误、副作用与演进规则写成双方可检查的约定,使 Agent 和企业系统可以独立升级而不靠提示词猜测。
内容类型:预习教材(不代表已完成)
日期:2027-01-05
阶段:P2 · AI Systems Engineering 90
总路线:Day 134 / 360
周次:W7 · Protocols & Enterprise Integration
节奏:周二最小实现
状态:教材已备;学习未完成
标签:contract-first、schema-evolution、event-envelope、versioning、compatibility
一句话定义
版本化契约把输入、输出、错误、副作用与演进规则写成双方可检查的约定,使 Agent 和企业系统可以独立升级而不靠提示词猜测。
学习目标
- 能为一个小工具定义 v1 输入、输出、错误和副作用语义。
- 区分工具契约版本、业务事件版本与传输协议版本。
- 判断新增字段、改名、收紧枚举和改变语义的兼容性影响。
- 设计一个包含 identity、correlation 和 idempotency 的事件 envelope。
核心知识
- Contract-first 不只是先写 schema,还要先明确业务语义:该操作是 query 还是 command,是否产生副作用,成功响应代表 accepted 还是 completed。
- 工具输入应优先使用有含义的类型、枚举和约束;描述必须指出单位、时区、货币、链 ID、敏感字段和默认值。
- 错误至少区分 validation、authentication、authorization、conflict、rate limit、dependency unavailable 和 unknown outcome,才能选择正确恢复动作。
- Event envelope 提供通用元数据;业务 payload 保存领域事实。将 trace、actor 和 schema version 混入每个 payload 会造成重复且不一致。
- 兼容性有 producer、consumer 两个方向。新增可选字段通常对宽容旧消费者安全;新增必填、删除字段、改变枚举语义或单位通常破坏兼容。
- v2 不应只是为了“看起来版本化”。若能以兼容新增表达,就先维护同一 major;真正语义断裂再并行支持和迁移。
机制与推导
一个简化 envelope:
{
"specversion": "1.0",
"id": "event-...",
"source": "case-system",
"type": "case.escalation.accepted.v1",
"subject": "case/123",
"time": "...",
"correlationid": "journey-...",
"causationid": "command-...",
"data": { "caseId": "123", "requestId": "biz-key", "status": "accepted" }
}
假设 v1 的 priority 是 low/high,v2 增加 medium。即使 schema 只是扩枚举,旧消费者若用 exhaustive switch 仍可能失败。因此兼容性不是只比较 JSON Schema;还要调查消费者行为。可用 consumer-driven 示例记录已知期望,但不要求建立重型契约测试平台。
最小练习或观察步骤
- 选择
submitCaseEscalation合成工具,写清 query/command、授权主体和成功语义。 - 定义 v1 的 4~6 个输入字段、输出和四类错误。
- 设计 v2 变化:新增可选
reasonCodes或改变一个字段,逐消费者分析兼容性。 - 为 accepted 事实写一份 event envelope,关联 command id 与 business key。
- 写一个旧消费者伪代码,验证新枚举为何可能破坏它。
- 不要求运行 schema generator;一页 YAML/JSON 与分析即可。
常见误区与边界
- 只有字段类型,没有单位、默认值、副作用和成功语义。
- 所有异常都返回
tool failed,runtime 只能盲目重试。 - 用 event id 代替业务幂等 key,生产者重发时生成新 id。
- 认为新增字段永远兼容,忽略严格解析器和签名计算。
- 原地改变同名事件含义,却不升级 type/version。
- 本日只做小契约,不建立覆盖所有企业标准的 canonical model。
系统 / 金融 / Web3 场景连接
金额字段若缺货币与最小单位,金融工具可能产生数量级错误;时间字段缺时区会破坏期限。Web3 工具必须明确 chainId、地址格式、原生单位、nonce 与操作是构造、签名还是广播;把三者都叫 sendTransaction 会隐藏完全不同的权限边界。
自检问题
- 工具成功响应到底可能表示哪些不同阶段?
- 为什么扩展 enum 仍可能破坏旧消费者?
- event id、command id 与 business key 分别做什么?
- 哪些变化值得 major version?
专业课程对齐
- 阅读 OpenAPI Specification 的 Operation、Schema、Responses 与 Security 相关章节导航,映射请求、响应、错误和授权声明。
- 阅读 AsyncAPI 官方文档 中 message、channel、operation 与 schema format,具体比较异步事件契约与同步工具契约的差异。
- 阅读 CloudEvents 官方站点 的 core attributes 与示例,观察
id/source/type/subject/time怎样形成通用 envelope,业务字段为何仍留在 data。
深入学习提示
从一个会破坏旧消费者的变化反推版本策略。阅读规范时只抓与本例有关的 operation、schema、message、event attributes,不需通读。深入时写出“生产者升级先/消费者升级先”两种顺序,检验是否需要双写、双读或过渡期。
学后填写区
- v1 契约与成功语义:
- v2 变化及兼容性:
- Event envelope 关键字段:
- 一个旧消费者风险:
- 未验证部分: