做移动端UI自动化测试的人应该都有这种体会用例脚本维护成本高、控件定位动不动就失效、机型一多就各种兼容问题。我去年参与一个移动端Agent测试项目前期一直纠结到底走哪条路线后来干脆把开源方案和自研方案都试了一遍其中Mobile-Agent-v3和自研GUI-Owl模型这两条路线都实际落地跑过。这篇把当时的选型思路、模型设计、实操细节和踩过的坑整理出来给后面做LLM驱动自动化测试的人做个参考。这个项目主要解决的是“让大语言模型看懂手机屏幕并自主操作App完成任务”这件事典型的应用就是把Agent接到自动化测试流水线里替代人工编写UI用例。适合已经在做移动端测试、或者想从传统UIAutomator/Appium切到LLM路线的同学阅读。下面从整体设计、GUI感知模型、实操链路、问题排查和选型建议几个维度展开。1. 两条技术路线的底层逻辑差异1.1 为什么不用通用多模态大模型直接做最早我想得很简单拿一个现成的多模态大模型把截图丢进去让它输出点击坐标不就行了。真跑起来才发现问题很多。通用多模态模型在“看图说话”上的能力很强但GUI理解和操作是另一码事。你问它这张截图里有什么它答得头头是道你让它找到“设置”里的“飞行模式”开关并说出精确点击位置它就开始凭感觉编了。坐标回归任务对模型来说天生就难因为一张1080x2400的截图映射到坐标空间误差几十个像素是常有的事而UI自动化里按钮就那么大点偏一点就点错。还有一个问题是动作空间。移动端操作不只是“点击”还有长按、滑动、输入文本、返回、等待等。通用模型没有经过专门的动作指令微调输出格式五花八门有的返回JSON有的直接说人话解析成本极高。再加上有些通用模型在图片里文字密度高的场景下OCR能力不够界面层级信息拿不到操作自然就飘。所以结论很明确通用大模型不能直接上手必须要么配一套Agent框架来约束行为要么针对GUI场景做一套专用的感知和决策模型。Mobile-Agent-v3属于前者GUI-Owl属于后者两条路线的出发点其实是互补的。1.2 Mobile-Agent-v3的架构感知-决策-执行三层分离Mobile-Agent-v3这套开源方案我看完最觉得有价值的地方是把智能体的工作拆成了三个职责明确的模块感知模块负责从设备上收集截图和界面层级结构规划模块负责拆解任务目标、指定每一步操作计划行动器则负责把计划翻译成具体的UI动作。模块之间通过一个轻量的上下文管理器做信息交换避免所有信息都塞进上下文导致模型“记不住前面做了什么”。这种设计的直接好处是容错率高。感知模块拿到的界面层级树如果解析失败可以回退到纯截图模式行动器如果点击失败反思器会把错误结果回传重新规划路径。相比之前那种把截图任务描述一次性丢给大模型的方案这种分层结构让每个环节都能单独调优也更容易在失败时定位问题出在哪一层。Mobile-Agent-v3在屏幕上使用点坐标或元素ID来定位目标语言规划器负责给出自然语言指令行动器内部会根据可用的Screen Encoder把坐标转换成可操作的动作参数。它同时支持纯截图输入和“截图UI树”混合输入实测下来混合输入的准确率明显更高尤其是在界面布局复杂、控件重叠多的页面上。1.3 自研GUI-Owl模型的定位专用GUI感知器加外部规划器Mobile-Agent-v3虽然好但它本质还是“把通用多模态模型包装成智能体”底层模型的感知能力仍然是通用视觉模型在某些密集UI场景下还是会犯错。我们后面决定自研GUI-Owl模型核心思路就一句话“感知专用化规划外部化”。GUI-Owl不做语言推理、不做任务规划只负责一件事——给定一张手机截图输出图中所有可交互控件的候选框、控件类型以及对应的操作坐标。任务规划和执行逻辑全部放在外部的LLM比如Qwen系列模型里完成。也就是说GUI-Owl解决的是“看清楚”的问题外部LLM解决的是“下一步干什么”的问题。这个划分是有实际考量的。专用感知模型可以做得比较小便于在测试机上低延迟推理同时因为它的输出空间被严格限定在“界面控件感知”范围内训练和调优都更可控不会像通用模型那样什么都想干、什么都不精。我们最终部署的GUI-Owl甚至可以把单帧感知延迟控制在几百毫秒以内这在自动化测试场景里非常有价值。2. 核心细节拆解GUI感知能力怎么设计才够用2.1 混合上下文感知截图加UI树为什么缺一不可在没做GUI-Owl之前我对“模型感知屏幕”的理解就是“给它一张截图”。后来大量实测案例告诉我单靠截图去理解屏幕尤其是复杂页面信息损耗非常大。举一个当时的实测例子微信聊天列表页面上一屏里同时有头像、昵称、时间戳、消息摘要、未读红点、底部Tab栏一张截图里视觉信息拥挤模型很容易把未读红点当成可点击按钮或者干脆漏掉右上角的“”号菜单。但如果同时把界面层级树UI Hierarchy的XML文本注入上下文模型就能清楚地知道每个元素的bounds、可点击属性、content-desc等关键信息定位准确率能提升一大截。这就是Mobile-Agent-v3和GUI-Owl都采用“截图UI树”混合感知的原因。Mobile-Agent-v3专门设计了Screen Encoder把截图与UI层级结构联合编码GUI-Owl则是在数据输入侧就把UI树文本和视觉特征做了对齐融合。实测中混合输入比纯截图模式的点击准确率高出大约20个百分点任务完成率提升相对有限但也很可观足以说明UI树不是锦上添花而是刚需。2.2 GUI-Owl的双编码器结构与数据构造GUI-Owl模型的基本结构并不复杂核心是双并联视觉编码器一个负责文本区域通过OCR分支或直接视觉编码一个负责图标和通用图形控件的视觉特征。两个分支输出的特征拼接后送入一个小型Transformer解码器最终输出所有候选控件的检测框和类别。训练GUI-Owl需要两个层面的数据第一是控件检测数据准备大量截图标注出每个可交互控件的位置、类型和边界框第二是动作映射数据要求模型能根据坐标附近的UI上下文推断当前控件最可能的操作点击、长按、滑动、输入文本。刚开始标注成本确实高我们走了一条省力的路——用已有的开源VLM模型批量生成伪标签再进行人工抽检修正效果基本可用。难例挖掘这块我特别想多说一句。界面上经常出现“看起来像按钮但其实不是”的元素比如广告浮层、Toast提示、页面底部的安全区域提示。训练数据里如果缺少这类负样本模型上线后大概率会乱点。我们在数据构造时有意保留了包含弹窗、横幅、半透明遮罩层的页面截图把“不操作”也作为一种输出类别模型误触率才明显降下来。2.3 为什么动作输出不直接回归全局坐标模型必须给出点击位置最直接的做法是让模型输出归一化坐标。这个方案我们最初也试过效果不稳定原因是坐标回归本质上和物体检测的定位分支类似但训练难度更高。后来我们把动作预测改成“区域检测局部坐标修正”的思路GUI-Owl不是直接预测屏幕上的绝对坐标而是先检测出候选控件框再在检测框内部做细粒度的坐标回归。本质上就是把“全图找点”变成“先找控件再定点击位置”难度降低了一个量级。加上动作分类头同时给出每个控件的推荐动作类型整个输出空间被压缩得非常小单帧推理速度也上来了。如果你也想自训类似的感知模型我建议不要一上来就学我们踩的坑去直接回归全局坐标。先用现成物体检测框架DETR类或YOLO类都可以做控件检测再在其上挂一个轻量动作分类头才是稳妥的做法。3. 实操过程从零搭建一条LLM移动端测试链路3.1 环境准备与设备接入先说一下基础环境。测试机我用的是Android设备系统版本覆盖Android 11到Android 15。Python环境用3.10以上依赖的核心库包括pip install torch torchvision pip install transformers pip install qwen-vl-utils pip install uiautomator2 pillow adb工具链需要单独安装并确保设备开启了开发者模式和USB调试。如果走Mobile-Agent-v3路线需要额外准备一个部署好的VLM服务。我们先用开源Qwen2.5-VL-7B作为底层模型通过vLLM起一个OpenAI兼容的服务接口方便Mobile-Agent-v3调用感知和规划能力。对Android端则需要提前在设备上安装好uiautomator2的atx-agent服务保证可以用Python脚本实时截屏和获取界面层级树。import uiautomator2 as u2 d u2.connect_usb(device_serial) d.app_start(com.android.settings) d.screenshot(screen.png) xml d.dump_hierarchy()这段代码就是整个链路的数据入口每次Agent需要感知屏幕时调用截图和dump_hierarchy拿到当前页面的UI树XML再把两者一起交给上层Agent做决策。这个操作在真机上耗时约1到2秒已经算是不错的水平。3.2 Mobile-Agent-v3跑通一个真实场景拿一个最简单的场景举例让Agent完成“打开设置开启飞行模式”这个任务。跑通它就理解了Mobile-Agent-v3整个执行链路的核心环节。第一轮Agent拿到截图和UI树感知模块抽取关键元素规划器判断当前页面是设置主页“飞行模式”开关应该在无线上网区域或直接可见。于是行动器给出动作原语CLICK目标坐标为(500, 680)。执行完之后Agent需要做验证。这里Mobile-Agent-v3会再次截图并解析UI树判断飞行模式开关是否已经打开。如果发现开关状态没有变化反思器会启动提示“点击可能未命中目标建议重新定位”然后调整坐标范围或者切换到通过UI树属性定位元素。整个过程中最精彩的部分在每一步操作都有结构化轨迹记录字段包括动作类型、坐标、界面元素属性、执行前后截图对比。这些轨迹可以直接输出成自动化测试报告对测试同学非常友好。后续如果你想做自定义断言只要在轨迹层加一个回调函数在每轮操作结束后检查状态即可。3.3 GUI-Owl模型的自研落地步骤GUI-Owl的落地分三步走数据准备、模型训练、端侧推理。数据准备阶段我们采集了大约2万张高分辨率手机截图来源包括测试机自动遍历采集和人工指定页面采集覆盖了设置、电商、社交、视频、新闻等几大类典型App。标注工作用开源VLM生成初始框再用标注工具人工校正。类别总共定了7类普通按钮、文字链接、输入框、开关、列表项、图标按钮、不可操作区域。训练时我们直接用预训练的视觉模型做骨干网络冻结底层参数只训练检测头和动作分类头单卡A100约十几个小时能收敛。这里有几个参数值得注意输入分辨率统一为960x1920过高的分辨率会显著增加推理耗时过低则小控件容易漏检检测置信度阈值定在0.45动作分类阈值定在0.6使用focal loss缓解正负样本不均衡因为屏幕上大量区域是不可操作的背景端侧推理则用ONNX导出量化到INT8后模型体积约1GB部署在一台普通Windows测试机上通过HTTP接口供Agent调用。单帧从输入截图到输出控件列表的延迟在300到500毫秒之间完全能接受。import onnxruntime as ort import cv2 import numpy as np session ort.InferenceSession(gui_owl_int8.onnx) img cv2.imread(screen.png) img cv2.resize(img, (960, 1920)) inputs np.transpose(img, (2, 0, 1))[None].astype(np.float32) outputs session.run(None, {input: inputs}) boxes, actions outputs[0], outputs[1]这是推理侧的真代码实际模型还包含NMS后处理等步骤但核心就这么几行。输出拿到候选框和动作类型后再配合外部LLM做任务规划就能拼成完整的Agent。3.4 两种路线的实际耗时与效果对比项目后期我们专门把两条路线放在同样的测试集上做了横向对比测试集包含30个移动端操作任务比如“将闹钟设置为早上7点”、“在购物App里搜索某商品并加入购物车”、“关闭某个App的消息通知”等。跑完数据是这样的指标Mobile-Agent-v3Qwen2.5-VL-7B自研GUI-Owl 外部LLM任务成功率约70%约65%到75%单步决策延迟2到4秒1到1.5秒控件定位误触率约15%约10%新增App适配成本低零样本可用较高需微调感知模型可控性中高Mobile-Agent-v3赢在开箱即用、泛化性好你随便拿一个新App扔给它它多少都能跑几步。GUI-Owl的优势在于行为稳定、速度快而且训练数据掌握在自己手里后续可以针对自家产品持续优化。两者不是替代关系更合理的用法是取长补短。4. 常见问题与排查技巧实录4.1 智能体像无头苍蝇一样在原地打转这是我遇到最多的问题Agent重复点击同一个位置或者绕来绕去回不到目标页面。主要原因不外乎三个一是坐标回归不稳定同一个按钮每次预测的位置偏差太大二是UI树解析出的元素信息有冗余模型被大量无关属性干扰三是历史轨迹没有给反思器提供足够信息它不知道自己已经重复踩过同一个坑。排查时我的第一步永远是把每步的完整轨迹拉出来看。Mobile-Agent-v3自带轨迹记录GUI-Owl路线需要自己加一个。如果发现连续超过3步都在同一页面、动作类型和坐标高度相似就该触发兜底逻辑切换定位方式从坐标定位改为控件属性定位或者强制触发页面回退回到上一个稳定状态再重新规划。4.2 界面层级树dump失败导致感知断档在部分Android系统版本和机型上uiautomator2的dump_hierarchy接口会返回空数据尤其是页面有WebView或者系统正在加载时。遇到这种情况AI Agent会瞬间“失明”因为感知模块拿不到UI树信息。我们的处理策略是数据源自动降级当UI树解析失败时自动切换到纯截图模式由感知模型只凭视觉信息输出候选控件同时在一个独立的日志通道里标记感知方式为“VISION_ONLY”方便后续回溯。纯视觉模式准确率会降但至少Agent不会直接卡死。4.3 误触率高、点击了不该点的东西误触主要来源于两个场景全屏广告弹窗和权限请求框。这些遮挡层的控件不在我们期望的UI树里Agent看到的是一个完全陌生的界面很容易乱点。我们的解法思路是配置一套“界面状态识别规则”在Agent决策前先对当前UI树做一次预检识别是否存在系统弹窗、广告浮层等非常规状态如果有则进入特殊处理分支比如点击关闭按钮或者直接跳过该页。这套规则逻辑可以用非常简单的JSON配置来维护实测能把误触率再降好几个百分点。5. 选型建议与真实数据复盘5.1 什么场景适合哪个方案如果你团队的目标是尽快让AI Agent在测试环境跑起来、验证可行性直接选Mobile-Agent-v3这类开源框架没毛病成本低、见效快。但如果Agent要进入生产级测试流程对响应延迟、行为可控性和误触率有硬性要求那么自研GUI感知模型这条路值得认真考虑。我实际经历过的情况是一开始All in Mobile-Agent-v3跑Demo效果确实惊艳但进入常态化回归测试后发现两个问题始终绕不过去——第一底层通用VLM偶尔会“自由发挥”同一个用例今天能过明天挂第二无法针对自家业务App的高频控件做定向优化因为模型权重不在手里。这些痛点倒逼我们启动了GUI-Owl自研路线。5.2 如果只做一件事先把感知数据管起来如果只让我提一条最值得投入的事那就是建立一套可持续累积的界面感知数据集。不管是开源路线还是自研路线都依赖高质量屏幕截图和标注数据。Mobile-Agent-v3虽然不需要训练但需要大量真实数据来评估效果GUI-Owl的整个训练过程更是完全建立在数据基础上。我们后来搭了一套自动数据回流管道每次Agent执行完任务屏幕截图、UI树、操作轨迹、执行结果全部入库每周用半自动方式挑出错例补充训练集。这个循环跑起来之后GUI-Owl的控件检测准确率几乎每个月都能看到明显提升。自动化测试做到最后拼的就是数据运营能力这一步越早做越省力。5.3 后续可以怎么扩展现在的链路是截图UI树输入、Agent决策输出动作。往深处做有几个方向值得探索一是与代码覆盖率数据打通让Agent不仅仅完成功能性任务还能自动探索未覆盖的代码分支二是引入多设备并行调度在几十台真机上同时跑Agent任务把兼容性测试的维度拉到更高层级三是把轨迹数据进一步结构化生成自然语言的过程描述直接作为测试报告的一部分。这些扩展的技术门槛都不比当前工作高出太多核心还是先把数据管道和模型训练迭代的闭环跑稳。在最后说一点个人感受。移动端自动化最磨人的从来不是写脚本而是脚本写完被UI变动批量打断后的反复修补。LLM驱动的Agent不会完全替代传统自动化但它把维护成本这块天花板打掉了一大截。如果你现在正犹豫要不要在这个方向投入我建议先从Mobile-Agent-v3跑通两个真实任务开始亲身感受一下整个链路再判断下一步到底怎么走。
阅读完成 · 觉得有帮助?