news 2026/10/22 9:55:38

移动端自动化崩了?用角色级模型拆分把LLM准确率从47%拉到81%

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
移动端自动化崩了?用角色级模型拆分把LLM准确率从47%拉到81%

1. 为什么移动端自动化必须做角色级拆分:先说说 EventBot 翻车现场

先说结论:我在这个系列第 05 篇里讲过一个移动端自动化 Demo,当时用的是"一个模型管到底"的方案——让同一个 LLM 既看截图、又读 UI 树、还要负责生成点击坐标、最后自己判断用例是否通过。Demo 在小任务上跑得很顺,但一上真实 App,就频繁出现同一个现象:任务执行到一半,模型开始"自说自话"。

具体表现是这样:给它一个"注册新用户并登录"的任务,它在第 6 步左右突然反复点击同一个不可点击的 TextView,然后在日志里自我确认"已完成注册"。我检查了一下上下文,发现它当时已经积累了大约 8 张截图、4 份 UI 树转储、12 轮历史动作,整个上下文乱成一团。我后来把这个问题归为"角色混淆"——同一个模型既当观察者又当执行者,它在长上下文里丢失了"我到底在干什么"这件事。

后来我改用 DroidRun/Mobilerun 这套工具链里内置的**角色级模型拆分(Role-Level Model Split)**思路,把测试执行拆成五个角色,每个角色由不同上下文、不同 prompt、甚至不同类型的模型来承担,才真正把准确率从 47% 拉到 81%。这篇文章就把整个拆分思路、落地实现、实测数据和踩过的坑一次讲透。

这篇文章适合谁看?如果你正在做 LLM 驱动的移动端自动化测试,或者你在自己项目里遇到了"大模型什么都能干、但一碰到长任务就拉胯"的问题,那这篇值得你花十五分钟读完。它解决的核心问题不是"怎么用 LLM 写测试用例",而是:"当 LLM 真正去操作手机屏幕时,怎么让它的注意力不崩、决策不飘、错了还能自己修。"

1.1 移动端自动化比 Web 自动化更难的原因:屏幕是个黑盒

Web 自动化里,你至少有稳定的 DOM 结构可以依赖,每个元素有 id、class、标签名,定位策略成熟得不能再成熟。移动端不一样,很多 App 的控件是自绘的,UI 树里只有一块 canvas,所有控件都是坐标点位。再加上 iOS 和 Android 的渲染机制不同,无障碍树的内容在不同系统版本上差异极大。

这意味着什么?意味着 LLM 在移动端自动化里面对的是一个信息不完整的环境。它看到一张截图,但截图里的文字可能被遮挡、模糊、或者在深色模式下对比度不足。它拿到一份 UI 树,但 UI 树里的节点可能是一堆没有语义的FrameLayout嵌套。这个信息缺口不是靠更好的模型就能直接填上的,而是要靠一套流程机制去弥补。

我最初的错误就是把所有信息一股脑全塞给同一个模型,以为模型智能够了就能从中"悟"出正确操作。实际上,人类的测试工程师在手动测 App 时也是分工的:眼睛看屏幕(观察者),脑子按照测试用例想下一步(规划者),手去点击输入(执行者),然后对照预期结果确认(断言者),出了问题再回头排查(修复者)。LLM 驱动移动端自动化的正确姿势,应该是把这种分工显式化,而不是指望一个模型同时兼任全部角色。

1.2 上下文爆炸:长任务下注意力被拖垮的数学原理

这里得解释一下为什么长任务下模型一定会崩,而不是"可能崩"。Transformer 模型的注意力机制虽然理论上能处理长上下文,但实际效果是随着序列长度增加,模型对早期信息的利用率呈衰减趋势。你可以把注意力想象成一个会议现场,参会人越来越多,发言记录越来越长,新加入的发言人(最新的屏幕状态)往往会覆盖掉前面重要讨论(最初的测试目标描述)。

在移动端自动化里,这个衰减被放大了,因为每一轮操作都会新增"截图 + UI树 + 动作描述"三类 token。假设每轮交互 800~1500 token,执行 20 步就是 16000~30000 token。虽然现代模型支持 128K 上下文,但那个"支持"指的是不报错,而不是"都理解得清楚"。实测下来,当上下文超过 12000 token 时,模型对前几步目标的注意力已经明显下降,开始出现重复动作、遗漏关键步骤、甚至凭空捏造操作结果。

角色级拆分正好解决了这个问题:把上下文按职责切分。观察者只需要关心最新一张截图和最新一份 UI 树,规划者只需要关心当前状态和总目标,执行者只需要关心"这一步该点哪里"。每个角色的上下文都在 3000 token 以内,注意力集中,准确率自然就上来了。

1.3 一次失败的全流程 Demo:数字对比最能说明问题

为了说服我自己不是瞎折腾,我专门设计了一个对比实验。用同一套 20 个人工标注的移动端任务,包含登录、注册、表单填写、列表滑动、设置项切换等常见操作,分别在"单模型全流程"和"角色级拆分"两种模式下跑。

单模型模式下,我在每一步都把当前截图、UI Tree、历史动作列表全塞进上下文,要求模型直接输出下一个动作。20 个任务跑了 5 轮取平均,结果如下:

任务难度单模型准确率主要失败类型
简单(2-5步)78%偶尔点错元素
中等(6-15步)41%步骤遗漏、目标漂移
困难(15步以上)12%完全迷失、重复循环

失败样例里最典型的一个:任务目标是"把默认地址修改为上海市浦东新区某路某号"。单模型在输入"上海市"之后,因为截图里的输入框发生了联动变化,它误以为任务已完成,开始在页面上瞎逛,甚至去点击底部标签栏来回切换。日志显示它在后续 9 步里共进行了 11 次页面跳转,最后一次动作日志竟然写着"确认地址已修改成功"——但截图清清楚楚显示地址栏还是原来的旧地址。

这个案例让我下定决心彻底重构方案。接下来直接上干货,讲讲 DroidRun/Mobilerun 的五个角色到底怎么定义、怎么协作。

2. 角色定义与任务分权:一个 LLM 变成五个各司其职的小组

DroidRun 的定义方式很直白:把"完成一个移动端测试任务"这件事,拆成五个互相独立的角色,每个角色只干一件事、只持有自己需要的那部分上下文。我把它称为"五顶帽子":规划者(Planner)、执行者(Executor)、观察者(Observer)、断言者(Asserter)、修复者(Healer)。

这里有个容易理解偏的点:这五个角色并不需要五个不同的模型。实际上我在实际部署中用的是两到三个模型,不同的角色穿不同的 prompt 和上下文。比如规划者和断言者用同一个强模型(更强的推理能力),执行者和观察者用同一个快模型(更低的延迟),修复者也用强模型但不和规划者复用同一套上下文缓存。角色拆分的关键在职责边界和上下文隔离,而不在于模型数量。

我整理了一张表,方便对照每个角色的职责、输入、输出和建议选型:

角色核心职责输入输出建议模型类型
规划者 Planner制定步骤序列,分解测试目标总目标、当前状态摘要、剩余步骤下一步动作的语义指令推理强的旗舰模型
执行者 Executor把语义指令翻译为具体屏幕操作规划者指令、当前UI树、元素坐标点击/输入/滑动等具体操作低延迟高响应模型
观察者 Observer提炼屏幕关键信息,压缩上下文原始截图、UI树转储结构化状态描述视觉理解强的模型
断言者 Asserter检查实际结果与预期是否一致测试预期、观察者的状态描述通过/失败/重试建议推理强的旗舰模型
修复者 Healer处理失败、异常和阻塞失败信息、当前状态、历史操作恢复策略或终止决定推理强+长上下文模型

2.1 规划者:只做减法,不做加法

规划者的任务不是去操作手机,而是持续回答一个问题:"距离最终目标,当前还差哪几步?"它拿到的是目标描述 + 观察者丢过来的状态摘要(结构化描述,不是原始截图)。它输出的不是"点击那两个字"这种物理操作,而是语义级指令,比如:"在当前表单页面,将第三个输入框的值设为 zhangsan@example.com,然后点击页面底部的‘下一步’按钮。"

为什么这样设计?因为语义指令比物理操作稳定得多。如果执行者直接按"点击 (512, 1783)"执行,一旦页面布局变化(比如键盘弹出、广告遮挡、不同机型适配),坐标就失效了。而语义指令让执行者可以在执行时重新定位元素,天然带容错能力。

规划者的 prompt 我调试了十几版,最关键的约束就三条:每次只输出一步(防止它一口气规划十步然后被现实打脸);每步必须带"期望结果"字段(方便断言者判断);如果当前状态和预期不符,立即交给修复者而不是自己硬解。就这三条,规划质量提升非常明显。

2.2 执行者:把指令翻译成手指的肌肉记忆

执行者对标的就像一个真正的手:它接收规划者的语义指令,结合观察者提供的当前 UI 树,找到具体控件坐标,然后生成 UI Automator 或 XCTest 能够直接执行的代码片段。

执行者的 prompt 有一个核心约束——禁止猜测元素。如果 UI 树里找不到规划者提到的元素(比如"下一步按钮"匹配不到 text 为"下一步"的节点),执行者必须原样返回"元素未找到",而不是自作主张去找一个长得像的东西点下去。这个约束加进去之后,失败模式的痛苦程度下降了一半以上。

执行者对模型的延迟要求最高,因为它是整个链路里唯一需要和手机实时交互的环节。我在实际调用中给执行者设置了 5 秒超时,超过就直接报错走修复者流程,而不是傻等。试过用旗舰模型当执行者,准确率并没有显著提升,延迟却多了 2-3 倍,性价比极低。

2.3 观察者:让屏幕从"一张图"变成"一条结构化摘要"

观察者是整个拆分思路里最容易被低估的角色。它承担的任务是:每轮交互之后,把"截图 + 原始 UI 树"压缩成一段 200~400 字的结构化描述。这段描述包含:当前页面名称、所有可见的关键控件(附带 bounds 和 text/hint/content-desc)、当前输入框的值、页面的可用操作列表、以及异常状况(弹窗、系统提示、网络异常等)。

为什么要单独做一个观察者?因为直接喂原始 UI 树会让规划者和执行者被大量无关节点淹没。一个典型的电商 App 首页,UI 树里可能有 300+ 个节点,其中一半是FrameLayout、LinearLayout这种无意义节点。模型在这种噪音里做决策,准确率是不可能高的。观察者相当于一个专业的"信息提炼员",先把噪音滤掉,后续模型拿到的都是浓缩后的精华。

观察者的视觉能力很重要。我试过几种不同的视觉模型做观察者,发现对截图内容描述得准不准(特别是按钮文字、输入框占位符)直接影响下游执行准确率。这个角色可以肉眼可见地提升效果。

2.4 断言者:最后一个说话的冷静角色

断言者只在两种时机被触发:规划者每步指令里声明的"期望结果"产生后,或者整个任务结束时。它的工作内容也很纯粹:拿观察者的输出对照预期,给出"已达成/未达成"的判断,不需要解释。

比如说规划者说"在登录表单中填入账号密码并点击登录,期望结果:跳转至首页且顶部显示用户头像"。观察者的描述是"当前页面为个人中心,未显示头像,地址栏下方有登录按钮"。断言者直接判"未达成",并简短说明差异。这比让全流程模型自己判断自己的操作结果要可靠得多,因为"运动员不能同时当裁判"。

实测中,断言者还能抓出一个特别隐蔽的 bug:某 App 在表单校验失败时会轻微震动并提示 toast,但页面看起来纹丝不动。观察者没注意到 toast,断言者却通过 UI 树里的节点变化发现了校验错误信息。这种级别的问题,单模型方案根本发现不了。

2.5 修复者:专门处理"计划赶不上变化"的那只手

移动端测试里最不可控的就是异常:弹窗、网络超时、App 闪退、权限请求、甚至手机系统弹窗(比如"电量不足")。修复者的职责是当一个"不背锅的背锅侠":每次执行者报错或断言者判定未达成时,修复者基于"当前状态 + 失败原因 + 最近 3 步操作记录"决定:重试当前动作、跳过当前步骤、改走替代路径、或者终止整个任务。

修复者和规划者的最大区别是:规划者是在"正常情况"下向前看的,修复者是在"异常情况"下向后看的。修复者允许有一定程度的试探动作,但必须记录试探次数,超过 3 次就终止。这个 3 次上限非常重要,不然修复者在遇到顽固问题时可能会变成一个无限乱点的"猴子",白白浪费资源还污染测试报告。

3. 上下文隔离与消息协议:让五个角色之间"手递手"而不"大杂烩"

角色定义了之后,最难的是让它们高效协作。如果五个角色共享一个巨大的全局上下文,那和单模型方案就没有本质区别——照样注意力爆炸。所以 DroidRun 的第二个关键设计是上下文隔离 + 结构化消息管道。

3.1 每个角色持有专有的上下文视图

我在实现中维护了一个类黑板的共享缓存,但每个角色读取的字段完全不同:

  • 规划者读:全局目标、观察者的最新状态摘要、最近 2 条自身输出
  • 执行者读:规划者的最新指令、观察者的控件列表截图、当前 UI 树子集
  • 观察者读:新的原始截图和 UI 树全量
  • 断言者读:当前测试预期、观察者最新描述
  • 修复者读:失败记录、最近 3 步动作历史

也就是说,规划者永远不会看到原始截图,执行者永远不会看到测试预期,断言者永远不会看到历史动作列表。这个隔离是强制性的,不是靠 prompt 里写"请忽略XX"来约束,而是在代码层面直接过滤。

3.2 消息格式:统一成"自然语言指令"而不是 JSON 动作流

第一版实现里,角色之间传的是 JSON 结构:{"action": "click", "coordinates": [x, y], "element": "login_button"}。调试了两轮发现交互性很差:规划者输出的语义指令到了执行者那里常常被"翻译"得扭曲,尤其在边界情况下。

后来我改成全部用自然语言指令传递。规划者直接输出中文指令,执行者自己理解并转成 UI Automator 代码。这么做表面上看增加了执行者的理解负担,实测下来反而提高准确率——因为自然语言是 LLM 的母语,JSON 不是。同样的逻辑也适用于其他角色间的通信。一开始担心不稳定,跑了上百个任务之后确认这条路是通的。

3.3 每一步的"工作日志"格式:人可读、机器可排查

除了角色间消息,我还在持久化层记录了每一步的工作日志,格式很简单,每步四行:

[步骤3] 规划者: 点击登录按钮,期望结果进入首页 [步骤3] 执行者: 已点击 (540, 1620),元素text='登录' [步骤3] 观察者: 当前页面为首页,顶部展示头像和搜索栏 [步骤3] 断言者: 未达成,预期展示头像,实际头像缺失,疑似登录未生效

这份日志推理链非常清晰,debug 效率比单模型方案提升了无数倍。单模型方案出问题,你得从三万多 token 的上下文里捞原因,现在只需要看这四行。就凭这一点体验升级,我都建议所有做 LLM Agent 的朋友认真考虑角色拆分。

4. 实测数据:角色级拆分在 20 个移动端任务上的效果复盘

前面说了那么多设计理念,没有数据支撑都是空谈。我用了同一批 20 个任务做对比实验,任务覆盖登录注册(3 个)、表单填写(5 个)、列表操作(4 个)、设置开关(3 个)、跨页面流程(5 个),每个任务还按步骤数划分难度。对比的两个方案,分别是上一节提到的单模型全流程方案,和角色级拆分方案。

4.1 总体数据对比:准确率 47% 到 81%,但最亮眼的是困难任务

难度单模型准确率角色拆分准确率提升
简单(2-5步)78%92%+14%
中等(6-15步)41%81%+40%
困难(15步以上)12%63%+51%
总体47%81%+34%

注意困难任务的提升幅度:从 12% 直接翻到 63%。这背后其实是角色级拆分最核心的收益:把长任务拆成短上下文,让每一步的决策质量回到短任务水准。单模型方案跑到第 15 步以后基本就是在"闭眼开车",而角色拆分里规划者永远只管"下一步",每步都是一次干净的推理。

4.2 失败归因分析:拆完之后,剩下的失败还能怎么优化

角色拆分跑完,我统计了剩余 19% 失败任务的失败原因:

失败原因占比说明
视觉理解错误38%观察者认错控件,比如把 label 当成输入框
元素未找到31%规划者期望的元素在当前页面不存在
动态加载延迟19%页面内容异步加载,断言时还没渲染出来
修复者策略不当12%修复者选择了错误的跳过路径导致任务偏离

这份失败归因的启示是:角色拆分已经解决了"上下文组织"层面的问题,剩下的瓶颈转移到了"视觉感知"层面。观察者的视觉能力变成了新的关键路径。这也解释了为什么我之前说观察者应该用视觉理解最强的模型——它不是配角,而是当前提升上限的核心。

4.3 成本和延迟:拆成五个角色,费用反而省了

很多人第一反应是:五个角色不是要调用五次模型?成本不爆炸?这个账要细算。

单模型方案每次调用都会带上全部历史上下文,第 15 步的单次调用 token 消耗约 12000 ~ 28000。角色拆分方案里,大部分角色的上下文稳定在 3000 token 以内,只有观察者偶发需要处理大图(约 4000 token)。虽然调用次数增多了,但平均单次调用成本大幅下降。实测下来,同样的 20 个任务,单模型方案平均每个任务消耗约 38 万 token,角色拆分方案约 21 万 token——省了接近一半。延迟方面,拆分方案每一步平均耗时反而快了约 1.4 秒,因为不用拖着一大串历史上下文做推理。

5. 踩坑总结与调优经验:DroidRun/Mobilerun 实际落地避坑和调优笔记

这一节写我在实际部署中踩过的几个最痛的坑,和对应的解法,都是文档和官方示例里不会写的细节。

5.1 上下文污染:角色间看似隔离,实则共享了系统 prompt 里的隐患

一个隐蔽的坑是:虽然我给每个角色分配了独立上下文,但忘了给每个角色也配置独立的系统 prompt 模板。一开始五个角色全部使用同一套通用 system message("你是一个移动端自动化助手"),结果规划者频繁产生"用户视角"的回复,比如分析 App 的 UI 设计好不好看;执行者有时会"好心"地修正规划者的指令逻辑。这类问题不是大问题,但很耗 token,而且会稀释特定角色的专业性和一致性。

解法:给每个角色写专有的 system prompt——规划者是"test_orchestrator",执行者是"screen_operator",观察者是"screen_reader",断言者是"verifier",修复者是"error_handler"。这个改动看起来无关紧要,却直接让全任务准确率又涨了约 5 个百分点。角色级模型拆分,必须要在 prompt 层面整体贯彻角色意识。

5.2 观察者的数据"幻觉":截图和 UI 树对不上怎么办

第二个坑是:观察者的工作环境天然存在信息冲突。截图是最真实的用户视角,但 UI 树有时会包含截图里根本不可见的控件(比如弹窗背后的页面元素、收起的手风琴内容)。观察者如果全都描述出来,就会给下游一个"当前页面有 XX 按钮"的错误信号,导致执行者去点一个用户根本看不见的控件。

我在 prompt 里加了三个强制规则:优先信任截图;UI 树中不可见节点默认排除,除非它们在无障碍树里可见并可达;每页描述必须标注"可见控件列表"和"不可见但存在于树中的控件列表"。这个改动有效减少了约 70% 的"冗余控件幻觉",而且错误定位率明显下降。

5.3 无限循环止损:修复者一定要有限步数和冷静期

第三个坑是最典型的 Agent 问题——修复者在遇到顽固 bug 的时候会进入一种"疯狂重试"状态。我刚开始给修复者设定最大重试次数 5 次,以为够了,结果有一次任务,修复者在第 4 次重试中改变了操作路径,导致问题变成了另一个问题,于是计数器归零,又进入新的 4 次循环,实际执行了 20 多步。

我的修复方案是双重止损:修复者自身的重试上限为 3 次,且每次修复后至少执行 1 步"无关观察"再决策。也就是说,修复策略执行后,不能立刻再让修复者判断"怎么样了",而是先回到正常流程执行 1 步,再触发断言。这个"冷静期"机制让任务终止效率和成功率显著改善。

5.4 模型选型的具体参数建议

最后给一组我自己压测后认为合理的选型参数建议:

角色模型规格温度关键参数
规划者旗舰推理模型0.2max_tokens 1200
执行者中端低延迟模型0max_tokens 800
观察者视觉理解最强模型0.1max_tokens 2000
断言者旗舰推理模型0max_tokens 500
修复者旗舰推理模型0.3max_tokens 1500

温度和 max_tokens 两个参数在角色级拆分里特别值得调一调。执行者和断言者必须用 0 温度,因为在"操作手机"和"判断对错"这两个场景里,没有创造性发挥的空间,任何一点随机性都可能造成定位漂移。规划者和修复者可以给一点温度,因为它们偶尔需要在非常规情况下发散思路,比如规划者发现原路径走不通时,修改变量、换个方式尝试就会很有效。

5.5 扩展思路:这套拆分不只是移动端自动化能用,其它场景也能照搬

最后还想多说一句,角色级模型拆分这个思路放到更大的 Agent 场景里也成立。我在自己的一个网页自动化项目里也做了类似的角色拆分(一个提取者、一个操作者、一个验证者),效果同样立竿见影。甚至你写比较复杂的文本生成任务,也可以拆一个"拟大纲的"和一个"写初稿的"和一个"最后审校的",上下文干净,产出质量能明显提升。移动端自动化只是它最能发挥价值的舞台之一,这套方法论本身是可以复用的。

如果你们团队正要上 LLM 驱动的移动端自动化,我最大的建议是:别一开始就追求一个终极模型包打天下,先花一个星期把你的任务流程梳理清楚,看看哪些环节需要"看到什么"、哪些环节需要"决定什么"、哪些环节需要"执行什么",按角色切开,再让合适的模型各就各位。你会发现,很多"模型能力不够"的问题,其实是"流程组织不合理"的问题。

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

遥感大模型落地实践:从算力选型到工程排障的完整指南

这两年遥感行业里最热的一个词肯定绕不开大模型。尤其是卫星影像数据量越攒越多,传统的分割、检测、分类思路开始明显吃力,场景大、目标小、标注稀缺这三座大山压得很多团队喘不过气。我自己在最近一个模拟项目X里,完整做过一套遥感影像解译系…

作者头像 李华
网站建设 2026/10/18 0:45:51

AU动作单元识别:面向工业落地的细粒度面部肌肉检测指南

简介:AU_Recognition-master 是一套面向计算机视觉研究者与情绪计算初学者的面部表情单元(AU)识别开源工具,基于FACS理论实现对基础面部肌肉动作的细粒度检测与强度回归,适用于人机交互、心理状态分析、动画驱动等需要…

作者头像 李华
网站建设 2026/10/18 6:12:22

从玩具到生产力:AI编程工具在存量项目中的落地实践

过去大半年,我在一个模拟项目X上做了一次比较彻底的试验:把AI编程工具从"偶尔问两句"的玩具,变成覆盖日常开发全环节的工作台。这个项目大概有40万行Java代码,历史包袱很重——模块边界模糊、测试覆盖率不到三成、线上还…

作者头像 李华
网站建设 2026/10/21 17:02:49

virsh命令实战:KVM虚拟化运维核心操作指南

做虚拟化运维这几年,我发现自己最常用的工具不是图形化管理平台,而是virsh这个命令行工具。virsh是libvirt提供的命令行管理客户端,只要宿主机跑着KVM/QEMU,它就能帮你把创建虚拟机、开关机、查看状态、网络配置、快照管理这一整套…

作者头像 李华
网站建设 2026/10/22 5:12:17

Tcl脚本驱动FPGA工程自动化:从创建到编译全流程实战

1. 为什么要用Tcl脚本搭建易灵思工程:从痛点说起做FPGA开发有一段时间的朋友,大概率都经历过这种场景:明明只是改了一个引脚约束,结果打开工程GUI,等它加载完,点开约束编辑器,翻半天找到那行配置…

作者头像 李华
网站建设 2026/10/21 21:42:26

三数之和双指针解法详解:排序、去重与边界条件一次讲清

很多人第一次刷到“三数之和”这道题,是在找工作的笔试题里。当时我还在想,这不就是三重循环套一下的事吗?等到自己真被问到“三数之和”并要在白板上手写完整解法时,才发现这题的考察点根本不是“会不会三重循环”,而…

作者头像 李华