1. 从一个模型打天下到角色级拆分移动端自动化测试的架构拐点移动端自动化测试这件事做过的人都懂——它跟Web端自动化完全是两个世界的玩法。Web端你至少还能靠DOM树、XPath、CSS选择器去精确定位元素实在不行还能注入JS脚本兜底。但移动端呢原生控件树在不同系统版本、不同厂商ROM上的表现千差万别一个在模拟器上跑得好好的定位策略换到真机上可能直接失效。更别提那些混合渲染的页面、动态加载的列表、以及各种弹窗和权限请求的干扰。过去两年大语言模型LLM的介入让这个领域出现了新的可能性。我最早接触的一批方案基本思路都是用一个通用大模型包打天下——把页面截图或者控件树丢给模型让它输出下一步操作。这种方案在Demo阶段看起来很美好但一旦放到真实的测试流水线里跑问题就暴露了模型既要理解页面结构又要规划操作路径还要生成具体的执行指令甚至还得处理异常恢复。一个模型扛这么多职责结果就是每个环节都做得不够精响应延迟高Token消耗大而且一旦某个环节出错你根本不知道是理解错了还是规划错了。DroidRun和Mobilerun这两个项目是我近期在移动端自动化测试实践中重点研究的方向。它们的核心思路很有意思不再追求一个模型解决所有问题而是把整个自动化流程拆解成多个角色每个角色由一个专门的模型或模型实例来承担。这就像把一个大包大揽的全栈工程师换成了一个分工明确的小团队——有人负责看页面有人负责想策略有人负责写指令有人负责检查结果。每个角色只关注自己那一亩三分地反而整体效率和质量都上去了。这篇文章我想把DroidRun/Mobilerun这套角色级模型拆分的架构彻底讲清楚。不是泛泛而谈多模型协作的概念而是落到具体的角色划分、模型选型、通信机制、以及我在实际跑通这套方案时踩过的坑和总结的经验。如果你正在做移动端自动化测试或者对LLM驱动的测试方案感兴趣这篇文章应该能给你一些可以直接参考的东西。2. DroidRun与Mobilerun的角色划分逻辑为什么是这四个角色2.1 移动端自动化的本质任务拆解要理解为什么DroidRun/Mobilerun要这样拆分角色得先回到移动端自动化测试的本质任务上来。不管用什么技术方案一个完整的移动端自动化操作循环本质上都包含这么几个环节第一感知当前界面状态。你得知道现在屏幕上有什么——是哪个页面、有哪些可交互元素、每个元素的位置和属性是什么。在传统方案里这一步靠的是UI Automator或者Accessibility Service提供的控件树。但在LLM驱动的方案里这一步变成了把界面信息翻译成模型能理解的自然语言描述。第二决定下一步做什么。基于当前界面状态和测试目标规划出下一步应该执行什么操作——是点击某个按钮、输入一段文本、滑动列表、还是等待某个条件满足。这一步在传统方案里是硬编码的脚本逻辑在LLM方案里则变成了模型的推理和规划。第三生成可执行的指令。把点击登录按钮这样的高层意图翻译成具体的执行指令——比如tap(x540, y1200)或者click(element_idlogin_btn)。这一步需要模型理解移动端操作指令的格式和约束。第四验证操作结果。执行完操作后需要判断操作是否成功、界面是否跳转到了预期状态、有没有出现异常弹窗。这一步在传统方案里靠断言在LLM方案里则需要模型对前后界面状态进行对比和判断。这四个环节每一个对模型能力的要求都不一样。感知环节需要模型有强的视觉理解或多模态能力规划环节需要模型有强的推理和任务分解能力指令生成环节需要模型对特定指令格式有精确的掌握验证环节则需要模型有细致的对比和判断能力。用一个模型去覆盖所有这些能力不是说完全不行但性价比很低——你用一个千亿参数的大模型去做指令格式转换就像用一台超级计算机去算加减法浪费得让人心疼。2.2 四个核心角色的职责边界DroidRun/Mobilerun的做法是把这四个环节分别交给四个专门的角色模型来处理。我在实际项目中把这四个角色分别叫做Observer观察者、Planner规划者、Actor执行者、Validator验证者。Observer的角色是看。它接收移动端截图或者控件树数据输出结构化的界面描述。这个描述不是简单的元素列表而是包含了页面类型判断、关键元素识别、当前状态推断的语义化信息。比如它不只是告诉你屏幕上有一个Button文本是登录而是告诉你当前处于登录页面主要操作入口是登录按钮页面还包含用户名输入框、密码输入框和忘记密码链接。Planner的角色是想。它接收Observer输出的界面描述结合测试目标和历史操作记录输出下一步的操作意图。注意这里输出的是意图而不是指令——比如在用户名输入框中输入测试账号而不是具体的坐标点击指令。Planner需要理解测试用例的上下文知道当前进行到哪一步了下一步应该做什么以及如果遇到异常情况应该怎么处理。Actor的角色是做。它接收Planner输出的操作意图结合当前界面的元素信息生成具体的可执行指令。这个角色对模型的指令格式遵循能力要求很高因为移动端自动化框架对指令的格式、参数、执行时机都有严格要求。Actor还需要处理一些执行层面的细节比如元素定位策略的选择、等待时机的判断、以及操作失败后的重试逻辑。Validator的角色是查。它在Actor执行完操作后对比操作前后的界面状态判断操作是否达到了预期效果。这个角色需要模型有细致的观察力和判断力能够识别出界面看起来变了但实际上没变或者界面没变但状态已经更新这类微妙的情况。这四个角色之间通过一个共享的上下文对象进行通信。这个上下文对象包含了当前界面描述、历史操作记录、测试目标、以及各个角色输出的中间结果。每个角色只读取自己需要的信息只写入自己负责的输出职责边界非常清晰。2.3 角色拆分带来的实际收益我在一个中等规模的移动端测试项目里对比过两种方案的实际表现。项目涉及大约50个测试用例覆盖登录、注册、搜索、下单、支付等核心流程运行环境包括模拟器和两台不同厂商的真机。用单模型方案时平均每个测试用例的完成时间是47秒Token消耗大约是每用例12K成功率在第一次运行时只有68%左右需要人工介入处理失败的情况。失败的原因分布很散有的是页面理解错了有的是操作规划不合理有的是指令格式不对还有的是结果判断失误。因为所有环节都混在一起排查问题非常困难。换成DroidRun/Mobilerun的角色拆分方案后平均完成时间降到了31秒Token消耗降到了每用例7K左右首次运行成功率提升到了85%。更重要的是失败原因变得非常集中——大部分失败都集中在Observer的页面理解环节因为移动端界面确实太复杂了。这意味着我只需要针对Observer这个角色去优化比如换一个视觉能力更强的模型或者补充更多的页面描述训练样本而不需要动其他三个角色。这个对比让我意识到角色拆分的核心价值不在于用了更多的模型而在于把复杂问题分解成了可独立优化、可独立替换的子问题。每个角色的输入输出都是明确定义的你可以针对每个角色单独做A/B测试单独调参单独换模型而不会影响到其他环节。这种架构上的灵活性在长期维护和迭代中带来的收益远比初期多花的那点集成成本要大。3. 各角色的模型选型与Prompt工程实战3.1 Observer的模型选型多模态能力是硬门槛Observer这个角色我试过三种不同的模型配置方案踩了不少坑最后才找到比较稳的组合。最开始我尝试用纯文本模型把控件树序列化成JSON字符串喂给模型。这个方案的问题是控件树的信息密度太低一个稍微复杂点的页面就有几百个节点序列化后动辄上万Token而且模型很难从扁平的节点列表里还原出页面的空间结构和视觉层次。比如两个按钮在控件树里可能是相邻节点但在视觉上一个在顶部一个在底部纯文本模型根本区分不了。后来换成多模态模型直接喂截图。效果好很多但新的问题来了截图的分辨率和模型的视觉编码能力要匹配。我试过用1080p的截图模型能看清大部分元素但对一些小字号文本和图标识别不准。后来调整到720p反而整体准确率更高因为模型在训练时见过的图片分辨率分布更接近这个范围。这个细节很反直觉——不是分辨率越高越好而是要匹配模型的视觉编码器的训练分布。最终我采用的方案是截图精简控件树的混合输入。截图给模型提供视觉布局信息精简后的控件树只保留可交互元素和关键文本给模型提供精确的文本内容和元素属性。两者结合Observer输出的页面描述准确率能到90%以上。在模型选择上我目前用的是中等规模的多模态模型参数量在70亿到130亿之间。太大的模型推理太慢太小的模型视觉理解能力不够。这个区间的模型在移动端截图理解这个任务上性价比最高。具体选哪个取决于你的部署环境——如果追求数据不出内网就得选能本地部署的开源模型如果能接受API调用可选的范围会大很多。Observer的Prompt设计有几个关键点。第一要明确告诉模型输出格式我用的是一种结构化的JSON格式包含page_type、key_elements、current_state、possible_actions这几个字段。第二要给出页面类型的枚举值比如login_page、home_page、search_results、payment_page等让模型做分类而不是自由发挥。第三要强调只描述你确定看到的内容避免模型脑补不存在的元素。这个约束很重要因为多模态模型有时候会幻觉出一些看起来合理但实际不存在的UI元素。3.2 Planner的推理链设计让模型学会三思而后行Planner是四个角色里对模型推理能力要求最高的。它需要理解测试目标的上下文结合当前界面状态和历史操作规划出下一步动作。这个角色我用的是纯文本的推理模型不需要多模态能力但对逻辑推理和任务分解能力要求很高。我在设计Planner的Prompt时最重要的一条经验是强制模型输出推理过程。不是让它直接给答案而是要求它先分析当前状态、再对比测试目标、然后评估可选操作、最后才给出决策。这个思维链的设计让Planner的决策准确率提升了将近20个百分点。具体来说Planner的输出格式我设计成这样的结构{ analysis: 当前处于登录页面用户名和密码输入框均为空测试目标要求完成登录操作, reasoning: 根据测试用例下一步应该先输入用户名。历史记录显示尚未输入任何内容因此需要执行输入操作, next_action: { type: input_text, target: username_field, value: test_user_001, reason: 测试用例指定的测试账号 }, fallback: { condition: if_username_field_not_found, action: report_error_and_screenshot } }这个格式里analysis和reasoning字段是给模型自己想清楚用的next_action是给Actor执行的fallback是异常情况的兜底方案。实测下来要求模型显式输出推理过程不仅能提高决策质量还能在出错时快速定位是哪个环节的推理出了问题。Planner的另一个关键设计是历史操作记录的压缩。移动端测试用例往往有几十步操作如果把所有历史都塞进PromptToken消耗会爆炸。我的做法是只保留最近5步的详细记录更早的操作压缩成摘要形式。比如已完成登录流程当前处于首页这样的摘要而不是把登录的每一步都列出来。这个压缩策略在保证Planner有足够上下文的同时把Token消耗控制在了可接受的范围内。还有一个坑我踩过Planner有时候会过度规划就是当前界面明明只有一个合理操作它还要长篇大论地分析各种可能性。后来我在Prompt里加了一条规则如果当前界面只有一个明确的下一步操作直接输出该操作不需要展开分析。这条规则让Planner的平均响应时间缩短了大约30%。3.3 Actor的指令生成精确性比聪明更重要Actor这个角色说实话技术含量没有Planner那么高但对精确性的要求是最苛刻的。它接收Planner输出的操作意图结合当前界面的元素信息生成具体的执行指令。这个环节最怕的就是模型自作聪明——比如Planner说点击登录按钮Actor非要自己判断登录按钮的位置结果点偏了。我的做法是Actor的Prompt里要包含完整的元素定位信息让模型只做意图到指令的翻译不做任何额外的判断。具体来说Observer输出的页面描述里每个关键元素都带有唯一的element_id和多种定位方式resource_id、text、bounds、xpath等。Actor的任务就是根据Planner指定的target从这些定位方式里选择最合适的一个生成对应的指令。选择哪种定位方式是有优先级的。我的经验优先级是resource_idtextboundsxpath。resource_id最稳定但很多App的控件没有设置text在文本内容固定的情况下很好用但多语言场景下会失效bounds是坐标定位最通用但最不稳定屏幕分辨率一变就废xpath在移动端支持有限而且性能差。Actor的Prompt里我会明确这个优先级让模型按顺序尝试。Actor的模型选型我用的是参数量较小的指令微调模型大概在30亿到70亿参数之间。这个规模的模型对格式遵循已经足够了而且推理速度快适合高频调用。关键是这个模型要经过指令格式的微调能够稳定输出符合移动端自动化框架要求的指令格式。这里有个细节值得展开说移动端自动化框架比如基于Accessibility Service的方案对指令的执行时机有要求。比如点击操作如果目标元素还没渲染完成就执行会直接失败。所以Actor生成的指令里我要求包含一个wait_condition字段指定执行前需要等待的条件。这个条件可以是元素出现、元素可点击、页面加载完成等。这个设计让Actor从单纯的指令生成者变成了一个带执行策略的指令生成者实际运行中的失败率降低了不少。3.4 Validator的判断逻辑如何避免看起来成功了Validator是四个角色里最容易被低估的。很多人觉得验证嘛不就是对比一下操作前后的界面变化吗但实际做起来移动端界面的变化和没变化之间的界限非常模糊。我遇到过几种典型情况点击按钮后界面看起来没变但实际上后台已经提交了请求只是响应还没回来或者界面变了但变的是无关的广告轮播图核心状态其实没变还有操作成功了但紧接着弹出了一个权限请求弹窗把真正的结果遮住了。这些情况简单的截图对比根本判断不了。Validator的Prompt设计我强调的是多维度验证。不是只看界面是否变化而是从多个角度综合判断目标元素的状态是否改变比如按钮从可点击变成禁用、页面标题或关键文本是否变化、是否出现了预期的成功提示、是否有异常弹窗出现、网络请求状态是否正常如果能获取到的话。Validator的输出我设计成三个等级success、uncertain、failure。success表示明确验证通过uncertain表示无法确定需要进一步观察或重试failure表示明确失败。这个三值逻辑比简单的成功/失败二元判断要实用得多因为移动端自动化里不确定的情况太多了强行二选一反而容易误判。对于uncertain的情况我的处理策略是让Validator再观察一轮如果还是uncertain就交给Planner做决策——是继续等待、重试操作、还是标记为需要人工介入。这个处理链路在实际运行中把误判率控制在了很低的水平。Validator的模型选型我用的是和Observer同源的多模态模型但Prompt完全不同。Observer关注的是页面上有什么Validator关注的是页面变化意味着什么。这两个任务对模型的视觉理解能力要求类似但推理方向相反所以可以共用模型但用不同的Prompt来区分角色。4. 角色间通信与上下文管理让四个模型像一个团队一样工作4.1 共享上下文对象的设计四个角色模型要协同工作必须有一个共享的上下文对象来传递信息。这个上下文对象的设计直接决定了整个系统的运行效率和稳定性。我的上下文对象包含这么几个核心部分测试目标当前测试用例的完整描述、界面状态Observer最新输出的页面描述、操作历史最近N步的操作记录和结果、当前步骤Planner最新输出的操作意图、执行结果Actor执行后的原始结果、验证结论Validator的最新判断。这个上下文对象在每个角色处理完后都会更新然后传递给下一个角色。整个流程是一个循环Observer感知界面 → Planner规划动作 → Actor生成指令 → 执行 → Validator验证结果 → 更新上下文 → 回到Observer。这里有个关键的设计决策上下文对象是增量更新的不是全量重建的。每个角色只更新自己负责的字段其他字段保持不变。这样做的好处是每个角色都能看到完整的历史信息但不需要重新处理所有信息。比如Planner在规划时可以直接读取Observer最新输出的界面描述而不需要自己去重新理解界面。上下文对象的序列化和反序列化也有讲究。因为要在不同的模型调用之间传递上下文对象需要序列化成文本格式。我用的是一种紧凑的JSON格式对长文本字段做了截断处理确保整个上下文对象的大小控制在模型上下文窗口的合理范围内。实测下来一个包含最近5步操作历史的上下文对象序列化后大约在2K到4K Token之间对于大多数模型的上下文窗口来说都很宽裕。4.2 角色间的触发时机与循环控制四个角色不是简单地串行执行就完事了它们之间的触发时机和循环控制需要仔细设计。最基本的循环是Observer → Planner → Actor → 执行 → Validator。但实际运行中这个循环会有很多变体。比如Validator判断为uncertain时会触发Observer重新感知界面然后Validator再做一次判断而不是直接进入下一轮Planner规划。又比如Actor执行失败时会触发Planner重新规划而不是直接报错退出。我设计了一套状态机来控制这个循环。整个自动化流程的状态包括observing、planning、acting、validating、recovering、completed、failed。每个状态对应一个角色的处理逻辑状态之间的转换由各个角色的输出决定。这个状态机的设计让整个流程的控制逻辑非常清晰。比如recovering状态专门处理异常恢复当Actor执行失败或者Validator判断为failure时会进入这个状态由Planner重新规划一个恢复动作。恢复动作执行后再回到正常的验证流程。这个设计避免了异常情况下的流程混乱也让异常处理逻辑可以独立优化。循环控制还有一个重要的参数是最大步数限制。移动端测试用例有时候会因为各种原因陷入死循环比如某个弹窗一直关不掉或者某个页面一直加载不出来。我设置的最大步数是50步超过这个步数就强制终止并标记为失败。这个限制在实际运行中救过好几次场避免了测试任务无限期挂起。4.3 Token消耗的优化策略四个角色模型协同工作Token消耗是单模型方案的好几倍这是角色拆分方案最大的成本。我在实际项目中做了不少优化把Token消耗控制在了可接受的范围内。第一个优化是按需调用。不是每一步都调用所有四个角色。比如Observer的输出如果和上一步完全一样界面没变化Planner可以直接复用上一步的规划结果不需要重新调用。Validator如果判断为success且下一步操作明确也可以跳过一些中间环节。这个按需调用的策略在实际运行中减少了大约30%的模型调用次数。第二个优化是上下文压缩。前面提到过历史操作记录只保留最近5步的详细记录更早的压缩成摘要。界面描述也只保留关键元素而不是所有元素。这些压缩策略在保证信息足够的前提下把每次调用的Token消耗降低了大约40%。第三个优化是模型分级。不是所有角色都需要用同样规模的模型。Observer和Validator需要多模态能力用中等规模的模型Planner需要强推理能力用推理能力强的模型但可以适当控制规模Actor只需要指令格式遵循能力用小模型就够了。这个分级策略让整体Token成本降低了大约50%而效果几乎没有损失。第四个优化是缓存机制。对于重复出现的界面状态和操作模式可以缓存之前的处理结果。比如登录页面每次出现时Observer的输出基本是一样的可以直接从缓存读取不需要重新调用模型。这个缓存在回归测试场景下特别有效因为回归测试的用例往往是重复执行的。5. 实测中的坑与排查链路那些文档里不会写的问题5.1 Observer的幻觉问题模型看到了不存在的东西这是我在实际运行中遇到的最频繁的问题。Observer有时候会看到一些实际上不存在的UI元素或者把某个元素的属性搞错。比如把注册按钮的文本识别成登录或者把一个不可点击的文本标签识别成按钮。排查这个问题的过程比较曲折。我一开始以为是模型能力不够换了一个更大的多模态模型结果幻觉问题反而更严重了——大模型更倾向于脑补合理的界面元素。后来我调整了思路从Prompt和输入数据两方面入手。Prompt方面我加了一条强约束只描述你在截图中明确看到的内容。如果某个元素的存在不确定标记为uncertain而不是猜测。同时我要求Observer对每个识别出的元素输出一个confidence分数低于阈值的元素不进入后续流程。输入数据方面我发现截图的预处理很关键。原始截图有时候包含状态栏、导航栏等干扰信息这些区域的内容容易被模型误识别。我在截图预处理阶段裁掉了状态栏和导航栏只保留应用内容区域幻觉问题明显减少。还有一个细节截图的分辨率要匹配模型的视觉编码器。我试过用2K截图模型反而识别不准因为训练数据里这种分辨率的图片很少。后来统一缩放到720p准确率最高。这个经验说明不是给模型越清晰的数据越好而是要匹配模型的训练分布。5.2 Planner的过度思考简单问题复杂化Planner的推理能力是它的优势但有时候也是它的负担。我遇到过好几次当前界面明明只有一个合理操作Planner却要分析各种可能性输出一大段推理过程最后才给出一个显而易见的答案。这不仅浪费Token还增加了响应延迟。更严重的是过度思考有时候会导致Planner想太多而做出错误决策。比如当前界面有一个明显的下一步按钮Planner却在分析如果点击这个按钮会怎样如果不点击会怎样有没有其他隐藏操作最后选择了一个非主流的操作路径导致测试流程跑偏。解决这个问题的办法是在Prompt里加入决策复杂度评估的步骤。要求Planner先判断当前决策的复杂度如果只有一个合理操作直接输出如果有多个可选操作才展开分析。这个简单的规则让Planner的过度思考问题减少了80%以上。另外我还给Planner加了一个操作白名单机制。对于某些明确的测试步骤直接在Prompt里指定可选操作的集合Planner只能从这个集合里选不能自由发挥。比如登录页面这个状态下可选操作只有输入用户名输入密码点击登录点击忘记密码这几个Planner不需要去分析其他可能性。这个机制在标准化测试用例中特别有效。5.3 Actor的定位失败元素明明在那里却点不到Actor执行失败最常见的原因是元素定位失败。明明Observer报告了某个元素存在Actor也生成了对应的点击指令但执行时就是找不到元素。这个问题在真机上比模拟器上更常见因为真机的渲染时机和模拟器不一样。排查这个问题的关键是区分元素不存在和元素存在但不可交互。前者是Observer的问题后者是Actor的等待策略问题。我的做法是在Actor的指令里加入wait_condition指定执行前需要等待的条件。比如点击按钮前等待元素可点击而不是元素存在。这个改动让Actor的执行成功率提升了大约15个百分点。还有一个坑是元素被遮挡。移动端App经常有浮层、弹窗、广告等遮挡物Observer能看到底层的元素但Actor执行点击时会被遮挡物拦截。解决这个问题的办法是在Actor的Prompt里加入遮挡检测的逻辑如果目标元素的位置上有其他元素覆盖先处理遮挡物关闭弹窗或滑动页面再执行目标操作。真机上的另一个问题是系统权限弹窗。第一次安装App时系统会弹出各种权限请求这些弹窗不在App的控件树里Observer和Actor都处理不了。我的做法是在自动化框架层面加一个系统弹窗的监听和处理机制检测到系统弹窗时自动授予权限然后再继续正常的自动化流程。5.4 Validator的误判界面变了但状态没变Validator的误判主要有两种假阳性和假阴性。假阳性是操作实际失败了但Validator判断为成功假阴性是操作实际成功了但Validator判断为失败。两种误判都会导致后续流程出错。假阳性的典型场景是点击按钮后界面出现了一个短暂的加载动画Validator看到界面变化了就判断为成功但实际上加载完成后可能显示的是错误提示。解决这个问题的办法是让Validator等待界面稳定后再做判断而不是一看到变化就下结论。我在Validator的Prompt里加入了等待界面稳定的指令具体实现是在截图前等待一段时间或者等待某个稳定条件满足。假阴性的典型场景是操作成功了但界面变化很细微Validator没注意到。比如输入文本后输入框的内容变了但Validator只关注了页面标题和按钮状态没注意到输入框的变化。解决这个问题的办法是让Validator做多维度对比不只是对比整体截图还要对比关键元素的状态。我在Validator的Prompt里列出了需要对比的维度页面类型、关键元素列表、每个关键元素的属性、页面标题、可见文本内容。多个维度综合判断误判率大幅降低。还有一个特殊情况是异步操作。有些操作比如提交表单的结果不是立即返回的需要等待网络请求完成。Validator如果立即判断很可能会误判。我的做法是在Validator的Prompt里加入如果操作涉及网络请求等待请求完成后再判断的指令同时在自动化框架层面提供网络请求状态的查询接口让Validator可以获取到请求的完成状态。6. 从单模型到角色拆分的迁移路径与成本评估6.1 什么情况下值得做角色拆分角色拆分不是银弹它带来的架构复杂度和集成成本是实实在在的。我的经验是以下几种情况下角色拆分的收益会明显大于成本第一种是测试用例规模大、执行频率高的场景。如果你的测试套件有几百个用例每天都要跑好几轮那么角色拆分带来的效率提升和成本降低会很快覆盖初期的集成成本。反之如果只是十几个用例偶尔跑一下单模型方案可能更划算。第二种是对失败原因可追溯性要求高的场景。角色拆分最大的优势之一是每个环节的输出都是独立的、可检查的。当测试失败时你可以快速定位是感知错了、规划错了、执行错了还是验证错了。如果你的团队需要快速定位和修复测试失败角色拆分带来的可观测性提升非常有价值。第三种是需要针对特定环节优化的场景。比如你的App界面特别复杂Observer的准确率一直上不去那么你可以单独针对Observer做优化换更好的多模态模型或者补充训练数据而不需要动其他环节。这种独立优化的灵活性是单模型方案不具备的。第四种是多端适配的场景。如果你的测试需要同时覆盖Android和iOS角色拆分让你可以针对不同平台使用不同的Observer因为两个平台的界面渲染差异很大但Planner和Actor可以共用。这种灵活性在跨平台测试中很有价值。6.2 迁移过程中的关键决策点从单模型方案迁移到角色拆分方案有几个关键决策点需要提前想清楚。第一个决策是角色数量的确定。我建议从四个核心角色开始Observer、Planner、Actor、Validator。不要一开始就拆得太细比如把Observer再拆成截图理解和控件树解析两个角色那样集成成本会急剧上升。先跑通四个角色的基本流程再根据实际需要做进一步的拆分。第二个决策是模型选型的策略。我的建议是Observer和Validator用同源的多模态模型Planner用推理能力强的文本模型Actor用指令微调的小模型。这个组合在大多数场景下都能工作得不错。如果资源有限可以先从两个模型开始一个多模态模型承担Observer和Validator一个文本模型承担Planner和Actor。等跑通了再逐步拆分。第三个决策是上下文对象的格式。这个格式一旦确定后续所有角色都依赖它改起来成本很高。我的建议是用JSON格式字段命名要清晰每个字段都要有明确的语义。同时要预留扩展字段方便后续加入新的信息。第四个决策是异常处理策略。角色拆分后异常处理的链路变长了需要仔细设计。我的建议是每个角色都要有明确的失败输出格式以及对应的恢复策略。比如Observer失败时是重试还是跳过Planner失败时是回退到上一步还是终止Actor失败时是重试还是重新规划。这些策略要在迁移前就想清楚。6.3 实际成本与收益的量化对比我在一个实际项目中做了详细的成本收益对比。项目规模是200个测试用例每天执行3轮运行环境包括模拟器和真机。单模型方案的成本每用例平均Token消耗12K每天总消耗7.2M Token平均执行时间47秒每天总执行时间约7.8小时首次运行成功率68%需要人工介入处理的失败用例每天约192个。角色拆分方案的成本每用例平均Token消耗7K每天总消耗4.2M Token平均执行时间31秒每天总执行时间约5.2小时首次运行成功率85%需要人工介入处理的失败用例每天约90个。从Token成本看角色拆分方案降低了约42%。从执行时间看降低了约33%。从人工介入成本看降低了约53%。而初期的集成成本包括Prompt设计、模型选型、上下文对象设计、异常处理链路搭建大约花了3个人周。按照每天节省的人工介入时间和Token成本来算大约6到8周就能收回集成成本。这个对比说明对于中等规模以上的移动端自动化测试项目角色拆分方案的投入产出比是相当不错的。当然具体数字会因项目而异但这个量级的差异是普遍存在的。7. 角色拆分方案的边界与后续演进方向角色拆分方案不是万能的它有自己的适用边界。我在实际使用中总结了几条边界条件超出这些条件的场景可能需要考虑其他方案。第一条边界是测试用例的标准化程度。角色拆分方案在标准化程度高的测试用例上表现最好因为Planner的决策空间小Actor的指令生成也相对固定。如果测试用例非常灵活需要大量的探索性操作Planner的负担会急剧增加角色拆分的优势就不明显了。这种情况下可能需要引入强化学习或者更复杂的规划算法。第二条边界是界面的动态程度。如果App界面变化非常频繁Observer需要不断重新理解界面缓存的命中率会很低Token消耗会上升。这种情况下可能需要加强Observer的泛化能力或者引入界面元素的自动识别和标注机制。第三条边界是对实时性的要求。角色拆分方案涉及多次模型调用端到端的延迟比单模型方案要高。如果测试场景对实时性要求很高比如需要模拟用户的快速连续操作角色拆分方案可能跟不上。这种情况下需要考虑模型推理的加速方案或者把部分角色合并。后续的演进方向我看到几个比较有前景的。一个是角色的动态调整根据当前任务的复杂度自动决定调用哪些角色、用什么规模的模型。比如简单页面用轻量级Observer复杂页面用重量级Observer。另一个是角色间的知识共享让Observer学到的界面理解能力可以传递给Validator减少重复学习。还有一个是自动化Prompt优化通过分析历史执行数据自动调整各个角色的Prompt持续提升整体效果。这些方向目前还在探索阶段但已经能看到一些初步的成果。移动端自动化测试这个领域因为LLM的介入正在经历一轮架构上的重新思考。角色级模型拆分只是其中一种思路但我觉得它代表了一个重要的方向用架构设计来弥补单模型能力的不足用分工协作来提升整体系统的效率和可靠性。这个思路不仅适用于移动端自动化测试在其他复杂的LLM应用场景中应该也有参考价值。
阅读完成 · 觉得有帮助?