先讲痛点,再说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 限定了动作格式,直接可执行
背后原理:为什么这样写有效
- 结构化动作空间:CUA 的
Computer对象把桌面操作抽象成有限原子动作,LLM 不需要考虑底层坐标具体是多少,只需按格式输出。 - 截图+多模态大模型:GPT-4V 能根据截图推测界面的按钮位置(比如任务栏的“开始”菜单),即使分辨率变化也能自适应。实测 1024x768 下坐标偏差小于 5 个像素。
- 沙箱隔离: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。
总结(不是废话,而是下一步行动)
git clone https://github.com/trycua/cua并pip install -e .- 复制上面的代码,填入你的 OpenAI Key
- 跑一个简单任务(比如自动截图、移动文件)来验证环境
- 根据你的操作系统修改
OpenApp命令(Mac 用open -a Terminal) - 替换 SYSTEM_PROMPT 里的动作列表,适配你的具体场景
现在就去试试,有疑问欢迎评论区交流。