1. "cua"的三重身份:先从热搜词聊到技术主线
最近几个技术交流群和社交平台上,“cua”这三个字母的出镜率突然高了起来。有人把它当拟声词刷,说“cua的一下就完成了”,有人拿着某个名字很像的开源项目来问,但如果把讨论上下文拉到一起看,会发现真正被反复推到台前的,是Computer-Using Agent这个方向,缩写刚好就是CUA。这个词在2025年密集出现,不是小众黑话,而是AI Agent赛道里非常具体的一条技术路线:让模型直接看屏幕、理解界面、像人一样操作鼠标键盘。这篇文章我把从概念到落地一套最小CUA环境的过程完整拆开,包括底层原理、工具选型、实测数据和踩坑记录,给正在研究这个方向的朋友一个可以动手照着做的样本。
1.1 先分清:你看到的"cua"是哪一个
在聊技术之前,得先把词义厘清。第一次看到“cua”,我也以为是什么方言谐音或者语气词——确实有人用它模拟“唰的一下”那种快速动作的声音,也有方言区的人用它表示“敲”“拍”的动作。另外Lua社区里有一个轻量Web框架也叫Cua,一小部分人聊的是这个。但从热点讨论的语境来看,绝大多数场景下,大家说的都是Computer-Using Agent,翻译过来就是“会操作电脑的智能体”。
判断方法其实很简单:如果这句话的上下文里出现了“Agent”“自动操作”“视觉模型”“鼠标键盘”这几个词里的任何一个,基本可以确定是后者。如果只是玩梗,跟技术没有太大关系。我在群里回复这类问题时,会先让对方发一下原始链接,避免几个人对着同一个缩写聊出三个方向。
1.2 Computer-Using Agent是什么,为什么是2025年爆发
CUA的定义不复杂:一个能够通过理解屏幕画面、定位界面元素、输出鼠标键盘操作序列,来完成真实电脑任务的智能体。它和传统聊天式Agent最大的区别在于,聊天式Agent只负责“说话”,CUA负责“动手”。
举个例子,以前你让AI助手“把桌面上那个Excel里的数据整理成表格发邮件”,传统Agent最多帮你写一段Python脚本,你还得自己跑、自己调试。而CUA的思路是:它先截取你的屏幕,看到桌面图标、Excel图标、邮件客户端界面之后,自己移动鼠标双击打开Excel,选中数据区域,打开邮件客户端,填写收件人和正文,点击发送。整个过程和你本人操作电脑没有本质区别。
为什么是2025年才集中爆发,我觉得有三个直接原因:
- 多模态模型的理解能力跨过了一个门槛。前几年的视觉模型能识别图像内容,但对“这是登录页”“这个按钮是提交”“这里需要输入验证码”这类界面语义的理解还很弱。新一代多模态模型在UI理解、截图问答、控件定位上有了质的变化,这是CUA能成立的前提。
- 模型调用成本降到了可以高频试错的程度。CUA一次任务要连续截图、反复推理,token消耗远高于普通对话。推理成本下降之后,实验和迭代的试错成本也降了下来。
- RPA和低代码自动化做了多年市场教育。企业早就理解“能用程序替代重复人工操作”的价值,CUA不需要像RPA那样复杂的元素选择器,接受门槛更低。
1.3 一张表看清CUA与传统自动化的分界
不少人会把CUA和RPA、传统UI自动化测试混在一起,实际区别非常大,我用一个表格直接对比:
| 对比项 | 传统RPA | 传统UI自动化测试 | CUA |
|---|---|---|---|
| 感知方式 | 固定坐标、控件选择器、录制脚本 | DOM元素、CSS选择器、XPath | 屏幕图像 + 可选的无障碍树/HTML语义 |
| 执行方式 | 执行脚本逻辑 | 执行测试用例代码 | 模型实时决策,输出动作序列 |
| 抗界面变动能力 | 弱,布局一改就失效 | 一般,选择器需要维护 | 较强,靠视觉理解适应小变动 |
| 适用场景 | 规则固定的重复操作 | 软件功能回归验证 | 跨应用、看情况调整的复杂任务 |
| 上手成本 | 需要学习工具、维护选择器 | 需要写代码、维护测试库 | 需要设计提示词、建立反馈闭环 |
这里最核心的分界线是“决策者是谁”。RPA和传统自动化里的逻辑是程序预先写死的,界面元素变了就断;CUA的每一步动作都是模型在看到当前屏幕后实时决定的,它更像是雇了一个“看得懂屏幕的实习生”,虽然偶有失误,但能适应大量不规则的场景。
2. CUA的底层闭环:屏幕感知、决策与动作执行
想用好CUA,光知道概念不够,得把它的工作闭环拆开看。一个完整的CUA流程,本质上是“感知→决策→执行→反馈”的不停循环,和人类操作电脑的认知过程是对应的。
2.1 屏幕怎么"喂"给模型:纯视觉与辅助信号两条路线
目前主流方案有两条路,一条是纯视觉,另一条是视觉加辅助结构化信号。
纯视觉路线最简单粗暴,直接把全屏或窗口截图传给多模态模型。它的好处是通用性强,任何能显示出来的界面都能处理,不需要额外开发适配。缺点是模型要自己从像素里推测哪些区域是按钮、哪些区域是输入框,对模糊背景、复杂界面的理解会打折扣,而且全屏截图很费token。
混合路线则是在截图之外,额外传入操作系统的无障碍树(Accessibility Tree)、浏览器DOM结构或者小程序里类似的控件描述。这些结构化数据会告诉模型每个控件的类型、文本、坐标范围,理解难度下降不少,准确率能提升一截。代价是需要运行环境支持获取这类信息,不是所有电脑都那么配合。浏览器页面用DOM辅助最方便,原生桌面应用就得看无障碍接口支持了。
我在实际项目里采用的是混合方式:能用浏览器打开的测试目标,就用Playwright的DOM树辅助;必须操作原生窗口时,退回纯视觉加坐标映射。两条路线并存,比只押一条稳得多。
2.2 模型输出的动作:从自然语言到可执行JSON
CUA的决策环节,核心是让模型输出结构化动作,而不是长篇大论的自然语言。常用的动作类型就四类:移动鼠标、点击按键、输入文本、滚动滚轮。为了让程序能直接解析,最好在提示词里约定统一格式。
我习惯用下面这样的JSON结构作为模型输出协议:
{ "thought": "当前页面显示登录表单,需要先点击用户名输入框", "action": "click", "params": { "x": 584, "y": 362 } }另一个典型动作是输入文本:
{ "thought": "用户名输入框已聚焦,输入用户名", "action": "type", "params": { "text": "admin", "enter": false } }这背后的道理很简单:模型的空间认知能力还不支持它输出“绝对精确到每一帧”的像素坐标,但支持它在截图坐标范围内给出一个大概位置;通过循环截图不断逼近,就能把误差消掉。把输出约束成JSON,是让这一整套系统可工程化的关键一步。
2.3 执行之后怎么确认:反馈闭环才是CUA的灵魂
很多第一次做CUA的人会忽略反馈环节,以为模型点了按钮、输入完文字就完事了。但真实界面的状态是动态的:按钮可能点下去没反应,弹窗可能突然冒出来,输入框可能有格式校验。没有反馈闭环的CUA,就是蒙着眼睛开车。
反馈闭环通常这样做:执行完一个动作后,程序自动截取一张新的屏幕图,交给模型判断“上一个动作是否生效”“当前页面状态是否符合预期”“如果不符合,应该采取什么纠正动作”。这个“判断→执行→再判断”的循环,让整个系统具备了自我纠错的能力。我在前面的项目里,反馈式的循环大约占了整个代码量的四成,比调用模型的部分还多,但它恰恰是稳定性提升最大的一块。
3. 动手搭一套最小CUA环境:选型逻辑与完整步骤
概念聊完,直接上实操。我会给你一套最小可用的CUA环境搭建过程,全程跑在本地,目标是让模型自动操作一个Windows计算器程序,完成“输入两个数字并求和”这个任务。
3.1 三条技术路线怎么选
市面上的CUA方案大概分三类,各有取舍:
| 方案 | 上手速度 | 隐私性 | 成本 | 适合人群 |
|---|---|---|---|---|
| 商业API(Claude Computer Use等) | 最快,按文档接入即可 | 低,屏幕数据要上传 | 按token计费,长任务偏贵 | 想快速验证效果的个人或团队 |
| 本地多模态模型(Qwen2.5-VL等) | 需要部署环境 | 高,数据不出本机 | GPU设备贵,推理耗电 | 对隐私敏感的企业场景 |
| 自组装(截图+任意视觉模型+pyautogui) | 中等,灵活度最高 | 取决于用哪个模型 | 可控,按需调用不同模型 | 想理解原理、定制化需求多的人 |
我第一次落地时选的是自组装方案,原因有三点:一是可以随时更换底层视觉模型,不被厂商绑定;二是能把每一步的截图和中间结果都记录下来,调试方便;三是代码完全可控,后续接任何模型都只需要改一个函数。
3.2 最小环境依赖与目标应用选择
技术选型定了之后,准备工作其实很少。我用到的组件有这些:
- Python 3.11,最好用虚拟环境隔离
- Pillow:负责截图
- pyautogui:负责模拟鼠标移动、点击和键盘输入
- 一个多模态视觉模型的API访问方式,或者本地部署的模型服务
测试目标我选了Windows自带的计算器。为什么选它?因为它界面固定、没有登录逻辑、不需要处理复杂动画,非常适合验证“截图→决策→点击→反馈”这条核心链路。等这个跑通了,再上真实业务系统会轻松很多。
安装依赖就三条命令:
pip install pillow pip install pyautogui pip install openai # 或者其他模型SDK3.3 核心代码骨架:截图-决策-执行-反馈循环
下面是一段最小可跑的核心逻辑,我尽量把关键部分展示出来:
import json import time from PIL import ImageGrab import pyautogui # 其他地方定义好 ask_model(),负责把截图送给多模态模型并返回结构化动作 def capture_screen(): img = ImageGrab.grab() img.save("screen.png") return "screen.png" def execute_action(action): action_type = action.get("action") params = action.get("params", {}) if action_type == "click": x, y = params["x"], params["y"] pyautogui.click(x, y) print(f"[执行] 点击坐标 ({x}, {y})") elif action_type == "type": pyautogui.write(params["text"]) if params.get("enter"): pyautogui.press("enter") print(f"[执行] 输入文本 {params['text']}") elif action_type == "scroll": pyautogui.scroll(params.get("delta", 0)) else: print(f"[跳过] 无法识别的动作: {action_type}") SYSTEM_PROMPT = """ 你是一个电脑操作员。我会给你一张屏幕截图,请分析当前界面, 然后输出下一步应该执行的操作。只输出JSON,不要输出任何解释。 action 只能取 click / type / scroll。 点击坐标必须是截图上的像素坐标。 """ def run_loop(max_steps=10): for step in range(max_steps): img_path = capture_screen() action = ask_model(img_path, SYSTEM_PROMPT) print(f"[第{step + 1}步] 模型决策: {json.dumps(action, ensure_ascii=False)}") execute_action(action) time.sleep(2) run_loop()这段代码干的事就是三个动作:截图、问模型、执行。每执行一步就等一下,让界面状态稳定后再进入下一轮判断。
3.4 提示词里必须写清楚的事
自组装方案的效果很大程度取决于提示词。我踩过几次后总结出,CUA提示词必须包含四个要素:
- 角色设定:明确告诉模型“你是一个电脑操作员,直接观察屏幕并操作”。
- 输出格式约束:只允许输出JSON,字段名和取值范围都要写死。
- 任务目标:要说清楚“最终要完成什么”,比如“打开计算器,计算123+456的结果”。
- 边界约束:提醒模型“不要点击无法确认的区域”“不要执行删除类高风险操作”,把自由度过大的空间先收住。
一个写得很清晰的提示词开头大概是这样的:“你是一个电脑操作员。你看到的是一张Windows计算器界面的截图,任务目标是计算123+456。请分析当前界面,输出下一步操作。只允许输出JSON,action字段仅支持click、type、scroll,坐标必须是截图内的像素坐标。”
4. 实测中的关键参数与优化:让CUA从"能跑"到"跑得稳"
第一版跑通只是起点,要让CUA真正稳定可用,必须在实测中处理几个绕不开的问题。
4.1 截图分辨率、DPI缩放与坐标系映射
这是我遇到的第一个硬坑。Windows系统默认会开启DPI缩放,很多笔记本的显示缩放比例是125%或者150%,导致ImageGrab截出来的图像尺寸和pyautogui实际控制的物理屏幕坐标不对应。模型看到的是截图坐标,点击动作却要发到物理坐标,不换算的话,每个点击都会偏移。
解决办法是先拿到缩放因子:
import tkinter as tk root = tk.Tk() scale = root.winfo_fpixels('1i') / 96 # 获取系统DPI缩放比例 root.destroy() print(f"当前系统缩放比例: {scale}")然后把模型给出的截图坐标乘以这个比例,转换成物理屏幕坐标再交给pyautogui。多显示器环境更麻烦一些,负坐标、不同缩放比会混在一起,我的建议是先固定一个主屏做测试,跑通后再处理扩展屏幕。
4.2 等待策略:用界面状态轮询替代固定sleep
一开始我直接用time.sleep(2)等待界面响应,运行几个任务后发现一个尴尬问题:如果界面响应快,这2秒纯属浪费;如果弹出个对话框卡住了,等再久也没用。固定的等待时间既拖慢了任务,又掩盖了异常状态。
后来我把等待逻辑改成了状态轮询:执行完动作后,每隔800毫秒截一次图,把当前截图和前一步的截图做对比,如果两张图的差异面积小于某个阈值,就认为界面已经稳定,可以进入下一步;超过一定轮询次数还没稳定,就判定该步骤异常,进入恢复流程。这个思路和人类等待页面加载是一个道理,你不是傻等,而是不断看页面好了没有。
4.3 任务规划与token成本控制
CUA的token消耗比普通对话高一个量级,尤其是采用全屏截图加单步决策的模式时,每步都要传一张截图给模型,走完一个十步任务,token消耗轻松过万。这里有几个控制成本的实测经验:
- 缩小截图区域:不用每次都截全屏,固定任务里截主窗口区域就够了,既省token又减少背景干扰。
- 裁剪动态区域:如果界面只有一块区域会变化,用上次截图时的坐标信息把变化区域裁剪出来,只传这部分给模型。
- 低频决策:不是每一步都需要模型深度推理。动作执行后的简单状态判断,可以用图像像素差异这种低成本脚本完成,只有遇到异常分支时才唤醒模型重新规划。
说实话,token成本这个事如果一开始不控制,很容易劝退团队。先把流程跑通,再逐步优化调用频率,是更务实的路径。
4.4 加一道"人在回路"的安全闸门
全自动的CUA跑起来很爽,但也藏着风险。谁也不能保证模型在复杂界面里不会突然点错按钮、误触发某个危险操作。所以在实际项目中,我给CUA加了两层闸门。
第一层是操作白名单:在代码层面对click、type、scroll以外的动作一律拒绝,同时对点击坐标范围做限制,超出预设窗口区域的点击直接丢弃。第二层是人工确认:任务开始时模型先生成一个完整操作计划,由人过目确认后才开始执行;执行过程中每完成一个高风险动作,暂停等待确认。这样做确实损失了一些自动化程度,但换来了很高的安全感,尤其是在操作真实业务系统时。
5. 踩坑记录:一次完整的问题排查链路
这一节记录一次让我印象深刻的排查过程。问题看着很简单,但排查链路相当有代表性。
5.1 现象:模型一直点击目标右侧偏移约15像素
某天实测时,更换了一个底层视觉模型后,所有点击动作都偏离目标按钮约15个像素。点输入框会点到输入框右侧边缘,点按钮会点到按钮右边界。误差稳定、方向一致,不是偶发问题。
我首先怀疑是模型定位能力下降了,于是换回旧模型,结果老模型也出现同样偏移。这就排除了模型能力因素,问题肯定出在环境或映射逻辑上。
5.2 排查:从显示器缩放比例到截图裁剪区
顺着环境因素排查,我先后检查了三处:
第一是缩放比例。前面提到过,系统DPI缩放会导致坐标偏移,但我确认了scale获取逻辑没变,而且计算器窗口一直在屏幕中央,缩放导致的不应该只是向右偏,而是整体偏移,这个嫌疑暂时排除。
第二是截图区域的裁剪。查看日志后我发现,因为某个任务设置了固定裁剪区域,截图范围并不是全屏,而是屏幕中间的窗口区域。裁出来的图虽然看起来正常,但模型的坐标输出是基于裁剪后的这张图的,执行时我却没有加上裁剪区域相对全屏的左上角偏移量,导致所有坐标都少了170像素左右的基准偏移。
等等——15像素这个数值和170像素对不上。进一步翻代码发现,裁剪区域坐标在代码中被重复应用了两次,其中一次偏移量是156像素,叠加DPI缩放后刚好表现为约15像素的视觉偏移。问题的根子不在模型,而在坐标系基准不统一:模型基于裁剪图输出坐标,而执行器按全屏坐标执行,中间差了一个裁剪区域偏移量。
5.3 定位与修复:统一坐标基准
定位之后修复很简单,把裁剪区域的左上角坐标加回模型输出上,然后再乘以缩放因子:
# 某次点击坐标换算 screen_x = (model_x + crop_left) * scale screen_y = (model_y + crop_top) * scale改完之后再次跑同样的任务,所有点击位置都精准落在目标控件内部,连续跑了20次只有一次因为弹窗遮挡失败。这个修复没有动模型,纯粹是修正了坐标换算逻辑。
5.4 这次排查留下的三个经验
这次之后我总结了三件事,分享给同样做CUA的朋友:
- 任何坐标都要有一个明确的基准坐标系。截图之前先定义好:模型看到的是哪张图,这张图的坐标系原点在哪,转换成物理屏幕坐标时经过几步换算。每步换算都应该有日志。
- 更换模型时要回归测试坐标换算。新模型的输出格式可能完全一致,但对截图边界的理解有细微差别,不回归测试很难发现。
- 排查问题时先锁定变量。我一开始怀疑模型换了导致偏差,但换回旧模型后问题依然存在,说明根因在外部环境。先用双变量法锁定是“模型问题”还是“环境问题”,再去翻细节,效率最高。
6. 从演示到工作流:CUA能接的几类真实活
最小环境跑通、稳定性调到可接受程度之后,CUA真正有价值的地方就出来了——它能把以前需要人肉处理的场景批量自动化。以下这几类是我实操中验证过的方向。
6.1 UI回归测试:让模型当"人眼"
传统UI自动化测试最大的痛点是选择器脆弱、维护成本高,页面稍微改版用例就挂。CUA在这里的用法是:让测试用例描述变成一句句自然语言操作步骤,比如“点击右上角登录按钮,输入账号密码,点击提交,断言页面右上角出现用户名”。模型自己看屏幕执行操作,用几张关键节点的截图作为断言依据,页面细节变了也不容易误报。
6.2 跨应用数据搬运:最典型的RPA替代场景
跨应用数据搬运是RPA的传统主场,CUA在这里的优势是不需要逐个控件写选择器。实际做过一个场景:从Excel的几列数据里读取内容,填入一个老旧的网页系统表单,点击保存后自动进入下一条。用RPA做这套,要在网页上提取控件路径、处理各种弹窗;用CUA,模型每一步都在看屏幕,遇到异常弹窗它自己识别、自己处理,整个流程的健壮性高了不少。
6.3 运维和旧系统场景:看得懂屏幕就能接管
很多老旧系统没有API,没有数据库直连权限,也没有自动化接口,只能在界面上操作。过去这些场景只能靠人肉,现在CUA补上了这个空缺。运维场景里的典型用法包括:自动识别并关闭异常弹窗、按固定流程巡检界面状态、在系统恢复后自动重新登录并完成数据同步。
我给一个用户的建议是从小处切入:每周一次的报表下载和数据整理,脚本只要能跑通这一个场景,节省的时间就足够覆盖成本了。
6.4 给团队落地CUA的节奏建议
如果说前面是横向场景,最后这条算纵向节奏建议。我见过不少团队一上来就规划“全自动无人值守大项目”,结果界面一换、模型一升级就崩,最后不了了之。
稳健的落地节奏我认为是三步:
- 先跑半CUA:模型负责决策和执行,人负责确认计划、监控状态。自动化程度不用强求100%,先把准确率拉起来。
- 挑一个稳定的小场景:流程尽量固定、操作风险低、反馈明确的场景,连续稳定运行两到三周,积累数据和信心。
- 再引入异常恢复机制:当小场景稳定以后,再逐步放开让模型自己处理异常分支,比如弹窗误点、输入校验失败等。每放开一种异常处理能力,都要单独验证一轮。
我在实际项目里最深的体会是,CUA的瓶颈往往不是模型不够聪明,而是工程侧的地基不牢:坐标换算、反馈闭环、日志回溯、安全闸门,这些细节做好了,一个"看得懂屏幕的执行器"才能真正变成生产力。如果只是体验技术,先把计算器那个demo跑起来就够了;但如果要考虑投入真实业务,建议就从上面的第一步——跑稳一个小场景、做全操作记录——开始。