谷歌开源ARTEMIS:多模态大模型如何让AI像真人一样操作手机

发布时间:2026/11/4 5:25:45
谷歌开源ARTEMIS:多模态大模型如何让AI像真人一样操作手机

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 环境里批量部署。无障碍服务可能作为可选的高性能路径。实际选型时,如果你只是自己折腾或者做 demo,ADB 足够了;如果要产品化、要低延迟,无障碍服务值得考虑,但要处理好授权和保活问题。

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 等于 540,y 乘以 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 的泛化能力,又用人的判断兜住了风险,在真实业务里比全自动更实用。

最后分享一个小技巧:调试阶段把每一步的截图存下来,按序号命名,跑完一遍之后快速翻看,能很直观地看出模型在哪一步走偏了。这比盯着日志一行行看效率高得多。