跳到主要内容
守卫者也要能失败

守卫者也要能失败

嘴替
嘴替

· 阅读约 3 分钟

速评:那篇 dev.to 长文我本来打算睡前随便翻翻,读到那个生产 bug 的时候坐起来了——一个网关校验检查永远返回 verified true,故意打的负对照样本也没能触发假结果,最后查出来的根因是一个游离的换行,把 assert 顶到了 return 后面。断言根本没执行。进程照常退出码 0。

八种调用方式跑完,五种放行的是假阳性。

这是最气人的一种事故,因为这单词条上写得明明白白,谁都可能犯,但一个"两三千测试全绿"的验证体系在它面前一点脾气都没有。全绿是因为空转,guard 睁着眼,没在看。

文章里给了个统计数字我当时就记住了:40 个 guard,7 个被证明能检测失败,0 个损坏,剩下 33 个——unproven。注意这个词不是"不能检测失败",是"没被证明过能检测失败"。两个完全不是一回事。7 个证明过能拦事的,33 个只是还没闯祸,这就是四十个把关人在场时,五十个缺位的那种状态的精确数字表达。

更妙的是后面评论区里 Ethan Walker 补的刀:他把那个 eval gate 对着 41 个已知退化重放了一遍,只抓住 23 个,而且在那十一个全绿周里,没有任何人测过它的命中率。一个都没测过。绿着,所以没人觉得需要跟它较劲。

这正好接上整篇文章最戳我的一层。社区有人把 reproducibility 和 falsifiability 分开讲——能重复同一个输出,不证明这个输出有意义;还有人补了 immutable evidence 不等于 immutable truth,证书能证明事件发生过,不能证明事件是对的。这两条本质上说的是同一件事:验证系统只对你跑过的东西负责,对它没跑过的东西,它给你一张绿票不等于它真的知道自己在放什么。

所以文章后半段的方案才会这么老实——每个 guard 必须声明一个负对照,那个对照必须非零退出。这句话的本质是要求每一个守卫者先证明自己具备失败的能力。能正常失败的守门员才谈得上守门,一个从来没拦住过任何东西的拦截器,你没法知道它是真的能拦,还是只是心软。

dual-arm verification 也是同一个逻辑的延伸——一条 claim receipt 要同时钉住一个跑的测试套件和一个故意弄死的 mutant,两个都钉住了才叫证据。这个思路比任何花哨的签名协议都值钱,因为它把验证从"证明我很厉害"翻了过来,变成"证明我服输"。

关于密码学签名那一段,我反而觉得讲得稍软了一点,但这不怪作者。签名能证明谁签的、什么时候签的、签完之后有没有被改——它就是不能证明内容是对的。很多人用的时候心里期待的是最后那个性能,这是签名协议被过度信任的根源,不只是 agent 领域,传统的软件供应链里同样的问题烂了十年了。

有个细节值得留意的是,dengyier 说 OpenWorkProof 用 STARTED_UNCONFIRMED 状态专门追踪那些走了一半最后不确定有没有完成的执行。这个状态名起得坦诚——不确定就标不确定,承认执行到一半有可能烂尾。这类"承认自己不知道"的状态设计,才是整个文章里唯一能对冲前文那 33 个 unproven 的东西。

最后立个 flag:那 33 个 unproven 的 guard 里,假如有人真去给它们挨个造负对照,我赌至少有 10 个会当场现出原形——不是坏了,是从来没被设计成能失败。这剧本我见过太多次了,一个门在你每次推的时候都向你敞开,你会慢慢把它叫成"验证通过",而不是"还没找到它挡住过什么"。