Skip to content

Computer Use Agent

CUA(Computer Use Agent)让 Agent 直接"看屏幕、操作鼠标键盘"完成 GUI 任务,而不再依赖被操作方提供 API。Anthropic 在 Claude 3.5 Sonnet 中首次开放 Computer Use 能力,OpenAI 紧接推出 CUA 模型驱动的 Operator 产品线,Browser Use、OpenHands 等开源项目也相继发力。CUA 的能力边界完全由"屏幕能看见什么、键鼠能做什么"决定——任何没有开放 API 的遗留 ERP、桌面软件、内网系统、行政系统都能被 Agent 接管,这是工具调用 Agent 永远无法触达的最后一公里。

CUA 与工具调用 Agent 的区别

工具调用 Agent 操作的是结构化的 JSON 接口,CUA 操作的是屏幕上的像素和操作系统的输入设备。这个本质区别决定了 CUA 在架构上必须额外引入"显示子系统"和"输入注入子系统",Agent 才能感知和控制目标环境。

维度工具调用 AgentCUA
输入自然语言 / 结构化查询截图(多模态视觉)
输出结构化数据鼠标移动、点击、键盘输入、滚动
依赖被调用方提供 API / MCP Server操作系统 + 桌面环境 + 输入设备
错误检测函数返回码屏幕视觉差分 + 元素存在性判断
任务空间受限于工具覆盖范围几乎所有可见的 GUI 操作

CUA 的核心循环与传统 Agent 高度相似——观察 → 推理 → 行动——但观察环节从"读消息"变成"截屏分析",行动环节从"调函数"变成"模拟键鼠"。这意味着每次推理都要把整张屏幕的图片送进多模态模型,token 消耗和延迟都远高于普通 Agent。优化方向主要有两类:缩小截图(只截关键区域、降低分辨率)、用结构化中间表示替代原始像素(DOM 快照、UI 树、可访问性树)。

为什么必须运行在容器里

CUA 本身是一个不可信代理——它会点击任何按钮、输入任何字符、在任意网页上自由操作。如果直接在用户的桌面环境运行,一个 prompt 注入就能让 Agent 删除文件、转账付款、下载恶意程序。把 CUA 装进容器是工业界的基本共识,本质上是给 Agent 一个"沙箱"。

容器提供的隔离能力是 CUA 安全运行的根基。文件系统层,Agent 看到的只是一个独立的 rootfs,写入操作只影响容器层;网络层,可以切断外网或仅放行必要域名,防止 Agent 被反向利用为跳板;进程层,目标软件运行在容器 PID 命名空间,与宿主机进程隔离;权限层,禁用特权模式,去掉 CAP_SYS_ADMIN 等危险能力,让 Agent 无法逃逸。

更重要的工程价值在于可复现性。每台 CUA 容器都从同一个镜像启动,浏览器版本、Cookie、扩展、字体、代理设置完全一致,调试一个任务时跑通的容器可以打包发版给其他节点使用。这种"环境即工件"的能力是 CUA 走向生产部署的前提条件——没有容器化的 CUA 永远停留在 demo 阶段。

容器内 CUA 的核心组件

一个能跑 CUA 的 Linux 容器与传统 Linux 容器最大的区别,是它必须包含完整的图形栈——没有图形栈,CUA 就看不见屏幕、操作不了任何东西。

组件自底向上分四层。最底层是显示协议层,决定屏幕内容如何被绘制:X11 是三十年的老协议,几乎所有 Linux GUI 程序都支持;Wayland 是新一代协议,更现代但部分老旧软件兼容差。中间层是合成器(Compositor),负责把多个窗口合成为一张最终图像:X11 下合成器可以由 X server 兼任,Wayland 下必须由独立的合成器实现(labwc、sway、Weston 都是常见选择)。第三层是远程访问协议层,负责把合成器输出的图像编码后传输出去:VNC 是最广泛兼容的方案,noVNC 让浏览器无需客户端即可连接,RDP 在 Windows 环境更流行。第四层是 Agent 控制器,运行在容器内某个进程中,负责截图、调用多模态模型、解析行动指令、再用输入工具执行——这是 CUA 的"大脑",其余三层都是它的"眼睛"和"手"。

容器内还需要安装输入注入工具,让 Agent 能真正控制鼠标键盘。X11 下用 xdotool 移动鼠标、点击、键入字符,截图用 scrotimport;Wayland 下鼠标键盘工具是 wtype(文本输入)和 dotool/ydotool(鼠标移动和点击),截图用 grim。这些工具是 Agent 与桌面交互的桥梁,比 PyAutoGUI 这种跨平台库更贴近协议层——PyAutoGUI 内部最终还是调用 xdotool,但在容器里直接用 xdotool 脚本更容易调试和审计。

两种主流的显示栈

业界最常见的两套方案都把 VNC 作为远程访问层,因为 VNC 协议足够简单、客户端兼容性好、H.264 编码成熟。区别在于显示协议层的选型。

X11 + Xtigervnc 路线

早期方案是分两步走:先用 Xvfb 启动一个无头 X server 提供显示能力,再启动 x11vnc 把 X server 的画面编码成 VNC 流。这种方案有两个明显缺陷——Xvfb 没有合成器,所有窗口绘制都是软件光栅,CPU 占用高;x11vnc 性能瓶颈大,延迟通常在 100ms 以上。

Xtigervnc(TigerVNC 项目的子模块)把 X server 和 VNC server 合二为一,启动一个进程就同时提供 X11 显示和 VNC 访问,绕过了 Xvfb + x11vnc 的双进程开销。dtinth/xtigervnc-docker 是这个路线的代表性镜像,十几行 Dockerfile 就能起一个完整桌面,国内不少 CUA 项目的镜像也是 fork 自此。

X11 路线最大的优势是兼容性——几乎所有 Linux GUI 程序都默认支持 X11,不需要额外适配。DISPLAY=:1 xdotool ... 这种命令在任何 Linux 容器里都能直接运行,对调试和原型验证非常友好。劣势在于 X11 本身的安全模型已经过时,键盘记录、截屏攻击、网络嗅探都是协议层面就能做到的事;以及 X11 的窗口坐标体系对现代多 DPI 屏幕支持混乱,在 4K 屏幕上 Agent 看到的截图分辨率可能与实际操作坐标不一致。

Wayland + labwc 路线

Wayland 是新一代显示协议,架构上比 X11 干净得多:合成器独占屏幕,每个应用通过协议直接提交窗口内容,截图、输入注入都是合成器提供的官方能力。labwc 是一个轻量级 Wayland 合成器,定位是"Openbox 的 Wayland 替代品",配置文件兼容 Openbox 的格式,启动只需几兆内存,适合塞进容器。

XT-Martinez/labwc-headless-docker 是这个路线的典型实现:labwc 作为合成器,wayvnc 把 labwc 的画面编码成 VNC 流,二者通过 Wayland 协议内部的截图和输入注入 API 协作。整套方案没有 X11 的任何代码,协议层面就杜绝了 X11 的诸多安全问题。

Wayland 路线的优势是延迟低、协议安全、内存占用小,特别适合多 CUA 实例并发的场景——单个宿主上可以同时跑十几个 labwc 容器,每个内存开销仅几十兆。劣势在于兼容性:部分老旧 GUI 程序还没有原生 Wayland 支持,需要跑在 XWayland 兼容层;部分截图/输入工具还在用 X11 的 API,需要换成 grimwtypeydotool 这套工具链;以及 Wayland 生态文档相比 X11 还是稀薄一些,踩坑时社区答案少。

选型对比

新项目无特殊依赖优先选 Wayland + labwc,延迟低、安全模型好、并发友好;遇到老旧 GUI 软件或调试复杂问题时回退 X11 + Xtigervnc,最大兼容性是它的护城河。两种方案都可以叠加 noVNC,让 Agent 通过浏览器访问容器,省去 VNC 客户端。

参考项目:dtinth/xtigervnc-docker(X11 路线)、XT-Martinez/labwc-headless-docker(Wayland 路线)、livinhigh/claude-computer-use-agent(多 VNC 显示隔离 + Anthropic Computer Use API 的 FastAPI 集成)、NAISYS/xfce-computer-use-guide(XFCE 桌面 + TigerVNC 的生产级实践指南)。这些项目的 Dockerfile 和脚本都是工业界验证过的模板,可以直接 fork 改造。

Agent 接入显示栈的工作流

Agent 在容器内的工作流是一个紧凑的循环。截图工具抓取当前合成器的输出,编码成 PNG/JPG 送进多模态模型;模型结合用户目标和历史轨迹,输出下一步动作——点击坐标 (x, y)、键入文本 hello、滚动 delta_y=300、等待 wait 2s;Agent 控制器解析动作指令,调用对应的输入工具执行;执行后再次截图,进入下一轮循环。

动作语义的规范化是工程关键。直接让模型输出 (x, y) 坐标是脆弱的,屏幕分辨率变化、网页响应式布局、缩放级别都会让坐标失效。更鲁棒的做法是让模型输出"语义动作"——click_button("提交")type_into_field("邮箱", "user@example.com")scroll_to("页面底部")——由 Agent 控制器翻译成具体的 xdotool/wtype 调用,翻译过程可以加入"先定位元素再点击"的中间步骤,提升成功率。

多模态模型的输入优化是性能瓶颈。每张截图 100KB 起,5MB 大图很常见。1280×720 的截图压缩后大约 500-800 token,2560×1440 直接超过 2000 token——一个 30 步的 CUA 任务,光截图就要消耗 6 万 token。优化手段包括:截图前裁剪到感兴趣区域(去掉空白和无关元素)、降低分辨率到 1024×768、统一缩放到模型训练的分辨率、用结构化表示(DOM 树、可访问性树)替代原始像素。

工程经验与陷阱

CUA 在生产环境跑起来后,真正的难点不是模型能力,而是"模型和现实之间"的无数边界条件。焦点丢失是最经典的坑——xdotool 点击 (x, y) 之前没有先 xdotool windowactivate,可能点到的是另一个窗口或者任务栏;多显示器环境同样要小心,DISPLAY=:1 选错了显示器,所有坐标全错位。

DPI 缩放是另一个深坑。宿主机 4K 屏配 200% 缩放,VNC 推流给 Agent 的画面按什么 DPI 计算?合成器内坐标和物理像素的对应关系在 X11 和 Wayland 下完全不同,跨平台迁移 Agent 脚本时务必把缩放参数当作一等公民处理。Cookie 弹窗、模态对话框、登录验证码这些"打断流程的元素"也要在 prompt 里提前警告,让模型遇到它们时主动等待或者截图给运维介入,而不是傻乎乎地点确认按钮。

反检测是商业 CUA 部署的高级话题。Cloudflare、Akamai 等服务的反机器人系统会通过 WebGL 指纹、Canvas 噪声、鼠标轨迹熵检测 CUA 流量。要让 CUA 看起来像真人,需要在 Agent 控制器里加入随机延迟、贝塞尔曲线鼠标轨迹、随机滚动、偶尔的"误触"回退,这些策略比模型能力更影响实际成功率。