ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

ARTEMIS 实战:用多模态 AI 与 MCP 协议重构移动端自动化

ARTEMIS 实战:用多模态 AI 与 MCP 协议重构移动端自动化 移动端自动化这个方向过去几年一直有个尴尬的瓶颈要么是基于坐标点击的脚本方案界面一改就全废要么是基于无障碍树的半自动方案遇到自绘控件和游戏引擎渲染的界面直接抓瞎。ARTEMIS 这个项目之所以值得单独拿出来聊是因为它换了一条路——让 AI 直接看屏幕然后像人一样决定点哪里、滑多少、输入什么。我第一次看到它的时候第一反应是这不就是把多模态模型塞进了一个自动化循环里但真正跑起来之后才发现里面关于截图压缩、动作空间设计、失败重试的工程细节才是决定它能不能用的关键。这篇文章会从 ARTEMIS 的整体架构讲起拆解它为什么选择视觉动作这条路线而不是传统的控件树方案然后给出完整的本地跑通步骤包括环境准备、设备连接、模型配置这些容易卡住的环节。接着会重点聊 MCP 协议在里面的角色——这是很多人搜artemis教程和mcp是什么时最困惑的部分。最后会分享我在实际测试中遇到的几个典型坑比如截图分辨率对识别率的影响、动作执行延迟导致的误判、以及多步任务中上下文丢失的问题。适合已经了解一点移动端自动化、想看看 AI 驱动方案到底能做到什么程度的开发者也适合刚接触 MCP 协议、想找一个真实项目来理解它怎么落地的人。1. ARTEMIS 到底在解决移动端自动化的哪个死结1.1 传统方案的三个天花板先说清楚为什么需要 ARTEMIS 这种东西。移动端自动化不是新话题ADB 命令、Appium、UiAutomator 这些工具已经存在很多年了但它们在通用性这个维度上一直有硬伤。第一个天花板是控件树依赖。Appium 和 UiAutomator 的核心逻辑是读取 Android 的 AccessibilityNodeInfo 树找到目标控件的 resource-id 或 text然后执行点击。这套逻辑在标准 Android 原生控件上工作得很好但一旦遇到 Flutter 自绘、Unity 游戏界面、或者某些厂商深度定制的 WebView 容器控件树要么是空的要么全是无意义的容器节点。我实测过某款主流电商 App 的商品详情页整个页面在控件树里只暴露了三个节点其余全是 Canvas 绘制传统方案直接失效。第二个天花板是坐标硬编码的脆弱性。很多团队退而求其次用固定坐标点击。问题是不同分辨率、不同刘海高度、不同系统导航栏样式下同一个按钮的坐标能差出几十像素。更别说 App 版本更新后布局微调脚本就得全部重录。第三个天花板是缺乏语义理解。传统方案只能执行点击 id 为 xxx 的按钮它不知道这个按钮是确认支付还是取消订单。当界面出现弹窗、广告、权限请求这些非预期元素时脚本没有任何判断能力只能靠预设的 if-else 去猜维护成本极高。1.2 ARTEMIS 的破局思路把屏幕当图片把操作当语言ARTEMIS 的核心思路非常直接既然控件树不可靠那就不依赖控件树。它把手机屏幕截图当作输入交给一个多模态大模型让模型输出一个结构化动作比如{action: tap, x: 540, y: 1200}或者{action: swipe, start: [540, 1800], end: [540, 600]}然后通过 ADB 或设备端 Agent 执行这个动作。执行完再截一张图继续下一轮形成一个感知-决策-执行的闭环。这个设计的好处是与界面实现完全解耦。不管你是原生控件、Flutter 自绘还是游戏引擎渲染对模型来说都只是一张图片。模型看到登录两个字就知道要点那里不需要知道这个按钮的类名是什么。但代价也很明显每一步都要调用一次多模态模型延迟和成本都比传统方案高一个量级。所以 ARTEMIS 在工程上做了大量优化比如截图压缩、动作空间离散化、缓存机制这些后面会详细讲。1.3 和AI 手机助手类产品的本质区别市面上有不少号称AI 操作手机的产品但大多数是录屏云端大模型远程控制的架构延迟高、隐私风险大。ARTEMIS 是本地优先的设计模型可以跑在本地比如通过 Ollama 部署量化后的多模态模型截图和操作数据不出设备。这一点对做企业内测、金融类 App 自动化的团队来说很关键。另一个区别是动作空间的规范性。很多 AI 助手输出的是自然语言指令比如点击屏幕下方的登录按钮然后需要一个额外的解析层去转换成坐标。ARTEMIS 直接让模型输出结构化 JSON减少了中间环节的误差累积。2. 拆开 ARTEMIS 的引擎盖感知、决策、执行三层怎么咬合2.1 感知层截图不是随便截的ARTEMIS 的感知层看起来只是截个图但里面有几个关键决策直接影响识别率。首先是分辨率选择。Android 设备原生截图往往是 1080x2400 甚至更高直接丢给模型会消耗大量 token而且很多模型对超大图的理解反而会下降。ARTEMIS 默认会把截图缩放到一个较短边约 720 或 1080 的尺寸。我实测下来短边 720 是一个比较好的平衡点再低会导致小字看不清再高对识别率提升有限但延迟明显增加。其次是截图时机。界面动画没结束时截图会拍到半透明的过渡状态模型容易误判。ARTEMIS 在执行动作后会等待一个settle_time默认约 500ms 到 1s等界面稳定后再截图。这个值在低端机上需要调大否则会拍到加载中的骨架屏。第三是状态压缩。连续多轮截图之间如果界面没有实质变化ARTEMIS 会复用上一轮的理解结果避免重复调用模型。这个缓存策略对长流程任务比如连续填写十个表单项的加速非常明显。2.2 决策层动作空间是怎么定义的这是 ARTEMIS 最值得细看的部分。它没有让模型自由发挥而是定义了一个封闭的动作空间模型只能从这个集合里选动作类型参数说明tapx, y单击指定坐标long_pressx, y, duration长按用于触发上下文菜单swipestart_x, start_y, end_x, end_y, duration滑动用于滚动和拖拽typetext输入文本需先聚焦输入框back无系统返回键home无回到桌面waitms主动等待用于加载场景done无任务完成信号这个设计的好处是输出可校验。模型如果输出了不在集合里的动作或者坐标超出屏幕范围系统可以直接拒绝并要求重试而不是执行一个错误操作把流程带偏。动作空间的粒度也经过权衡。比如没有单独的滚动到顶部动作而是用 swipe 配合足够大的距离来实现。这样减少了动作种类降低了模型的学习负担。2.3 执行层ADB 还是设备端 AgentARTEMIS 支持两种执行后端。一种是通过 ADB 从主机发送指令适合开发调试场景一台电脑控制一台或多台设备。另一种是设备端 Agent在手机上跑一个轻量服务接收动作指令并执行适合脱离电脑的独立运行场景。ADB 方案的优势是调试方便所有日志都在电脑上截图也能直接保存到本地分析。劣势是依赖 USB 连接或网络调试移动性差。设备端 Agent 方案更接近产品化形态但需要在设备上处理权限、保活、截图编码等问题工程复杂度更高。我建议刚开始接触的话先用 ADB 方案跑通全流程理解清楚每一轮循环在干什么再考虑往设备端迁移。3. 从零跑通 ARTEMIS环境、设备、模型三步走3.1 环境准备里最容易忽略的两个细节ARTEMIS 的代码仓库里 README 写得还算清楚但有两个地方新手几乎必踩。第一个是Python 版本和依赖冲突。ARTEMIS 依赖的一些图像处理库和模型推理库对版本比较敏感。我建议用Python 3.10 或 3.11不要用 3.12因为部分依赖还没适配。创建虚拟环境后先装requirements.txt如果遇到torch相关报错大概率是 CUDA 版本和驱动不匹配这时候要么装 CPU 版本先跑通逻辑要么根据自己显卡的 CUDA 版本去 PyTorch 官网找对应的安装命令。第二个是ADB 的环境变量和驱动。Windows 上装完 platform-tools 后一定要把路径加到系统 PATH 里否则 ARTEMIS 调用adb时会报command not found。另外部分国产手机需要额外安装厂商的 USB 驱动并且在开发者选项里打开USB 调试和USB 安装两个开关。我遇到过一台设备只开了 USB 调试结果截图正常但点击无效排查了半天才发现是USB 安装没开导致输入事件被拦截。提示连接设备后先用adb devices确认设备列表里能看到你的手机状态是device而不是unauthorized。如果是后者需要在手机上确认 RSA 授权弹窗。3.2 设备连接与权限配置设备连上之后还有几个权限要处理截图权限ADB 方案下adb exec-out screencap -p可以直接截图不需要额外授权。但如果用设备端 Agent需要申请 MediaProjection 权限。输入权限adb shell input tap x y可以模拟点击但部分定制系统会限制后台输入。如果发现点击无效检查是否开启了模拟点击相关的系统限制。悬浮窗权限如果 Agent 需要显示状态浮层需要申请SYSTEM_ALERT_WINDOW。我建议在正式跑任务前先用几条简单的 ADB 命令手动验证一下截图和点击是否正常# 截图并保存到本地 adb exec-out screencap -p screen.png # 点击屏幕中心假设分辨率 1080x2400 adb shell input tap 540 1200 # 滑动 adb shell input swipe 540 1800 540 600 300这几条命令能跑通说明基础链路没问题再往上叠 ARTEMIS 的逻辑就顺了。3.3 模型选型本地跑还是调 APIARTEMIS 本身不绑定特定模型只要模型支持图像输入并输出结构化文本即可。实际选型时有两个方向本地模型方面可以选一些开源的多模态模型用 Ollama 或类似工具部署。优势是数据不出本地、无调用成本劣势是对硬件有要求而且小参数量的模型在复杂界面上的识别率会明显下降。我实测下来参数量太小的模型在密集列表页面上经常点错行建议至少用 7B 以上的多模态模型并且做好量化。云端 API方面调用成熟的多模态接口识别率有保障但要注意截图里可能包含敏感信息需要做脱敏处理。另外延迟受网络影响长流程任务的体验会打折扣。一个折中方案是混合模式简单界面用本地小模型遇到复杂界面再切换到云端大模型。ARTEMIS 的架构支持这种动态切换但需要自己写路由逻辑。4. MCP 协议在 ARTEMIS 里扮演什么角色4.1 先搞清楚 MCP 到底解决什么问题很多人搜mcp是什么的时候看到的解释都很抽象。用一句话说MCP 是一套让 AI 模型能够标准化地调用外部工具和数据的协议。在没有 MCP 之前你想让模型操作手机得自己写一套模型输出→解析→执行的胶水代码每个项目都不一样。有了 MCP模型和工具之间有了统一的接口描述工具方只需要暴露一个符合 MCP 规范的 Server模型方就能自动发现并调用这些工具。放到 ARTEMIS 的场景里手机操作能力可以被封装成一个 MCP Server暴露的工具包括screenshot、tap、swipe、type_text等。任何支持 MCP 的 AI 客户端比如一些 IDE 插件、Agent 框架都能直接调用这些工具来操作手机而不需要关心底层是 ADB 还是设备端 Agent。4.2 ARTEMIS 的 MCP 工具集设计ARTEMIS 暴露的 MCP 工具大致分三类感知类工具get_screen返回当前屏幕截图通常是 base64 编码或文件路径get_screen_info返回屏幕分辨率、当前前台应用包名等元信息。这类工具是模型决策的基础。动作类工具tap、long_press、swipe、type_text、press_key。每个工具都有明确的参数 schema模型调用时会被校验。流程类工具start_task、end_task、get_task_status。用于管理多步任务的上下文避免模型在长流程中忘记自己在干什么。这个设计的精妙之处在于把状态管理从模型侧转移到了工具侧。模型不需要记住我已经点了三步了它只需要在每一步调用get_screen看当前状态然后决定下一步动作。任务的整体进度由 MCP Server 维护。4.3 自己写一个 MCP Server 接入 ARTEMIS 的思路如果你想基于 ARTEMIS 做二次开发比如接入自己公司的设备管理平台可以自己写一个 MCP Server。核心步骤定义工具 schema用 JSON Schema 描述每个工具的名称、参数、返回值。实现工具逻辑底层可以调用 ARTEMIS 的 Python API或者直接调 ADB。启动 MCP Server通常是一个本地 HTTP 或 stdio 服务等待客户端连接。在 AI 客户端里注册把 Server 地址配置到客户端模型就能发现这些工具了。# 伪代码示意一个最小的 tap 工具实现 def handle_tap(x: int, y: int): # 校验坐标范围 if not (0 x screen_width and 0 y screen_height): return {error: coordinate out of range} # 执行点击 subprocess.run([adb, shell, input, tap, str(x), str(y)]) # 等待界面稳定 time.sleep(0.5) return {status: ok}实际写的时候要注意错误处理和超时。ADB 命令偶尔会卡住如果不设超时整个 MCP Server 会被阻塞。5. 实测中暴露的问题和我的处理方式5.1 截图分辨率与识别率的非线性关系我一开始想当然地认为截图越清晰模型识别越准于是把截图保持在原生 1080x2400。结果发现两个问题一是单次推理时间从 1.2 秒涨到了 3.5 秒二是模型在密集列表里反而更容易点错因为高分辨率下相似元素太多模型的注意力被分散了。后来我把截图缩放到短边 720识别率反而提升了。分析下来原因是适度的信息压缩帮助模型聚焦在关键元素上就像人眯着眼睛看东西反而能看清轮廓一样。当然这个值不是固定的需要根据你的目标 App 界面密度来调。列表项特别密集的界面可以适当提高到短边 900。5.2 动作执行延迟导致的幽灵点击这个问题很隐蔽。ARTEMIS 发出 tap 指令后如果立即截图可能截到的是点击前的界面因为渲染还没完成模型会以为点击没生效于是再点一次结果两次点击叠加触发了非预期操作。我的处理方式是在动作执行后加一个动态等待先等 300ms然后连续截图两次如果两张图差异小于阈值认为界面已稳定继续下一步如果差异大再等 500ms 重新判断。这个逻辑比固定 sleep 更可靠尤其在低端机上效果明显。5.3 多步任务中的上下文漂移跑长流程任务时比如打开设置→找到关于手机→连续点击版本号七次模型跑到第四五步时经常忘记最初的目标开始做一些无关操作。这是多模态模型在长上下文下的通病。ARTEMIS 的缓解方式是在每一轮 prompt 里重新注入任务目标而不是依赖模型自己记住。具体做法是把原始任务描述和已完成步骤的摘要一起放进 system prompt。这样虽然增加了 token 消耗但任务完成率提升很明显。我实测同一个七步任务注入目标后完成率从 40% 左右提升到了 85% 以上。5.4 输入法带来的意外type_text这个动作看起来简单但中文输入是个大坑。ADB 的input text命令对中文支持不好直接传中文会乱码或丢失。ARTEMIS 的处理方式是先通过 ADB 设置剪贴板然后模拟粘贴操作。但不同系统版本的剪贴板 API 不一样需要做兼容。另一个坑是输入法弹窗遮挡界面。输入完成后如果不收起键盘下一轮截图会拍到键盘模型可能把键盘上的按键当成目标元素。所以type_text之后通常要跟一个press_key收起键盘或者点击输入框外的区域。6. 这套方案适合什么场景不适合什么场景6.1 适合的场景跨 App 的流程自动化是 ARTEMIS 最擅长的。比如从聊天记录里提取地址→打开地图 App→搜索这个地址→截图保存这种任务涉及多个 App 切换传统方案需要为每个 App 单独写适配而 ARTEMIS 用同一套视觉逻辑就能覆盖。界面频繁变动的测试场景也很合适。App 每次发版 UI 都可能调整传统脚本要重新录ARTEMIS 只要模型能认出元素语义布局变了也能点对。一次性任务的性价比很高。比如帮朋友批量处理某个 App 里的重复操作写传统脚本的时间可能比手动做还长用 ARTEMIS 描述一下任务就能跑。6.2 不适合的场景高频重复的固定流程不适合。比如每分钟要执行一次的签到操作ARTEMIS 每轮都要调模型延迟和成本都划不来这种场景用传统 ADB 脚本更合适。对时序精度要求极高的操作也不适合。比如抢购、秒杀这类场景模型推理的几百毫秒延迟是致命的。涉及敏感数据的场景要谨慎。虽然 ARTEMIS 支持本地模型但截图本身包含了屏幕上的所有信息如果任务涉及密码、验证码需要额外的脱敏处理。7. 几个能明显提升成功率的实操技巧7.1 给模型更明确的界面描述ARTEMIS 的 prompt 里可以加入一些界面先验知识。比如告诉模型这是一个电商 App 的商品列表页每个商品卡片包含图片、标题、价格模型定位元素的准确率会提升。这些描述不需要很精确但能帮模型建立基本的空间认知。7.2 用分步确认代替一步到位不要指望模型一次输出一长串动作序列。ARTEMIS 的设计就是一步一截图一决策这个节奏虽然慢但容错率高。如果发现某一步执行后界面不符合预期可以立即回退重试而不是等到整个序列跑完才发现错了。7.3 建立动作白名单和黑名单对于已知的危险操作比如删除、支付、确认转账可以在执行层加一道拦截要求二次确认。ARTEMIS 支持在动作执行前插入校验钩子这个机制在生产环境里很有必要。7.4 日志要记全尤其是截图调试 ARTEMIS 任务时最有用的信息是每一轮的截图和模型输出。我习惯把每轮的截图按序号保存模型输出的 JSON 也写到日志里。出问题时回放一遍基本能定位到是哪一步的判断出了偏差。这个习惯帮我省了大量排查时间。7.5 控制单次任务的步数上限再好的模型也有犯错的时候长流程任务一旦某一步跑偏后面会越跑越离谱。我通常会给任务设一个步数上限比如 30 步超过就强制终止并报警。这样至少不会让错误操作无限执行下去。8. 关于 ARTEMIS 后续可以怎么玩ARTEMIS 目前还是一个偏框架性质的项目它提供的是感知-决策-执行的骨架具体的模型接入、任务编排、错误恢复策略都需要使用者自己补。这既是门槛也是空间。我最近在尝试的一个方向是把常用 App 的操作封装成技能库。比如微信发消息这个技能内部包含了打开微信、搜索联系人、点击输入框、输入文本、点击发送这一串动作但对上层只暴露一个send_wechat_message(contact, text)的接口。这样模型不需要每次都从零推理调用技能库就行速度和稳定性都能提升。另一个方向是结合无障碍服务做混合感知。纯视觉方案在文字密集的界面上还是有局限如果能同时拿到控件树的文本信息作为辅助识别率还能再上一个台阶。ARTEMIS 的架构是开放的感知层可以替换成截图控件树的融合方案。最后分享一个我在实际使用中的体会不要追求 100% 的自动化率。移动端界面的复杂度和不确定性太高能做到 80% 到 90% 的自动完成率剩下的用人工兜底整体效率已经比纯手动高很多了。把精力花在优化那 80% 的稳定性上比死磕最后 20% 的极端情况要划算得多。
返回列表