用极小WebAssembly模块在AI代理与浏览器之间建立确定性边界,避免DOM选择器、时间窗口等脆弱路径导致的维护地狱。核心洞见是把"教AI找什么元素"改为"教AI什么结果必须为真"。
我坐在一个非常庞大的自动化系统旁边,面对一个再熟悉不过的问题:系统已经变得脆弱了。
话术很快涌上来。DOM、时间戳、定时窗口、选择器、重试、循环回去。
每一个词都言之成理。
它们共同描述的是一座山。
系统的脆弱并非源于构建者缺乏纪律,而是因为路径本身成了产品。机器人被教会的是要找到哪个元素、在哪里点击、等待多久、页面不配合时重试什么——而不是什么样的结果必须为真。每个变通方案在局部都合理。但叠加在一起,它们把变化本身变成了维护工作。
我机器上的第一个证明只有 636 字节。
不是模型,不是浏览器,也不是围绕它的平台。那是一个 WebAssembly 模块:一个微小、可移植的程序,注入在智能提案与授权浏览器操作之间的边界处。它的小体积很重要,因为它保持了边界的确定性、可审查性,让复杂性难以藏身其中。
它不是万能的。这才是重点。
这 636 字节的模块是注入的证明;该构建中经过硬化的 Rust 内核编译后为 26,893 字节。两者都不包含模型、调度器、凭证存储、策略引擎或证据系统。这些职责位于浏览器边界之外,在那里它们可以被隔离、治理和独立替换。小不是架构的缺位。小是在哪里允许复杂性存在的决策。
AI 模型可以解读意图、检查当前页面、提出下一步该做什么。但它不能自行授予自己权限。它不会因为"这样做很方便"就跨越租户、工作区或源边界。它不会因为推理听起来自信就获得凭证或按下有影响的按钮。这些决策属于本地策略和执行层。智能保持灵活;授权保持边界。
这种分离形成了一个生命周期:
intent → lease → observe → decide → act → verify → artifact
意图定义结果。租约给一个工作者对这项工作的短期声明权。工作者观察页面,推理层提出决策,策略决定操作是否可以执行。验证检查结果状态,而不是信任点击动作。最后,产物保存了所发生事情因果关联的证据。每个箭头都是一个边界,系统可以在此处拒绝、恢复或解释自己。
那座山也有一张账单。为了让这种摩擦变得可见,我通过 agent-calc 运行了一个说明性规划场景——不是客户遥测。假设 100 个工作流,每个工作流每月两次变更,每次变更四个维护工时, fully loaded 人力成本每小时 140 美元。模型化对比非常鲜明:
这就是 82.1% 的模型化降幅。这个百分比不是承诺;假设条件是透明的,以便可以被挑战。有用的问题是模型暴露了什么:我们花了多少资源来保留描述昨天界面的指令,而不是今天想要的结果?
当然,如果一种架构只能在一个精心策划的演示中存活,那它只是更便宜的失败。所以我们构建了 Component Gym:一个旨在抵抗记忆化的合成 Web 应用。控件在运行之间移动。按钮使用不同的事件监听器。目标可能被埋在一堆诱饵中间,位于随机化标签页和分页列表里。一个种子使每个恶意排列可复现,但对智能体不可预测。
智能体收到的是意图,不是选择器脚本。然后 harness 在带外对结果应用状态评分。它不在乎哪条路径看起来令人信服,也不关心点击事件是否触发。它在乎的是请求的结果是否为真。
在拍摄运行中,种子 710003 将针放置在一个跨标签页和页面分布的动态集合内。智能体被给予期望的结果和浏览器当前状态——而不是目标的坐标或预先记录的路线。它必须导航、从诱饵中区分目标、行动、并留下请求的状态。只有这样,独立评分器才返回 PASSED。智能体不能自己给自己的作业打分。
这些都不能让 DOM、定时或选择器消失。浏览器仍然有结构。事件仍然在时间中发生。选择器对于特定操作可能仍然是正确的策略。改变的是它们的生命周期和所有权。在路径驱动的系统中,这些细节硬化为持久业务逻辑。在这里,它们是运行时观察和一次性策略,在环境变化时被抛弃。确定性没有被移除;它被重新定位到了授权、状态转换、验证和证据中。
一次 gym 运行通过只能证明原始组件,不能证明平台。小的浏览器边界减少了一类脆弱性;它不能抹除围绕它的分布式系统、安全和运营工作。剩余的义务不那么有戏剧性,但更重要:
隔离:在每个操作中保持租户、工作区、工作者声明和源边界。
工作所有权:安全地使租约过期,恢复中断的工作,防止重试复制有影响的操作。
密钥和 MFA:只在授权执行边界解析凭证,绝不放在模型上下文、作业、日志、截图、视频或产物中。MFA 是代表执行的,永远不是认证绕过。
浏览器生命周期:附加、控制、恢复和释放浏览器会话不在工作者或租户之间泄漏状态。
策略:拒绝超过授权意图的操作,即使提议的操作在技术上是可能的。
证据:因果关联意图、观察、决策、授权、操作、验证和产物,这样在浏览器消失后结果仍然可以解释。
636 字节有趣不是因为更小的软件自动更好。它们有趣是因为它们让拒绝变得具象化:不要把编排、密钥和授权埋进接触页面的那个东西里。把可信浏览器边界编译得更小。让推理适应它周围的环境。在每个有意义的后果之后要求证明。
我不断回到那个房间。房间里没有人说过任何荒谬的话。那座山是由在一个继承前提下的理性决策建造的:路径必须被保留。改变这个前提,山就改变了形状。我们不需要一直教自动化每条穿过界面的路线。我们可以保留意图、重新发现路线、约束操作、验证目的地。
下一次自动化中断并要求另一个选择器、超时或恢复层时,先问一个问题:这个系统有多少是在保护结果——有多少是在保护昨天的路线?