ARTEMIS 这个名字刚火起来的时候,我第一反应是:又是个玩具 Demo 吧。等真的把它接到一台 Android 真机上,看着 AI Agent 自己把设置页翻了三层、点开开发者选项、还把亮度拉到顶,我才意识到,这次可能真的不一样了。
Google 开源的 ARTEMIS,正是冲着“让 AI Agent 接管 Android 真机测试”这件事来的。它的思路很直接:不再依赖我们手写的定位符和等待条件,而是让多模态大模型直接看着屏幕截图,理解当前页面,然后输出下一个操作动作。就像你招了个实习生,给他一台手机、一个任务描述,他不用看测试用例,自己摸索着就能把事情办了。这篇文章我会从框架解决什么问题、核心设计怎么拆、到真机实操怎么跑通,再到我实际踩过的坑,全流程讲一遍。
1. 先搞清楚 ARTEMIS 在替代哪一部分工作
1.1 传统 UI 自动化脚本为什么让我天天加班
做 Android 测试的人都知道,传统的 UI 自动化主要靠两套东西:一套是 UIAutomator / Espresso 这类基于控件的框架,另一套是 Appium、Airtest 这种跨平台的工具。它们的共同点是:脚本里写满了resource-id、content-desc、xpath,再配上各种waitForElement。
看起来没什么问题,但真实业务里你会遇到什么?开发改了一个控件的 id,脚本挂了;某个页面的加载速度在低端机上慢了 500ms,你设的等待时间不够,挂了;Android 系统弹了个权限框,把你要点的按钮挡住了,挂了。光是在“定位元素”和“处理弹窗”这两件事上,维护成本就能吃掉你一半的排期。
更麻烦的是真机场景。很多问题是只在真机上出现的,比如弱网切换、推送横幅遮挡、系统级弹窗、后台进程被杀,模拟器根本不给你机会复现。所以真机测试从来不是“可选项”,而是“必选项”。但真机的问题在于,它太不稳定了,脚本跑着跑着就断,设备莫名其妙弹一个系统升级的对话框,整个用例就白跑了。
1.2 AI Agent 的目标不是“跑脚本”,而是“看着屏幕干活”
ARTEMIS 的出现,是换了一条路:我不告诉你元素在哪,我让你看屏幕,你自己决定下一步做什么。
它本质上是一个“端到端的 GUI Agent 框架”。你给它一个自然语言任务,比如“打开设置,找到关于手机,截图保存”,它会自己调用视觉语言模型(VLM),把当前屏幕截图转换成一段关于页面内容的理解,然后推断该执行哪个动作。这个动作不局限于点击某个坐标,还包括滑动、输入文字、返回、打开应用等。
这和 AppAgent、Mobile-Agent 这些同类项目做的事很接近,但 ARTEMIS 有几个让我愿意从源码开始看的点:一是它由 Google 开源,工程化程度相对高;二是它对 Android 真机的支持是原生级别的,不是跑在通用模拟器上;三是它把“感知、执行、评估”做成了模块化,不是绑定单一模型,你可以换掉视觉模型,也可以改动作空间。
这个思路解决了一个很实际的问题:脚本是死的,但 App 是活的。页面上多一个 banner、少一个 tab,脚本就废了。但模型看的是语义,它知道“更多设置”在哪里,哪怕按钮位置变了,它仍然能找到。这正是 AI Agent 相比传统脚本最核心的竞争力。
1.3 在动手之前先想清楚:这个框架适合谁,不适合谁
我在分享社区里看到不少人拿它跑了一下 Demo,然后就说“AI 测试已经要取代人了”,这种说法太夸张了。我把它用了两三周之后的感觉是:它是一个非常好的补位工具,但它不是银弹。
适合谁?如果你需要做 App 的冒烟测试、遍历测试、兼容性探索,尤其是系统弹窗多、页面结构复杂、迭代快的项目,ARTEMIS 这类 Agent 的维稳能力比脚本强很多。如果你正在搞 AI 落地,想让模型真正在真实环境里“动手干活”,它也是一个非常好的参考实现。
不适合谁?如果你的团队连基础的真机设备池都还没搭起来,或者你期望它给出 100% 稳定的回归测试结果,那现在还不是时候。AI Agent 的随机性依然存在,你不可能指望它像传统断言那样一丝不苟,它更适合做“探索性检测”和“兜底覆盖”。
2. 拆开框架看核心设计:从屏幕像素到动作输出
2.1 感知模块:截图、控件树、设备状态三者怎么配合
ARTEMIS 的第一步,是让 Agent 知道当前屏幕上发生了什么。这部分设计得很务实,它没有只依赖截图,而是把截图和 Android 的控件树(XML)结合起来用。
截图好理解,就是把真机屏幕实时画面拍下来,交给视觉模型去解析。但只用截图有个问题:视觉模型在识别复杂列表、细小图标、多层嵌套页面的准确率还不算高,而且有些信息光靠看是看不出来的。所以 ARTEMIS 会通过adb shell uiautomator dump把当前页面的控件层级拉出来,作为额外的“文本上下文”喂给模型。
这个设计我非常认同。很多纯视觉的 GUI Agent 跑得磕磕绊绊,就是因为模型看不清屏幕上的字,尤其是中文小字号和深色背景。加了 XML 之后,模型相当于拿到了一份“页面说明书”,虽然它没有坐标那么精确,但语义信息足够了。
设备状态也不能忽略。ARTEMIS 会在每轮交互前检查当前的 Activity 栈、系统弹窗状态、以及是否处于锁屏页面。为什么要这么做?因为模型如果不知道当前设备锁着屏,它会一直发呆,不知道自己点击为什么没反应。把设备状态加进去,Agent 才能做出符合真实情况的判断。
2.2 决策模块:想办法让模型说出“我现在要做什么,为什么”
感知之后进入决策层。ARTEMIS 的决策模块,本质上是一次多次推理(multi-step reasoning)过程。它不会让模型直接输出坐标,而是先让模型描述当前看到了什么,再推断离目标还差哪些步骤,最后才输出一个具体的动作。
我在本地复现时看了一眼它内部构造的 prompt 结构,核心逻辑是这样的:系统提示词里会写明当前任务、可用动作空间、设备信息,然后附上截图和 XML 内容。模型需要先回答“当前界面状态”,再回答“下一步动作”,最后给出“动作参数”。用术语讲,这就是把“感知—推理—行动”显式拆开了。
这个“先想再说”的好处是:当模型的动作连续出错时,你可以从它的推理文本里看到它到底哪里理解错了。是没找到控件?还是概念理解反了?这比传统的黑盒脚本要好排查得多。
动作空间也是有限集合,不是让模型随便输出文字。它只能从有限的几个动作类型里选,比如click、swipe、input_text、open_app、press_back、wait、done。这样做的原因很简单:如果让模型自由发挥,它可能输出一个根本不存在的点击坐标,或者乱写一段文字输入。限制动作空间,等于给 Agent 修了一条轨道,它只能沿着轨道前进,而不是满地乱爬。
2.3 执行模块:真机操作的落地细节,比你想的更琐碎
决策层输出“我想点击坐标 (x, y)”,执行层就要真正在真机上把这件事完成了。ARTEMIS 的执行层和 ADB 深度绑定,本质上是把动作翻译成 ADB 命令,比如点击就是adb shell input tap x y,滑动就是input swipe,输入文本则是adb shell input text。
听起来简单,但真机执行有很多琐碎的坑。首先是坐标系统,真机有不同分辨率,截图的分辨率和实际触控坐标并不总是一一对应。ARTEMIS 会自动处理截图的尺寸缩放和坐标映射关系,这一步如果做错了,模型看到的和实际点击的位置就会有偏移。
其次是执行时序。点完屏幕之后 UI 不会立刻静止下来,页面可能有动画、有加载、有数据回填。ARTEMIS 在每次执行完动作后会等待一段时间,然后重新拉取截图和 XML,再进行下一轮决策。等待时间如果太短,Agent 看到的是旧页面,会重复执行上一个动作;等待时间太长,又会拖慢整个任务的执行速度。真机上的网络和硬件差异,会让这个等待策略变得非常微妙。
另外,真机还有一个桌面环境没有的麻烦:物理按键和系统手势。返回键、Home 键、最近任务键,以及屏幕边缘手势,这些真机特有的东西在模拟器里往往被弱化了。ARTEMIS 把press_back、go_home、recents都纳入动作空间,我才意识到设计者是真的在真机上踩过坑的,因为很多 UI 自动化框架根本不会管你“按了返回之后页面有没有真的退出”。
2.4 评估模块:怎么判断“这一步完成了”而不是“模型觉得自己完成了”
传统测试有断言,跑完一步是好是坏一目了然。AI Agent 怎么知道任务做完了?ARTEMIS 的思路是:不依赖动作序列,而是让一个“评估器”来判断最终状态是否达到任务目标。
比如任务目标是“因为要检查亮度,所以把亮度调到最高”。你在配置里写清楚目标特征,评估器会拉取最终的截图和页面描述,判断屏幕上的亮度条是否处于最大值。这比检查“有没有执行某个点击动作”要可靠得多,因为动作执行了不代表结果出现了,可能那个点击被拦截了,可能根本没有点中。
我在用的过程中总结出一个经验:把任务目标写得越具体,评估就越准。不要写“把系统设置改一下”,要写“检查系统设置中显示页面的亮度滑块是否处于最右侧”。这样评估器才能有据可依。
3. 从零跑通一个 Android 真机测试任务
3.1 环境准备:有哪些东西必须先装好
先说结论:不要一上来就在模拟器里试,ARETMIS 的价值就在真机,直接在真机上跑。模拟器很多页面渲染和系统弹窗行为跟真机不一样,你花半天调好的脚本,到真机上又是另一副面孔。
你需要准备的东西不算多,我列一个清单:
- 一台 Android 真机,建议 Android 10 以上,系统版本不要太旧;
- 数据线,或者提前配好无线 ADB;
- 电脑上装好 Android SDK platform-tools,确保
adb devices能识别设备; - Python 环境,建议 3.10 以上;
- 一个可用的视觉语言模型接口,或者本地部署的 VLM;
- 到 GitHub 拉下 ARTEMIS 仓库,按 README 装好依赖。
这里有个很容易踩的坑:很多人的adb版本不是最新的,结果在 Android 13 以上的设备上频繁掉线。建议先检查adb --version,把 platform-tools 升级到较新版本,然后再连设备。
还有一个小建议:先把手机上的“开发者选项”和“USB 调试”打开,第一次用数据线连接时,手机上会弹出“是否允许 USB 调试”的授权对话框。这个对话框,AI Agent 是点不了的,你得先手动点掉,不然它会一直卡在那里等授权。这是新手最常见的翻车点。
3.2 配置一个最简单的冒烟任务
ARTEMIS 的配置文件是 YAML 格式,核心要写的不是代码,而是“任务描述”和“模型配置”。我第一次跑的时候,把任务写成:
- 任务目标:打开系统设置,进入“显示”页面,将亮度调到最高,停留 3 秒;
- 期望结果:设置页面的亮度滑块位于最右侧。
配置文件里还需要指定设备序列号(adb devices里能查到),以及模型相关参数。如果你用的是云端模型 API,就填好 API Key 和模型名称;如果是本地模型,就要配置本地推理服务的地址和模型名称。
第一次创建一个真实的冒烟任务,我不建议上来就搞复杂流程。选一个步骤数不超过十步的任务,比如“打开计算器,输入 123+456,检查结果是否显示 579”。这种任务步骤清晰、结果好评估,用来熟悉框架的执行流程刚刚好。
3.3 把一个任务跑起来,逐步看它怎么操作
跑起来之后,ARTEMIS 的执行流程大概是这样:
- 框架通过 ADB 拉取当前屏幕截图和 XML 控件树;
- 把任务描述、截图、XML、设备状态拼成一段 prompt,发给视觉语言模型;
- 模型返回推理结果,包含当前界面分析和下一步动作;
- 执行模块把动作转成 ADB 命令,在真机上执行;
- 等待一小段时间,让页面稳定下来;
- 重复步骤 1,直到任务完成,或者达到最大步数限制。
我跑“打开设置调亮度”这个任务时,印象最深的是模型对页面变化的适应能力。它没有死记“亮度滑块在第三行”,而是根据看到的页面内容动态调整。第一次它点进设置列表,发现没找到“显示”,就返回重新找;第二次看到了“显示”入口,点进去之后又花了两次操作才找到亮度滑块。
整个过程中,它的推理文本会输出到日志里。我在终端里盯着这些日志,那种感觉非常奇妙——你会觉得对面似乎有一个对手机并不熟悉但愿意尝试的新同事,在一步一步摸索着完成任务。
不过要注意,并不是每次都会顺利。模型偶尔会犯“自以为点到了,其实没点到”的错误。比如它判断亮度滑块在当前页,直接执行了滑动,但屏幕上根本没有这个滑块,于是任务就出现了无效动作。这种问题需要配合配置里的连续重复动作限制来兜底。
3.4 关键参数怎么调:速度、效率与稳定性的权衡
真正把 ARTEMIS 跑起来之后,有几个参数是需要你根据自己的设备环境调的。
第一个是模型温度(temperature)。温度太高,输出随机性增大,Agent 会做很多天马行空的操作;温度太低,模型会变得保守,经常输出“无权完成”或重复同一个动作。我个人的经验是把温度调到 0.2 到 0.4 之间,既能保持适当探索性,又不会乱来。
第二个是每一轮交互后的等待时间。这个要看具体设备的响应速度,有点复杂。低端机上页面切换可能要 2 秒才能渲染完,高端机 0.5 秒就结束了。你设置一个固定等待 1 秒,低端机会因为页面没加载完而误判;设置 3 秒,高端机每个任务多花几十秒时间。我后来干脆把等待时间拉长到 2 秒左右,宁慢勿错,因为出错一次导致的重新执行,比等待多花的时间要多得多。
第三个是最大步数(max steps)。默认值如果太小,复杂任务根本跑不完。但设得太大,Agent 会一直空转,直到超出限制。我会按任务复杂度预估一个步数上限,比如冒烟任务 20 步左右,复杂探索任务给到 50 步。如果跑完发现 Agent 频繁用到上限,那就不是步数问题,而是动作空间设计有问题,需要回头调整配置了。
4. 我在实际跑测中踩过的问题和解决办法
4.1 ADB 设备掉线、授权弹窗把 Agent 卡住的那些事
这个可以说是我的首要翻车点。ARTEMIS 跑得好好的,突然设备状态变成 offline,所有操作都失效。一开始我以为是数据线的问题,换了根线还是掉,最后才发现是 USB 供电不稳定,手机在持续高负载运行的时候触发了自我保护,断开了 ADB 连接。
解决办法有两个:一是改用无线 ADB 模式,通过adb pair和adb tcpip 5555配置网络连接,少了一根物理线缆,稳定性反而高不少;二是给手机上插着充电线,避免“持续 USB 调试导致电池过热”触发的降级策略。
另一个让我苦恼的问题,是系统弹窗拦截了 Agent 的操作。比如小米手机第一次连接 ADB 时会弹“是否同意安装应用”,ColorOS 会出现“允许后台弹窗吗”,这些弹窗不会主动消失,Agent 看到的是一个似乎能点击但实际什么都点不动的页面。
我的做法是把这些动效和弹窗尽量关闭。系统开发者选项里有一堆切换开关,我建议提前关掉系统动画,关闭“USB 安装”相关确认,最好在准备环境的时候就一次性处理好。不要指望 Agent 在真机上自主处理这些系统级弹窗,至少在现阶段,人工前置处理是必要的。
4.2 模型幻觉导致原地打转,怎么限制动作空间
AI Agent 跑起来之后,最让人崩溃的不是它不会操作,而是它“觉得自己已经操作了”。模型输出一个点击动作,执行层照做了,但截图像素完全没有变化,模型却在下一次推理时说“当前页面显示亮度滑块已在最右侧”。这就是典型的模型幻觉。
应对幻觉,我用的是组合策略。第一,把动作空间尽量缩小,只保留当前任务真正需要的动作类型,减少模型乱选的空间。第二,引入“重复动作检测”,如果连续两个循环输出的动作完全一致,且屏幕截图没有变化,就强制终止当前动作,让它重新观察页面。第三,明确要求模型在推理文本里描述“执行结果是否产生了变化”,用变化来逼迫模型更谨慎地给出结论。
这里有个技巧:ARTEMIS 的配置里可以设置“无操作最大连续次数”。我设置的是 3 次。一旦连续 3 次没有带来页面变化,就中止任务并标记为失败。与其让它在原地转圈烧 token,不如早点结束,人工看一下到底是哪里出了问题。
4.3 权限弹窗、系统弹窗对连续任务的干扰
做真机测试,权限弹窗是绕不开的大山。App 第一次启动会要存储权限、定位权限、相机权限,安卓系统的弹窗样式千奇百怪,不同厂家的定制系统弹窗位置还都不一样。
ARTEMIS 碰到权限弹窗,其实是可以尝试处理的。因为弹窗上的按钮是“仅在使用期间允许”“使用应用时允许”“允许”“拒绝”这类明确的文本,模型只要能看到这些文字,基本能理解该怎么按。但难点在于,弹窗出现的时机不可预测,可能正好挡在 Agent 下一步要点击的位置上。
我的经验是分两层来治理。首先,在跑任务之前,针对被测 App 提前把常规权限全部手动授予一遍,减少运行中弹窗的概率。其次,在 ARTEMIS 的动作空间和提示词里明确加上“当检测到系统权限弹窗时,选择允许/继续按钮”,相当于给 Agent 一个处理弹窗的预案。这两步做完之后,连续任务的稳定性提升非常明显。
4.4 Token 消耗和响应速度的平衡方案
AI Agent 跑真机测试,烧的不只是电,还有真金白银的 token。每一轮交互,你都得把截图和 XML 发给视觉模型,一次任务动辄十几次交互。如果一个任务要跑 50 步,光截图输入就是 50 张图。
我用了 ARTEMIS 之后,想尽办法压缩成本。把截图分辨率降到模型可以接受的较低档位,同时把当前页面的 XML 控件树做裁剪,只保留可见的控件节点,忽略掉大量冗余布局信息。从实际的准确率来看,降分辨率后模型在识别中文和定位按钮上的能力差别不大,但 token 成本能降一半以上。
速度方面,如果完全依赖云端模型,每轮交互要等好几秒。我后来在自己服务器上部署了一个开源的视觉模型,用 vLLM 做推理加速,虽然单轮响应速度还是比云上慢一些,但整体成本一下子就打下来了。如果你的场景是长时间、大批次的真机测试,算力自持几乎是从成本上的必然选择。
4.5 接入 CI 后,我用哪些指标判断任务真的可靠
ARTEMIS 跑通一个 Demo 不难,难的是怎么把它放进团队的 CI 流水线里,让它可以稳定输出结果。在这个问题上,我自己绕了不少弯路,最后沉淀下来几个核心指标。
第一个是任务成功率,也就是“任务级别”的完成比例。很多传统脚本看的是“用例内断言是否通过”,但 Agent 跑的流程本身就不稳定,我认为应该看“最终目标是否达成”。第二个是平均步数,如果任务路径越来越长、步数越来越多,说明 Agent 越来越吃力,可能是模型效果变差或者 App 改版了。第三个是无效动作率。我通过记录每一步的截图哈希值,计算出连续重复画面的比例,这个指标能直观反映 Agent 是否在高效完成任务还是在那里乱试。
当这三个指标回传稳定之后,我认为才算真正能把 AI Agent 接进生产环境。不然的话,它更像一个偶尔翻车的探索工具,而不是一个可交付的测试能力。
我现在的习惯是,把 ARTEMIS 设计成“兜底探索层”,配合传统自动化一起跑。传统脚本负责回归主流程,AI Agent 负责在真机上做无脚本的探索性冒烟和页面兜底检测。跑了几轮之后我发现,两边正好互补了传统脚本的盲区,也让真机测试的覆盖率往上拉了一大截。
如果你正打算在自己的设备池里尝试这个方向,我的建议是先从每天固定跑一条最繁琐的冒烟流程开始,不要一开始就追求它替代所有测试。先让它稳定产出结果,再逐步扩大任务的复杂度。那种“AI 自己把 App 从头点到尾”的画面确实很有吸引力,但更重要的,是你能在日志里看到 Agent 每一次决策背后的逻辑,并把这种逻辑转化为团队自己的测试经验。这一步,才是工具真正开始为项目创造价值的起点。