ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

多模态Agent如何破解UI测试路径规划难题:从感知到决策的工程实践

多模态Agent如何破解UI测试路径规划难题:从感知到决策的工程实践

1. 为什么UI测试路径规划难,而不是UI测试难

做自动化测试很多年的人,第一次接触AI驱动的UI测试时,往往都有一个错觉:多模态模型能看懂屏幕,所以自动化就不难了。实际真正动手去搭,你会发现“看懂屏幕”只是入场券,核心难点在于另一个词——路径规划。

传统的UI自动化测试,本质上是“预先录入的剧本”。测试工程师打开录制工具,点一遍流程,脚本记下坐标、元素ID、文本内容,之后每次回归都照着这条固定路线走。这套模式最大的问题不是脚本会过期,而是它只有“肌肉记忆”,没有“方向感”。界面改版、按钮挪位、弹窗出现,脚本瞬间失效,因为脚本不知道“本来想去支付页面,现在要绕一步”。

多模态Agent解决的不是“点击”本身,而是把“如何从当前状态到达目标状态”这件事从硬编码变成了在线推理。你可以把它理解成一个人进了陌生商场,要找到某个店铺。他看的不是店门口固定的地标,而是结合眼睛看到的指示牌、楼层分布图、当前所在位置,以及记忆中“这家店在四楼靠东侧”的信息,现场规划一条路出来。UI测试同理——Agent需要实时感知页面状态,理解当前界面有什么,然后决定下一步在哪个位置、做什么操作、操作后预期出现什么,再重新感知验证,形成一个完整的闭环。

会点鼠标的人很多,能在陌生环境里一次次正确决定“下一步该点哪里”的人很少。过去我们把后者交给了测试工程师,现在想把这份能力复制到机器上,这就是多模态Agent做UI测试路径规划的真正价值所在。

也正因为它是一个连续决策问题,而不是一个图像识别问题,所以网上那些“调用多模态大模型识别一下页面就能自动测试”的说法,基本都属于削足适履。真正靠谱的方案,是围绕路径规划这件事,把感知、决策、执行、验证四个环节按测试场景重新设计。下面每一节,我都会按这条主线来拆解。

2. 多模态感知层:Agent是怎么“看见”界面的

路径规划的第一步永远不是“想”,而是“看”。多模态Agent和传统OCR方案最大的进化点在于,它能把像素信息、文本信息、结构信息三者融合起来理解,而不是孤立地提取一个文本框。

2.1 不是只有截图,DOM和坐标才是“硬骨架”

很多人以为多模态就是给模型丢一张截图让它自由发挥。实测下来的经验是:纯截图方案在静态页面上效果尚可,但一遇到动态交互、遮罩层、iframe嵌套等场景就立刻拉胯。原因是很多关键信息不在截图里,而在页面结构里——某个元素是否可点击、是否在可视区内、是否被遮挡,这些从像素上很难判断。

我自己的做法是构建一个“四层感知输入”:

  • 第一层:整屏截图,让模型理解全局布局、视觉风格、当前焦点区域
  • 第二层:DOM树精简快照,按可见性过滤后的元素清单,包含标签、文本、角色、位置
  • 第三层:可交互元素坐标表,把所有a、button、input、select等可操作节点提取出来,附上边界框
  • 第四层:OCR文本层,专门处理Canvas渲染、图片内文字等DOM取不到的内容

多模态模型需要同时拿到这四层信息,才能形成“这张表单里的‘提交’按钮,和那个坐标框里的‘提交’文本,其实是同一个东西”的结论。我曾经用纯截图方案跑一个后台管理系统,弹窗类元素识别率只有60%多,加入DOM层后直接拉到90%上下。视觉信息辅助理解“长什么样”,结构性信息保证“定位准”,两者缺一不可。

2.2 感知压缩:如何让模型在有限上下文里看全页面

一个成熟的网页经常同时存在几百个可交互元素,如果全部塞给模型,token消耗先不说,注意力也被稀释了。但压缩盗有压缩的代价——压缩过狠,Agent就会“瞎”。

我踩过一段时间后总结出一个相对可靠的预筛选顺序:

  1. 先按可视区域切分,只保留viewport内的元素,折叠菜单、隐藏元素直接剔除
  2. 按角色优先级排序,button、input、select、a这类操作型节点优先
  3. 删除装饰性内容(纯装饰span、无事件绑定的div)
  4. 相邻的同类型元素做聚合,比如一组Tab按钮压缩成一行描述

这样处理后,一个后台管理页通常能压到40至80个关键节点左右。这个体量丢给多模态模型,既不会超过上下文窗口,又能保留足够的决策依据。

2.3 屏幕变化检测:判断操作是否真的生效

感知不只是“打开页面看第一眼”,更重要的是“操作完后重新感知,确认状态是否变化”。Agent在做路径规划时,每执行一次点击或输入,都要静置一小段时间(通常是500毫秒到1秒),然后重新截图和提取DOM,对比变化区域。

有一种很隐蔽的失败:按钮点了,页面确实刷新了,但只是局部加载动画在转,实际接口报错,页面没有切到预期状态。如果Agent只看“页面动了”就认为成功,这条测试路径就会走歪。所以我会额外做一个“状态指纹”判断——把当前页面的URL、标题、关键表单字段、主区域文本拼成一个Hash,每步执行完比对Hash变化。如果Hash没变,说明操作没有造成实质性导航,路径规划就要进入“异常分支”处理,而不是傻傻地继续往下点。

3. 路径决策:从“看见”到“决定下一步”的推理链路

感知把信息送到面前之后,真正的路径规划才开始。这也是多模态Agent和传统规则引擎的分水岭。

3.1 先拆解任务目标,生成高层子目标序列

我不建议让Agent直接输出“点击坐标(x,y)”这种魔法数字。正确做法是先把用户给的目标拆成几个里程碑式的子目标,再针对每个子目标去生成具体操作。

举个例子,测试“找回密码”完整流程,高层目标可以拆成:

  • 子目标1:从登录页进入“忘记密码”入口
  • 子目标2:完成账号验证方式选择
  • 子目标3:填写新密码并提交
  • 子目标4:验证跳转回登录页且新密码生效

这里的核心技巧是:子目标的粒度要够大,大到每一步执行完都能明确验证是否完成。粒度太粗,比如“走完整个找回密码流程”,Agent执行到一半迷失了都不知道在哪;粒度太细,比如“点击第一个输入框”,就退化成和普通脚本一样脆弱的步骤序列了。

有了子目标序列后,Agent的每一步决策都是围绕“当前处于哪个子目标、完成它需要什么操作”来进行的。即便中途出现意外弹窗,Agent也清楚这个弹窗只是干扰项,“当前要解决的是子目标2”,从而能主动关闭弹窗然后回到主线。

3.2 从元素清单里选“动作候选”,不是直接给坐标

决策层拿到感知层的精简元素清单后,需要找出当前状态下可执行的候选动作集。这一步我一般这样建模:

候选动作 = 操作类型(click、input、select、hover、scroll) + 目标元素 + 预期结果描述

操作类型的判断不能单靠DOM标签。有些div加了click事件也是按钮,有些input是只读展示用的。过去我吃过亏,Agent对着一个只读输入框狂敲键盘,浪费了很多重试次数。后来我在元素提取阶段增加了一个“操作潜力值”字段,规则大概是这样:

  • 元素本身有onclick或role=button → 高可点击
  • 元素是a标签且href有效 → 可点击,目标明确
  • 元素是input且readonly未开启 → 可输入
  • 元素是select或div模拟下拉 → 可展开
  • 元素是纯展示区块但上位有滚动容器 → 可滚动

模型拿到这些元数据后,会结合视觉信息综合判断哪个动作最符合当前子目标。这个方法每次跑一个流程,对候选动作数量会从一个页面的几百个,收敛到个位数,路径规划从“大海捞针”变成了“几选一”。

3.3 决策不靠“猜”,靠内部概率与规则校验

多模态大模型在决策时,本质上是基于视觉和文本信息做分布式的概率推理。直接拿它的一次输出当最终答案风险很大。我的方案是让模型同时给出三个候选动作及其置信度,再叠加一层轻量规则校验:

  1. 候选元素是否还在最新一次的DOM快照中(防止屏幕变了还在点旧位置)
  2. 坐标是否落在元素边界框内(防止模型“想到左边但实际点了右边”)
  3. 操作类型与元素“操作潜力值”是否匹配(防止对着按钮执行input)

这套流程像一个过滤器,把模型的“灵光一现”约束在可验证的范围内。一次执行时,Agent可能第一候选被规则拦下了,但第二候选通过了校验,照样能顺利走下去。我才意识到,路径规划的能力上限,并不取决于模型的聪明程度,还取决于工程上对模型输出的约束力。

3.4 动态路径修正:实时感知后的“原路返回”与“绕路”

凡是真实业务系统,都不会让Agent畅通无阻地一路点到底。弹窗、系统通知、动态加载失败、表单校验报错,随时会打断路径。传统脚本遇到这些是panic,Agent需要具备路径修正能力。

我在工程里把修正策略分成了三层:

第一层,局部修正。页面多了一个可关闭的广告弹窗,Agent识别它和当前子目标无关,点击关闭按钮后回到原计划路径。这里的关键是在子目标层不改变序列,只是在动作序列中插入一个“清除障碍”操作。

第二层,重走分支。当前页面和预期状态不一致(比如点击注册按钮后没跳转,反而停在原页且出现报错),Agent要根据报错文本判断是自己操作错了还是系统缺陷,如果判定为操作偏差,需要回溯到上一个可靠状态重新选择候选动作。

第三层,全局重规划。比如中途被强制登出,回到登录页。Agent需要识别“当前所在位置已经偏离所有子目标”,进而直接触发重新规划机制,而不是试图在当前页面强行找到通往目标的路径。

这三层修正的实现方式并不复杂,核心是一个维护“当前计划栈”的模块:每执行以达到一个子目标,就压入一个标记;每发现状态偏差,就执行对应的回退策略。多模态模型负责“意识到偏了”,工程代码负责“决定怎么回来”。两者配合,路径规划的鲁棒性才能起来。

4. 执行验证与动态调整:路径规划不是一次性输出

很多做AI测试的人犯过同一个错误——让Agent一口气输出完整的步骤列表,然后纯机械地执行。真实世界不这么运转,条件会在执行中变化,路径规划应该是“边执行边规划”的滚动过程,而不是“先规划后执行”的静态产物。

4.1 每步执行后的验证清单:如何确认这一步真的对了

每执行完一个动作,Agent要回答三个问题:

  • 目标的元素是否达到了“操作生效”的状态(比如input值正确、checkbox勾选上)
  • 页面状态指纹是否发生变化(URL、标题、关键内容是否切换到了预期)
  • 是否出现了非预期元素(错误提示、异常弹窗、加载超时)

如果三项全部正常或只有预期的变化,则标记当前子目标完成;如果出现预期外的元素,进入异常分支处理;如果状态指纹和视觉都显示页面没动,需要区分是“动作失效”还是“网络延迟”导致的假死。实际操作中,我会在验证阶段加一个“轮询窗口”——等待1秒、2秒、3秒,三次增量轮询,超过3次还没变化才判定动作失败。

4.2 失败后的重试与回退策略:不盲目重跑,要带记忆地重试

盲目重试是低效的。Agent重试时必须知道上次为什么失败,只调整对应变量。

我把失败原因做成了几个分类,每个分类对应一种回退策略:

失败类型判定方式回退策略
元素位置变化元素仍在DOM但坐标偏移重新定位元素、用文本+角色锚定而非坐标锚定
元素状态不可交互元素被遮罩层覆盖或disabled先处理遮罩层,再重试,最多2次
页面跳转失败URL无变化、关键内容缺失等待重载后触发“重新执行当前子目标”
必填项校验拦截出现表单错误提示根据提示补齐或修正输入,重新提交
模型决策漂移连续两次选择的元素都是装饰性节点强制触发全局重规划

回退策略之所以要分类,是因为很多失败不是用一句“再点一次”就能解决的。被遮罩挡住你点十次还是被挡住;以为成功实际失败,盲目前进会越跑越偏。带记忆地重试,才是路径规划系统该有的素质。

4.3 执行日志的可视化:路径规划过程也要能被审阅

做测试的人应该都有执念:失败用例要能排查、要能还原现场。Agent测试路径规划具有概率性,同一场景两次走的路径可能不同,所以过程可回放比结果正确更重要。

我在落地方案中,把每一步的感知快照、候选动作、模型置信度、规则校验结果、执行结果统一写入日志系统,再在Web平台上做时间线回放。这个可视化的过程,说白了就是给Agent的“思维过程”装了行车记录仪。某个步骤出现离奇决策时,你能看到模型当时的界面截图、它选择的元素、它的置信度,排查效率提升几个量级。

这里分享一个经验:回放界面上除了展示Agent做了什么,还要展示它“看到了什么”。有一次Agent在一个页面上反复点击同一个元素不生效,排查了好久,后来看时间线截图才发现那个元素在view之外,屏幕上是看不到的。多模态模型容易被截图诱导“看到”并不在可视区域内的东西,回放里标注感知边界,这类问题一眼就能暴露。

5. 关键路径的稳定性优化:从“能跑通”到“长期能跑”

一旦路径规划的方案能在测试环境里跑通某个业务流,接下来就要面对一个更折磨人的问题:同样的流程,今天跑通了,明天还能不能跑通?这一节聊稳定性问题。

5.1 视觉锚点与结构锚点的择优

Agent在规划路径时需要决定“下一步操作哪个元素”,而元素锚定的方式直接决定了稳定性。

我推荐按优先级使用:

第一优先,文本+角色锚定。“提交”按钮 + button角色,这是最直观的,UI只要不改文案基本不会挂。

第二优先,结构路径锚定。通过DOM层级定位,比如“main区域 > 表单区域 > 第3个按钮”。这种锚定在元素本身信息弱的时候很可靠,但页面结构调整时会受影响。

第三优先,视觉特征锚定。比如“右上角橙色圆底白色图标的按钮”。这是属性和布局的综合判断,最灵活但相对最容易遇到混淆。多个橙色图标的页面,就有可能误选。

我一般的做法是在场景分析阶段把元素的各个锚点信息都采集出来,预计算一个“锚点稳定性评分”:文本唯一性、结构路径长度、视觉显著性。然后让Agent优先选择评分最高的锚点组合。不要小看这一步,它能把回归测试场景路径规划的稳定性从“看命”变成“看设计”。

5.2 动态等待与智能超时:让路径规划不焦虑

不稳定的另一大源头,是页面的动态加载时序。很多接口请求是异步的,UI组件出现的时间不确定。Agent如果在组件还没渲染出来时就尝试找它,就会陷入“找不到元素”的假失败。

传统框架的做法是固定sleep或者轮询等待元素出现。Agent的做法可以有更优雅的变体:在等待期间同时进行视觉推理。

实操中我会在等待逻辑里增加一个“中间态解释”模块:轮询期间如果发现页面存在加载动画或骨架屏,模型会识别出“加载中”状态,等待继续;如果页面出现的是空状态或报错组件,模型会判断为“加载失败”或“无数据”,从而结束等待并触发对应的分支逻辑。这样等待不再是死等,而是被纳入路径规划的决策体系里。

5.3 回归场景中的路径收敛:让Agent越跑越“老练”

同一个测试路径如果每次都完全靠模型推理,效率和稳定性都不理想。但如果你做一个记录机制,让Agent把跑过的成功路径沉淀下来,情况就不一样了。

我们的实现是在Agent执行完一条流程后,把经过的页面状态指纹、选择的关键元素、采取的决策序列存入知识库。下一次执行同类流程时,系统先进知识库直接匹配“历史路径”,如果页面状态指纹闭环一致,就直接沿用历史动作序列,不再让模型从零推理。只有历史路径匹配失败时,才重新触发多模态规划。

这个“先用记忆,再用推理”的设计,把路径规划从每次烧脑决策变成了“半记忆半推理”。跑过10次以上的稳定流程,执行时间能缩短40%左右,稳定性接近传统录制脚本,但遇到界面变化时又比传统脚本抗造得多。

6. 实操中的模型选型与成本控制思路

多模态Agent的落地,绕不开模型选型和成本账。很多团队在这个环节踩的坑,比路径规划本身还要多。

6.1 能力分层:别拿大模型干所有活

我习惯把UI测试路径规划拆成三种不同能力级别的任务:

  • 轻量任务:元素定位、坐标计算、状态指纹对比。这些用小模型或者干脆用规则脚本即可,又快又省钱
  • 中等任务:常规路径决策、候选动作筛选、异常识别分类。这类用中等规模的多模态模型就够,精度和成本比较平衡
  • 重量任务:跨页面复杂流程规划、模糊需求的目标拆解、多步异常的归因分析。这些才值得调用顶级多模态模型

实际经验是,一条普通业务路径,真正需要重量级模型的调用次数只占20%左右。其余环节用好策略做任务分流,成本能降一半以上,首屏决策延迟也从几秒压缩到几百毫秒,跑起来能明显感觉到流畅。

6.2 提示词模板的结构化设计

路径规划任务落地时,真正影响上限的往往是提示词设计。多模态模型决策不稳,很多时候是给的信息缺料、提问方式误导。

推荐一个我长期使用的结构化模板骨架:

当前页面信息:{页面截图} + {DOM快照} + {可交互元素表} 当前任务目标:{当前子目标} 已完成步骤:{历史关键动作摘要} 最近一次操作结果:{动作描述 + 验证结论} 请完成:从当前可交互元素表中选择下一步最优操作,输出JSON格式,包含元素ID、操作类型、理由、预期结果。

模板里有三个容易忽略的细节,写的时候要特别注意:

  • 子目标必须单独列出,不要藏在长文本里,模型对独立字段的注意力明显更高
  • 已完成的步骤要压缩成摘要,不要堆全部日志,否则上下文干扰决策
  • 历史记录里不要包含明显的错误操作细节,只保留关键信息,以免模型模仿了错误路径

6.3 本地部署与API调配的取舍

我在多个项目里分别试过本地部署开源多模态模型和API调用商业模型。用一个不精确但直观的比例来说:

  • 界面结构简单、元素规整的业务系统,本地小模型就能扛住80%以上的场景
  • 界面复杂、视觉元素杂乱的页面,商业模型在理解力和容错上优势明显
  • 涉及大量隐私数据的内部系统,模型数据不出内网几乎是硬性要求

双轨并行是我觉得目前最舒服的方案:本地模型走常规路径的轻量决策,API模型只处理本地模型置信度低的情况。这样既守住了数据安全底线,又保住了复杂场景的上限。

7. 实用场景边界:哪些UI测试真的适合用多模态Agent

路径规划不是万能的,有一说一,这个方案也有明确的适用边界。团队在接入前最好先判断清楚,避免把“屠龙刀”拿去切菜还嫌切得慢。

7.1 高动态、弱结构场景是主战场

多模态Agent路径规划最适合的场景,是那些元素没有稳定ID、class命名混乱、甚至大量内容由Canvas或WebGL渲染的页面。传统Selenium脚本面对这类页面基本只能靠截图OCR硬扛,而多模态Agent可以结合视觉理解和坐标定位直接操作,成熟度会好很多。

登录、注册、支付、搜索这类“每天走一万遍”的核心链路,也是最值得先尝试的场景。因为这些流程路径相对固定、状态分支清晰,Agent完成一次完整规划后,沉淀下来的历史路径能复用很多次,收益非常确定。

7.2 不适合硬上的场景也要提前识别

有三类场景我不建议一开始就硬上:

  • 完全无头浏览器环境,无渲染截图、无窗口,多模态模型缺了视觉输入就等同于少了一条腿
  • 纯接口级联调测试,根本不需要UI,用Agent纯属浪费
  • 极强时序依赖的动画交互场景,比如需要精确控制时间轴的音视频编辑软件,Agent的轮询节奏难以匹配毫秒级的时序

另外,任何UI自动化方案都替代不了人的探索性测试。多模态Agent的路径规划是“基于经验和推理的账本式执行”,它不会像资深测试员那样天马行空地去“乱点”找隐藏bug。这一点想清楚,团队上下就不会对这个技术抱有不切实际的期望。

7.3 从一个场景切入,而不是立刻全面铺开

团队真要落地,我强烈建议从一条“每周回归必挂”的用例开始,而不是一上来让Agent替掉全部自动化框架。

选那条用例的时候注意几个特征:流程步骤在10步以上、涉及跨页面跳转、需要处理弹窗或错表单。用多模态Agent把这一条跑稳,跑出一个可以回放、可以报bug、可以解释每一步决策的完整闭环。然后,再从这条主干路径横向复制扩展到附近的路径。路径规划的“记忆库”是越积累越值钱的,起步慢一点,后面会越来越顺手。

8. 验证方法论:一套UI路径规划方案的评测标准

最后聊一个容易被忽视的问题:怎么判断这套路径规划方案做得行不行?很多团队上线后全凭感觉,“好像比以前稳了”“有时候会挂”是听惯了的话,缺少可量化的衡量标准。

8.1 三个值得盯的核心指标

第一,路径完成率。指“全流程跑通并到达目标页面”的用例占总执行用例的比例。这是最终效果的底线指标,低于70%基本不具备回归价值。

第二,平均决策步数与最优步数的比值。这个比值衡量路径规划的效率。最优步数是人工预估的“理想最短路径”,Agent决策次数如果超过最优路径的1.5倍,说明规划存在绕路,需要优化感知或加大历史路径复用。

第三,单步决策成功率。路径中每一步动作“选对了元素并成功执行”的占比。实测里单步成功率95%以上,整体流程跑通率才有可能到80%——因为连环概率会快速放大失败率。这个指标适合定位“拖后腿”的具体环节。

8.2 建立回归样本库,迭代路径规划

光有指标还不够,还要有稳定的验证集。我建议团队维护一个“界面临时变异库”——收集历史上导致脚本挂掉的那些页面改动案例,定期回放给Agent跑,验证它在这些变异下是否还能重新规划路径。

固化一个经验:让人手动调整Agent走错过的步骤,再把调整后的路径当作标准答案,去反向提示模型哪里判断失误,比反复改提示词更有效。多模态Agent的规划能力提升,不是靠疲劳式试错,而是靠积累“错例—正确规划”的配对数据,形成持续反馈闭环。

8.3 把路径规划结果放在CI里跑一段时间看趋势

一个新方案就算单次跑得很好,也不能立刻全信。放在CI里跑上一两周,观察每天的通过率曲线是否在30天内有下跌趋势。真正的路径规划能力,必须经得起“每天早上都有几百个用例跑给你的新页面新广告新组件”这种日常折磨。

我见过不少方案在Demo演示时光鲜亮丽,投入真实回归后被各种随机弹窗搞得七零八落。背锅的不是多模态模型,而是路径规划的鲁棒性设计不够:感知层没有过滤噪音、决策层没有约束候选、执行层没有异常回退、记忆层没有积累替代路径。这四个环节缺一环,整体就悬。

在我个人的实践中,最深的体会是:多模态Agent路径规划不是一个“模型问题”,而是一个“系统工程问题”。模型负责认知和推理,工程负责约束和兜底。两者各司其职,互相补齐,才能在真实业务里站稳脚跟。如果你正在被“AI能看懂界面但总是瞎点一气”的问题困扰,不妨回头检查一下自己的感知层是否把DOM和结构信息漏掉了,决策层是否把候选动作收敛到了足够小,执行层是否有分类明确的回退机制。这三处扎实了,路径规划的水平自然会见风就长。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进