ARTEMIS 开源框架:用视觉语言模型让 AI 像真人一样操作手机

发布时间:2026/11/4 10:18:27
ARTEMIS 开源框架:用视觉语言模型让 AI 像真人一样操作手机 1. 为什么移动端 AI 自动化突然成了热门赛道第一次看到 ARTEMIS 这个项目的时候我正在折腾一个跨端测试的活儿——手动在十几台设备上重复点击同一个流程点到手指发麻。当时脑子里就一个念头能不能让 AI 直接看着屏幕、自己决定点哪儿ARTEMIS 干的就是这件事而且它是谷歌开源的定位很明确——让 AI 助手像真人一样操作手机。先说清楚它是什么。ARTEMIS 是一个运行在移动端的 AI 自动化框架核心能力是把「屏幕理解」和「动作执行」这两件事串起来。传统自动化工具比如基于控件 ID 的脚本依赖开发者提前知道界面上有什么元素、叫什么名字而 ARTEMIS 走的是另一条路——它让 AI 模型直接「看」屏幕截图理解当前界面在表达什么然后输出下一步该点哪里、输入什么、滑动多少。这就意味着哪怕界面改版了、按钮换位置了、甚至是个从没见过的 App它也能靠视觉理解去操作。这件事解决的核心痛点有三个。第一是脆弱性写死的脚本一改 UI 就崩维护成本高得离谱。第二是泛化能力不同 App、不同机型、不同分辨率传统方案要分别适配而视觉方案天然跨端。第三是门槛不会写代码的人也能通过自然语言描述任务让 AI 去执行。适合谁来参考做移动端测试的工程师、想搞 RPA机器人流程自动化的开发者、研究 GUI Agent 的算法同学以及单纯想让自己手机「自动干活」的折腾党。我把它定位成一个「移动端的 GUI Agent 基础设施」——它不只是一个脚本工具而是一套让 AI 与手机界面交互的完整链路。下面我会从设计思路、核心细节、实操落地到踩坑排查把这条链路拆开讲透。2. ARTEMIS 的整体设计与思路拆解2.1 从「控件驱动」到「视觉驱动」的范式转变要理解 ARTEMIS 的价值得先明白传统移动端自动化的两条老路。第一条是UI Automator / Accessibility 路线通过系统提供的无障碍服务读取控件树拿到每个按钮的 ID、文本、坐标然后精确点击。这条路稳定、快但死穴是控件树里没有的东西它就没辙比如游戏画面、Canvas 绘制的界面、Flutter 自绘控件读出来一片空白。第二条是坐标录制路线把人的操作录成坐标序列回放简单粗暴但换个分辨率就全废。ARTEMIS 选的是第三条路——视觉语言模型VLM驱动。它的逻辑是截一张当前屏幕的图把图喂给一个能理解界面的多模态模型模型输出结构化的动作指令比如{action: tap, x: 0.5, y: 0.8}框架再把指令翻译成系统级的触摸事件执行。这个设计的精妙之处在于它把「理解界面」这个最难的活儿外包给了 AI 模型框架本身只负责「截图—推理—执行」的循环调度。为什么这么设计因为界面理解的本质是语义问题不是坐标问题。人看到「登录」两个字就知道该点它不需要知道它的控件 ID 是btn_login_001。VLM 恰好擅长这种语义理解而且天然具备跨 App、跨语言的泛化能力。代价是推理有延迟、有成本但对于「正确性优先于速度」的场景比如自动化测试、辅助操作这个 trade-off 完全划算。2.2 框架的分层架构与职责边界ARTEMIS 在工程上做了清晰的分层我把它归纳成四层从下往上说。设备控制层是最底层负责和 Android 系统打交道——截图、注入触摸事件、输入文本、按键。这一层通常依赖 ADBAndroid Debug Bridge或者设备端的无障碍服务。截图走的是screencap或者 MediaProjection触摸注入走的是input tap或者更底层的sendevent。这一层的关键指标是延迟和稳定性截图慢一拍整个循环就卡。感知层负责把原始截图处理成模型能吃的输入。这里有个容易被忽略的细节手机截图分辨率动辄 1080×2400直接喂给模型既慢又浪费 token。所以感知层通常会做缩放、压缩甚至把坐标归一化到 0~1 的相对空间。归一化这一步特别重要它让同一套动作指令能适配不同分辨率的设备——模型说「点屏幕宽度的 50%、高度的 80%」框架自己换算成具体像素。决策层是核心调用 VLM 做推理。输入是当前截图加任务描述比如「打开设置把亮度调到最低」输出是下一步动作。这里涉及一个关键设计单步决策还是多步规划。ARTEMIS 走的是单步决策为主、配合历史上下文的路子——每一步都重新看屏幕、重新决策而不是一次性规划十步然后盲执行。这样做的好处是容错性强某一步点错了下一步看到新界面能自我纠正坏处是推理次数多、慢。对于需要长流程的任务框架会维护一个动作历史让模型知道「我已经做过什么」避免原地打转。编排层在最上面负责任务的生命周期管理——任务怎么下发、循环怎么终止、异常怎么处理、日志怎么记录。这一层是给使用者直接接触的也是决定「好不好用」的关键。2.3 为什么选择「截图 VLM」而不是「控件树 LLM」有人会问既然要语义理解为什么不直接读控件树的文本喂给纯文本 LLM这样又快又省。我实测过这条路线问题在于控件树的信息损失太严重。一个界面在控件树里可能是一堆嵌套的 FrameLayout文本散落在各个节点层级关系混乱而且很多视觉上重要的信息图标、颜色、位置关系根本不在文本里。模型拿到一堆残缺的文本经常做出错误判断。截图方案虽然重但信息是完整的——所见即所得。模型看到的就是用户看到的没有信息损失。这也是为什么 ARTEMIS 这类框架普遍选择视觉路线在界面理解这件事上视觉信息的保真度远高于控件树。当然理想方案是两者结合视觉为主、控件树为辅做坐标校正这也是后续可以优化的方向。3. 核心细节解析与实操要点3.1 环境准备从零搭起一套可运行的链路动手之前先把地基打好。ARTEMIS 跑起来需要三样东西一台或模拟器Android 设备、一个能调用的 VLM 服务、以及框架本身的运行环境。设备这块我建议用Android 模拟器起步原因很实际真机调试时截图和触摸注入经常遇到权限问题模拟器比如 Android Studio 自带的 AVD默认就开了 rootADB 权限齐全省去一堆麻烦。模拟器选 Android 11 以上的镜像分辨率建议 1080×1920 这种标准比例别用太奇葩的尺寸否则坐标换算容易出偏差。如果你要用真机记得在开发者选项里打开USB 调试并且确认adb devices能识别到设备。VLM 服务是另一个关键。ARTEMIS 本身不绑定特定模型它需要一个能接受图像输入、返回结构化动作的推理后端。你可以用云端的多模态 API也可以在本地跑一个量化后的小模型。本地跑的好处是数据不出设备、没有网络延迟坏处是对硬件有要求。我的经验是如果只是验证流程先用云端 API 快速跑通等逻辑稳定了再考虑本地化降本。框架运行环境通常是 Python。建议用Python 3.10 以上建一个独立的虚拟环境别和系统环境混在一起。依赖装完后第一件事是跑通「截图—显示」这个最小闭环确认框架能拿到屏幕画面再往下走。提示模拟器首次启动后建议先手动把系统语言、时区、输入法都设置好避免自动化过程中弹出系统引导页打断流程。这个坑我踩过脚本跑到一半卡在「欢迎使用」界面排查半天才发现是模拟器没初始化完。3.2 动作空间设计AI 到底能对手机做哪些操作ARTEMIS 的动作空间决定了它的能力边界。一个设计良好的动作集应该覆盖人操作手机的所有基本手势同时保持足够精简让模型容易学习和输出。核心动作大致有这么几类动作类型参数典型场景实现要点tap点击x, y 归一化坐标点按钮、点图标坐标用相对值适配分辨率swipe滑动起点、终点、时长翻页、滚动列表时长影响惯性短滑快、长滑慢text输入文本内容填表单、搜索需先聚焦输入框key按键键码返回、Home、回车系统级按键走 ADBwait等待毫秒数等加载、等动画别写死配合状态检测done完成无任务结束信号必须有否则死循环这里有个设计细节值得说坐标为什么用归一化值。假设模型输出tap(540, 1600)这是绝对像素换台 720×1280 的设备就点偏了。而输出tap(0.5, 0.83)框架自己乘以当前屏幕宽高就能适配任意分辨率。归一化是跨设备泛化的基础几乎所有视觉自动化框架都这么做。另一个细节是wait 动作的处理。新手容易犯的错是让模型输出固定等待时间比如「等 3 秒」。但网络快慢、设备性能都不一样固定等待要么不够要么浪费。更好的做法是框架层面做状态轮询——截图对比等界面稳定了再进入下一步。ARTEMIS 这类框架通常会在执行动作后自动加一个「稳定检测」检测到画面连续两帧变化很小才认为可以继续。3.3 提示词工程怎么让模型「看懂」任务并输出正确动作这是整个框架里最考验经验的部分。模型再强提示词写得烂输出就是一堆废话。ARTEMIS 的提示词设计有几个关键要素我拆开讲。第一是角色和任务定义。要明确告诉模型「你是一个手机操作助手你的任务是根据当前屏幕截图决定下一步操作」。任务描述要具体比如「打开微信找到文件传输助手发送一条消息说你好」而不是「帮我用微信」。任务越具体模型越不容易跑偏。第二是动作格式约束。必须用严格的 JSON schema 约束输出比如要求模型只能返回{action: ..., params: {...}}这种结构。不加约束的话模型可能返回一大段自然语言解释框架解析不了。我一般会在提示词里给两三个 few-shot 示例展示「看到什么界面、输出什么动作」模型模仿能力很强给了例子准确率明显提升。第三是坐标输出规范。要明确告诉模型坐标是归一化的 0~1 浮点数并且给出参照比如「屏幕左上角是 (0,0)右下角是 (1,1)」。有些模型对坐标系理解有偏差会在提示词里反复强调。第四是历史上下文。把前面几步的动作和结果拼进提示词让模型知道进展。但要注意长度控制历史太长会挤占图像 token 的空间一般保留最近 3~5 步就够了。注意提示词里的动作空间描述要和框架实际支持的动作严格一致。我见过有人提示词里写了「长按」但框架没实现 long_press模型输出后直接报错。这种低级错误排查起来很费时间。3.4 坐标换算与触摸注入的实操细节模型输出归一化坐标后框架要做两步转换才能真正点到屏幕上。第一步是乘以屏幕实际尺寸得到像素坐标。第二步是考虑状态栏和导航栏的偏移。很多框架的截图是包含状态栏的但触摸注入的坐标系原点可能从内容区开始这中间差了一个状态栏高度不处理的话所有点击都会偏上几十像素。触摸注入的实现方式也有讲究。最简单的是调adb shell input tap x y但这种方式每次都要起一个 shell 进程延迟高高频操作时明显卡顿。进阶方案是用sendevent直接写设备节点速度快但需要 root 且不同设备的事件节点路径不一样适配麻烦。ARTEMIS 这类框架通常会封装一个设备控制模块优先用高效方式失败时降级到 ADB。滑动操作还有个坑时长参数。input swipe x1 y1 x2 y2 duration里的 duration 单位是毫秒太短会变成快速甩动触发惯性滚动太长会变成慢速拖拽可能触发长按菜单。翻页场景一般 300~500ms 比较合适具体要看目标 App 的手势响应阈值。这个参数没有万能值得针对具体场景调。4. 实操过程与核心环节实现4.1 最小可运行 Demo让 AI 点开设置并进入关于手机理论讲完上真家伙。我以一个最经典的任务为例——「打开设置进入关于手机页面」把完整流程走一遍。选这个任务是因为它路径清晰、界面标准适合验证链路是否通畅。第一步初始化设备连接。确认 ADB 能连上设备拿到屏幕分辨率。这一步的代码逻辑大概是import subprocess def get_screen_size(): result subprocess.run( [adb, shell, wm, size], capture_outputTrue, textTrue ) # 输出形如 Physical size: 1080x2400 size_str result.stdout.strip().split(:)[-1].strip() width, height map(int, size_str.split(x)) return width, height def take_screenshot(pathscreen.png): subprocess.run([adb, exec-out, screencap, -p], stdoutopen(path, wb)) return pathwm size拿分辨率screencap -p截图。注意exec-out比shell更适合传二进制数据用shell会因为换行符转换把 PNG 搞坏这是老坑了。第二步构造提示词并调用模型。把截图编码成 base64拼进提示词发给 VLM。提示词模板我一般这么写你是一个 Android 手机操作助手。当前任务打开设置进入关于手机页面。 请观察截图输出下一步操作严格按 JSON 格式返回 {action: tap|swipe|text|key|done, params: {...}, reason: 简短说明} 坐标使用归一化值左上角(0,0)右下角(1,1)。模型返回类似{action: tap, params: {x: 0.5, y: 0.95}, reason: 点击设置图标}。第三步解析并执行动作。把归一化坐标换算成像素调 ADB 注入def execute_action(action, width, height): if action[action] tap: x int(action[params][x] * width) y int(action[params][y] * height) subprocess.run([adb, shell, input, tap, str(x), str(y)]) elif action[action] swipe: # 类似换算调 input swipe pass elif action[action] done: return False # 结束循环 return True第四步循环直到完成。每执行一步等界面稳定重新截图再问模型。循环的终止条件是模型返回done或者达到最大步数上限防止死循环。实测下来这个任务在标准 Android 模拟器上大概 4~6 步能完成点设置图标 → 滑到底部 → 点关于手机 → 模型判断已到达 → 返回 done。整个过程十几秒比人手操作慢但胜在无人值守。4.2 参数选择截图质量、模型温度、循环上限怎么定这几个参数直接决定框架的稳定性和成本我一个个说。截图质量别用原图。1080×2400 的 PNG 动辄两三兆base64 编码后更大传给模型又慢又贵。我的做法是缩放到宽度 720 左右转成 JPEG 质量 80体积能压到 100KB 以内模型识别准确率几乎不受影响。缩放用 Pillow 一行搞定注意保持宽高比否则坐标会变形。模型温度temperature这个参数控制输出的随机性。自动化场景要的是稳定复现温度必须调低我一般设 0 或者 0.1。温度高了模型会「发挥创意」同样的界面这次点左边下次点右边流程没法复现。有些模型还支持 top_p 参数配合温度一起调原则就是让输出尽可能确定。循环上限必须设。我一般设 20~30 步。正常任务十几步内能完成超过这个数基本说明模型卡住了比如在两个界面之间反复横跳。设上限是为了防止无限循环烧钱。同时要记录每一步的动作和截图卡住的时候回看日志一眼就能看出问题在哪。等待策略动作执行后不要立刻截图给界面一点响应时间。我的经验值是先等 500ms然后连续截两帧对比如果差异小于阈值就认为稳定了最多等 3 秒。这样既不会等太久也不会截到动画中间态。4.3 一个真实场景的完整拆解自动填写表单光点按钮不够过瘾来个有实际价值的——自动填写一个登录表单。这个场景涉及点击、输入、滑动多种动作的组合更能体现框架的能力。任务描述「在浏览器打开登录页输入用户名 testuser密码 123456点击登录按钮」。流程是这样的。模型先看到浏览器界面识别出用户名输入框输出tap聚焦。框架执行点击后模型看到光标在输入框里输出text动作参数是testuser。这里有个细节输入文本前必须确保输入框已聚焦否则文字会丢到别处。框架层面可以在 text 动作前加一个隐式的 tap 确认或者依赖模型自己判断。输入完用户名模型需要点密码框。但密码框可能被键盘遮挡这时候模型要输出swipe先把页面往上滑露出密码框再点。这就是视觉方案的优势——模型能看到键盘挡住了什么主动规避。传统脚本如果没考虑键盘遮挡直接点坐标就会点到键盘上。密码输入有个安全考量敏感信息不要走模型。用户名可以让模型看到但密码最好由框架层面直接注入不经过模型推理。ARTEMIS 这类框架一般支持「变量替换」——提示词里写占位符执行时框架把真实密码填进去模型全程看不到明文。这个设计在真实业务里很重要。最后点登录按钮模型识别按钮位置输出 tap任务完成返回 done。整个流程大概 8~10 步涉及三种动作类型跑通一次之后换个表单改改任务描述就能复用这就是视觉方案的泛化价值。5. 常见问题与排查技巧实录5.1 模型「看不懂」界面识别错误的三大原因跑自动化最常遇到的问题就是模型点错地方。排查下来原因基本逃不出这三类。第一类是截图质量问题。截图糊了、压缩过头了、或者截到了动画中间态模型自然看不清。排查方法很简单把传给模型的图存下来自己看一眼。如果人眼都觉得模糊模型肯定也不行。解决就是提高截图质量或者加稳定检测。第二类是提示词歧义。比如任务说「点击确认」但界面上有「确认」和「确认支付」两个按钮模型可能选错。这时候要把任务描述写得更具体或者把界面上的候选元素在提示词里列出来让模型选。我一般会在提示词里加一句「如果存在多个相似元素选择最符合任务语义的那个」。第三类是模型能力边界。小模型对复杂界面的理解确实有限图标密集、文字小的界面容易出错。这种情况要么换更强的模型要么在框架层面做界面简化——比如把截图放大、或者用 OCR 先把文字提取出来辅助模型。5.2 动作执行了但没反应触摸注入的排查链路有时候模型决策是对的但点了没反应。这条排查链路我走过很多次按顺序查基本能定位。先确认坐标是否算对。把归一化坐标乘以分辨率看看算出来的像素点是不是在目标元素上。常见错误是忘了处理状态栏偏移导致所有点击都偏上。可以在截图里把计算出的坐标画个红点直观确认。再确认触摸事件是否真的注入了。adb shell input tap有时候会因为设备忙或者权限问题静默失败。可以在执行后立刻截图对比看界面有没有变化。没变化就是注入失败检查 ADB 连接和设备状态。还要确认目标元素是否可点击。有些界面元素看着是按钮实际被一层透明遮罩盖住了点击事件被遮罩拦截。这种情况模型看不出来需要人工分析界面层级。解决方法是先点掉遮罩或者用更底层的注入方式绕过。5.3 死循环与卡死如何让框架「知道该停」死循环是自动化框架的经典病。表现是模型在两个界面之间反复横跳或者对着同一个按钮点了又点。根因通常是任务没有明确的完成信号或者模型陷入了局部最优。我的解法有三层。第一层是步数硬上限超过就强制终止并报警这是兜底。第二层是状态去重记录最近几步的截图哈希如果发现重复出现同一画面超过两次说明卡住了主动中断。第三层是提示词里强化完成条件明确告诉模型「当看到 XX 界面时返回 done」给它一个清晰的终点。还有个隐蔽的坑界面加载慢导致的误判。模型截图时页面还在加载看到的是空白或者骨架屏于是做出错误决策。解决就是前面说的稳定检测等画面连续两帧一致再决策。5.4 常见问题速查表现象可能原因排查方向解决手段点击位置偏移坐标未归一化/状态栏偏移截图标注坐标点统一归一化扣除状态栏模型输出无法解析提示词约束不足看模型原始返回加 JSON schema 和示例输入文字丢失输入框未聚焦检查点击是否生效text 前强制 tap 聚焦流程卡死无完成信号/死循环看动作历史日志设步数上限状态去重截图模糊压缩过度/动画中人眼看截图提高质量稳定检测触摸无反应注入失败/被遮挡执行后对比截图检查 ADB/绕过遮罩推理太慢图太大/模型太重测单步耗时缩图换轻量模型敏感信息泄露密码走模型检查提示词变量替换模型不碰明文5.5 几个我踩过的坑和独家心得说几个文档里不会写、但实际会遇到的坑。坑一模拟器的输入法。默认输入法可能弹广告或者联想词干扰输入。我一般会先adb shell ime切换到一个干净的输入法或者直接用 ADB 的input text绕过输入法。注意input text不支持中文和特殊字符中文得用其他方式注入。坑二屏幕常亮。自动化跑一半屏幕熄了截图全黑。跑之前记得adb shell svc power stayon true保持屏幕常亮。坑三模型对深色模式的误判。深色模式下界面元素对比度低模型识别率下降。如果目标 App 支持尽量在浅色模式下跑。坑四多语言界面。模型对英文界面识别最稳中文次之小语种容易翻车。如果目标 App 有多语言切到英文能提升稳定性。心得方面我最大的体会是别指望一次跑通长流程。正确的做法是把长任务拆成短任务每段单独验证稳定了再串起来。比如「登录并下单」拆成「登录」「搜索商品」「加购物车」「结算」四段每段跑通再组合。这样出问题能快速定位是哪一段的锅。另外日志要记全。每一步的截图、模型输入、模型输出、执行结果全部落盘。出问题的时候回看日志比重新跑一遍高效得多。我一般按时间戳建目录一次运行一个目录方便对比。6. 这套框架还能怎么扩展跑通基础流程后我琢磨了几个扩展方向也分享给想深入的同学。方向一是多设备并行。ARTEMIS 的单设备链路跑通后可以横向扩展到多台设备同时跑做批量测试或者批量操作。关键是把设备控制层抽象成接口每台设备一个实例任务调度器统一分发。难点在于资源竞争和结果聚合但工程上不难。方向二是结合控件树做坐标校正。纯视觉方案偶尔会点偏如果能同时拿到控件树用控件的位置去校正模型的坐标输出准确率能上一个台阶。这是视觉和传统方案的融合也是工业级自动化常见的做法。方向三是本地化模型降本。云端 API 按 token 计费跑量大了成本可观。把量化后的小模型部署到本地虽然单步准确率可能略降但配合重试机制和坐标校正整体可用性未必差而且数据不出设备隐私性更好。方向四是任务编排与断点续跑。真实业务里任务可能很长中途失败要能从中断处继续而不是从头再来。这需要框架记录每一步的状态支持快照和恢复。做测试的同学应该对这个需求很有共鸣。我个人在实际操作中的体会是移动端 AI 自动化现在还在早期框架能力、模型能力、工程稳定性都有很大提升空间。ARTEMIS 这类开源项目的价值不在于它现在多完美而在于它把「AI 操作手机」这条链路跑通了给了大家一个可参考、可修改、可扩展的起点。真正落地到业务里还需要根据具体场景做大量适配和优化但方向是清晰的——让机器替人干重复的活儿这件事在移动端终于有了靠谱的技术路径。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询