Agent 工具版本演进:契约测试、兼容窗口与审批失效 @ Lin | 2026-10-28T08:00:00+08:00 | 4 分钟阅读 | 更新于 2026-09-16T08:00:00+08:00

把工具 schema、业务语义和审批记录一起纳入版本管理,防止升级后的工具错误解释旧任务。

工具 schema 没变,业务语义也可能变了

某个创建工单工具的参数一直是 projectId、priority 和 summary。新版本把 priority 从“数字越大越紧急”改成“数字越小越紧急”,JSON Schema 仍然合法,旧任务却会产生完全相反的业务效果。

因此工具升级不仅是接口字段的增删。默认值、单位、权限范围、副作用和错误含义都会影响 Agent 决策,尤其是已经规划完或正在等待审批的长任务。

版本治理要同时覆盖工具定义、调用执行和历史任务恢复,而不是只记录一个 SDK 依赖版本。

区分协议版本与业务契约版本

MCP 工具规范提供工具发现、调用、输入 schema 和可选输出 schema 等机制。协议版本描述交互规则,不等于业务工具自身的语义版本。

应用可以维护额外的工具注册信息:

toolId: create-ticket
contractVersion: 2
inputSchemaDigest: sha256-demo-input
outputSchemaDigest: sha256-demo-output
behaviorVersion: priority-semantics-v2
permissionPolicy: ticket-write-v3
implementationRevision: example-revision

这是自定义注册表,不是向 MCP 标准工具对象随意添加字段的建议。摘要值为占位示例,生产中应使用明确的规范化与哈希过程生成。

运行时绑定的是一组实际契约,而不只是工具名。实现补丁是否需要改变语义版本,取决于可观察行为;权限收紧即便不改 schema,也应让执行阶段重新验证当前授权。

用兼容矩阵讨论变更

变化 可能影响 建议处理
增加可选输入字段 旧调用通常仍可工作,但默认值可能改变行为 验证默认行为和提示选择
增加必填字段 旧计划不具备完整参数 新版本工具或显式适配
改变金额、时长单位 类型相同但语义不兼容 升级语义版本,禁止隐式猜测
增加输出字段 严格解析器可能拒绝 检查消费方容忍规则
增加错误类型 重试决策可能改变 更新错误分类与恢复测试
扩大写入范围 原审批不一定覆盖新副作用 新提案与重新审批

“新增字段向后兼容”必须附带前提。若旧消费者禁止额外字段,或新增字段使模型选择不同动作,仍然可能出现回归。工具描述文字变化同样值得评测,因为它直接影响模型何时调用工具。

契约测试分开验证三类行为

第一类是结构:允许和拒绝的参数样本、输出格式和错误码。由代码校验,避免将所有问题交给模型评判。

第二类是语义:使用固定业务数据检查优先级、单位、默认值和资源范围。例如输入 2 小时后,下游不能保存成 2 分钟;查项目 A 的工单时,不能包含项目 B 的记录。

第三类是决策:在相同任务样本上观察模型是否选对工具、是否新增无关调用、是否因描述变化而绕远路。结构契约通过不代表决策行为没有退化。

测试环境要使用模拟写工具或隔离业务数据。回放真实执行轨迹时,将已记录观察作为输入,不能为了测试兼容性重复触发生产副作用。

审批绑定不可变提案

待审批任务保存提案正文、工具契约版本、参数摘要和批准范围。执行时从服务端读取原提案,不让模型重新生成一份“意思差不多”的参数。

如果旧提案仍有对应实现,可在兼容窗口内按旧契约执行,同时重新检查当前权限。若工具行为已经变化,应该生成新提案并请求确认,不能将旧审批自动挪到新版本。

安全修复也可能要求旧版本立即停止服务,此时“锁定旧版本”不能成为继续调用已撤销能力的理由。任务进入需要重新规划或人工处理的状态,明确说明哪个条件已失效。

可以关联此前的人工审批与幂等执行设计:审批身份、业务操作 ID 和工具版本分别承担不同职责,不能互相替代。

工具目录变化不等于任务已迁移

支持相应能力的 MCP 服务可以发送工具列表变更通知,客户端刷新目录后看到新定义;这并不会自动迁移已经持久化的计划、上下文和审批记录。

客户端缓存应有失效策略。收到目录变化后,新任务使用新的目录快照,旧任务则根据兼容规则继续或暂停。执行器最终还要核对请求指定的契约是否仍可用,不能只依赖几小时前发现的工具列表。

版本退役前统计仍引用旧契约的运行任务、审批提案和重试事件。明确兼容窗口结束后怎样处理这些对象,避免旧消息到达时被新逻辑错误解释。

一次版本升级应该留下什么证据

准备一组旧版本成功样本和故障样本,在新版本上执行结构、语义和决策对照。故意改变一个默认值,检查测试能否发现;让一个旧审批在升级后恢复,检查执行器是否识别版本冲突。

再模拟工具列表通知丢失,确认执行器不会因为客户端缓存过期而接受不兼容调用。发布记录关联契约差异、评测结果、兼容期和回滚条件。

这篇可以与Agent 版本发布流程一起阅读。发布清单负责说明运行了哪一套组件,契约治理负责说明这套组件能否正确理解旧任务,两者共同决定升级是否可控。

© 2019 - 2026 Lin 的博客

Powered by Hugo with theme Dream.

avatar

Lin 的博客 A merry heart goes all the way.

关于我

Lin 的 ❤️ 博客

技术专题:Java Agent 工程化:从知识库问答到可靠业务执行。围绕 RAG、工具治理、任务恢复与 Java 平台架构整理设计思路和验证方法。

记录一些 🌈 生活上,技术上的事

  • 🛠️ 技术阵地: 深耕 Java 开发 ,目前向 AI 应用领域探索与拓展。这里主要记录我从后端架构到 AI 赋能的进阶之路、技术思考以及日常的 debug 血泪史。始终致力于写出优雅且没有 bug 的代码(尽量)。
  • 🌈 生活侧写: 偶尔脱下极客的外衣,我也会在这里分享生活中的灵光一现。不管是好用的效率工具,还是周末的一场骑行,都是构成我真实生活的一部分。