1. 为什么移动端 AI 自动化突然成了热门赛道移动端自动化这件事其实在测试圈子里已经存在很多年了。早年间大家用 Appium、UiAutomator、Espresso 这些工具写脚本本质上都是靠控件 ID、坐标、层级结构去定位元素然后模拟点击和输入。这套东西在稳定的测试环境里跑得还行但一旦换机型、换分辨率、换系统版本脚本就大面积失效维护成本高得离谱。做过移动端自动化测试的朋友应该都有体会一个几百行的脚本可能因为一个按钮的 ID 变了就全盘崩溃。大模型能力成熟之后情况开始发生变化。以前机器看不懂屏幕只能靠开发者提前告诉它“这个按钮在哪个坐标、叫什么名字”现在多模态模型可以直接“看”屏幕截图理解界面上有什么、当前处于什么状态、下一步该点哪里。这就把移动端自动化的门槛从“写代码定位元素”拉低到了“描述你想做什么”。ARTEMIS 就是在这个背景下由谷歌开源出来的一个框架它的核心目标很明确让 AI 助手像真人一样操作手机而不是依赖脆弱的控件树。这个项目适合谁看如果你是做移动端测试、RPA 流程自动化、无障碍辅助工具或者单纯对“AI 操作手机”这件事好奇想自己搭一套跑起来看看效果那这篇内容会对你有帮助。我会从整体设计思路讲到具体怎么落地包括环境准备、核心模块拆解、实操步骤以及我在实际折腾过程中踩过的坑。需要说明的是ARTEMIS 本身还在演进中很多细节官方文档写得比较简略下面涉及具体操作的部分我会结合移动端自动化的通用实践做合理补充并标注哪些是推断、哪些是确定的做法。先给一个整体判断ARTEMIS 的价值不在于它现在有多成熟而在于它给出了一套“感知—决策—执行”的闭环范式。理解了这个范式你就算不用这个框架自己拿大模型 API 加 ADB 也能拼出一套类似的东西。所以下面我会把重点放在这套闭环是怎么设计的以及每一环落地时要注意什么。2. ARTEMIS 的整体设计与核心思路拆解2.1 它到底解决了传统自动化的哪个死结传统移动端自动化最大的死结是“定位脆弱”。控件 ID 会变、层级会变、不同厂商 ROM 会魔改、WebView 里的元素根本拿不到原生控件树。你写脚本的时候是在跟一个不断变化的靶子较劲。ARTEMIS 的思路是绕开控件树直接让多模态模型看屏幕截图输出“下一步该做什么”的决策再由执行层把这个决策翻译成具体的触摸、滑动、输入动作。这个转变的意义在于定位这件事从“精确匹配”变成了“语义理解”。模型不需要知道那个按钮的 resource-id 是什么它只需要知道“屏幕上有个写着‘登录’的按钮我要点它”。哪怕按钮位置变了、样式变了只要语义还在模型大概率还能认出来。这就把脚本的鲁棒性从“依赖实现细节”提升到了“依赖语义意图”。当然这个方案也有代价。多模态模型的推理是有延迟的每操作一步都要截屏、上传、推理、下发指令整个链路比直接调 UiAutomator 慢得多。所以 ARTEMIS 这类框架更适合“步骤不多但环境多变”的场景比如跨 App 的流程编排、需要理解界面语义的复杂操作而不是那种要跑几千次的高频回归测试。选型的时候一定要想清楚你的场景到底是“稳”优先还是“快”优先。2.2 感知层截图、控件树还是两者结合感知层是整套系统的眼睛。ARTEMIS 主要依赖屏幕截图把当前界面以图像形式喂给多模态模型。为什么是截图而不是控件树因为控件树在跨 App、跨 ROM 场景下太不稳定而且很多界面元素比如游戏画面、自定义绘制的 UI压根就没有可用的控件信息。截图是“所见即所得”模型看到的就是用户看到的信息最完整。但纯截图也有短板。模型对精确坐标的估计不够准尤其是小屏幕上的密集元素它可能知道要点“设置”但给出的坐标偏了几个像素就点空了。所以一个常见的工程做法是截图加控件树混合用截图让模型理解语义和意图用控件树或 OCR 辅助确定精确的可点击区域。ARTEMIS 在实际实现里应该也做了类似的坐标校准具体机制官方没有完全公开但从工程合理性推断纯靠模型输出坐标而不做任何校准误点率会高到没法用。这里有个实操要点截图的分辨率很关键。太高模型推理慢、token 消耗大太低小字看不清、图标认不出。一般建议把截图缩放到模型输入的最佳尺寸同时保留一份原图用于坐标映射。这个缩放比例要记录清楚否则模型给的坐标和实际屏幕坐标对不上点击就会系统性偏移。2.3 决策层大模型怎么把“意图”翻译成“动作”决策层是大脑。用户给一个高层目标比如“帮我在设置里把蓝牙打开”决策层要把它拆成一步步的具体动作打开设置、找到蓝牙选项、点击开关、确认状态。ARTEMIS 用的是多模态大模型来做这个拆解每一步都基于当前屏幕状态重新决策而不是一次性规划好所有步骤。这种“逐步决策”的方式叫 ReAct 式的循环观察当前状态、思考下一步、执行动作、再观察。好处是能应对界面变化和意外弹窗坏处是容易陷入循环或者走偏。比如模型点进了一个广告页它可能不知道该怎么退出来就在那儿反复点。所以决策层通常需要配合一些约束限制最大步数、检测是否卡住、必要时回退到上一个稳定状态。动作空间的设计也很讲究。模型能输出的动作类型要覆盖移动端的基本操作点击、长按、滑动、输入文本、返回、Home、等待。动作定义得越清晰模型越不容易输出无效指令。ARTEMIS 应该定义了一套结构化的动作 schema模型按格式输出执行层再解析。如果你自己搭建议把动作定义成 JSON字段包括 action 类型、目标坐标或文本、以及可选的说明方便调试和日志追踪。2.4 执行层ADB 还是无障碍服务执行层是手脚负责把决策变成真实的触摸事件。移动端上有两条主流路径一条是 ADB通过adb shell input系列命令模拟点击滑动输入另一条是 Android 的无障碍服务AccessibilityService在设备上直接注入事件。ADB 的优点是通用、不需要在设备上装额外的东西、跨设备一致性好缺点是每次操作都要走一遍命令通道延迟相对高而且某些系统对 ADB 输入有限制。无障碍服务的优点是延迟低、能拿到更丰富的界面事件缺点是需要用户手动授权、不同 ROM 对无障碍的管控越来越严、后台容易被杀。ARTEMIS 作为谷歌开源的项目大概率是优先走 ADB 这条路的因为它最通用、最容易在 CI 环境里批量部署。无障碍服务可能作为可选的高性能路径。实际选型时如果你只是自己折腾或者做 demoADB 足够了如果要产品化、要低延迟无障碍服务值得考虑但要处理好授权和保活问题。3. 核心细节解析与实操要点3.1 环境准备从零把架子搭起来先把基础环境理清楚。你需要一台 Android 设备或者模拟器、一台开发机、以及 ADB 工具链。开发机上装好 Python 环境ARTEMIS 这类框架通常以 Python 为主然后从项目仓库拉代码、装依赖。具体步骤大致是这样先确认adb devices能列出你的设备这是所有后续操作的前提。如果设备连不上后面全是白搭。然后配置模型访问ARTEMIS 需要调用多模态大模型你要准备好相应的 API 凭证填到配置文件或者环境变量里。接着安装项目依赖一般会有 requirements.txt 或者 pyproject.toml用 pip 或 poetry 装。这里有个容易忽略的点屏幕分辨率和 DPI。不同设备的截图尺寸不一样模型对坐标的理解会受影响。建议在配置里明确记录设备的实际分辨率和截图缩放比例执行层做坐标映射时要用到。我见过有人因为没处理这个模型说点 (500, 800)结果实际点到了别的地方排查半天才发现是缩放没对齐。提示模拟器虽然方便但它的渲染和真机有差异某些界面元素在模拟器上能识别、真机上识别不了。如果条件允许尽量用真机做最终验证。3.2 动作空间设计让模型输出可执行的结构化指令动作空间是模型和执行层之间的契约。设计得好模型输出稳定、执行层解析简单设计得差模型经常输出模棱两可的指令执行层一脸懵。一个合理的动作集合至少包括tap点击带坐标、long_press长按、swipe滑动带起止坐标和时长、type输入文本、back返回、home回桌面、wait等待若干秒、done任务完成。每个动作用 JSON 表示比如点击就是{action: tap, x: 540, y: 1200}。为什么要用结构化输出而不是让模型自由发挥因为自由文本解析起来太脆弱模型今天说“点击登录按钮”明天说“按下那个写着登录的地方”你的解析器就得写一堆正则去兜底。结构化 schema 配合模型的 function calling 或者 JSON mode能大幅提升稳定性。实操心得在 prompt 里把动作 schema 写清楚并给一两个示例模型输出的合规率会明显提高。另外坐标最好让模型输出归一化值0 到 1 之间执行层再乘以实际分辨率这样换设备时不用改 prompt。3.3 坐标校准模型说点这里实际要点哪里这是整个链路里最容易出问题的一环。模型看的是缩放后的截图它给出的坐标是基于那张图的。执行层要把它映射回真实屏幕坐标中间涉及缩放比例、可能的黑边、状态栏高度等。假设你的设备分辨率是 1080x2400截图缩放到了 720x1600 喂给模型。模型说点 (360, 800)这是缩放图上的坐标。映射回真机就是 x 乘以 1080/720 等于 540y 乘以 2400/1600 等于 1200。看起来简单但如果截图带了状态栏或者导航栏的裁剪映射就要加上偏移量。更麻烦的是模型本身的坐标估计误差。多模态模型对空间位置的感知不是像素级的它可能把“登录按钮”的中心估偏几十个像素。对于大按钮无所谓对于小图标就可能点空。工程上的缓解办法是拿到模型给的粗略坐标后在该坐标附近用 OCR 或控件树找精确的可点击区域做一次吸附。ARTEMIS 具体怎么做的我不确定但这是行业里比较通用的做法。注意每次换设备或改分辨率都要重新验证坐标映射。别指望一套参数走天下。3.4 状态判断与循环控制怎么知道任务完成了任务什么时候算完成这是自动化里一个看似简单实则棘手的问题。用户说“把蓝牙打开”模型操作完之后系统怎么确认蓝牙真的开了一种做法是让模型自己判断它在每步观察后输出“任务是否完成”。但模型可能误判比如它以为点了开关就是开了实际开关没响应。更可靠的做法是结合外部状态校验蓝牙状态可以通过 ADB 命令查询那就查一下真实状态确认了再结束。对于没有直接查询接口的任务可以用界面上的标志性元素来判断比如“已开启”的文字或特定图标。循环控制方面必须设最大步数上限防止模型陷入死循环。一般简单任务 10 到 20 步够了复杂流程可以放宽到 50 步。同时要检测“卡住”状态如果连续几步屏幕截图几乎没变化说明操作没生效或者模型在原地打转这时候应该中断并报错而不是继续烧 token。4. 完整实操流程与关键环节实现4.1 从安装到跑通第一个任务假设你已经有一台开启了 USB 调试的 Android 设备开发机是 Linux 或 macOS。第一步确认 ADB 可用adb devices能看到设备序列号就说明连接正常。如果显示 unauthorized在设备上确认授权弹窗如果列表为空检查数据线和驱动。第二步拉取 ARTEMIS 代码并安装依赖。具体命令以项目仓库为准大致是git clone artemis-repo-url cd artemis pip install -r requirements.txt第三步配置模型访问。找到配置文件通常是 config.yaml 或 .env填入模型 API 的地址和密钥以及你要用的模型名称。多模态能力是必须的纯文本模型看不了截图。第四步写一个最简单的任务描述比如“打开设置进入关于手机读出系统版本号”。运行框架观察日志里模型每一步的决策和实际执行结果。第一次跑大概率不会一次成功。可能是坐标偏了、可能是模型没理解界面、可能是某一步等待时间不够。别急看日志逐步调。日志里应该记录每一步的截图、模型输出、执行动作、执行后的新截图这四个信息对齐了问题就好定位。4.2 一个具体任务的逐步拆解拿“打开蓝牙”这个任务举例走一遍完整链路。初始状态是手机桌面。感知层截屏决策层看到桌面判断需要先打开设置。模型输出{action: tap, x: ..., y: ...}指向设置图标。执行层映射坐标通过 ADB 发送点击。等待一秒让界面加载。新截图显示设置页面。模型看到一堆选项找到“蓝牙”或“连接”相关入口输出点击动作。进入蓝牙页面后模型看到开关输出点击开关的动作。执行后模型再截屏确认开关状态变成“开启”。这里的关键是每一步之间的等待。界面切换有动画点完立刻截屏可能截到过渡状态模型会误判。一般建议动作后固定等待 0.5 到 1.5 秒或者用轮询检测界面稳定连续两次截图差异小于阈值再继续。另一个细节是滚动。如果目标选项不在当前屏幕内模型需要先滑动。滑动动作要给出合理的起止点和时长太快可能触发 fling 惯性滚动太慢又浪费时间。一般从屏幕下方三分之一滑到上方三分之一时长 300 到 500 毫秒比较合适。4.3 参数选择与性能权衡模型选型直接影响体验。能力强的模型理解准、误操作少但推理慢、成本高轻量模型快、便宜但可能看不懂复杂界面。实际用的时候可以分级简单明确的界面用轻量模型复杂或模糊的界面升级到强模型。截图策略也要权衡。每步都截全屏、高分辨率信息最全但最慢。可以只在界面发生较大变化时重新截屏或者对截图做压缩。但压缩太狠会丢细节小字和图标认不出来。我一般把长边压到 1080 到 1280 之间兼顾清晰度和速度。超时和重试策略也得配。ADB 命令偶尔会超时模型 API 偶尔会抽风。给每个动作设一个超时失败后重试一到两次还不行就中断并记录现场。别让一个卡住的步骤把整个任务拖死。5. 常见问题与排查技巧实录5.1 点击没反应或点错位置这是最高频的问题。排查顺序是这样先确认坐标映射对不对拿模型输出的坐标和实际点击坐标对比看缩放比例和偏移量是否算错。再确认点击是否真的发出去了看 ADB 命令的返回。然后确认点击的目标是否可点击有些元素看着像按钮其实是装饰。如果坐标映射没问题但就是点不准考虑加坐标吸附。用 OCR 在目标坐标附近找文字把点击点调整到文字中心。或者用控件树查该坐标下有没有可点击的节点有就点节点中心。还有一种情况是点击被系统拦截了比如权限弹窗、悬浮窗遮挡。这时候要先处理遮挡再执行原动作。模型有时候能识别出弹窗并关掉有时候不能可以在 prompt 里明确要求“遇到弹窗先关闭”。5.2 模型理解偏差与幻觉模型可能“看到”屏幕上不存在的东西或者把相似的元素认错。比如把“取消”认成“确定”把广告里的“立即下载”当成正常按钮。这类问题很难完全避免但可以缓解。一是提高截图质量让模型看得更清楚。二是 prompt 里加约束比如“只操作与任务直接相关的元素忽略广告和推广”。三是关键操作加二次确认比如点击“删除”或“支付”前让模型再确认一次目标。四是设置动作白名单危险操作直接禁止。如果模型反复在同一个地方出错可以把那一步的截图和正确操作作为示例加进 prompt做 few-shot 引导。这招对固定流程特别有效。5.3 设备连接与 ADB 稳定性ADB 连接不稳定是另一个常见坑。表现为命令偶尔超时、设备突然掉线、截图返回空。排查时先看 USB 线材和接口劣质线材是重灾区。然后看设备是否进入了省电模式某些 ROM 在息屏后会限制 ADB。无线 ADB 虽然方便但稳定性通常不如有线对网络质量敏感。做长时间任务建议用有线。如果必须无线确保设备和开发机在同一稳定网络下并设置合理的重连逻辑。还有一个隐蔽问题多个 ADB 客户端抢占设备。如果你同时开了 Android Studio 和其他工具它们可能都在跟 ADB 通信导致命令互相干扰。排查时先adb kill-server再adb start-server只保留一个客户端。5.4 常见问题速查表现象可能原因排查方向点击无反应坐标映射错误核对缩放比例与偏移点击位置偏移模型坐标估计误差加 OCR 或控件树吸附模型认错元素截图不清或 prompt 不足提高分辨率、加约束任务卡住不结束无最大步数限制设置步数上限与卡住检测ADB 命令超时线材或省电限制换线、关省电、重连截图返回空设备掉线或权限问题检查连接与授权界面切换误判等待时间不足增加等待或轮询稳定模型输出格式错schema 不清晰强化 prompt 与示例5.5 几个我踩过的坑第一个坑是忽略了输入法的干扰。用 ADB 输入文本时如果当前焦点不在输入框文字会丢。而且不同输入法对 ADB 输入的支持不一样有的会把拼音当字符输入。稳妥做法是输入前先点击输入框确认焦点必要时切换到系统自带输入法。第二个坑是没处理权限弹窗。第一次安装 App 或者首次使用某功能时系统会弹权限请求。模型如果没预料到就会卡在那儿。可以在任务开始前用 ADB 预授权常用权限或者在 prompt 里教模型识别并处理权限弹窗。第三个坑是低估了界面加载时间。网络慢的时候点进去要好几秒才出内容模型截到的是白屏或加载中决策就错了。解决办法是轮询等待直到界面稳定或者出现预期元素再继续而不是固定等一秒。第四个坑是日志不够详细。出问题的时候如果日志里只有“执行了点击”没有截图和模型原始输出根本没法定位。一定要把每步的输入输出完整记录下来包括时间戳、截图路径、模型返回的原始 JSON、执行结果。这些日志是排查问题的命根子。6. 这套框架还能怎么扩展跑通基本流程之后可以往几个方向扩展。一是多设备并行同时控制多台手机跑不同任务适合批量场景。二是任务编排把多个小任务串成一个大流程中间加条件判断和错误恢复。三是接入更多感知能力比如用 OCR 补充文字识别、用目标检测定位图标减少对模型坐标估计的依赖。四是做任务录制与回放人工操作一遍生成轨迹再用模型泛化到相似场景。我个人觉得最有价值的方向是“人在回路”的混合模式简单步骤让 AI 自动跑遇到不确定的地方暂停下来问人人给个提示再继续。这样既利用了 AI 的泛化能力又用人的判断兜住了风险在真实业务里比全自动更实用。最后分享一个小技巧调试阶段把每一步的截图存下来按序号命名跑完一遍之后快速翻看能很直观地看出模型在哪一步走偏了。这比盯着日志一行行看效率高得多。
阅读完成 · 觉得有帮助?