Computer Use 拆解:从一次点击到长任务的最后一公里

October 4, 2026 · Tech Blog

Computer use 的技术路线、一次点击背后的完整链路、主流方案的真实用法、常见的坑,以及上下文管理的几个关键判断。


2026 年,computer use 走到了一个有意思的节点:在 OSWorld 这类短任务基准上,头部 agent 已经超过人类基线(72.4%),最高的验证成绩到了 80% 以上;可一旦换成 OSWorld 2.0,任务中位数需要熟练人类操作约 1.6 小时,表现最好的 Opus 4.8 严格完成率也只有 20.6%。

模型已经"会用电脑",但还做不到"可靠地替你干完一件 1 小时以上的活"。这篇文章想把中间这段距离拆开讲清楚:computer use 在工程上到底是怎么跑起来的,主流方案各自怎么用,坑在哪里,以及我认为最被低估的一块,上下文管理。

Highlight computer use 的瓶颈正在从"模型能力"转向"工程":同一个模型,换一套执行框架,OSWorld 成绩可以差出好几个点。GUI 正在退化成长尾兜底,而不是主通道。


一、它不是视频,是回合制

第一个常见误解是以为 agent 在"看"屏幕,像人一样持续感知。实际上主流实现全是回合制循环:

截图 → 模型推理 → 输出一个动作 → 执行器执行 → 等界面稳定 → 再截图 → ...

截图不是按固定频率,而是每做一步截一次。一轮要经过截图上传、模型推理、执行动作、等待界面响应,通常要几秒到十几秒。换算下来大约 0.1–0.3 帧每秒,比人眼慢两个数量级。

这直接决定了能力边界:拖动滑块到精确位置、视频播放中途操作、任何实时对抗的游戏,纯视觉 agent 天生做不了。网上那些"AI 打 MOBA"的演示,真正在实时循环里的几乎都不是 LLM,而是 LLM 写出来的 bot 程序,或者 LLM 只做每隔几秒一次的高层决策、底层由脚本执行。OpenAI Five 打 Dota 2 时也没有看像素,而是走官方 Bot API 读结构化状态、每秒决策七八次。


二、一次点击的完整链路

"点一下"这个动作,背后至少有四层。

第一步,模型输出坐标。 模型看的是截图,输出的是截图上的位置。不同模型坐标系不同:Claude 输出截图里的绝对像素;UI-TARS、AutoGLM 这一类输出 0–999 的归一化坐标,执行器再换算。

第二步,执行器做坐标换算。 截图通常被缩小过再送给模型(比如 2880×1800 缩到 1280×800),所以要按比例放大回去。Mac 的 Retina 屏还要再处理一层逻辑点和物理像素的 2 倍关系;多显示器还要加上屏幕偏移;浏览器里设备像素和 CSS 像素之间还有一个设备像素比。这一步算错,是点击整体偏移最常见的原因,而且很容易被误诊成"模型定位不准"。

第三步,注入事件。 在算好的位置发送"按下"和"抬起"。不同层的注入方式完全不同:

层级注入方式特点
操作系统macOS CGEvent、Windows SendInput、Linux xdotool/XTest等同真实鼠标,会移动光标,默认前台
无障碍macOS AX API 对元素执行 press可以完全不用坐标
浏览器CDP Input.dispatchMouseEvent走命中测试,生成可信事件(isTrusted)
浏览器(不推荐)JS el.click() / 合成事件不走命中测试、事件不可信,常被网站忽略
手机ADB input tap、无障碍服务、系统级事件注入权限越深越稳定

第四步,系统做命中测试。 这是最关键的一点:agent 只告诉系统"在哪里点",点到的是哪个元素,由操作系统或浏览器自己判断。 窗口服务器先决定这个点落在哪个窗口,应用再沿视图树找到具体控件。

所以只要截图和点击之间界面变了(弹窗盖上来、列表刷新、布局抖动),点击就会落在别的东西上。agent 按旧截图点,系统按当前界面判定,二者对不上。

Highlight Playwright 的 click() 是"先定元素 → 滚动到可见 → 等它稳定 → 检查是否被遮挡 → 再按中心坐标点击"。纯视觉 agent 恰好缺了中间三步,这就是它不稳的根源之一。

后台运行又是另一个难度。要在用户正常用电脑的同时操作别的窗口,事件必须直接发给指定窗口,但很多应用不在前台时会忽略输入。据第三方分析,Codex 的后台 computer use 用到了 macOS 私有的 SkyLight 接口,让窗口接收输入却不被切到前台。这是纯工程问题,和模型能力无关。


三、感知路线:从结构化,到纯像素,再回到混合

结构化路线读 DOM 或无障碍树(macOS AX、Windows UIA、Linux AT-SPI、Android View 层级)。优点是快、省 token、定位准,还能直接对元素执行动作;缺点是覆盖不全:自绘 UI、canvas、游戏、远程桌面里什么都拿不到,很多 Electron 应用默认也只暴露不完整的树。

纯视觉路线是"截图进、坐标出"。微软的 Fara-7B 是典型:直接预测坐标点击,不依赖无障碍树或额外的解析模型。豆包手机的感知也是纯截图,所以 Flutter、自绘 UI、游戏界面都能处理。代价是每帧 1000–2000 token,密集界面上的小按钮容易点偏。

混合路线是现在的生产实践,常见三种形态:

  • 结构为主、视觉兜底:先读无障碍树,遇到图表、canvas 才截图。
  • 视觉预测、结构吸附:模型给出坐标,执行器把它吸附到最近的无障碍元素包围盒上,消除差几像素的误点。
  • Set-of-Mark:先用结构信息找出可交互元素,在截图上画编号框,模型只需回答"点 17 号",执行器再映射回元素。

另一条思路是规划和定位分离:大模型看截图和无障碍树做规划,输出"点击提交按钮"这样的高层指令;小模型只负责把指令落到像素坐标。


四、主流方案到底怎么用

先澄清一个容易混淆的点:各家 API 里的 computer 工具,都是**"卖大脑、不卖手"**。工具的动作格式由模型厂商定义,模型在这套格式上专门训练过;但真正去截图、去点击的执行器,要开发者自己搭。

OpenAI:从"输出点击"转向"写代码操作电脑"

OpenAI 的 computer use 指南里有两条路径,而且推荐顺序很有信号意义:对 GPT-6 Astra,官方推荐代码执行,computer 工具只是备选。

结构化工具路径(备选)。 请求里写 tools: [{ type: "computer" }],模型返回 computer_call,里面是一个有序的 actions 数组(click、double_click、drag、move、scroll、keypress、type、wait、screenshot),你执行完把截图作为 computer_call_output 回传。这是一个纯视觉协议:输入只有截图,输出只有基于坐标的动作。

代码执行路径(推荐)。 给模型一个函数工具 exec_js 或 exec_py,模型直接生成代码,你在一个持久会话里执行:

  • exec_js 暴露 Playwright 的 browser、context、page,用 globalThis 跨调用保存变量,视口 1440×900;
  • exec_py 暴露 pyautogui、time,变量同样跨调用保留;
  • 两边都有一个 display(),模型想看屏幕时自己调用,截图作为图像观察回到对话里。

这个设计里有几个值得展开的点:

  1. computer use 正在被 coding agent 吸收。 动作空间从十几个固定动作变成了一门编程语言。模型可以写循环和条件判断,用 page.wait_for_selector() 等元素出现,用 locator 按 DOM 定位,必要时再退回坐标点击。这等于把 computer use 转化成了模型最擅长的编程问题。
  2. 混合感知由模型自己选。 指南里没有专门的"无障碍树功能",但 page 对象本身就能读完整的 DOM。什么时候读结构、什么时候截图,不再由框架写死,而是模型每一步自己决定。
  3. 观察变成了模型主动发起的动作。 结构化工具路径每轮都要回传一张截图;代码路径里,截图要模型显式调用 display() 才会产生,模型完全可以只打印一行文字(当前 URL、元素文本、结果数量)来确认状态。
  4. 验证可以写进动作本身。 操作后立刻在代码里检查结果,失败就重试或换方法,"截早了"这类时序问题被程序化等待替代。

局限也很明显:桌面端只给了 pyautogui,它本身也只能截图和按坐标操作,读不到原生应用的控件树。所以代码路径的收益主要集中在浏览器场景。

另外,指南里有一句很容易被忽略的话:用 previous_response_id 续接对话,不会恢复浏览器会话、登录状态或运行时变量。后面讲上下文管理时会再回到这一点。

Highlight OpenAI 的方向是用编程代替点击,用主动观察代替被动截图。这比单纯提升视觉定位能力更根本:它绕开了纯视觉路线最贵、最不稳的部分。

Claude:API 是纯视觉,产品是分层路由

API 层面,Anthropic 提供一个预定义的 computer 工具,动作包括截图、移动、点击、输入、按键、滚动和局部放大。执行器同样要开发者自己搭。官方参考实现是一个 Docker 容器:Ubuntu + Xvfb 虚拟显示器 + xdotool 注入输入 + 截图工具,同时配 bash 和文本编辑器两个工具,能用命令行做的就不去点。官方建议分辨率控制在 1024×768 左右,高分辨率屏要做坐标缩放。

截图策略上,两家正好是两种取舍:OpenAI 建议用 detail: "original" 保留原始分辨率,缩放了就把坐标换算回去,用 token 换精度;Anthropic 建议降低分辨率省 token,再用局部放大按需补细节。

产品层面(Cowork、Claude Code),2026 年 3 月在 macOS 上线,9 月支持后台运行。它的设计重点是分层:

  1. 能用连接器(MCP)就用连接器,不碰界面;
  2. 网页交给浏览器通道(Chrome 扩展或内置浏览器),可以读页面结构、按描述找元素、直接填表;
  3. 只有原生应用才走桌面 computer use,而且在这一层浏览器是只读的。

截图加坐标是最慢、最贵、最容易出错的通道,所以只留给其他方法覆盖不到的那部分。

Codex:桌面插件 + 后台并行

2026 年 4 月,Codex 在 macOS 上加入后台 computer use,有自己的虚拟光标,可以在你正常用电脑的同时在后台操作 Mac 应用,并且能并行跑多个 agent。需要授予"屏幕录制"和"辅助功能"两个系统权限,分别对应看屏幕和发输入。内置浏览器基于 Atlas,和桌面 computer use 是两条通道。它不是 Playwright 包了一层:Playwright 只能控制浏览器,碰不到原生应用。

Gemini:只做浏览器

Gemini 2.5 Computer Use 明确只针对浏览器优化,没有针对桌面系统级操作优化。Project Mariner 已于 2026 年 5 月停止,能力以 API 形式开放给开发者。

开源浏览器 agent:Playwright 系

Playwright MCP 读浏览器的无障碍树而不是截图,给 agent 一个结构化、省 token 的页面视图。browser-use、Stagehand 也大多基于 Playwright 或同类库,截图只是辅助。对大多数网页自动化场景,这条路比纯视觉便宜、稳定得多。

手机:外挂式 vs 内置式

AutoGLM 和豆包手机代表了两种完全不同的工程选择:

  • AutoGLM(外挂式):普通 App + 无障碍服务(开源版走 ADB),感知用 layout XML 加截图。拿不到系统权限,所以要靠控件树来补感知的可靠性。
  • 豆包手机(内置式):可以概括为视觉感知 + 混合动作 + 系统级执行。
    • 感知基本是纯视觉:根据第三方逆向分析,它上传的是屏幕帧缓冲截图加任务栈事件,不 dump 控件树,界面理解完全交给云端的 UI-TARS 模型。任务栈事件只说明当前在哪个应用、哪个页面,不说明界面上有哪些按钮。
    • 动作是混合的:UI-TARS-2 把动作空间扩成了"GUI 操作 + 终端、文件、MCP 调用",在手机上就是能调系统接口的地方直接调,调不到的才模拟点击。
    • 执行是系统级的,这是它真正的壁垒:拿到 INJECT_EVENTS、READ_FRAME_BUFFER 这类系统签名权限直接注入事件,还提供"虚拟显示屏",让 agent 在后台操作而不占用你正在看的屏幕。

两者正好相反:豆包把"看"押在模型能力上,把"做"押在和手机厂商的深度集成上;AutoGLM 拿不到深度集成,就用结构化感知来补。(以上豆包的细节都来自第三方拆解,字节没有公开完整技术细节。)

Highlight 各家在产品层殊途同归:都在想办法不让模型看像素。UI-TARS-2 把动作空间扩成"GUI 操作 + 终端 / 文件 / MCP 调用",Codex 配了上百个插件,Claude 优先走连接器,OpenAI 干脆让模型写代码。GUI 的价值是泛化,API 的价值是快和稳,最终形态是两者混合。


五、那些坑

截早了。 点完立刻截图,看到的是动画或加载中的过渡态,模型以为没点上,于是重复点击。要么固定等待,要么让模型显式输出 wait,要么用结构化信号判断界面已稳定。

坐标系没对齐。 截图缩放、Retina、多显示器、设备像素比,任何一处漏算都会整体偏移。排查时先拿一个已知位置的元素做校准,不要急着怪模型。

旧截图问题。 截图和点击之间界面变了,命中测试会落到别的元素上。批量执行多个动作时尤其明显。

无障碍树不可信。 有的应用动态加载的控件不进树,有的 Electron 应用默认关闭了完整的无障碍信息。树里没有,不代表界面上没有。

后台窗口不响应。 很多应用在非前台时会忽略输入,或者表现不一致。后台运行不是"把事件发过去"那么简单。

模型状态和环境状态脱节。 只回退对话不回退环境,重试时 agent 以为自己回到了第 5 步,浏览器其实还停在第 8 步出错后的样子。

远程桌面和虚拟桌面。 Citrix 这类环境只有一路视频画面,没有任何结构信息,还有网络延迟。这是传统 RPA 行业最头疼的场景,computer use 进企业一样绕不开。

提示注入。 agent 读到的屏幕内容就是攻击面。Anthropic 在 Opus 4.6 系统卡里披露,没有防护时,对 GUI agent 的单次注入成功率是 17.8%,尝试 200 次后升到 78.6%。加上防护能压到很低,但对一个每周读成千上万条不可信内容的 agent,1% 依然是实打实的风险。代码执行路径还多出一个风险面:模型生成的是任意代码。

宣布胜利。 模型发现"做错了"的能力远强于发现"漏做了"。它会自信地报告完成,而实际上还有一项根本没做。


六、上下文管理:最被低估的一块

如果只能挑一个工程方向深挖,我会选上下文管理。它同时决定成本、稳定性和长任务能不能跑完。

截图是最贵的上下文

一张截图约 1000–2000 token,几百步的任务不可能全留。常见做法是只保留最近几张图,更早的步骤只留文字形式的动作和推理记录。

Insight 1:截图是"现在",文字是"过去"。 旧截图对决策几乎没有边际价值,模型真正需要的是"之前做过什么、结果如何"。把每一步压成一行结构化记录(动作、目标元素、观察到的结果),比留一张旧图有用得多,也便宜得多。

能读结构就别截图

确认一个按钮的状态,读无障碍树几百 token 就够,截图要一两千。很多步骤的目的只是"确认上一步生效了",这类验证完全可以走结构化通道,只在需要看视觉内容时才截图。

Insight 2:把"观察"按目的分流。 决策用的观察(我下一步该做什么)需要截图;验证用的观察(上一步成功了吗)通常只需要结构化状态或一个程序化检查。把两类混在一起,是 token 预算失控的主要原因。

OpenAI 的代码执行路径直接把这一点做进了接口:截图必须由模型主动调用 display() 才会产生,验证完全可以用一行 console.log 完成。观察从"每轮被动塞进来"变成了"按需主动发起",token 成本能降一个量级。

批量动作:用验证频率换成本

OSWorld 2.0 里,同样是 Opus 4.8,单次调用和批量调用的严格完成率分别是 18.5% 和 20.6%。批量调用就是一次截图后连续执行多个动作(点输入框、打字、回车),中间不截图。省时间、省 token,代价是中间出错要晚一点才发现。OpenAI 的 actions 数组也是同一个思路,同时指南建议"做一小组动作后检查一次屏幕"。

Insight 3:批量的边界应该由"可逆性"决定。 可撤销、低风险的动作序列可以合并;任何不可逆或会改变后续界面结构的动作(提交、跳转、删除),后面都应该强制截一次图重新对齐。

目标会在压缩中丢失

长会话一定要压缩上下文,而压缩时最容易丢的恰恰是最开始的目标和约束。Codex 就有公开 issue:长会话压缩后,续跑提示可能被丢掉,agent 失去原始目标。

Insight 4:目标和进度必须外置。 目标、验收标准、已完成的子任务、遇到的关键决定,应该写在上下文之外的持久状态里(一个文件、一份任务清单),每轮重新注入,而不是指望它在压缩后还活着。上下文是工作记忆,不是档案柜。代码执行路径里的运行时变量(globalThis、Python 命名空间)也是一种外置:抓到的数据、已处理的条目列表放在变量里,不占 token,压缩时也不会丢。

模型状态和环境状态是两套东西

Insight 5:回滚要把两套状态绑在一起。 OpenAI 指南特别提醒,用 previous_response_id 续接对话不会恢复浏览器会话、登录状态或运行时变量。这句话的工程含义很重:如果想从某一步分叉重试,只回退对话是不够的,环境还停在出错后的状态,两边会对不上。真正可用的回滚,需要把环境快照和对应的 response id 一起存下来。这是做重试和长任务恢复机制时最容易踩的坑。

失败经验要按"动作"路由

跨会话的失败记忆(我之前做过一个叫 Pitfall Registry 的东西)在规模小的时候,一个 md 全量注入就够了。规模上来以后,最容易犯的错是拿任务描述做语义检索:坑是在失败之后写下的,描述的是错误现象;检索发生在失败之前,agent 还不知道自己要掉坑里,两者在字面上往往对不上。

Insight 6:按 agent 马上要做的动作检索,而不是按任务描述检索。 给每条坑打上结构化标签(涉及哪个 API、哪类元素、哪个版本),在工具调用的那一刻拦截并注入。这样的路由是确定性的、可以测的。更妙的是,每条坑都诞生于一条具体的失败轨迹,把轨迹截到出错前一步回放,就是天然的召回测试集。

Insight 7:高频坑应该"毕业"到工具层。 一条坑被反复命中,说明问题出在工具本身。与其每次提醒 agent,不如直接在工具封装里做校验或自动修正。健康的失败记忆是流动的:新坑进来,高频坑毕业,过期坑清理,总量长期保持在一个文件装得下的规模。


七、长任务和最后一公里

最近流行的 goal mode(Codex 和 Claude Code 的 /goal)本质上是:持久目标 + 外部循环 + 可验证的停止条件 + 预算上限。模型想停的时候,由外层循环把目标重新塞回去,直到验证通过或者预算耗尽。

它解决的是"提前停止"和"忘记目标",没有解决"怎么知道做对了"。这也是为什么它先在编程场景火起来:测试、编译、CI 是现成的、可信的验证器。换到 GUI 场景,验证器难得多。OSWorld 2.0 的结论是,多花推理只能换来部分进度,换不来严格完成。

最后一公里难,本质上是一个乘法问题。严格完成要求所有子要求都对,概率相乘。假设一个任务有 15 个独立的子要求、每个做对的概率是 90%,全对的概率是 0.9¹⁵ ≈ 20.6%,几乎正好对上 OSWorld 2.0 的数字。单项准确率提到 95%,完成率也只有约 46%;要到 86%,单项准确率得到 99%。

Highlight "每一步再强一点"的收益会被指数吃掉。真正的杠杆在三处:把隐含要求在开头变成显式的验收标准;把长任务切成能独立验证的小段,切短乘法链;让验证独立于执行,执行者不给自己打分。

短期内最有价值的形态,其实不是全自动,而是"做到 80% + 一次高效交接":agent 明确告诉人"这些做完了、这三处不确定、这一项没找到依据",把一个 1.6 小时的任务变成 20 分钟的复核。


八、写在最后

回头看,computer use 是一个工程含量极高的方向。coding agent 面对的是干净的文本环境;computer use 面对的是一个为人设计、充满时序和视觉不确定性的世界。坐标、时序、焦点、权限、上下文、验证、恢复、安全,每一层都要在模型之外补上。

这也意味着两件事:模型能力在趋同,但"在某个具体环境里跑得稳"仍然是应用层的护城河;而真实的企业环境(老系统、虚拟桌面、单点登录、安全软件)比任何 benchmark 都脏,这正是需要人去解决的最后一公里。


参考