news 2026/9/24 23:30:32

CUA智能体实战:从多模态屏幕感知到自动操作的核心技术拆解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CUA智能体实战:从多模态屏幕感知到自动操作的核心技术拆解

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年才集中爆发,我觉得有三个直接原因:

  1. 多模态模型的理解能力跨过了一个门槛。前几年的视觉模型能识别图像内容,但对“这是登录页”“这个按钮是提交”“这里需要输入验证码”这类界面语义的理解还很弱。新一代多模态模型在UI理解、截图问答、控件定位上有了质的变化,这是CUA能成立的前提。
  2. 模型调用成本降到了可以高频试错的程度。CUA一次任务要连续截图、反复推理,token消耗远高于普通对话。推理成本下降之后,实验和迭代的试错成本也降了下来。
  3. 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 # 或者其他模型SDK

3.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提示词必须包含四个要素:

  1. 角色设定:明确告诉模型“你是一个电脑操作员,直接观察屏幕并操作”。
  2. 输出格式约束:只允许输出JSON,字段名和取值范围都要写死。
  3. 任务目标:要说清楚“最终要完成什么”,比如“打开计算器,计算123+456的结果”。
  4. 边界约束:提醒模型“不要点击无法确认的区域”“不要执行删除类高风险操作”,把自由度过大的空间先收住。

一个写得很清晰的提示词开头大概是这样的:“你是一个电脑操作员。你看到的是一张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的朋友:

  1. 任何坐标都要有一个明确的基准坐标系。截图之前先定义好:模型看到的是哪张图,这张图的坐标系原点在哪,转换成物理屏幕坐标时经过几步换算。每步换算都应该有日志。
  2. 更换模型时要回归测试坐标换算。新模型的输出格式可能完全一致,但对截图边界的理解有细微差别,不回归测试很难发现。
  3. 排查问题时先锁定变量。我一开始怀疑模型换了导致偏差,但换回旧模型后问题依然存在,说明根因在外部环境。先用双变量法锁定是“模型问题”还是“环境问题”,再去翻细节,效率最高。

6. 从演示到工作流:CUA能接的几类真实活

最小环境跑通、稳定性调到可接受程度之后,CUA真正有价值的地方就出来了——它能把以前需要人肉处理的场景批量自动化。以下这几类是我实操中验证过的方向。

6.1 UI回归测试:让模型当"人眼"

传统UI自动化测试最大的痛点是选择器脆弱、维护成本高,页面稍微改版用例就挂。CUA在这里的用法是:让测试用例描述变成一句句自然语言操作步骤,比如“点击右上角登录按钮,输入账号密码,点击提交,断言页面右上角出现用户名”。模型自己看屏幕执行操作,用几张关键节点的截图作为断言依据,页面细节变了也不容易误报。

6.2 跨应用数据搬运:最典型的RPA替代场景

跨应用数据搬运是RPA的传统主场,CUA在这里的优势是不需要逐个控件写选择器。实际做过一个场景:从Excel的几列数据里读取内容,填入一个老旧的网页系统表单,点击保存后自动进入下一条。用RPA做这套,要在网页上提取控件路径、处理各种弹窗;用CUA,模型每一步都在看屏幕,遇到异常弹窗它自己识别、自己处理,整个流程的健壮性高了不少。

6.3 运维和旧系统场景:看得懂屏幕就能接管

很多老旧系统没有API,没有数据库直连权限,也没有自动化接口,只能在界面上操作。过去这些场景只能靠人肉,现在CUA补上了这个空缺。运维场景里的典型用法包括:自动识别并关闭异常弹窗、按固定流程巡检界面状态、在系统恢复后自动重新登录并完成数据同步。

我给一个用户的建议是从小处切入:每周一次的报表下载和数据整理,脚本只要能跑通这一个场景,节省的时间就足够覆盖成本了。

6.4 给团队落地CUA的节奏建议

如果说前面是横向场景,最后这条算纵向节奏建议。我见过不少团队一上来就规划“全自动无人值守大项目”,结果界面一换、模型一升级就崩,最后不了了之。

稳健的落地节奏我认为是三步:

  1. 先跑半CUA:模型负责决策和执行,人负责确认计划、监控状态。自动化程度不用强求100%,先把准确率拉起来。
  2. 挑一个稳定的小场景:流程尽量固定、操作风险低、反馈明确的场景,连续稳定运行两到三周,积累数据和信心。
  3. 再引入异常恢复机制:当小场景稳定以后,再逐步放开让模型自己处理异常分支,比如弹窗误点、输入校验失败等。每放开一种异常处理能力,都要单独验证一轮。

我在实际项目里最深的体会是,CUA的瓶颈往往不是模型不够聪明,而是工程侧的地基不牢:坐标换算、反馈闭环、日志回溯、安全闸门,这些细节做好了,一个"看得懂屏幕的执行器"才能真正变成生产力。如果只是体验技术,先把计算器那个demo跑起来就够了;但如果要考虑投入真实业务,建议就从上面的第一步——跑稳一个小场景、做全操作记录——开始。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/24 23:29:49

DeepSeek Harness:本地AI工作流编排引擎实战指南

1. 为什么“弃用Claude”不是情绪化选择,而是本地工作流演进的必然节点我从去年初开始把Claude作为主力模型接入日常知识管理、文档润色和代码辅助流程,用的是官方API加自建中间层路由。前两周体验确实惊艳——长上下文理解稳,逻辑链路清晰&a…

作者头像 李华
网站建设 2026/9/24 23:28:51

Agent技能体系:从对话到任务执行的关键工程实践

这几年大模型应用里最热的一个词,除了 RAG、Fine-tuning,就是 Agent。而真正上手做 Agent 的人,很快会撞上一个共同的坎:模型知道怎么聊天,但不知道怎么"干活"。你让它调个接口,它编一个不存在的…

作者头像 李华
网站建设 2026/9/24 23:28:10

胰腺病变分割数据集实战:210张训练图与可视化脚本

简介:本资源为胰腺病变图像分割数据集,面向医学图像分割方向的研究者、算法工程师及深度学习学习者,用于训练和评估二类别分割模型(背景与病变区域)。包内按训练集与测试集组织,训练集约210张图像及对应mas…

作者头像 李华
网站建设 2026/9/24 23:27:34

STM32入门到落地:从选型到实战的完整生态指南

如果你第一次接触STM32,八成是被它庞大的资料量和搜索词吓到的:你搜“STM32简介”,能同时蹦出“江科大STM32入门”“STM32时钟树”“STM32 OTA”“基于STM32的毕业设计”这些跨度巨大的话题。作为在这个圈子里干了快十年嵌入式开发的人&#…

作者头像 李华
网站建设 2026/9/24 23:27:17

线程同步与页面置换:从原理到实战的并发与内存调优指南

刚处理完一个线上服务的并发问题:多个线程同时向一个缓存结构里写数据,明明在代码里加了锁,线上还是偶发数据错乱。排查到最后,问题出在锁的实现方式上——一台高配机器上大量线程并发热切一个锁,互斥锁切换上下文耗掉…

作者头像 李华
网站建设 2026/9/24 23:26:10

Agent技能体系实战:从提示词堆砌到结构化技能编排

1. 为什么Agent需要一套独立的“技能体系”1.1 从“提示词堆砌”到“技能原子化”的转变我最早做Agent的时候,思路特别朴素:把所有工具描述写进System Prompt,再把例子塞进去,让模型自己决定什么时候调用、怎么调用。最初几个场景…

作者头像 李华