展示如何用多个 AI Agent 相互检查代码(如支付场景中的隐蔽数据泄露风险),通过相互验证提高生成代码可靠性的实战工作流。
一百万个格子的网格,每个格子恰好卖一次,六天内完成,以及那个发现了 AI 自己最坏修复的验证模式。
AI 提出的某个修复会在陌生人还在刷卡的时候释放他们已经预留的格子。
在 diff 中看起来很合理。已过期的预留应该被释放,而这个修复通过将 reserved_by_ip_hash 与传入的请求进行匹配来释放它们。
对抗性审查者,其唯一的指示是驳斥它,杀死了它。IP 地址的哈希值并不代表一个人。在 CGNAT 或 VPN 出口节点后面,它是一个人群的哈希值。处于 Stripe Checkout 中途的人会有他们被持有的格子在下面被释放,并在他们的付款仍在进行中时被转售。这个修复被完全撤销了。代码是正确的。影响范围超出了任何人正在查看的 diff。
这是整个构建中最具可迁移性的东西,它与这个产品无关。写出修复的模型是判断它的错误实体,而最廉价的纠正手段是另一个模型,其工作是发动攻击。
2005 年,Alex Tew 以每个一美元的价格出售了 1,000,000 个像素来支付大学费用。百万美元主页赚了大约 $1,037,100,二十一年后仍然在线。它也基本上是一个墓地。大部分链接的公司都已消失,横幅指向已死的域名。出售给广告商的像素像广告一样老化。
Word Monument 翻转了这个变量。改为向人而不是公司出售,并出售字母而不是像素。没有人对像素有情感依附。字母是一个名字、一个日期、一个去世的人、四个人才懂的笑话。
该网站今天是实时的,完全可以探索,在预览中:Supabase 和 Stripe 还没有连接,/api/reserve 返回预览通知,你看到的网格是生成的演示内容。下面描述的任何东西都没有针对真实金钱运行。

一百万个格子,每个一个字符,每个一美元。每个格子恰好卖一次,永远。没有帐户、没有登录、没有信息流、没有算法。每笔交易最多 300 个格子,以及 35 分钟的预留保留期,故意比 Stripe Checkout 会话多活五分钟。当网格填满时,它关闭。

永久性是一个产品承诺,最终归结为一个数据库保证。
不可原谅的一个错误
卖同一个格子两次,两个人各支付了一美元购买同一个字母。只有一个人能拥有它,在一个整个前提就是什么都不改变的产品中。向失败者退款无法修复这一点。它出卖了产品本身。
朴素的形状是检查后进行写入。选择请求的格子,确认它们可用,然后将其更新为已预留。两个请求都可以在任何一个执行更新之前通过选择。这个窗口很小,而小窗口正是启动峰值填充的东西。
将保证推下到约束中也无法完成工作。格子已经是具有状态列的行,所以没有键可以变为唯一的,即使有,违反也会中止整个事务,并且只告诉调用者某些东西发生了碰撞。它不会说 300 个格子中的哪一个发生了碰撞,而这个列表正是购买者需要的,以便移动他们的字母。约束是对错误的后备。它不是预留协议。
代替的是一个 SECURITY DEFINER Postgres 函数,返回 TABLE (success boolean, unavailable_cell_ids integer[])。它的中间部分,逐字:
-- Lock candidates in ascending id order (deadlock-safe).
PERFORM 1 FROM cells WHERE id = ANY (p_cell_ids) ORDER BY id FOR UPDATE;
-- Self-heal lapsed reservations back to available before checking.
UPDATE cells
SET status = 'available',
character = NULL,
background_color = NULL,
reservation_id = NULL,
reserved_until = NULL,
reserved_by_ip_hash = NULL,
owner_label = NULL,
updated_at = v_now
WHERE id = ANY (p_cell_ids)
AND status = 'reserved'
AND reserved_until < v_now;
SELECT coalesce(array_agg(id ORDER BY id), ARRAY[]::integer[])
INTO v_unavailable
FROM cells
WHERE id = ANY (p_cell_ids)
AND status <> 'available';
IF cardinality(v_unavailable) > 0 THEN
RETURN QUERY SELECT false, v_unavailable;
RETURN;
END IF;
三件事在做工作。按升序 id 锁定意味着共享单元格的两个重叠请求总是以相同的顺序获取它们的锁,所以它们不能相互死锁。自我修复发生在那个锁内,所以一个过期的保留变为可用,没有单独的扫描,也没有第二次读取。结果是全有或全无:每个请求的格子都被预留,或者都没有预留,调用者得到失去竞争的确切 id。预留路径从不将可用性读取然后将其作为两个语句进行写入。
完整函数:supabase/migrations/0008_reserve_per_cell_colors.sql。该文件会在你展示一个东西,摘录上方几行:reserved_by_ip_hash 也用于限制一个哈希值最多可以保留多少个格子。同样的共享哈希问题,不同的权衡。一个人群在一个 NAT 后面更快地达到上限,最坏的结果是拒绝,而不是别人的字母在结账中途消失。

其他一些决定来自同样的姿态:
行级安全在每个基表上是全部否定,格子只能通过显式列白名单视图读取,所以六个月后添加的列对匿名读者是不可见的,直到有人列出它。
支付竞争被处理而不是忽视。如果付款在其预留被扫除并转售后到达,webhook 会自动退款确切的差额,并向付款异常审计表写入一行。部分履行退款差额,而不是整个费用。
网格读取通过一个缓存的路由,边缘缓存键从绑定框派生,捕捉到瓷砖边缘。通过一个格子平移,或攻击者抖动坐标,无法创建新的缓存条目。实时验证:两个不同的原始 URL 捕捉到同一个瓷砖共享一个缓存条目。
渲染器是 Canvas 2D,而不是 WebGL,有目的。每帧的绘制计数在每个缩放级别都很小,所以真正的瓶颈是视口相关的数据获取,而不是绘制调用吞吐量,而且 WebGL 会添加着色器和上下文丢失复杂性毫无用处。有四个细节级别,由每个格子的像素数键入:预呈现的马赛克、来自 400 行汇总表的每瓷砖矩形、没有字形的每格子矩形,然后是带有真实等宽字形的完整账本网格。视口状态存在于一个可变 ref 中,由手势处理程序变异并在 requestAnimationFrame 上绘制,所以平移和缩放从不触发 React 重新渲染。
官方 Stripe SDK 在 workerd 下挂起,所以出站调用通过针对 REST API 的手工卷取客户端进行。Webhook 签名用 crypto.subtle 验证,任何解析之前原始体读取,时间戳超过五分钟的被拒绝。

对抗性验证,足够详细可以复制
整个东西都是用 Claude Code 编写的,使用 Claude Opus 5 和 Claude Fable 5,以多智能体模式运行,其中工作流脚本以并行方式将工作扇出到许多子智能体,并通过阶段对其进行管道化。扇出工作纯粹是吞吐量决定。这是使输出可信的循环:
生成阶段产生候选发现。错误、漏洞、提出的修复、任何东西。以你喜欢的方式提示它。体积在这里很好。
每个发现都送到一个或多个独立的智能体,它们从不看到产生它的推理。他们得到主张和代码。
指示不是"审查这个",而是"驳斥这个",有一个明确的默认:当不确定时,答案是"不是一个错误"。
一个发现只有在可以独立再现时才能生存。一个失败的断言、一个查询、一个实际运行。一个论证不是一个再现。
修复通过与发现相同的大门。提出的修复是关于行为的一个主张,并且获得了相同的攻击。
第三步承载了大部分重量,而且它是提示的一行。一个被要求审查的模型会发现什么,因为产生一个列表是审查看起来的样子。驳斥产生一个判决而不是一个列表,并将默认从"标记它"反转到"清除它"剥离出了未经验证的 AI 审查大量生成的有信心、似是而非但错误的物质。
第四步是昂贵的部分,也是人们容易跳过的部分。这里的验证是针对真实的 PostgreSQL 17 实例进行的,而不是模拟对象:40 个支付逻辑断言,所有 13 个迁移都在类 Supabase 的引导权限下应用,以及对 webhook 签名验证使用畸形和伪造的签名进行攻击,全部被拒绝。
成本是多少。 令牌消耗会乘以每个发现的驳斥轮数,乘数作用在验证而非代码编写上。驳斥是令人尴尬的并行操作,所以原则上它消耗令牌而不是时间。这里没有进行仪器化,所以将其视为结构性预期而非测量。真正的成本是环保工作。在没有声明能够被实际执行的地方,你无法运行这种模式。
失败的地方。 三个诚实的局限。
它回答"这个声明是真的吗",对"这是应该构建的东西吗"毫无答案。再多的驳斥智能体也无法告诉你网格应该是一千个单元而不是一百万个。
它在共同的盲点上收敛。来自同一模型族的智能体携带相同的先验。如果它们都对平台的行为方式有相同的错误信念,它们会彼此同意,信心十足,而共识会显得像证据。IP 哈希捕获有效是因为声明可以根据 NAT 实际工作方式进行检查。相关性失败是为什么真实环境比智能体数量更重要。Postgres 不共享模型的先验。
而且它找不到没有人指向它的一类 bug。来自循环的沉默不是不存在的证据。
第二个陷阱:可以擦除网格的公钥
Supabase 按设计将匿名密钥交给浏览器。它随客户端捆绑包一起发送。安全完全取决于 RLS 策略和表授权,失败模式是沉默的,因为正常工作的密钥和权限过大的密钥从外部看起来完全相同。
一个审计声称在 Supabase 自己的项目引导运行后,匿名角色仍然通过公共视图具有对单元的写入权限。声明不是根据论证的强度而被接受的。它被再现了:所有 13 个迁移都在本地 PostgreSQL 17 实例上应用,使用 Supabase 应用的相同引导权限,然后以匿名角色发出 UPDATE,将已售单元重置为可用并清空其字符。
它有效,链中的每个环节都是默认设置。Supabase 的引导运行 ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO anon, authenticated,该默认设置覆盖视图。cells_public 是一个单表投影,这使得 Postgres 将其视为自更新视图。它是在没有 security_invoker 的情况下创建的,所以通过它的 DML 以视图所有者身份运行,永远不会遇到单元上的全部拒绝 RLS。PostgREST 在自更新视图上暴露 PATCH 和 DELETE。这是网格擦除,使用任何人都可以从页面源代码中读出的密钥。
修复是两行必须在每次创建视图时记住的代码:
CREATE VIEW cells_public AS
SELECT id, x, y, status, character, background_color, updated_at
FROM cells;
REVOKE ALL ON cells_public FROM anon, authenticated;
GRANT SELECT ON cells_public TO anon, authenticated;
"每次"不是修辞。后来的迁移向视图添加一列,Postgres 只允许 CREATE OR REPLACE VIEW 在末尾追加列,所以列必须通过 DROP VIEW 和 CREATE VIEW 到达,而重新创建会静悄悄地重新应用引导的全权授予。撤销也必须在那里重复。(0010_lock_public_read_surface.sql)
公共表面是视图而不是一组表策略的原因完全是关于未来。添加到具有宽松策略的表的列在存在的那一刻就是公共的。添加到允许列表视图后面的列在某人列出它之前保持不可见。
AI 在这方面真正不擅长的地方
三件事,直言不讳。
它对边缘处的平台行为充满自信地犯错。Stripe SDK 在 workerd 下的挂起不是通过任何东西推断出来的。它是通过运行它而被发现的。
它无法看到不在存储库中的状态。十三个迁移文件中没有任何内容记录托管平台已经授予匿名角色所有权限,而读取代码对部署的数据库实际拥有的权限证明什么。危险的默认值位于被审查的工件之外,这对于 IP 哈希修复也是如此,是值得担心的错误的一般形状。
容量冒充进度,这才是真正的成本。 单次生成轮次会产生一个长列表,读起来像彻底性,而其中很大一部分在驳斥下蒸发。没有门控,你花时间应用修复到从未损坏的代码。未验证的 AI 审查比没有审查更糟,因为每个不必要的修复都是破坏有效工作的新机会。
六天,以及它们包含的内容
构建于 2026-07-26 至 2026-07-31。
116 个 TypeScript 和 TSX 文件,src/ 中约 12,000 行
13 个 SQL 迁移,1,765 行,11 个 Postgres 函数,11 个表
11 个 API 路由,33 个 React 组件
6 个运行时依赖:next、react、react-dom、@supabase/supabase-js、@number-flow/react、bcryptjs
2.2 MB gzip 压缩 Worker 捆绑
没有状态管理库、没有 canvas 库、没有 UI 工具包、没有运行时 ORM
Next.js 15.5 App Router 通过 @opennextjs/cloudflare 在 Cloudflare Workers 上运行,Supabase Postgres,Stripe 托管结账,Tailwind v4 无配置文件,R2 用于增量缓存,以及三个 KV 命名空间保持分离,因此一个中的事件不会与日志中的其他事件混淆。
六个依赖是一个验证预算。它们中的每一个都是对抗轮必须审计或信任的东西,而信任是昂贵的选项。
这些天本身看起来不像提示和接收产品。大部分经过的时间用于使声明可检查:建立真实的 Postgres,在现实权限下应用迁移,编写建议修复可能失败的断言,伪造 webhook 签名以便可以观察而不是假设拒绝。智能体很快。构建能够反驳它们的东西是工作。
没有真实的金钱流动。顶部描述的预览状态是当前状态:Supabase 和 Stripe 未连接,/api/reserve 返回预览通知,网格呈现生成的演示内容,声称在后端接线时打开。零单元已出售给公众。吸收比其他任何东西都多的关注的预订函数从未同时面对两个真正的买家。
同样的规则适用于更高的层次。这个方法是拒绝相信没有被再现的声明,而"这有效"是一个没有再现的声明。
网格可能永远不会填满。一百万个单元每个一美元是一个很大的数字,代码中没有什么让任何人想要一封信。已经真实的更小:《百万美元主页》在二十一年后仍然在线,仍然指向不再存在的公司,这就是当你向广告商出售空间时发生的情况。人们是否会购买字母代替是 Postgres 函数无法回答的问题。这是唯一无法预先验证的部分。