用途
agent-device 是一个用于控制 iOS 模拟器或 Android 模拟器/真机的命令行工具,主要面向需要在移动设备上执行自动化交互的场景。其核心交互方式是基于无障碍树快照(accessibility tree snapshot):先获取快照,找到目标元素的矩形区域,计算中心点,再执行按压操作。
资料强调,agent-device 是设备交互的唯一工具,所有模拟器/模拟器交互都必须通过 agent-device 命令完成,不允许使用其他替代方案。
主要能力
- 快照与元素定位:通过
snapshot -i -c --json获取带矩形坐标的交互元素,每个元素包含@ref、role、label、rect等字段,可据此精确计算点击位置。 - 交互操作:支持
press(点击、双击)、longpress(长按)、type(输入文本)、scroll(方向滚动)、swipe(精确滑动)、wait(等待,最大 500ms)。 - 导航操作:
open(启动应用)、close(关闭应用)、back、home、app-switcher。 - 截图与录屏:
screenshot保存截图,record start/stop录制视频(iOS 可用;Android 模拟器 API 35+ 存在已知问题,需改用 adb 的 screenrecord 方案)。 - 设备与状态查询:
devices列出设备、apps列出已安装应用、appstate查看前台应用/活动、keyboard dismiss收起键盘、clipboard read/write读写剪贴板。 - 设置切换:
settings appearance dark/light、settings wifi off、settings permission grant camera等,便于测试。
使用方式
设备定位
每次会话开始时,应先运行 agent-device devices 列出可用设备,识别正确的已启动设备,并通过 --device "<name>" 指定目标,避免启动错误的模拟器。
探测已有会话
在调用 open 之前,应先用 appstate 探测是否已有会话占用该设备。若成功,说明默认会话已拥有该设备,可直接使用;若提示被会话 X 占用,则后续命令使用 --session X;若默认会话绑定到其他设备,则需新建 --session <name> 并执行 open。
iOS 示例
agent-device devices
agent-device appstate --device "iPhone 16"
agent-device open FlatListPro --device "iPhone 16"
agent-device snapshot -i -c --json
agent-device press <x> <y>
agent-device screenshot /tmp/verify.png && sips --resampleHeight 852 /tmp/verify.png >/dev/null
Android 示例
Android 需要同时指定 --session 和 --platform,并可用 apps --platform android --user-installed 发现已安装包名。
agent-device appstate --device "Android35" --session droid --platform android
agent-device open <package> --session droid --platform android \
--device "Android35" \
--activity <package>/.MainActivity
agent-device snapshot -i -c --json --session droid
agent-device press <x> <y> --session droid
核心工作流:快照优先
- 执行
snapshot -i -c --json获取交互元素及矩形坐标。 - 按 label、identifier 或 value 匹配目标元素。
- 计算中心点:
x = rect.x + rect.width / 2,y = rect.y + rect.height / 2。 - 执行
press,必要时用截图验证。
当元素不在无障碍树中(如 canvas 渲染内容、自定义绘制视图)时,可回退到基于截图的视觉估算方式。
坐标系差异
- Android:
press使用原始像素坐标(与截图尺寸一致)。 - iOS:
press使用逻辑点坐标(截图像素 / 缩放因子)。现代 iPhone(X 及以后)为 3x,iPhone SE 及旧机型为 2x,iPad 为 2x。
快照返回的 rect 值已处于正确的按压坐标空间;仅在使用截图估算坐标时才需要动态发现按压尺寸。
减少往返
- 对明显的大目标(标签栏项、显眼按钮)可跳过验证截图。
- 同一屏幕内需要点击多个元素时,可从一次快照中计算所有中心点并依次按压,除非布局发生变化。
捕获瞬时状态
截图约 300ms 一次,难以捕捉短暂的加载指示器或动画。可使用录屏加 ffmpeg 抽帧,并用 MD5 哈希找出发生变化的帧。录屏时 record start 需要约 3 秒预热,动作后需等待至少 4-5 秒再停止。资料特别提醒不要将录屏命令放入同一个 bash 脚本,应分步作为独立的 Bash 调用执行。
适用场景
- 在 iOS 模拟器或 Android 模拟器/真机上执行 UI 自动化交互。
- 需要基于无障碍树进行精确元素定位的测试或调试。
- 需要截图、录屏作为证据的 PR、调试或缺陷报告场景。
- 需要切换外观、Wi-Fi、权限等设置进行测试的场景。
限制与注意事项
- 禁止使用 adb 进行 UI 交互(如 input tap、input swipe、input text、screencap 等),仅允许
adb devices、adb wait-for-device、adb install、adb reverse、adb shell getprop、adb shell am、adb shell pm、adb shell screenrecord + adb pull、adb shell kill/adb shell pidof等例外。 - 禁止使用 Mobile MCP 工具、
xcrun simctl(除simctl list devices、simctl get_app_container、simctl install、simctl launch外)、osascript/AppleScript、Appium 或其他自动化框架。 - 禁止将
click、find、fill、focus、get text、get attrs、scrollintoview、is、wait text、wait @ref、diff snapshot作为独立子命令使用。 - 所有延迟应保持在 1 秒以内,唯一例外是应用启动(
open)可能需要数秒。 - Android 模拟器 API 35+ 上
record存在缺陷,会向本地 adb 进程发送 SIGINT 而非设备端 screenrecord,导致 MP4 损坏,需改用 adb 方案。 - CI 环境存在已知问题:
open可能无限挂起;应使用完整 bundle ID;快照和会话可能持续超时,若不可用则记录反馈并仅使用自动化测试。 - iOS 上
back会导航到上一个应用,而非总在当前应用内,建议改用点击返回箭头。 - Android 上使用
type前需先用press点击输入框;在屏幕顶部附近下滑可能触发通知栏,滑动应起始于内容区域内。 - 坐标应四舍五入到最近整数,瞄准目标元素中心;若点击未命中,应重新获取快照并重新计算,而非反复猜测。