一百万条断言无法裁决的事
Bun 在十一天里靠 AI 对抗式审查从 Zig 重写成了 Rust —— 一个真正的里程碑,也值得细读,因为它讲清了你如何去不信任一台机器的产出。他们的方法和我们的看起来不一样,而这个差别不是口味问题:它由什么东西能当裁判所决定。Bun 有 1,386,826 条测试断言和六平台 CI,所以一套能通过的套件可以裁决正确性,于是他们在单一模型家族之内用 context window 来隔离审查者。StrayMark 审计的是那种"正确答案"是一次判断、没有测试能裁决的改动 —— 所以我们跨模型家族做多样化,并把它们独立的趋同当作信号。Sentinel 项目里 25 个真实的审计周期展示了这买到了什么、它抓到了绿色测试漏掉的什么,以及 —— 作为趣闻 —— 七个不同的模型家族到底表现如何,包括一个不得不因为悄悄变瞎而被降级的家族。
同一个 Charter 上的 v0 周期产出了 0 个实质性 finding。同一份代码上的 v1 周期,用同样的审计模型家族,产出了 1 个已验证的 runtime-fatal bug 外加 3 个更深的 finding。文件系统工具使用和完整的 git range,把基于粘贴文本的表演变成了真正的工程审查。
这是 审计以为自己是谁 的一段尾声 —— 那篇讲的是把审计的归因做到无法伪造;这篇讲的是审计到底做了什么,带着数字。它是被 Bun 用 Rust 重写的那篇 post 触发的,那篇描述了一套规模值得认真对待、也值得诚实对比的 AI 审计方法论。
不信任一台机器的两种方式
Bun 的流程设计得很漂亮。Jarred Sumner 在 11 天里用大约 50 个 Claude 动态 workflow 重写了 Bun:一个实现者、两个或更多对抗式审查者、一个 fixer,审查者跑在分开的 context window 里并被要求假定代码是错的 —— 因为"写代码的那个 Claude 想让代码被接受;做审查的那个 Claude 想找到 bug。"峰值时,约 64 个 Claude 分布在 4 个 git worktree 上;6502 个 commit;约 $165,000 的 token。而承重的部分是:这一切都立在一个客观的神谕之上 —— Bun 的测试套件是用 TypeScript 写的,所以不依赖 runtime 的语言;1,386,826 条 expect() 断言、跨 60,624 个测试在全部六个平台上通过之后,Sumner 才"按下 merge 按钮",并且他还亲手核实了测试没有被跳过。
最后这个事实,正是让单一家族、分裂上下文的设计对这项工作恰好正确的原因。一次 Zig→Rust 重写是一个保持行为的 port:"正确"有一个干净、机器可核对的定义。对抗式审查者不必是最终定论,因为那套百万断言的套件才是。靠上下文实现的独立性就够了,因为审查者漏掉的任何东西,神谕都会抓住。
StrayMark 审计的是那个神谕不存在的情形。大多数工程不是 port;问题是这是对的设计吗?它在并发下扛得住吗?这个契约还和定义它的那个决策一致吗? —— 这些判断没有任何套件能裁决。当审查本身就是神谕时,一颗心智的盲点是不可见的:如果你唯一的审查者对某一类 bug 系统性地视而不见,下游没有任何东西会抓到它。所以 StrayMark 的审计周期沿着 Bun 不需要的那条轴做多样化 —— 模型家族 —— 并把跨家族的独立趋同当作最强的信号,由一个单独的 calibrator 模型来对账各份报告并给审计者评分。
| Bun 重写审计 | StrayMark 审计周期 | |
|---|---|---|
| 由什么裁决"正确" | 一个客观神谕 —— 1,386,826 条测试断言,6 平台 CI | 一次人类主导的判断;没有测试能裁决 |
| 独立性来自 | 分开的 context window(作者 vs. 对抗式审查者) | 分开的模型家族盲审,外加上下文分离 |
| 模型多样性 | 一个家族(Claude / Fable 5),许多实例 | 语料里七个家族 —— gpt、gemini、glm、qwen、claude、deepseek、kimi |
| 对账 | 一个 fixer 应用审查者的意见 | 一个 calibrator 模型来合并、去重,并给每个审计者评分 |
| 人类 | 盯着 loop、核实测试跑了、按 merge | 主导身份、裁定趋同、决定关闭 |
两者没有"更好"之分。它们校准到不同的目标。Bun 的那种,是当一套套件能当裁判时正确的形状;我们的这种,是当它不能时你需要的形状。
为什么是家族多样性,而不只是上下文
先给出论点,再给出支撑它的数据。如果审查者是最终裁判,而你只跑一个模型家族,你就是在赌这个家族没有任何系统性盲点。这个赌注从内部无法核对 —— 盲点按定义就是你看不见的那个东西。把它逼出来的唯一办法,是去问一颗不同的心智,并注意到那个分歧。跨家族的多样性不是关于冗余;它是关于把盲点变得可被表示。
Sentinel —— StrayMark 治理并在其上做 dogfood 的项目 —— 至今已经跑了 25 个审计周期,跨 21 个 Charter、68 份审计者报告、七个模型家族,从 2026-05-05 到 2026-07-10。而数据表明独立性在做真活。在被合并的 finding 里,大约 70% 只由一个审计者提出 —— 不同家族确实浮现出不同的东西 —— 而那 ~19% 跨家族趋同的,恰恰是 calibrator 标记为最高置信的部分。引自 CHARTER-40 的 review:"预算上限是一个非原子的 check-then-act —— 由 gpt-5-codex 和 claude-fable 各自独立发现,最强的趋同信号。"
审计抓到了、而绿色测试没抓到的东西
这一切的重点是软件质量,所以这里就是质量,量化版。在那 25 个周期里:211 个原始 finding,合并为 169 个,按类别拆分为 92 个 implementation-gap、89 个 real-debt、23 个假阳性、6 个幻觉。在 Sentinel 的 188 条 follow-up 里,55 条提到某次审计;它四条技术债里的三条直接追溯到审计 review(其中一条 —— CommsHub 里一个声明了却从未真正被调用的 scope guard,一个鉴权漏洞 —— 被提升为 TDE 随后解决)。
但这些数字低估了它。反复出现的主题是那种绿色测试套件和人类审查都放过的缺陷,因为它们不是测试在盯着的那类东西:
- **一个 runtime-fatal 的 SQL bug(
CHARTER-07)。**一个作用在COALESCE(col, '')表达式上的ON CONFLICT子句,Postgres 在 runtime 会拒绝它 —— "最早的消费者 Charter 在第一次写入尝试时就会撞上它。" 编译门在结构上无法看见一个 SQL 语义错误。gpt-5.3-codex抓到了;gemini漏了。 - **绿色套件下的一个并发竞态(
CHARTER-17)。**实现发布时是 "build + vet + 单元 + 集成套件全绿,12/12 声明任务。" 审计者仍然找到一个在 READ COMMITTED 下的SELECT-然后-INSERT,两个副本都看到isNew=true—— "重复的副作用:管理员邮件、法律文本发送" —— 并对照cloud-run.yaml真实的多实例拓扑加以确认。任何单节点测试都永远复现不出它。 - 一个被自己的测试掩盖的、阻塞生产的 bug(
CHARTER-42)。SafeMode的测试 "通过注入一个宽容的假 MCP 客户端把它掩盖了。" 绿色,而错误。 - **LLM 安全类 finding(
CHARTER-40)。**一个AUTO动作让模型对一个由模型自己挑的邮箱执行全局压制;模型的自由文本推理被持久化进一行审计记录,"被标为PIIRedacted: true,却从未经过 redactor。"
而单个最有说服力的数据点,是同一个 Charter 上一次天然的前后对照:遗留的 v0 审计周期 —— 基于粘贴文本、无工具使用 —— 产出了 0 个实质性 finding;v1 周期,同样的代码、同样的模型家族,但带上文件系统工具使用和完整的 git range,产出了那个 runtime-fatal 的 SQL bug 外加三个更深的 finding。是方法论,而不是模型,把"看起来没问题"变成了一个被抓住的生产缺陷。
一则趣闻:七个家族到底怎么表现
因为每份 review 都用一套固定的评分标准给它的审计者打分 —— scope 精度(25%)、技术深度(25%)、bug 检出(30%)、假阳性率(20%) —— 这份语料也顺便成了一份坦白的行为记录,尽管样本小、时间有限。跨 25 个周期聚合:
| 模型家族 | 审计次数 | 提出的 finding | 评分区间 | 一句话 |
|---|---|---|---|---|
| gpt(5.2 / 5.3 / 5-codex / 5.5) | 26 | 99 | 7.6 – 9.8 | 主力 —— 跑了 go build/go test,抓到实质性 bug,"扛起了这次审计"。 |
| glm(5.1 / 5.2) | 6 | 37 | 7.9 – 9.4 | 强势新人;高产,偶有假阳性膨胀。 |
| claude-fable-5 | 2 | 24 | 8.4 – 9.2 | 唯一真去跑了所声明验证命令的审计者;倾向于把严重度评低。 |
| qwen(3.7-max / plus) | 6 | 23 | 5.5 – 9.0 | 起伏不定;在后端和密钥管理批次上很强。 |
| gemini(2.5-pro、3.1-pro、cli) | 24 | 19 | 2.1 – 10 | 见下 —— 那个有教训的告诫。 |
| deepseek-v4-pro | 2 | 5 | 6.4 – 6.7 | 深度中等。 |
| kimi-k26 | 1 | 4 | 5.4 | 把两处严重度评高了,漏掉了实质性 finding。 |
gemini 这一行才是为整个设计正名的那一行,而它在语料里被作为一个被跟踪的模式记录着(FU-030-003)。在 24 次审计里它总共只提出了 19 个 finding —— 而且更要命的是,它总在漏掉真的那些。calibrator 在四个周期里把它从一个观察升级到一条正式建议:"降级为 advisory-only…… 在 integration-gap 类 finding 上不可靠 —— RLS 绕过、缺失的接线、约定漂移。" 在一次安全审计里它得了 2.1/10,因为它 "九个真实 finding 一个都没检出,还肯定地把那个 guard 错描成在强制优先级 —— 一个被幻觉出来的虚假保证,对一次安全审计而言是主动误导的。" 它在那一类上被测得的检出率徘徊在 四分之一 左右。
停下来想想这意味着什么。假如 Sentinel 在那个家族上跑一次单一家族的审计,这些 finding 就根本不会存在 —— 没有测试会抓到它们,而那个本该抓到的 review 会返回一个自信的 PASS。这个盲点从家族内部看不见,而在一个不同的家族看同一份 diff 的那一刻就一目了然。这就是支持跨家族独立性的全部论证,而这里它是一个被测量出的事实,而不是一条原则。
我们刻意不主张的事
这不是一张模型排行榜。样本是一个项目、跨约两个月、跑在几周内就会过时的特定模型版本上;gemini 有一个真实的高光时刻(在 CHARTER-31 上干净地 10/10 抓中),而一份不同的语料或一个更新的版本,可能把整张表重新排序。诚实的读法不是"家族 X 很差" —— 而是方法论上的那个:任何单一心智都可能系统性地变瞎,这种失明从内部无法核对,而多样性正是让它变可见的东西。这个主张会在下个月无论哪个模型登顶时都活下来。
这也不是对 Bun 的贬损。他们那套单一家族、分裂上下文、由神谕支撑的设计,对一个 port 而言是正确的,而且在一个 —— 一百万条断言、六个平台、零跳过测试 —— 大多数团队从未达到的规模上。区别只在于:当测试套件能当裁判时,按上下文隔离审查者;当裁判是一个人在下判断时,按家族隔离他们,并让人继续主导那个决定。StrayMark 审计里的一切 —— 包括那个让跨家族趋同无法伪造的 operator 提供身份的修复 —— 都是为了保护那第二种情形而存在。
如果你读到了这里
可移植的问题,是关于你自己的审查流程,无论人工还是自动。问一问:你的审查者会漏掉什么,而且是以一种下游也同样抓不到的方式 —— 那类没有测试、没有 linter、没有类型能拦住的缺陷。对那一类,单一视角内部的冗余几乎买不到什么;两个同样的审查者共享同一个盲点。能买到东西的,是一个不同种类的审查者,以及一种在他们分歧时能注意到的办法。Bun 可以靠一百万条断言来当裁判。你发布的大多数东西不能。对那些,你唯一有的神谕,是一颗看得不一样的第二心智 —— 所以要确保那颗第二心智真的不一样,并且确保还有一个人在读那个分歧。
数据来自 Sentinel 项目的 .straymark/audits/ —— 25 个审计周期、21 个 Charter、68 份审计者报告、7 个模型家族,2026-05-05 → 2026-07-10(read-only)。Bun 的数字来自 bun.com/blog/bun-in-rust。相关:审计以为自己是谁。
本文档在生成式 AI 工具(Claude Opus 4.8)的协助下完成;内容的全部责任由人类作者承担。