什么是计算机操作,为什么它很重要?计算机操作的理念很简单,却影响深远:我们不再要求模型回答问题,而是让它们操作软件——浏览网站、填写表单、逐步完成工作流,并自主地端到端完成任务。
这让一大类现实任务成为可能。这些任务目前分散在不同界面中,例如端到端预订、电商结账、多步骤旅行规划,以及没有简洁 API 可用的后台工作流。这些问题并不新鲜。新变化在于,如今已可以借助通用模型解决这些问题。
Anthropic 和 OpenAI 最近推出的系统已证明,智能体不仅能执行操作,还能推理当前状态、从错误中恢复,并即时构建针对具体任务的解决方案。这使浏览器成为智能体的通用执行环境,但也立即带来一个设计问题:我们应向模型开放多少环境能力?
早期系统的做法是将浏览器封装为一组固定、安全的预定义操作。正如本文将要论述的,这种方法正逐渐触及极限。


构建浏览器智能体时,人们往往有一种熟悉的直觉:不要过度信任模型。
因此,我们对浏览器进行封装。我们开放 click、type、scroll、select 和 read_text 等预定义工具。我们简化文档对象模型(DOM)。我们缩小操作空间。我们试图通过自行设计的抽象,让行为变得易于理解和控制。
这是一个合理的起点。但它也日益成为一种错误的长期架构。
随着前沿模型不断进步,问题已不再只是模型缺少工具。真正的问题是,我们迫使模型通过抽象层运行,而这些抽象剥离了太多底层系统信息。我们把杂乱而动态的环境压缩成固定的操作接口,然后要求模型在信息缺失的情况下表现出色。
这种权衡正变得越来越不划算。
我们一直探索的转变说起来很简单,却会带来重大影响。我们不再把智能体视为预定义操作的选择器,而是将其视为在受约束运行时中工作的程序合成器。
模型已经变得非常强大,不再需要抽象化的护栏;它们需要完整的操作空间,以便设计、执行并迭代任务,直至实现目标。
本文探讨的正是这一转变:从高度依赖抽象的浏览器自动化转向受约束的计算机操作,以及以这种方式设计系统会带来哪些变化。
问题并不在于固定操作接口的理念本身有误。而在于 Web 并不配合这种理念。


现代界面基于 React、Vue 和 Angular 构建,包含异步状态更新、合成事件系统,以及嵌入跨源 iframe 且各自具有独立生命周期的第三方组件。只有当页面认同你对“输入”的定义时,声称“在此输入框中键入内容”的封装才是正确的。很多页面并不认同。直接设置值往往会完全绕过框架的变更检测。输入框看起来已经填好。验证却从未触发。表单仍然无法使用。
你可以打补丁。你可以为 React 输入框添加特殊处理,在获得焦点后派发 blur 事件,并等到网络空闲后再读取状态。每个补丁单独来看都是正确的。但这些补丁累积起来,会让系统越来越难以维护,也越来越局限于你已经遇到过的网站。
更深层的问题在于,你把有关交互应如何运作的假设编码进了抽象层,随后却发现 Web 遵循的是另一套假设。
以通过 Stripe 或 Adyen 嵌入跨源 iframe 的支付表单为例。由于它位于不同的源,你的封装无法直接访问它。read_text 工具无法观察其内部状态。type 工具无法操作其中的输入框。基于封装的智能体在这里会陷入困境。这种抽象是针对主文档设计的。实际任务却位于抽象无法看到的位置。
类似的不匹配也会出现在不那么明显的流程中。受框架控制的下拉菜单可能完全不响应直接点击,因为可见元素并非真正的控件。它可能需要一系列键盘事件才能触发底层状态转换。从外部看,UI 似乎可以点击。抽象层发出“点击”指令,却什么也没有发生。
再比如一个多步骤模态流程,其中可见 DOM 的更新落后于内部状态变化。正确的下一步操作取决于一次状态转换,但该转换尚未反映在封装可见的元素中。基于封装的智能体最终会过早执行操作或读取过时状态,因为它看到的系统信息并不完整。
在每种情况下,抽象都隐藏了智能体真正需要的信号。
在更底层运行的模型可以检查实时 DOM、推理框架边界,并针对具体界面合成交互序列,因此能够应对这些情况。这并不是因为模型本身更聪明。而是因为它能够访问此前被剥离的信息。
我们一直推动的变化很容易描述:不再要求模型从预定义操作中进行选择,而是为其提供更底层的执行接口,并通过运行时策略而非抽象设计来约束该接口。
这一设计选择源自更广泛的行业转变:行业开始青睐更底层的基础工具。这类工具能发挥智能体在运行时纠错和生成高质量代码方面的固有能力,而非采用虽然稳健、却会削弱模型适应不同环境能力的硬编码专用工具。
看看 Claude Code 如何成为许多开发者工具箱中的首选,以及整个行业如何广泛转向基于终端的智能体。Claude Code 最大的优势并非模型本身,而是更底层的执行框架。为模型提供数量更少、模块化程度更高且更底层的工具——也就是终端——可以改善工具调用表现,主要原因是智能体能针对当前任务进行推理并创建自定义脚本,而不必尝试使用会污染上下文窗口的通用工具。
具体到浏览器自动化场景,这意味着模型可以直接检查实时页面状态、遍历框架,并根据当前界面构建定制的交互代码,而不必把所有操作映射到一组固定的预构建操作上。
模型不再像一个选择器,而更像运行时代码的编写者。它会检查当前状态、推理界面行为,并针对具体情况合成交互逻辑。它可以构建多步骤序列、适应非常规流程,并在继续之前验证结果。操作失败时,模型能看到底层错误并自行纠正。这种方式能力更强、风险也更高,但它更贴近问题的真实形态。
重要的是,移除抽象层并不意味着系统会变得不严谨。严谨性只是转移到了其他位置。
过去由封装设计和边缘情况处理承担的工作转移到了三个部分:提示(成为一种操作训练)、运行时(强制执行导航范围、敏感操作和重试行为等边界)以及评估层(不仅评估任务是否成功,还评估中间步骤是否正确)。减少脆弱的抽象。强化周边系统。
这一转变带来的一个结果是:即使整个系统的能力更强,产品代码往往反而更简单。智能体不再将交互模式编码为可复用的封装,而是在运行时合成行为。你只需维护一小组功能强大的基础操作和一个受约束的执行环境,而不必不断扩充专用工具和边缘情况逻辑。
这也改变了系统的泛化方式。基于封装的智能体能够很好地泛化到与你已构建的封装相似的任务。受约束的运行时智能体则可以泛化到采用相同执行基础的任务,即使其可见界面不同。
例如,搜索表单、预订流程和设置页面在 UI 层面看起来可能截然不同。但在底层,它们具有共同的模式:读取状态、触发事件、验证结果以及处理异步更新。在这一层面运行的系统能更自然地将能力迁移到不同任务。
可复用的部分并不是操作列表,而是模型检查状态、安全执行操作并验证结果的能力。


这项工作带来的最明确启示是:可靠性并非源于为模型提供更多辅助函数。它往往源于提供数量更少但功能更强的基础操作,并以恰当方式约束这些操作。过度辅助会把有关任务执行方式的假设硬编码到系统中。约束可以划定安全的运行边界,让模型自行找到更好的局部解决方案。
更强大的执行接口也需要更严密的安全模型。一旦智能体不再局限于少量预定义操作,它实际上就是在直接操作真实软件。这会立即改变其风险状况。
设计时需要考虑四个问题:
数据暴露。智能体与真实界面交互时,往往会接触敏感信息。因此,必须严格实施信息遮蔽和访问控制。仅在执行所必需时才应披露数据,并且必须谨慎处理日志和追踪信息,避免可观测性组件成为系统中最敏感的部分。
执行范围。不能允许功能强大的智能体任意操作。在实践中,这意味着要限制它可以导航到的位置、可以访问的域以及获准交互的系统。这些约束应在运行时层面强制执行,而不能只作为提示中的约定。
环境可信度。现代界面可能包含误导性甚至主动发起攻击的指令、内容或流程。通过页面内容实施提示注入是一个真实存在的攻击面。系统需要明确的指令层级、验证检查和终止条件,防止智能体遵循非预期指引。
自主性范围。并非所有操作都应完全自主执行。在许多生产环境中,必须将自主性视为一个连续范围。系统在探索和执行方式上可以高度智能体化,但某些类别的操作仍需获得批准。
基本原则很简单:赋予模型越强的能力,就越需要强化其周边系统。没有策略约束的自主性尚不足以用于生产环境。
我们不再问:应该开放哪些浏览器操作?
我们开始问:如何为模型提供完整的操作空间,同时围绕它制定运行时策略,确保其依然安全?
这种重新定义改变了关注重点。操作分类和封装的完整性不再那么重要。运行时策略、可观测性和步骤级评估则变得更加重要。模型能力与系统设计无法相互替代。模型能力越强,系统承担的工作就越重要,而不是越不重要。
浏览器智能体之所以常能在演示中成功,是因为任务范围狭窄且环境较为配合。生产系统需要不同的要素:受约束的执行、可检测的行为,以及能够区分正确结果与侥幸成功的评估机制。
减少封装设计。加强系统工程。
虽然本文重点讨论浏览器智能体,但这也揭示了一种更广泛的思路:把计算机操作视为一门系统工程学科。