实战 📋 6 个步骤 第 553 / 554 篇

用 Google ARTEMIS 让编码 Agent 直接操作 Android 真机:安装、Flash/Pro 双模式与 MCP 接入实操

Google 开源的 Android 自动化框架 ARTEMIS 把自然语言指令翻译成端到端真机操作,并内置原生 MCP Server 供 Claude Code、Codex、Cursor 驱动测试设备。本教程从一键脚本搭环境、Flash 与 Pro 双模式的取舍、MCP 接入与规则挂载,到用 Python SDK 把用例写进 pytest 与 CI,一步步打通「改完代码自己装包验收」。

2026.10.21· 11 分钟上手· 约 3677 字· 📱 ARTEMIS / 🤖 编码智能体

让编码 Agent 改完代码就去手机上验收,过去是件很别扭的事:改完要手动打 APK、手动装、手动点开机和用户流程、手动抓 Logcat,每一步都得人盯着。Google 开源的 ARTEMIS 把这个链条的中间也交给机器了——它是一个 Android 自动化框架,把一句自然语言指令翻译成端到端的真机操作:它看屏幕、理解界面、点按钮、跨 App 完成流程,顺路把 Logcat 日志与截图带回来。真正让它和「AI 刷手机」类工具拉开差距的,是它内置了原生 MCP Server:Claude Code、Codex、Cursor、Antigravity 这类编码 IDE 可以直接把它当工具调用,于是「改完代码 → 装到真机 → 走一遍流程 → 返回截图和日志」变成一句话的事。本教程从环境准备、跑通命令行,到接 MCP、接 pytest,一步步做下去。

📱 本教程适合:Android 应用开发者与测试工程师,尤其是希望编码 Agent 能自己完成真机验收的团队。你需要一台开了 USB 调试的 Android 真机或模拟器,以及 Python 3.12 以上环境;项目不在本地跑模型权重,推理调用外部多模态服务,所以本机不需要 GPU。许可证为 Apache-2.0,商用前请自行核对依赖许可与所在组织的合规要求。

Step 1:准备环境,一键脚本会把工具链补齐

1 门槛在设备,不在算力

前置条件只有三样:Python 3.12 或更高版本、一台开启了 USB 调试的 Android 真机或模拟器,以及能联网的环境。ADB、scrcpy、FFmpeg 与 Python 侧的 uv 依赖都不用你提前装——一键启动脚本会检测系统并自动补齐。启动之后它会打开浏览器控制台 http://localhost:8000,里面是设备连接向导、实时投屏、提示词沙盒与执行回放面板。如果你就是想在命令行干活,完全可以不碰那套界面。Windows 用户在 PowerShell 里要注意:默认不从当前目录查找可执行脚本,所以要写成带前导点的形式;在 CMD 里则不带。

# macOS / Linux
git clone https://github.com/google/artemis.git && cd artemis
./start.sh

# Windows PowerShell(注意前导点)
git clone https://github.com/google/artemis.git
cd artemis
.\start.bat

# 想在任意目录直接用 artemis 命令(可选,项目根目录执行一次)
uv tool install -e .

还有两个值得提前知道的服务端组件。其一,开始在一台设备上跑任务时,它会往手机安装一个无障碍辅助服务 Artemis Accessibility Helper,用来在不占用 UiAutomation 连接的前提下读取屏幕布局;如果它中途失效,框架会自动回退到 UIAutomator2,并且会把这次回退写进任务时间线、任务状态与最终报告里,便于你事后判断这批结果的可靠性。辅助服务只在手机本地监听,不向外部发送数据。其二,可以用下面的命令预装,避开任务开始那几秒的安装等待。

# 预装 / 查看 / 卸载手机端辅助服务
uv run artemis helper install
uv run artemis helper status
uv run artemis helper uninstall

# 服务生命周期与体检
uv run artemis status
uv run artemis restart
uv run artemis stop
uv run artemis doctor

用测试机,别用主力机:它要靠无障碍服务读取屏幕、要点按任意位置、要跨 App 完成流程,这意味着屏上的支付 App、聊天记录、短信验证码都可能进入它与多模态模型的视野。准备一台专门的测试机或使用模拟器,测试账号不要绑定真实支付渠道。

Step 2:先跑通一条指令,搞清 Flash 与 Pro 的分工

2 快而糙 vs 慢而稳

命令行的最小用法就是把想做的事用自然语言写进引号里。真正要理解的是两种执行模式的分野:Flash 是反应式的「观察—行动」循环,配合异步历史摘要,典型单步三到五秒,适合界面确定、路径清晰的常规任务;代价是它没有任务计划与笔记、没有执行前的安全检查网、没有检查点验证或最终报告,也拿不到 ADB shell。Pro 则是一张多智能体图,有 Planner、Operator、Explorer、Checker 这些角色,每个动作执行前会校验目标,遇到被拦下的动作会交回上层恢复,典型单步十五到四十秒,换来的是长链路任务(一百步以上)与探索性、稳定性测试的可靠度。

# Flash:快,适合确定性 UI 任务
uv run artemis run "打开系统设置,找到电池,告诉我当前电量" --profile flash

# Pro:稳,适合长链路与探索性测试
uv run artemis run "检查设置里是否有崩溃弹窗,给出截图" --profile pro

# 交互配置(补装 MCP 用,与 start.sh 的安装提示互补)
uv run artemis init

选型上有一条很实用的经验:确定性回归、单条明确路径用 Flash;探索性测试、需要最终报告或一致性校验的场景才上 Pro。官方还给出了 Pro 侧的校验强度选项,可以在「关闭、仅最终、按检查点、严格」之间选,倾向自动驾驶的创作之外,把 verification-level 调高通常能换来更少的返工。另一处细节:Pro 模式里 Explorer 的定位精度档位是跟着 profile 由人来设定的,不会让 Agent 自己随意升级——这是刻意留给你控制的成本闸。

💡 把「期待的验收结果」写进指令,比只说「测一下」有效得多。它依赖结构化结果来判断成功与否,「验证登录后是否出现非预期弹窗并返回最终页面截图」这类写法的完成度,明显高于「把登录流程走一遍」。

Step 3:把它接进你的编码 Agent(MCP)

3 一条命令挂到所有 IDE

这一步才是整个方案的价值拐点。ARTEMIS 自带一个原生 MCP Server(入口是仓库里的 mcp_server 模块),官方支持的一键安装目标包括 Antigravity、Cursor、Claude Code、Codex、Windsurf、VS Code、Cline/Roo、OpenClaw。安装的同时还会挂载一份「移动端测试思维准则」的规则文件,里面写的是官方踩出来的几条硬经验:先主动探索再动手写代码、Flash 与 Pro 的路由策略、延迟与时序补偿,以及「动态元素优先、坐标兜底」的定位器写法。规则文件只装一处即可,重复挂载只会白白占用上下文。

# 装到所有支持的 IDE(含 Codex)
uv run artemis mcp --install all

# 只装某一个
uv run artemis mcp --install antigravity     # Antigravity / Jetski
uv run artemis mcp --install claude          # Claude Code

# 规则文件的落点(不同客户端不同)
# Claude Code  : ~/.claude/rules/artemis.md
# Codex        : ~/.codex/AGENTS.md(或生效的 AGENTS.override.md)
# Cursor       : .cursorrules 或 .cursor/rules/artemis.mdc
# Windsurf / OpenClaw : workspace rules 或全局 system prompt

如果你的客户端不在自动覆盖范围内,或者你想把配置写进版本库统一管理,可以让它生成配置片段再手工粘贴。注意两点:路径要换成你本地仓库的真实路径,command 要指向虚拟环境里的 Python 可执行文件(Windows 上通常在 .venv/Scripts 而不是 .venv/bin)。Windows 用户在这里容易卡住,所以下面两种都列出来。

# 先生成片段
uv run artemis mcp --generate-config codex
uv run artemis mcp --generate-config antigravity

# Codex  ~/.codex/config.toml
[mcp_servers.artemis]
command = "/path/to/artemis/.venv/bin/python"
args = ["-m", "mcp_server"]
cwd = "/path/to/artemis"

[mcp_servers.artemis.env]
PYTHONUNBUFFERED = "1"
PYTHONPATH = "/path/to/artemis"

# Claude Desktop  claude_desktop_config.json
{
  "mcpServers": {
    "artemis": {
      "command": "/path/to/artemis/.venv/bin/python",
      "args": ["-m", "mcp_server"],
      "cwd": "/path/to/artemis"
    }
  }
}

Windows 与 Python 路径:官方示例里写的是 .venv/bin/python,这是 macOS / Linux 的写法;Windows 虚拟环境的解释器在 .venv/Scripts/python.exe,照抄示例会导致客户端拉不起服务。改完配置后先让客户端列一次工具,确认识别到移动端的那些工具再开始干活。

Step 4:让 Agent 改完代码自己装包验收

4 一句话串起构建、安装、巡检

接上 MCP 之后,编码 Agent 就多了一双手。官方演示的这句指令很能说明意图:把最新改动打成 APK、装到已连接的设备、用测试账号打开登录页、检查登录后有没有非预期弹窗、把最终页面的截图带回来。对日常开发来说,「改完就验收」这件事终于不用人肉盯了。但心里要有笔账:这条链路上的每一步都在调用多模态模型理解屏幕,步数与耗时、花费都成正比,它省的是你的时间,不是 token。

# 给编码 Agent 的自然语言指令(走 MCP 工具调用)
用 artemis 把刚才的改动构建成 APK,装到已连接的设备上,
用测试账号打开登录页,检查登录后有没有非预期弹窗,
把最终页面截图和 Logcat 片段带回来。

# 只想拉一次当前屏幕状态
看看当前屏幕上是什么界面?把可见元素列出来。

# 想排查某次失败
回放刚才那个任务的 trace,指出卡在第几步。
💡 把「要用哪台设备」也写清楚。多设备同时连着的时候,用 adb devices 确认序列号,然后在指令或 SDK 参数里指明目标——否则它可能随意挑一台,包括你不想动的那台。

Step 5:接进 pytest 与 CI

5 零依赖客户端 + Pydantic 强类型结果

除了 MCP 与命令行,它还提供了一个 Python SDK:安装的是一个零运行时依赖的客户端(ADB、模型、图像处理这些重活仍然留在连接设备的那台宿主上,不会在你的开发机上重复安装一份),跑完之后返回强类型的结构化结果,可以直接断言。这样你就把它塞进了现有测试体系——pytest 里写用例,CI 里跑夜构建巡检,失败拿 trace_id 回去回放。下面是官方给出的异步用法。

# 安装客户端(注意 subdirectory 指向 packages/artemis-client)
uv add "artemis-client @ git+https://github.com/google/artemis.git#subdirectory=packages/artemis-client"
import asyncio
from artemis_client import ArtemisClient

async def main():
    client = ArtemisClient(
        "http://artemis-host:8000",
        device_serial="emulator-5554",   # 可选:指定目标设备
        default_profile="flash",         # "flash"(快速反应)或 "pro"(深度推理)
    )
    result = await client.run(
        "打开系统设置,进入电池,确认显示了电量百分比,并检查有没有崩溃弹窗。"
    )
    assert result.succeeded, f"测试失败: {result.error or result.status}"
    print(f"通过 | 设备: {result.device_serial} | Trace ID: {result.trace_id}")

if __name__ == "__main__":
    asyncio.run(main())

放进 pytest 时有两种写法:装了 pytest-asyncio 就直接用异步测试函数;没有的话,在普通同步用例里用 asyncio.run 包一层同样成立。无论哪种,断言都落在 succeeded 上,失败信息从 error 或 status 里取,排查靠 trace_id。真实工程里建议把设备序列号与 profile 做成环境变量,同一份用例可以在本地模拟器与 CI 的真机池之间切换。

CI 里别用 Flash 跑关键回归:Flash 明确没有执行前安全检查网、没有检查点验证、也没有最终报告,也就是说它跑「成功」你未必拿得到可核查的证据。做发布门禁的回归用例请用 Pro 并调高校验强度,把报告与截图留档;Flash 适合冒烟与快速巡检。

Step 6:成本、稳定性与已知边界

6 别把稳定一轮当成稳定全局

要给它定预算与预期,先看清三条账。其一是时间与钱:Flash 单步三到五秒、Pro 单步十五到四十秒,流程越长成本线性上升,长流程不要指望很快产出;进阶手段是把长任务拆短、让长链路在后台跑完再取结果,而不是让它一口气跑两百步。其二是平台范围:当前只有 Android,iOS 支持还在路线图上,跨平台团队别误以为能一套覆盖。其三是界面类型:标准控件能拿到元素索引,命中率最高;而 Canvas、Compose、Flutter 这类自绘界面拿不到索引,只能回退到坐标与视觉定位,稳定性会明显依赖多模态模型与 OCR 的水平。

# 你的三项日常运维动作
uv run artemis status       # 服务是否在跑
uv run artemis doctor       # 环境 / 辅助服务诊断
uv run artemis helper install   # 预装辅助服务,省掉任务开头的等待

# 强制改用 UIAutomator2(在 .env 里)
ARTEMIS_HIERARCHY_BACKEND=uiautomator
ARTEMIS_HELPER_AUTO_INSTALL=false      # 禁止自动安装辅助服务
💡 定位策略上照抄官方那句「动态优先、坐标回退」:只要有元素索引就用索引,实在拿不到再退到坐标。反过来的写法——图省事直接写死坐标——在分辨率或系统字体一变就全崩,而且崩得很安静。

基准成绩不等于你的成绩:官方在 Google Research 的 AndroidWorld 基准(二十多个应用、一百多个多步任务)上给出了 99% 以上的任务完成率,这是可复核的硬指标,但那是标准环境与标准任务集上的数字。你自己的 App 如果大量自绘控件、弱网依赖重、或有大量随机弹窗,实际表现会低于这个水平。上线前用你自己的用例集跑一轮,别拿公开基准当验收结论。

常见问题速查

现象原因与处理
start.bat 提示找不到命令PowerShell 默认不搜当前目录;写成 .\start.bat,或改用 CMD 里的 start.bat
Python 版本报错要求 3.12 以上;升级解释器后重跑启动脚本
找不到设备确认 USB 调试已开且授权弹窗已通过;adb devices 能看到序列号才算连上
客户端拉不起 MCP 服务Windows 下改用 .venv/Scripts/python.exe;cwd 与 PYTHONPATH 要指向真实仓库路径
自绘界面点不准拿不到元素索引,只能走坐标与视觉回退;给自绘页面补测试数据或固定 fixtures
任务开头卡几秒在装辅助服务;跑 uv run artemis helper install 预装即可避开
结果报告里提到回退 UIAutomator2辅助服务中途失效已自动降级;回退会写明在任务时间线与最终报告里,据此判断这批结果的可信度
费用远超预期流程长 + 用的 Pro 模式;拆短任务、审计资质的作用,必要时只保留关键链路自动化
← 返回教程中心