如果你上周听说了 Google 开源了一个叫 ARTEMIS 的 Android 自动化项目——自然语言指令驱动真实 Android 设备,99%+ 的 AndroidWorld 完成率,原生 MCP Server 支持 Gemini/Claude/Cursor/Codex 等 AI 编码助手——你可能以为它又是一个「用 LLM 调 ADB」的玩具。
但实际读下来,ARTEMIS 的工程深度远超我的预期。它不只是把「看屏幕 → 决策 → 点击」这个循环套上了 LLM,而是在 LangGraph 上构建了一套生产级的多 Agent 编排系统,有两个完整的执行模式引擎、一个可插拔的感知流水线,和一套 MCP 生态集成层。
这篇文章从源码层面拆解它的架构设计。在开始之前,先交代一下我研究后的几个核心判断:
- ARTEMIS 是当前开源 Android 自动化领域工程最完善的项目,没有之一
- Flash 模式 3-5s/step 的反应速度不是靠更小的模型,而是靠精巧的上下文压缩和状态管理
- Pro 模式的多 Agent 编排(Planner → Operator → Checker → Explorer)是 LangGraph 在实际产品中我看到过的最完整落地
- 代码归属争议是真实存在的——228/229 个文件与 Minitap 的 mobile-use 项目完全相同
1. 项目概览
| 元数据 | 值 |
|---|---|
| 仓库 | github.com/google/artemis |
| 作者 | Farley Wang (farleyw@google.com) |
| 语言 | Python 3.12+ |
| 许可 | Apache 2.0 |
| Forks | 806 |
| Open Issues | 98 |
| 创建 | 2026-08-13 |
| 最后推送 | 2026-09-12 |
| 核心依赖 | LangGraph, LangChain, MCP, ADB, OpenCV |
依赖栈分四个层次:
- 编排层:LangGraph 1.0+、LangChain Core、LangChain MCP Adapters
- LLM 层:Google GenAI SDK、LangChain Google GenAI、LangChain OpenAI、LangChain Anthropic——支持 Gemini、Claude、GPT-4o、Qwen-VL
- 设备层:adbutils、uiautomator2、scrcpy
- 感知层:OpenCV、Pillow、Tesseract OCR
2. 架构全景:LangGraph 多 Agent 编排
ARTEMIS 的源码结构清晰地反映了其架构分层:
artemis/
├── agents/ # Agent 节点实现 (9 个 Agent)
│ ├── flash/ # Flash 模式(反应式循环)
│ ├── operator/ # Pro 模式的核心执行 Agent
│ ├── planner/ # 计划维护 Agent
│ ├── checker/ # 验证 Agent
│ ├── explorer/ # 目标预检 Agent
│ ├── validator/ # 动作后验证 Agent
│ ├── summarizer/ # 历史压缩 Agent
│ ├── video_analyzer/ # 视频回放分析 Agent
│ └── diagnoser/ # ADB 诊断 Agent
├── graph/ # LangGraph 状态图定义
├── tools/ # 工具函数层
├── controllers/ # 统一设备控制器
├── drivers/ # 设备驱动抽象层
├── runtime/ # 后台服务层
├── llm/ # LLM 路由与可靠性层
├── memory/ # 记忆系统
└── mcp/ # MCP 集成
状态图(StateGraph)的核心设计
文件 artemis/graph/graph.py(44,453 bytes)和 artemis/graph/state.py(5,552 bytes)定义了完整的 LangGraph 状态机。
State 的字段按职责分四组:
- 控制平面:
initial_goal、injected_instruction、user_stop_requested(latch 语义)、checker_success、run_outcome - 感知数据:
latest_ui_hierarchy、latest_screenshot、indexed_points、indexed_elements - 回合产物:
structured_decisions、last_execution_result、open_incident、last_closed_incident - 子 Agent 状态:
subagent_calls、operator_tool_limit_exceeded
关键设计选择:
extra="forbid":State 不接受未声明的字段写入。LangGraph 中节点可能向 State 写入任何键,这个配置强制每写入一个字段必须先显式声明——避免幽灵键导致的状态不一致sticky_or:user_stop_requested字段使用 latch 语义——一旦设为 True 就不可逆转。这是安全设计:如果用户要求停止,后续节点不能取消这个信号take_last:大部分字段使用后写入者覆盖(last-write-wins)的 reducer
Pro 模式的多 Agent 工作流
Pro 模式的核心编排逻辑在 graph.py 中。它不是简单的「调用 LLM → 执行 → 重复」,而是一个异步多 Agent 协作图:
用户指令 → Planner(维护计划)→ Operator(执行动作)
→ Explorer(Safety Net 预检)→ Checker(验证检查点)
→ Validator(动作后验证)→ Exit Settlement
Operator 的 Incident 机制是一个亮点:当 Explorer 预检发现某个动作被阻塞或失败时,不是直接把错误丢回给 LLM 等它随机重试,而是创建一个 execution incident 留在 Operator 的上下文中。后续动作成功执行后会关闭 incident——这意味着 Operator 可以自己决定「换个方式达到同一目标」,而不需要专门的 Repair Agent。
3. Flash 模式:3-5s/step 的反应式引擎
Flash 模式的 runner 实现位于 artemis/agents/flash/runner.py(51,614 bytes),是整个项目最大的单体文件。
核心循环
Flash 是一个极简的 observe-and-act 循环:
- 观察:截屏 + 获取 UI 层次结构 + OCR
- 推理:单次 LLM 调用,决定下一步动作
- 执行:通过 ADB/UI Automator 执行动作
- 汇总:异步生成历史摘要,压缩上下文
没有图编排、没有 Planner、没有 Checker——就是一段直的 while 循环。
上下文压缩(关键优化)
Flash 能达到 3-5s/step 的效率,不是因为用了更快(更蠢)的模型,而是因为它在上下文管理上做了大量工程。
文件 artemis/agents/flash/context_compressor.py(20,864 bytes)实现了三层压缩:
- L1 - 视觉摘要:将较旧的截屏替换为视觉摘要(summarizer 生成的文字描述),原始截屏在摘要后被丢弃
- L2 - 步骤压缩:将已完成的步骤压缩为可搜索的 chunk,每个 chunk 包含步骤摘要 + 关键截图
- L3 - 历史归档:当上下文超过配置阈值时,将早期回合整体归档为「Era」,通过
search_history按需召回
这意味着 Flash 在理论上可以无限回合运行——agent.flash.max_turns = 0(默认无限)不是因为「反正不会跑那么远」,而是因为压缩机制确保了上下文不会爆炸。
关键缺陷(来自 README)
- 没有任务计划或笔记
- 没有执行前的 Safety Net
- 没有检查点验证或最终报告
- 没有 ADB shell 权限
4. Pro 模式:15-40s/step 的多 Agent 协作
Planner(计划维护 Agent)
Planner 维护一个活着的 Markdown 计划文档。这不是一次性生成的静态计划——它在任务执行过程中持续更新:
- Milestones:顶层子目标(
[ ]和[x]) - Verify items:每个 milestone 下的验证条件(
verify:前缀) - Assert items:断言条件(
assert:前缀) - Checkpoints:自动生成的检查点,供 Checker 节点验证
计划文件本身是 Markdown,artemis/utils/plan_grammar.py 中维护了一个完整的 Markdown 解析器,用于提取 milestone、check items、subgoal hash 等结构。
Checker(只读验证 Agent)
Checker 的核心职责:
- 验证检查点(
verify/assert) - 在最终出口执行 Final Review——对比原始目标 vs 实际结果
- 生成 verdict(通过/失败/待定)
Checker 不修改任何状态。它的输出写入 operator_feedback 字段,该字段作为 [checker] 标签注入到 Operator 的下一次 Prompt 中。
Explorer(Safety Net 核心)
Explorer 在 Operator 调用每个动作之前检查目标:
- 通过 UI 树定位目标(XML-first)
- 如果 XML 找不到,回退到像素级别的视觉定位(坐标 + OCR)
- 热度等级:
flash/pro/ultra(用户配置,Agent 无权选择)
如果 Explorer 发现目标不可达,它创建一个 execution incident,Operator 在后续回合中自行恢复。
5. 设备控制层的三层抽象
ARTEMIS 的设备控制分为三个层次:
Drivers——设备抽象
drivers/
├── base.py # BaseDeviceDriver 抽象类
├── factory.py # 工厂模式创建驱动
├── android/ # Android 设备驱动
├── cloud/ # 云设备驱动(Firebase Test Lab)
└── mock/ # 测试 Mock 驱动
Controllers——统一控制层
unified_controller.py(36,104 B)是整个设备控制逻辑的枢纽:理解 UI 树、执行点击/滑动/输入、处理弹窗、管理应用生命周期、收集 Logcat。
Runtime——后台服务
device_lock.py(40KB)和 helper_manager.py(45KB)是最大文件。设备锁确保同一台设备不会同时被两个任务调度;Helper Manager 管理安装在 Android 设备上的 Accessibility Service。
6. MCP 集成:将 Android 设备接入 AI IDE
这是 ARTEMIS 最务实的工程决策。它不试图成为 IDE,而是通过 MCP Server 让自己成为 IDE 的工具。
MCP Server 提供 5 个 Eager 工具:
| MCP 工具 | 功能 |
|---|---|
mobile_run_task |
运行自动化任务(自然语言 → 执行 → 报告) |
mobile_manage_task |
管理任务生命周期 |
mobile_get_device_state |
获取设备状态 |
mobile_inspect_trace |
检查任务追踪记录 |
mobile_diagnose |
运行 ADB 诊断 |
Eager 工具会在 AI IDE 中自动可用,无需用户显式请求。
mcp_server/rules.md(13,606 bytes)是一个完整的「移动测试工程师思维」规则集,指导 AI IDE 在调用 ARTEMIS 时遵循正确流程:Active Exploration、Flash vs Pro 路由策略、延迟补偿、定位器模式选择。
集成方式:
- Antigravity/Codex:
uv run artemis mcp --install antigravity - Claude Code:
uv run artemis mcp --install claude - Cursor:复制
rules.md到.cursor/rules/artemis.mdc
7. AndroidWorld SOTA:99%+ 的秘密
AndroidWorld 是 Google Research 的 Android 自动化基准测试,涵盖 20+ 应用和 100+ 多步骤任务。ARTEMIS 宣称达到 99%+ 任务完成率。
这个成绩来自几个工程选择的叠加:
- 元素定位三层回退:Accessibility 层次结构 → UI Automator → 像素级视觉定位。每层有独立的验证
- Pro 模式的 Safety Net:每次动作前由 Explorer 预检,不是动作出错后再重试
- Context 三维压缩:L1/L2/L3 压缩让长任务不会因上下文膨胀而退化
- 多模型支持:支持 Gemini、Claude、GPT-4o、Qwen-VL,允许不同认知负载使用不同模型
但需要注意的是:99%+ 的数据来自 Google Research 的官方 AndroidWorld 基准。
8. 代码归属争议:Minitap 的 228/229 文件
在 ARTEMIS 开源后不久,Minitap(一家移动测试公司)发现 ARTEMIS 的代码与他们的开源项目 mobile-use 高度相似。根据 Minitap CEO Nicholas deHansehowercker 的声明:
「我们打开 Google 的 Artemis 仓库,认出了我们自己为 mobile-use 写的代码。然后我们在其提交历史中找到了我们的名字——以及删除这些名字的那次修改。」
Minitap 列出的对比数据:
- ARTEMIS 共 229 个文件
- 其中 228 个文件与 mobile-use 完全相同
- Google 在某个提交中删除了 Minitap 贡献者的作者信息
mobile-use 基于 Apache 2.0 协议发布,允许商业使用和衍生作品。争议焦点是 Google 是否遵守了 Apache 2.0 的署名要求——使用 Apache 2.0 代码时必须保留原始版权声明。
截至写作时,Google 已在 ARTEMIS 仓库中增加了对 mobile-use 的致谢,但 Minitap 认为这不足以弥补初始发布时移除署名的行为。
9. 总结:ARTEMIS 的工程启示
ARTEMIS 对 Android 自动化领域做了三件事:
第一,验证了 LangGraph 多 Agent 编排的工程可行性。 Planner → Operator → Checker → Explorer 的协作模式不是学术 Demo,而是 40KB+ 的生产代码。checkpoints.py 到 graph.py 再到 operator.py(60KB),这三层合起来构成了在开源项目中见过的最复杂的 LangGraph 落地。
第二,Flash/Pro 双模式是务实的架构决策。 不是「一个模型走天下」,而是根据任务复杂度切换执行模式。Flash 模式 3-5s/step 用于确定性 UI 操作,Pro 模式 15-40s/step 用于复杂多步骤工作流。
第三,MCP 集成是基础设施层面的正确选择。 与其重新发明一个 IDE,不如通过协议成为 IDE 的一部分。ARTEMIS 的 MCP Server + rules.md 模式是将移动设备接入 AI 开发生态的最优雅方案之一。
至于代码归属争议——技术上说,228/229 个文件相同意味着 ARTEMIS 的初始版本在很大程度上是 mobile-use 的重新打包。Google 后来补充了致谢,但初始发布时移除署名的行为在法律和社区规范上都站不住脚。这不会让 ARTEMIS 变差,但它提醒我们:即使是大公司,在开源发布时也需要更谨慎地处理上游贡献者的署名权。
关于作者:万戈(Chengqi),AI Infra 工程师,前华为/万翼,现构建 MCPZERO、ClawGuard 和 NanoRuntime。