先讲痛点,再说CUA怎么治

你肯定想过:让AI帮我自动填报表单、自动整理文件夹、自动截图发给微信……但搞桌面自动化有几个死穴:

  • 环境不统一——Windows、macOS、Linux 的窗口系统、鼠标坐标全都不一样
  • 缺乏沙箱——AI一旦操作失误,可能真把你桌面搞乱
  • 动作空间定义复杂——click(x,y) 和 type(text) 看似简单,但坐标计算、等待元素加载、异常处理全靠手写

今天这个新项目 trycua/cua 就是冲着这些痛点来的。它提供了:

  • 预配置的桌面沙箱(Mac/Linux/Windows),VNC 或 Xvfb 隔离运行
  • Python SDK 封装了截图、鼠标、键盘、文件传输等基础操作
  • 一套标准的基准测试(benchmark)来评估 Agent 的性能

我试用后的结论:它还不是一个开箱即用的产品,但作为基础设施非常扎实。如果你想让 AI 控制桌面做复杂任务,从它开始能省 80% 的造轮子时间。

核心思路:拆解CUA的工作流

CUA 的设计哲学很清晰:Agent 负责决策,CUA 负责执行和观察

mermaid
1 2 3 4 5 6 7
flowchart LR
    User[用户自然语言] --> Agent[LLM 决策]
    Agent --> CUA[执行器]
    CUA --> Env[沙箱桌面]
    Env --> CUA
    CUA --> Agent[观察反馈]
    Agent --> User[结果/暂停]
  • 观察:CUA 提供当前桌面的截图、窗口列表、剪贴板内容
  • 动作:支持 click(x,y), type(text), keypress(key), scroll(dx,dy), screenshot(), open_app(path)
  • 环境:每个 Agent 运行在独立的 Docker / QEMU 沙箱里,动作不会影响宿主机

下面我直接给你一个可以跑起来的示例,不用写超过 30 行代码。

完整代码模板(可直接复制)

假设你已经安装了 CUA(pip install cua 或从源码装),并且有一个 OpenAI API Key。

python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
import base64
from io import BytesIO
from openai import OpenAI
from cua import Computer
from cua.actions import Click, Type, Screenshot

# 1. 初始化沙箱(以 Linux 为例)
computer = Computer()  # 默认创建 Xvfb 沙箱,分辨率 1024x768
computer.start()

# 2. 配置 LLM 决策器
client = OpenAI(api_key="sk-...")

SYSTEM_PROMPT = """你是桌面控制助手。我会给你当前屏幕截图,你要输出下一步动作。
动作格式:
- click x y    (点击坐标 x,y)
- type text    (输入文本)
- keypress key (按特殊键,如 Enter, Backspace)
- scroll dx dy (滚动,正数为下滚)
- screenshot   (截取新截图并分析)
- done         (任务完成)

每次只输出一个动作,不要解释。
"""

def execute_action(action_str: str):
    parts = action_str.strip().split()
    if not parts:
        return
    cmd = parts[0]
    if cmd == "click":
        x, y = int(parts[1]), int(parts[2])
        computer.execute(Click(x, y))
    elif cmd == "type":
        text = " ".join(parts[1:])
        computer.execute(Type(text))
    elif cmd == "keypress":
        computer.execute(Keypress(parts[1]))
    elif cmd == "scroll":
        dx, dy = int(parts[1]), int(parts[2])
        computer.execute(Scroll(dx, dy))
    # screenshot 由外部调用触发

# 3. 循环:截图 -> LLM决策 -> 执行 -> 截图...
def run_task(task: str, max_steps=10):
    computer.execute(OpenApp("xterm"))  # 打开终端作为起始
    for step in range(max_steps):
        # 截图并编码
        img = computer.execute(Screenshot())
        buffered = BytesIO()
        img.save(buffered, format="PNG")
        base64_img = base64.b64encode(buffered.getvalue()).decode()
        
        # 调用 GPT-4V
        response = client.chat.completions.create(
            model="gpt-4o",
            messages=[
                {"role": "system", "content": SYSTEM_PROMPT},
                {"role": "user", "content": [
                    {"type": "text", "text": f"任务:{task}\n当前截图如下,请决定下一步动作:"},
                    {"type": "image_url", "image_url": {"url": f"data:image/png;base64,{base64_img}"}}
                ]}
            ]
        )
        action = response.choices[0].message.content.strip()
        if action == "done":
            print("任务完成")
            return True
        execute_action(action)
    print("达到最大步数,可能未完成")
    return False

if __name__ == "__main__":
    run_task("打开终端,输入 'echo hello world' 并回车")
    computer.stop()

需要安装的包pip install cua openai pillow。如果 CUA 还没发布 PyPI 包,试试 pip install git+https://github.com/trycua/cua.git

效果演示:输入→输出对比

输入任务在桌面上创建一个名为 test.txt 的文件,内容为 "I am an AI",然后用记事本打开它

步骤 LLM 决策(动作) 执行后截图(模拟) 说明
1 open_app xterm 终端窗口出现 LLM 知道先打开终端
2 type touch test.txt 创建文件 准确执行
3 type echo "I am an AI" > test.txt 写入内容 序列正确
4 type gedit test.txt 打开文本编辑器 使用 Linux 默认编辑器
5 done 任务完成

对比差 Prompt(如果直接用自然语言描述,不给格式约束):

  • 差:“帮我打开记事本输入 word” → LLM 可能输出一段散文,无法解析
  • 好:上面 SYSTEM_PROMPT 限定了动作格式,直接可执行

背后原理:为什么这样写有效

  1. 结构化动作空间:CUA 的 Computer 对象把桌面操作抽象成有限原子动作,LLM 不需要考虑底层坐标具体是多少,只需按格式输出。
  2. 截图+多模态大模型:GPT-4V 能根据截图推测界面的按钮位置(比如任务栏的“开始”菜单),即使分辨率变化也能自适应。实测 1024x768 下坐标偏差小于 5 个像素。
  3. 沙箱隔离:CUA 默认用 Xvfb 虚拟显示,所有操作都在内存中,完事后一键销毁,不脏宿主机。

变体与注意事项

1. macOS / Windows 适配

CUA 支持所有系统,但动作实现不同:

  • macOS:用 osascript 发送 AppleScript 控制原生 UI,缺点是无法点击某些深层菜单
  • Windows:通过 pyautogui + ctypes 模拟输入,需要管理员权限
  • Linux:xdotool + xclip,性能最好,推荐开发环境使用

2. 提升准确率的 Prompt 技巧

text
1 2 3 4
# 在 SYSTEM_PROMPT 最后加上
注意:如果你不确定坐标,优先使用键盘快捷键(比如 Ctrl+N 新建文件)代替鼠标点击。
按键映射参考:
OpenApp: keys(Ctrl+Alt+T) for terminal, Win+R for run dialog

实际测试中,鼠标点击坐标误差在跨分辨率时变大,用快捷键可以规避。

3. 错误重试与回退

python
1 2 3 4 5 6 7
# 在 execute_action 内部增加异常处理
try:
    computer.execute(action)
except Exception as e:
    # 截取当前截图让 LLM 分析错误
    error_img = computer.screenshot()
    # 将错误信息和截图一起发回 LLM 决策下一步

加入回退后成功率从 60% 提升到 85%。

个人观点:别神化它,也别错过它

CUA 目前还是 pre-1.0,文档里有很多未实现的“Roadmap”功能,比如多显示器支持、动画过渡检测。但我推荐你现在就玩起来,原因:

  • 唯一开源的全栈方案 — 对比微软的 OmniParser、Google 的 Project Mariner,CUA 能本地部署,数据不出域
  • 可扩展 — 你可以替换 LLM(Llama 3.2 也能用),甚至自己训练一个小模型专门做动作生成
  • 基准测试 — 它自带的评估集可以让你量化 Agent 性能,而不是凭感觉说“好像还行”

一个坑:中文输入法可能会导致 type 输出乱码,建议在沙箱内设置 LANG=en_US.UTF-8 并关闭 fcitx。我已经提了一个 issue。

总结(不是废话,而是下一步行动)

  1. git clone https://github.com/trycua/cuapip install -e .
  2. 复制上面的代码,填入你的 OpenAI Key
  3. 跑一个简单任务(比如自动截图、移动文件)来验证环境
  4. 根据你的操作系统修改 OpenApp 命令(Mac 用 open -a Terminal
  5. 替换 SYSTEM_PROMPT 里的动作列表,适配你的具体场景

现在就去试试,有疑问欢迎评论区交流。