作者提出用「Proof Kernel」替代盲目信任模型输出,在 Agent 每步输出后强制验证,而非依赖更大模型来减少错误,引用论文证明验证是自主性的前提。
我信任过的每一个 Agent,最终都做过我没让它做的事。不是恶意——只是自信地错了。它在错误的表上写了正确的 SQL。它"修复"了一个配置文件,导致 staging 宕机。它把一个失败的工具调用重试了十四次,因为没人告诉它停下来。
常见的答案是换更好的模型。我不买账。问题不在模型,在于信任本身。我把 LLM 的输出当作已经是正确的,然后用它不正确时感到惊讶。
真正有效的修复方案是:停止信任输出,改为验证输出。每个 Agent 输出在被接受之前都要经过一个 proof kernel。模型提议,kernel 裁决。
有一篇论文把这个概念形式化得比我更清晰——"AI with Authority, from Application to Silicon"(https://arxiv.org/abs/2608.21356v1)。他们称之为 Salt 方法,在每一层运行验证,从应用层一直到硅层。其核心观点是:验证不是最终的 QA 步骤——它是使自主性成为可能的东西。Agent 只有在其产生的每个输出都经过一份它无法争辩的契约检查后,才能被信任来无人值守地工作。
这和我过去一年手工做的一致,所以让我给你实际操作的版本。
这是人们搞错的地方。他们构建的"验证器"只是第二个 prompt——"检查这个输出是否正确"——然后当第二个模型同意第一个模型的结论时感到惊讶。那不是验证,那是两个人互相点头。
proof kernel 是确定性的。它是一段代码,接受 Agent 的输出并根据正式契约进行检查。没有判断,没有感觉。要么通过,要么不通过。
具体来说,我是这样做的。我运行一个 Agent 来编写针对数据仓库的 SQL。kernel 会:
如果任何检查失败,输出就会被拒绝。不是修复,不是轻轻推一下——是拒绝。Agent 收到拒绝原因,然后重试。这就是那个循环。
另一个例子:编辑代码文件的 Agent。kernel 将提议的变更与 Agent 被允许操作的文件的清单进行 diff,拒绝任何超出范围的内容。它还会在变更被接受之前运行 linter 和测试套件。Agent 不能合并任何未通过检查的内容。
这是诚实的地方。写 kernel 很容易。写契约——那个定义"正确"意味着什么的规格说明——才是真正的工作。这很无聊,很繁琐,但 90% 的价值就在这里。
模型是便宜且快速可替换的部分。契约是你两年后仍需维护的部分。如果你不愿写契约,你就得不到自主性。这是交易,而且这不是一个坏交易。
它有延迟成本。每个输出都必须被检查,而检查不是免费的。对于我的 SQL Agent,kernel 大约增加 100 毫秒。对于代码编辑 Agent,测试套件是瓶颈——那是分钟级,不是毫秒级。你必须决定 gate 放在哪里。
它也有灵活性成本。proof kernel 对于真正开放式的任务是错误的工具。如果你的 Agent 的工作是"帮我写一份战略备忘录",没有什么契约可以检查它,kernel 就是无意义的。但大多数生产环境中的 Agent 不是开放式的。它们在做一份有定义契约的狭义任务——如果你写不出契约,你可能本来就不应该无人值守地运行那个 Agent。
让我惊讶的是:kernel 使得无人值守操作成为可能。在此之前,我一直在看守——盯着日志,等待 Agent 做出奇怪的事情,准备杀掉进程。有了 kernel 之后,我不再盯着了。Agent 可以重试、循环、通宵工作,因为每个被接受的输出都经过了验证。失败仍然会发生,但它们发生在循环内部,那里成本低廉,而不是在生产环境中,那里成本高昂。
Salt 论文关于在每一层验证——从应用到硅——的观点,是同样的原则向下延伸。如果你只验证最终输出,你就会错过中间发生的 bug。Agent 调用一个工具,得到一个结果,然后基于一个幻觉的中间值做出决策。最终输出可能看起来没问题。顶层的 kernel 不会捕获它。你需要在边界处检查,而不是只在末尾。
我还没有端到端地运行 Salt——论文还很新,我不打算假装我已经部署了它。但核心动作——验证作为使自主性安全的 gate——我已经在生产环境中运行了一年。这是一个我监督的 Agent 和一个我信任的 Agent 之间的区别。
模型提议,kernel 裁决。这就是全部建议。