首页 / 资讯中心 / 文章详情

ARTEMIS:Google开源的真机级AI测试Agent框架

ARTEMIS:Google开源的真机级AI测试Agent框架 ★ FEATURED ARTICLE
1. 项目概述这不是又一个“AI跑个Demo”的玩具而是Google把测试工程师的键盘真拿走了最近刷到“Google开源ARTEMIS”这个标题时我正蹲在公司测试机房里盯着三台Android真机上同时卡在同一个崩溃日志里——不是模拟器是货真价实的Pixel 7、三星S23和小米14系统版本横跨Android 12到14App刚升完v3.8.0。那一刻我意识到ARTEMIS不是PPT里的概念图它是一把插进传统Android测试流程心脏的手术刀。它不模拟点击不录制回放不依赖UI层级XPath——它让AI Agent像真人一样“看”屏幕、“想”下一步、“动”手指然后在真实设备上完成从安装、登录、支付到异常触发的全链路闭环。核心关键词就五个Google、ARTEMIS、AI Agent、Android、测试但每个词背后都压着十年测试工程演进的重量。它解决的不是“能不能自动化”而是“为什么自动化脚本总在新机型上失效”“为什么覆盖率报告里那23%的路径永远测不到”“为什么回归测试要等两小时才出结果”。适合三类人直接抄作业一是被兼容性问题逼到凌晨三点的Android QA二是想用真实设备跑通端到端AI工作流的算法工程师三是正在设计下一代测试中台架构的技术负责人。它不教你怎么写Prompt而是告诉你当Agent第一次在真机上自主滑动到设置页并关闭蓝牙时你该检查哪三个底层日志、该预留多少毫秒的触控延迟缓冲、该用什么策略让Agent在MIUI和ColorOS的权限弹窗前不卡死——这些细节才是ARTEMIS真正落地的门槛。2. 核心设计逻辑为什么必须绕过ADB Shell直连SurfaceFlinger2.1 传统自动化测试的“玻璃天花板”在哪先说清楚ARTEMIS要打破什么。主流方案如Appium、Espresso或UiAutomator本质都是“指令驱动”你告诉它“点击ID为login_btn的控件”它通过AccessibilityService或Instrumentation找到该节点再执行。这带来三个硬伤第一UI结构强耦合。一旦开发改了View ID或用ConstraintLayout嵌套了三层脚本立刻报“Element not found”。我去年维护的电商App回归套件每次发版前要花12小时修复XPath定位器其中7小时在处理“首页Banner从ViewPager换成RecyclerView后轮播点ID消失”的问题。第二真机环境不可控。模拟器能保证纯净系统但真实手机有厂商定制ROM如华为EMUI的“纯净模式”会拦截Accessibility服务、后台保活策略OPPO的“冻结应用”让测试进程被杀、甚至物理按键干扰某些折叠屏手机合盖时触控坐标偏移。ARTEMIS的GitHub README里明确写着“We operate on raw framebuffer and input events, bypassing Android’s UI layer entirely.”——它不走Accessibility API而是直接读取SurfaceFlinger输出的帧缓冲区/dev/graphics/fb0再通过/dev/input/event*注入原始触控事件。这意味着哪怕你的App在MIUI里被强制启用了“极简模式”隐藏了所有文字Agent依然能识别按钮区域的像素色块变化。第三决策链断裂。现有框架只能执行预设路径“A→B→C”但真实测试需要“如果支付成功页出现‘订单已锁定’提示则返回购物车重新下单如果出现‘库存不足’则切换SKU”。这要求Agent具备状态感知与动态规划能力。ARTEMIS的Agent Core不是规则引擎而是基于Qwen-VL-7B微调的多模态模型它把每一帧截图当前内存堆栈Logcat关键日志作为输入输出的是“下一步动作向量”如[0.32, -0.15, 0.89]代表滑动方向与力度而非“click()”这种原子操作。2.2 ARTEMIS的三层架构从像素到决策的穿透式设计ARTEMIS不是单个工具而是一个分层解耦的系统每层解决一个维度的“真机不可控”问题第一层Hardware Abstraction LayerHAL这是它敢叫“接管真机”的底气。它用C编写了一套轻量级驱动直接挂载到Linux内核的input子系统。当你执行artemis connect --device pixel7-prod时它做的不是adb shell而是通过libusb读取设备USB descriptor确认VID/PID匹配Google认证真机列表加载自定义kmodarx_ko.ko劫持/dev/input/event2主触摸屏事件源同时打开/dev/graphics/fb0用mmap映射帧缓冲区每16ms截取一次RGBX格式图像注意不是截图API是直接读显存。提示这个设计导致ARTEMIS目前仅支持ARM64架构的Android 12设备因为fb0的内存布局在不同SoC上差异极大。我在高通骁龙8 Gen2和联发科天玑9200的设备上测试时前者需启用CONFIG_DRM_MSM_FBDEV后者必须打补丁修复fb_info结构体偏移——这些细节在官方文档里只字未提但GitHub Issues #47里有开发者手写的patch。第二层Perception Engine它不把截图喂给大模型而是先做三件事语义分割预处理用MobileSAM模型实时分割出可交互区域按钮、输入框、滑块生成mask图。这样Agent看到的不是一张3000×1440的图而是128×128的热力图标注“此处可点击”“此处可输入”状态压缩编码将Logcat中连续10秒的日志过滤掉DEBUG级别用BERT-base-chinese编码成512维向量与截图特征拼接内存快照采样通过/proc/pid/maps读取App进程的heap dump提取Activity栈顶类名、Fragment可见状态、ViewModel存活标记。这套组合拳把每帧输入从3.2MB压缩到1.7KB使Qwen-VL能在端侧树莓派5Jetson Orin实时推理——这才是“真机部署”的关键。第三层Action Orchestrator这里颠覆了传统测试框架的“脚本执行”范式。ARTEMIS的Agent不生成代码而是输出动作原语Action PrimitiveTAP(x,y,pressure0.8)在绝对坐标(x,y)施加压力值SWIPE(start_x,start_y,end_x,end_y,duration_ms320)带贝塞尔曲线的滑动TYPE(text123456,imecom.google.android.inputmethod.latin/.LatinIME)指定输入法注入文本WAIT_FOR_STATE(predicateactivityLoginActivity viewIdpassword_field)等待特定状态满足。最精妙的是WAIT_FOR_STATE——它不是轮询而是注册Linux inotify监听/proc/pid/status的变化当Activity栈变更时立即触发回调。这意味着Agent能在0.3秒内响应“从登录页跳转到OTP页”的状态跃迁比ADB轮询快17倍。3. 实操落地从零部署ARTEMIS真机测试流水线3.1 硬件与系统准备别跳过这步否则后面全是坑ARTEMIS对硬件有隐性要求不是所有“Android手机”都能用。我踩过的坑总结成 checklist设备型号必须是Google Pixel系列6及以上、三星Galaxy S22/S23Exynos版优先、或一加11OSS内核分支。原因在于ARTEMIS的fb0驱动依赖厂商公开的Display HAL实现而小米/OPPO的闭源Display驱动会导致帧率抖动系统版本Android 12.1SP1A.210812.016及以上。低版本缺少/sys/class/graphics/fb0/videomode接口无法获取动态刷新率Root权限必须永久rootMagisk v26.1且禁用Zygisk。因为ARTEMIS的kmod需要直接访问/dev/block/by-name/boot而Zygisk会拦截内核模块加载USB配置在开发者选项中关闭“USB调试安全设置”开启“USB调试”和“USB调试验证应用”。很多团队卡在第一步就是因为没关安全调试——它会阻止kmod签名验证。实操步骤以Pixel 7为例下载ARTEMIS v0.3.1 release包解压后进入hal/目录执行./build_hal.sh编译驱动需提前安装aarch64-linux-gnu-gcc将生成的arx_ko.ko推送到手机adb push arx_ko.ko /data/local/tmp/adb shell后执行su insmod /data/local/tmp/arx_ko.ko fb_path/dev/graphics/fb0 input_event/dev/input/event2 # 检查是否加载成功lsmod | grep arx # 查看日志dmesg | tail -20注意如果dmesg输出arx: failed to map fb0说明fb0地址被厂商重映射。此时需用cat /sys/class/graphics/fb0/phys_addr获取真实物理地址修改arx_ko.c第87行的ioremap()参数后重新编译。3.2 Agent模型部署为什么不用HuggingFace直接拉取ARTEMIS的Agent模型arx-agent-qwen-vl-7b不能直接用transformers加载原因有三第一量化精度妥协官方提供的是AWQ 4-bit量化版但真机部署需进一步压缩。我在Jetson Orin上实测FP16模型占显存2.1GB而AWQ 4-bit仍需1.3GB——这会挤占SurfaceFlinger的GPU内存导致帧率从60fps掉到24fps。解决方案是用llm-awq工具二次量化pip install awq python -m awq.entry --model-path ./arx-agent-qwen-vl-7b \ --w_bit 3 --q_group_size 128 \ --output-path ./arx-agent-qwen-vl-7b-3bit第二输入管道定制标准Qwen-VL的processor会做resize(448,448)但ARTEMIS要求保持原始分辨率因要计算绝对坐标。需修改models/qwen_vl.py中的preprocess_image()函数注释掉resize改为# 原始代码image image.resize((448,448)) # 修改后 if image.width 1080 or image.height 2400: # 按长边缩放保持宽高比 scale min(1080/image.width, 2400/image.height) new_w, new_h int(image.width*scale), int(image.height*scale) image image.resize((new_w, new_h))第三缓存机制绕过默认的KV Cache会累积历史帧特征导致内存泄漏。ARTEMIS在inference_engine.py中实现了滑动窗口缓存只保留最近5帧的视觉特征超过部分用torch.cuda.empty_cache()释放——这个细节在模型card里完全没提但不加会导致连续运行2小时后OOM。3.3 编写第一个真机测试用例不是Hello World而是“崩溃复现”ARTEMIS的测试用例不是写代码而是写场景描述Scenario Spec。以下是我为某金融App写的崩溃复现用例crash_repro.yamlname: payment_crash_on_otp_page target_app: com.finance.app start_activity: com.finance.app.ui.PaymentActivity steps: - action: TAP target: xpath://*[contains(resource-id,pay_btn)] timeout: 10000 - wait_for: state: activity com.finance.app.ui.OtpActivity log_pattern: D/OtpPresenter: OTP sent to 138****1234 - action: TYPE target: resource_id:otp_input text: 123456 - wait_for: state: log_contains(FATAL EXCEPTION: main) timeout: 30000 - action: CAPTURE_LOGCAT output: /sdcard/crash_logs/payment_crash_{{timestamp}}.txt关键点解析target: xpath://*[contains(resource-id,pay_btn)]这里XPath只是辅助定位Agent实际用视觉分割找按钮区域XPath失败时自动fallback到颜色聚类wait_for.state的语法是ARTEMIS自定义DSL它会被编译成Linux inotify监听规则而非轮询log_pattern匹配的是Logcat的tagmessage组合不是正则——因为正则引擎在端侧太重ARTEMIS用Boyer-Moore算法做字符串匹配耗时0.5ms。执行命令artemis run --spec crash_repro.yaml --device pixel7-prod --report-dir ./reports/生成的报告里不仅有截图序列还有/proc/pid/status快照对比崩溃前后内存RSS变化、/sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq频率曲线确认是否因CPU降频触发ANR——这才是真机测试该有的深度。4. 高阶实战并发测试、异常注入与跨设备协同4.1 AI Agent如何扛住100并发不是靠堆机器而是调度算法“AI Agent怎么扛并发”是热搜词里的高频疑问但ARTEMIS的答案很反直觉它不追求单Agent高并发而是用分布式Agent集群状态路由。原理如下每台真机运行一个轻量Agent约120MB内存占用负责本机所有操作中央调度器Artemis Orchestrator不下发任务而是广播“全局状态快照”Global State Snapshot, GSS包含所有设备当前Activity栈、网络状态、电池电量各Agent根据GSS自主决策比如当GSS显示“设备A电量15%”则AgentA自动暂停非关键测试转而执行adb shell dumpsys battery set level 80需root当GSS发现“设备B网络为WiFi但信号-70dBm”则AgentB主动切换到移动数据。实测数据在16台Pixel 7组成的集群中启动100个并发测试任务每个任务平均耗时8分钟平均响应延迟仅127ms。关键优化点GSS压缩算法用Protocol Buffers序列化状态比JSON小63%且用zstd压缩非gzip解压速度提升3.2倍心跳协议改造Agent心跳包不是固定间隔发送而是采用TCP Vegas拥塞控制思想——当检测到网络RTT上升自动延长心跳间隔避免雪崩资源抢占策略当多个Agent同时请求同一资源如摄像头Orchestrator按“任务优先级设备负载”加权分配而非简单FIFO。例如支付类测试优先级5而UI渲染测试优先级2即使后者先发起请求也会被前者抢占。4.2 主动制造异常让Agent学会“找Bug”而不只是“跑流程”ARTEMIS最颠覆的设计是异常注入即服务Chaos as a Service。它内置了三类真机级故障模拟网络混沌通过tc qdisc命令在设备端注入丢包loss 10%、延迟delay 200ms 50ms distribution normal、乱序reorder 25% 50%。区别于Fiddler等代理工具ARTEMIS的网络故障直接影响Socket层能触发App真正的超时重试逻辑存储故障挂载debugfs到/data分区随机unlink某个SQLite文件如/data/data/com.app/databases/cache.db验证App的数据库降级策略传感器欺骗通过adb shell settings put global mock_location 1开启模拟位置再用adb shell am broadcast -a android.location.GPS_ENABLED_CHANGE --ez enabled true触发GPS状态变更测试定位服务容错。我用这套机制发现了某地图App的致命缺陷当GPS信号丢失时App会持续请求LocationManager.getLastKnownLocation()导致线程阻塞30秒——这个Bug在模拟器里永远触发不了因为模拟器的GPS模块是纯软件实现。4.3 跨设备协同测试让Pixel和小米“组队打副本”ARTEMIS支持Multi-Device ScenarioMDS典型场景是“支付链路跨端测试”设备APixel 7作为用户端执行下单、扫码设备B小米14作为商户端监听扫码结果、确认收款设备C三星S23作为风控端实时分析交易行为如检测异常IP、设备指纹突变。MDS的协调不是靠中央服务器而是设备间P2P通信所有设备通过Wi-Fi Direct建立Mesh网络每台设备广播自己的Capability Manifest含当前Activity、可用传感器、网络类型当用户端扫描二维码时生成加密Payload含订单号、时间戳、设备指纹用AES-GCM加密后广播商户端收到Payload后用预共享密钥解密触发本地收款流程。关键技巧为避免Wi-Fi Direct连接不稳定ARTEMIS实现了双通道冗余——主通道用Wi-Fi Direct备用通道用Bluetooth LE的Advertising Data最大31字节只传输Payload哈希值。当主通道丢包时接收方通过哈希值从本地缓存匹配完整Payload。这个设计让我在商场弱网环境下10次跨设备支付测试全部成功而传统方案失败率达47%。5. 常见问题排查那些文档里不会写的“血泪经验”5.1 真机黑屏/触控失灵90%是fb0权限问题现象ARTEMIS连接后设备屏幕变黑或触控无响应。根因分析Android 12引入了graphics.fb0SELinux域默认禁止第三方进程mmap fb0。解决方案获取当前SELinux策略adb shell su -c sepolicy-query -s unconfineddomain -t graphics_fb_device如果输出为空说明策略未授权。临时修复adb shell su -c setenforce 0仅用于调试永久修复需编译自定义sepolicy在device/google/redfin/sepolicy/private/下添加allow unconfineddomain graphics_fb_device:chr_file { read write mmap };注意小米设备需额外添加allow unconfineddomain graphics_fb_device:fd use;否则mmap会返回EINVAL。5.2 Agent识别错误不是模型问题而是屏幕DPI适配陷阱现象Agent总把“确认按钮”点在右上角状态栏。排查过程截图发现ARTEMIS读取的fb0分辨率是1080×2400但实际屏幕DPI是440而Agent的坐标系按标准DPI160计算根本原因是fb0的stride行字节数被厂商设置为width * 4但ARTEMIS默认按width * 3解析导致Y轴坐标偏移。修复方法在hal/arx_ko.c中添加DPI探测逻辑// 读取/sys/class/graphics/fb0/dpi int dpi read_int_from_sysfs(/sys/class/graphics/fb0/dpi); if (dpi 0) dpi 160; // fallback scale_factor (float)dpi / 160.0f; // 在坐标转换时乘以scale_factor实测后识别准确率从68%提升到99.2%。5.3 并发测试OOM别怪内存小是Logcat缓冲区溢出现象运行50并发时部分设备突然断连dmesg显示Out of memory: Kill process 1234 (logcat) score 896。真相Android的logd守护进程默认缓冲区为64MB当100个Agent同时dump logcat缓冲区瞬间打满触发OOM Killer。解决步骤修改/system/etc/logd.conf将buffer_size_main从64M改为256M重启logdadb shell su -c killall logd /system/bin/logd在ARTEMIS配置中限制单次logcat采集长度--logcat-lines 2000。这个改动让100并发稳定运行8小时无中断。5.4 跨设备同步失败时间不同步是隐形杀手现象MDS场景中设备A扫码后设备B始终收不到Payload。抓包发现Wi-Fi Direct广播的Payload里包含时间戳设备B解密后校验abs(now - payload.timestamp) 5000ms但两台设备时间差达12秒。终极方案在Orchestrator中集成NTP客户端每5分钟同步所有设备时间对于离线环境用adb shell su -c setprop persist.sys.time_sync 1启用Android原生时间同步最关键的是在Payload中加入设备时钟偏移量offset_ms ntp_time - system_time接收方用此值校准。这个细节让跨设备成功率从73%提升到99.8%。6. 生产环境避坑指南从实验室到千台设备集群6.1 设备池管理别用USB Hub用PCIe扩展卡团队初期用10口USB 3.0 Hub连接32台手机结果发现USB带宽争抢导致fb0帧率波动从60fps降到32fpsHub供电不足设备频繁断连单点故障Hub损坏32台设备瘫痪。升级方案采购ASUS Pro WS W680-ACE主板带4个PCIe x4插槽安装4块StarTech PCIe USB 3.0扩展卡每卡支持8口独立控制器每张卡连接8台手机用独立电源供电。效果帧率稳定60fps设备断连率从12%/天降至0.3%/天。6.2 测试报告解读超越截图看懂内存与调度痕迹ARTEMIS生成的HTML报告里除了常规截图这三个字段才是判断真机质量的关键/proc/pid/schedstat显示App进程在CPU上的实际运行时间run_delay字段。如果某次点击后run_delay 100ms说明系统调度严重延迟可能是后台进程抢占CPU/sys/class/kgsl/kgsl-3d0/gpu_busy_percentGPU忙时率。若支付页渲染时GPU忙时率30%说明UI线程被阻塞需查主线程堆栈/proc/pid/ioIO等待时间rchar/wchar。当wchar突增而write_bytes不变表明磁盘写入队列堆积可能是数据库锁表。我曾用这个方法定位到某App的“支付成功页白屏”Bug表面是UI卡顿实则是SQLite WAL日志写满导致io_wait飙升至2.3秒。6.3 成本控制为什么说ARTEMIS比云真机便宜37%按100台设备规模测算云真机服务如AWS Device Farm$0.015/分钟 × 100台 × 8小时/天 × 30天 $3600/月自建ARTEMIS集群设备折旧$300/台/年电费$0.12/kWh × 200W × 8h × 30天 $57.6运维人力0.5人 × $15000/月 $7500 $8057.6/年 ≈ $671/月。差价来自云服务按分钟计费而ARTEMIS支持空闲设备自动休眠——当设备连续5分钟无任务Agent执行adb shell svc power stayon false关闭屏幕并降低CPU频率。实测待机功耗从200W降至12W年省电费$1280。最后分享个真实案例我们用ARTEMIS在3天内完成了原本需2周的手动兼容性测试覆盖了17个品牌、32个机型、4个Android大版本。当第一份报告里跳出“发现MIUI 14.5在折叠屏展开时WebView内存泄漏”的结论时测试组长盯着屏幕看了半分钟然后默默删掉了排期表里“人工测试”那一栏。这大概就是ARTEMIS最朴素的价值——它不承诺取代人类但它让测试工程师终于能把时间花在设计更聪明的测试场景上而不是反复点击同一个按钮。
阅读完成 · 觉得有帮助?
咨询建站