Schema 熵:为什么你的工具定义正在生产环境中腐烂
你的 Agent 在 1 月份时运行良好。到了 3 月,它开始在 15% 的工具调用中失败。到了 5 月,它在另外 20% 的情况下会静默地产生错误输出。你的部署日志没有任何变化。没有人动过 Agent 的代码。工具定义看起来和六个月前一模一样——而这恰恰就是问题所在。
工具 Schema 并不需要被修改才会出错。它们所描述的服务在底层发生了变化。Enum(枚举)值增加了。后端重构使必填字段变成了可选字段。以前接受字符串的参数现在需要 ISO 8601 时间戳。Schema 文档保持冻结,而底层的 API 却在不断演进,你的 Agent 仍在自信地调用它,完全不知道契约(contract)已经发生了变化。
这就是 Schema 熵(Schema entropy):你的 Agent 接受训练时所使用的工具定义与生产环境服务实际表现出的行为之间逐渐产生的差异。它是生产环境 AI 系统中最被低估的可靠性问题之一,研究表明,工具版本控制问题约占生产环境 Agent 故障的 60%。
Schema 熵到底是什么样子的
Schema 熵并不是单一的失败模式,而是一类具有共同根源的失败。
最显的形式是硬中断(hard break):你重命名了一个必填参数,Agent 立即开始生成会导致 400 错误的调用。这些实际上是容易处理的情况。你能看到失败,找到不匹配的地方,然后修复它。
更危险的形式是软腐化(soft rot)。考虑以下场景:
- 你在
status字段中添加了一个新的枚举值PENDING_REVIEW。你的 Agent 的工具描述中仍然只列出了发布时已知的四个值。当 API 开始返回PENDING_REVIEW时,Agent 会尝试用其现有的思维模型去理解它——有时能通过推理正确处理,有时则不能。 - 你将一个以前必填的参数改为可选。省略该参数的调用现在在 API 层级可以成功,但在后端会触发不同的行为。你的 Agent 并不知道存在这个分支。
- 你将一个字段从接受纯整数改为需要字符串格式的整数(
"42"vs42)。API 会在一段时间内静默地进行强制转换,然后某次框架升级停止了这种转换。在后端更改几周后,Agent 的调用开始出现晦涩的类型错误。 - 你在现有的工具(
search_positions)旁边添加了一个更具体的同级工具(search_position_budgets)。在你的工具清单中,两者看起来很相似。Agent 开始混淆它们,将 30% 的预算查询路由到了错误的端点。
关于 Agent 工具测试的研究恰恰发现了最后一种模式:通过改进工具描述来更好地区分相似工具,对 Agent 准确性的提升比改进 Agent 自身的逻辑更大。描述本身 就是那个 Bug。
为什么 Agent 是不称职的 Schema 消费者
当人类开发者调用带有过时 Schema 的 API 时,工作流包括阅读错误消息、查阅更新后的文档并进行调整。Agent 默认情况下没有这种恢复循环。它们在运行开始时接收工具定义,并在整个过程中将其视为绝对真理(ground truth)。
更关键的是,Agent 失败的方式在结构上与代码失败不同。一项针对 Schema 优先工具 API 的对照研究发现,区分以下三类失败非常有用:
- 接口误用(Interface misuse):结构畸形的调用——错误的类型、缺失必填字段、幻觉出的参数名称。这些是正式 Schema 可以预防的失败。
- 执行失败(Execution failures):调用结构正确,但触发了 Agent 不知道的运行时前提条件。
- 语义误用(Semantic misuse):符合 Schema 规范但在逻辑上对于任务是错误的调用。Agent 使用正确的结构调用了正确的工具,但使用了语义上错误的值。
Schema 熵主要导致第 2 和第 3 类失败。一个工具定义在语法上可能是正确的,但仍会引导你的 Agent 做出错误的行为,因为 Schema 的含义已经偏离了服务的行为。
一个顽固的可观测性问题加剧了这种情况:许多 API 即使在操作失败时也会返回 HTTP 200。StackOne 关于 Agent 测试的研究发现,埋在响应体中的速率限制错误(以 {"status": 200, "data": null} 形式返回)被 Agent 理解为“不存在记录”,而不是“请求失败”。当 HTTP 的成功不代表业务逻辑的成功时,你的 Agent 就无法获得 Schema 已将其引入歧途的信号。
Schema 腐化开始的三个地方
了解熵是从哪里进入系统的,就能知道应该在哪里部署防御。
外部服务。 你无法控制第三方 API 何时更改其 Schema。支付处理器会增加新的扣费状态,CRM 会演进其联系人模型。每一个外部工具依赖都是潜在的 Schema 腐化向量,而且当它们的 API 发生变化时,你不会收到 Webhook 通知。
跨团队边界的内部服务。 后端团队重构了一个服务端点。他们更新了 API 文档。但他们没有更新同事六个月前在另一个仓库中编写的 LLM 工具定义。这是实践中最常见的场景——工具定义存在于 Agent 代码附近,而它们描述的服务则存在于别处。
模型侧的变化。 模型提供商的更新可能会改变模型解析 Schema 的方式。强制执行严格模式(Strict mode)、对可选字段处理方式的变化、模型处理模糊枚举值时的行为差异——即使你的 JSON Schema 字节没有变化,这些也会改变实际生效的契约。
工具 Schema 的向后兼容规则
核心原则是非对称的:增加永远是安全的,移除永 远是不安全的,而更改则取决于具体方向,有时安全。
安全变更:
- 添加带有文档说明默认值的新可选参数
- 添加新的枚举值(如果 agent 在遇到未知值时可以优雅地处理失败)
- 在清单中添加全新的工具
- 将之前的必填参数改为可选(前提是默认行为对于现有的调用模式是正确的)
破坏性变更:
- 移除或重命名任何参数
- 将可选参数改为必填
- 更改现有参数的类型(即使在传输层面技术上是兼容的)
- 移除 agent 目前可能正在发送的枚举值
- 在不更改参数名称的情况下更改其语义
- https://arxiv.org/html/2603.13404v1
- https://www.stackone.com/blog/ai-agent-testing-failures/
- https://medium.com/@nraman.n6/versioning-rollback-lifecycle-management-of-ai-agents-treating-intelligence-as-deployable-deac757e4dea
- https://mindra.co/blog/ci-cd-for-ai-agents-testing-deployment-pipelines
- https://collinwilkins.com/articles/structured-output
- https://www.dataexpert.io/blog/backward-compatibility-schema-evolution-guide
- https://snowplow.io/blog/introducing-schemaver-for-semantic-versioning-of-schemas
