通过具体失败案例说明:Schema验证只证明字段存在,无法证明值对应现实;溯源检查只能证明对象到达某节点,无法证明状态正确。
让我对这件事有具体认知的故障,简单到令人乏味。在一个确定性 fixture 中,一个生成 Agent 读取了错误的 Git 分支。它记录下的认证提供者和行数都与被交接的工作树不符。JSON 是合法的。它的溯源图是连通的。它的承诺可重新计算。两个独立实现的编码器产生了相同的语义世界。
七个检查都接受了这个制品。唯一提出拒绝的检查,来自于查看仓库而非交接本身的证据:
FAIL examples/common-mode-handoff.json
7 verified · 1 FAILED
structure ............. verified contract 0.1, 4 objects
identity .............. verified agent-b -> agent-c
checkpoint ............ verified cp-4412-02
provenance ............ verified 4 objects to repo@a1b2c3d4
retained constraints .. verified 2 MUST, 1 SHOULD
conflicts ............. verified none, 1 open
authority agreement ... verified 3 encodings agree
external truth ........ FAILED
EXTERNAL_RECEIPT_REJECTED
repository working tree at repo@a1b2c3d4 rejected this world
- auth.provider is okta-oidc in the tree, not auth0-oidc
- legacy.sessions counted 1843 rows, not 12
这不是生产事故,也不能说明 Agent 犯这个错的频率。没有语言模型产生这个结果。这些 Agent 和已知答案 oracle 是确定性 fixture,用来隔离一个边界:制品内部的协议不是对外部世界的观察。
当把"已验证"拆分成其中隐藏的不同声明时,这个边界变得更容易理解。
Schema 检查可以证明必填字段存在、值具有预期类型、文档具有合法形状。这些是有用的保证。它们让格式错误或不完整的输入在后续检查尝试解释之前就失败。
它们无法证明任何值对应于现实。在 fixture 中,错误的提供者和错误的行数和正确的一样符合 Schema。虚假内容不会仅仅因为它是假的就变成格式错误。
溯源检查可以证明每个断言都通过连通的、无环的边到达声明的权威根。它可以检测缺失的边、断开的引用或没有到达根的路径的声明。
它无法证明声明的根是生产者实际检查过的源。fixture 对错误的分支保持一致,所以它的溯源图是干净的。它证明了制品声称其事实来自哪里。它没有证明生产者查看了那里。
承诺将字节或结构化状态绑定到标识符。重新计算它可以证明状态自承诺以来没有静默改变。保留约束检查同样可以证明必填声明在交接中存活了下来。
两种检查都无法改进它所绑定的输入。错误分支的 fixture 忠实地携带了其不正确的状态,所以 checkpoint 和保留约束都通过了验证。完整性保护假值免于变更,其效果和保护真值一样有效。
两个实现可以编码同一个制品并就其语义含义达成一致。这比信任一个实现更强:分歧可以暴露歧义或一个编码器中的 bug。
但实现独立不等于观察独立。两个编码器都读取了同一个交接。在 fixture 中,它们就错误的提供者和行数达成一致,因为这些值是明确的。它们共同的输入创造了共模失效,第二次编码无法消除。
精确的结论是"这个制品有一个稳定的解释",而不是"这个解释描述了实际发生的事"。
外部收据不同,因为它咨询了另一个证据源。这里,仓库检查拒绝了交接中记录的提供者和行数。它是这次运行中唯一能够区分这个内聚制品与它声称描述的工作树的检查。
这并没有消除信任。收据可能检查了错误的 checkout,使用了过时的测试结果,或者编码了它自己的错误。外部证据将信任根转移到了一个更小的、具名的检查器。它没有让信任根消失。
还有一个有用的边缘情况。如果存在正确的前身,语义 diff 可以标记提供者和决策发生了变化。第一次交接没有前身。如果第一个记录的世界已经是错误的,就没有历史比较可用。外部源正在做本地一致性无法完成的工作。
我不再把验证当作一个裁决。
每一层现在都单独报告。强大的 Schema 结果无法弥补缺失的收据,协议也无法投票压倒外部证据。一个没有运行的检查报告未确立,而不是通过。收据保持它们自己的溯源,因为"外部"命名的是一个边界,而不是自动的质量保证。
这些规则适用于 Agent 交接之外。每当一个系统验证签名的清单、构建证明、迁移记录或结构化报告时,值得写下每一层检查所赢得的狭义句子——以及它无法赢得的更有诱惑力的广义句子。
我构建了一个名为 Babel Context Integrity 的小型验证器来使这个失效可执行。它检查结构化的 Agent 交接契约;它不是一个任意文本的真伪检查器或幻觉检测器。
python -m pip install babel-context-integrity==0.2.0
babelci demo
这个 demo 是离线的,包含上面的错误分支 fixture。Fixture 和验证器都是公开的,完整的局限性表说明了每个通过的层有权——无权——得出什么结论。
披露:我构建了 Babel Context Integrity。我使用了一个 AI 编程助手来帮助编辑这篇文章,然后对照公开的 0.2.0 包检查了技术声明和命令输出。