工具结果 Schema 演进:Producer 与活跃 Consumer 兼容矩阵
新结果通过最新 validator,不代表仍在线的旧 Agent、渲染器和审计任务都能读取。本文把 producer revision、真实消费者集合、解码证明和 representation 路由组成工具结果专用兼容门。
本文要点
- 主题聚焦:AI Agent、MCP、TypeScript
- 适合人群:独立开发者、全栈工程师、AI 应用开发者
- 核心价值:快速理解背景、实践路径、常见误区和工程建议
工具把 status: "open" 扩展出 "deferred",producer 的新测试会通过,旧 Agent 中穷举 switch 却可能抛异常;把缺失的 nextCursor 改成 null,UI 也许开始无限翻页。所谓“只增加字段”还会撞上严格反序列化器。结果兼容性必须从仍在生产读取它的 consumer 行为判断,而不是由 schema 作者单方面宣布。
MCP 工具 Schema 设计讲输入输出字段的基本形状,Agent 工具输出防线阻断超大、恶意或跨租户内容。本篇假定结果已经可信,专门回答同一个工具的 producer、Agent planner、UI、日志转换器和异步任务处于不同版本时,哪种表示可以被谁消费。
合同要同时登记表示与语义
每次发布不可变 toolResultRelease.v1,绑定稳定 tool ID、descriptor digest、representation ID、schema dialect、schema digest、语义 revision、producer artifact、字段生命周期、错误模型和支持窗口。schemaRevision 描述机器结构,semanticRevision 标记单位、排序、空值、截断或枚举含义变化;结构不变但金额从分改成元也必须升级语义版本。
schema: toolResultRelease.v1
tool: ticket.search
release: 4
representation: ticket.search.result.v3
dialect: https://json-schema.org/draft/2020-12/schema
schemaDigest: sha256:3b8...
semanticRevision: 6
producer: ticket-mcp@sha256:77a...
predecessor: ticket.search.result.v2
MCP 工具可声明 outputSchema,结果可在 structuredContent 返回结构化内容;声明 schema 时,Server 应让结构化结果符合它。为兼容旧客户端,规范还建议同时提供序列化 JSON 的文本内容。这个兼容表示必须由同一规范对象确定性生成并共享 result digest,不能让两套手写 mapper 给出不同事实。JSON Schema 2020-12 的 dialect、vocabulary、引用闭包和格式断言模式都纳入 digest;仅写“JSON Schema”不足以复现验证。
活跃消费者集合必须来自证据
兼容注册表维护 consumerAttestation.v1:consumer ID 与制品摘要、owner、读取的 tool/representation、parser 配置、接受 revision、fixture root 和到期时间。activeConsumerSetGeneration 取以下集合的并集:签名部署/制品清单、排程与队列订阅、受支持客户端最低版本、灾备镜像、owner 声明,以及网关观测流量。30 天观测只能发现漏登记项,不能删除月度任务、离线 worker、休眠客户端或灾备 reader;它们必须由 owner 提交带版本的退役 receipt 后才移除。身份不从 User-Agent 推断,无归属流量进入 UNKNOWN_CONSUMER 并阻断破坏性切换。
矩阵至少运行四个方向:旧 consumer 读旧/新 producer,以及新 consumer 读旧/新 producer。夹具包含成功、业务错误、空列表、分页、截断、未知枚举、大整数、null 与 absent、字段重排和额外字段。兼容不等于“能 parse”:consumer 的决策 oracle 还要保持一致,例如未知状态必须降级为 UNKNOWN,不能误当 CLOSED;游标缺失不能被解释成第一页。
Protobuf 二进制演进中不得复用 field number,删除字段应保留编号和名称;未知字段可在二进制消息链路中保留,但经过 JSON 转换时可能丢失,因此 protobuf 测试通过不能证明 MCP JSON consumer 安全。增加 enum、改变数值类型或切换表示都按实际 reader 测试。通用 REST 与事件变更可参考Agent 改 API 的契约兼容门,本矩阵额外限定到工具调用 receipt 与同一会话中可能并存的 planner/renderer 版本。
激活 Producer 只有一个接受点
release 状态为 DRAFT -> SHADOW -> COMPATIBLE -> ACTIVE -> DEPRECATED -> RETIRED。唯一接受点是注册表事务对 (toolId, representation) 的 producer alias 做 CAS:候选的跨版本矩阵全部通过,activeConsumerSetGeneration 未变化,所有有效 consumer attestation 覆盖候选或已有可验证 bridge,UNKNOWN 流量为 0,才能切换 alias 并写 activation receipt。若验证期间新 consumer 上线,generation 比较失败,候选重新跑矩阵。
调用网关按认证 consumer ID、协商的 representation 和 active alias 选择 producer;receipt 保存 consumer artifact、release、schema/semantic revision 与 result digest。Agent 工具能力目录把 output descriptor digest 绑定到计划,实际返回仍以这里的路由 receipt 为准。未协商客户端只获得声明的 legacy 表示,不能默认投递最新结构。
迁移可先让新 producer shadow 生成 v3 但仍交付 v2,比较两个表示的规范事实;随后给已证明兼容的 1% consumer 开启 v3。必要时用有期限的 down-converter,但它必须对无法无损表达的新枚举明确报 UNREPRESENTABLE,不能静默改值。旧 reader 与旧 producer 持续消费回归样本,直到支持窗口和真实流量都归零。
用消费者漂移击穿假兼容
故障注入包括严格拒绝未知字段的旧 decoder、未知 enum 穷举崩溃、null/absent 互换、大整数越过 JavaScript 安全范围、文本与 structuredContent 不一致、缓存旧 schema、consumer 在切换事务前加入、attestation 过期、bridge 漏字段和 rollback 后新 consumer 只会读 v3。Agent 回放评测可重放真实工具轨迹,但 oracle 必须按 consumer artifact 分层。
门禁要求部署、排程、订阅、客户端支持窗与灾备清单覆盖率 100%,其并集中的 consumer 结构与语义夹具通过率 100%,UNKNOWN 流量为 0、两种 MCP 表示 digest 分歧为 0、静默转换为 0。若出现一次错误决策或解码率超过 0.01%,CAS 回切上一 producer alias;回切前确认新 consumer 仍能读旧表示,否则先启用已验证 bridge。旧 schema、producer 与 fixture 至少保留完整支持窗口,不能把数据库备份当回滚方案。
Related