0

AI操作手机实战:用Agent控制安卓手机自动执行任务

2026.05.24 | youres | 12次围观

AI操作手机的技术原理与价值

AI操作手机不是简单的模拟点击,而是通过计算机视觉+大语言模型+自动化框架三者结合,让AI理解屏幕内容、做出决策并执行操作。这种技术将手机从"需要人手操作工具"变成"可以对话执行的智能代理"。

  • 视觉理解:通过屏幕截图+OCR识别UI元素
  • 决策规划:LLM将用户指令分解为操作步骤
  • 精准执行:ADB/AccessibilityService执行点击、滑动、输入
  • 反馈循环:操作后重新截图,验证执行结果

技术架构深度解析

组件功能主流方案延迟
屏幕捕获获取当前界面截图ADB screencap / MediaProjection50-200ms
UI解析识别可操作元素OCR / 布局树解析100-500ms
决策引擎生成操作序列GPT-4o / Claude 3.5 / Qwen1-3s
执行层执行点击滑动输入ADB / Appium / UiAutomator10-50ms
验证层确认操作结果图像对比 / OCR验证100-300ms

环境搭建完整指南

下面是生产级环境的搭建流程,包含Windows、macOS、Linux三平台:

1. 安卓设备准备

# 开启开发者选项(各品牌略有不同)
# 小米:设置 -> 我的设备 -> 全部参数 -> 连点MIUI版本7次
# 华为:设置 -> 关于手机 -> 连点版本号7次
# OPPO:设置 -> 关于手机 -> 版本信息 -> 连点版本号7次

# 开启USB调试
设置 -> 开发者选项 -> USB调试(开启)
设置 -> 开发者选项 -> USB调试(安全设置)(开启,允许ADB修改系统)

# 连接电脑后,手机端选择"文件传输"模式,并信任电脑

2. ADB工具安装与验证

# Windows安装(使用巧克力)
choco install adb -y

# macOS安装
brew install android-platform-tools

# Linux安装
sudo apt install adb  # Ubuntu/Debian
sudo dnf install android-tools  # Fedora

# 验证连接
adb devices
# 输出应该显示设备序列号和设备状态
# List of devices attached
# 1234567890abcdef    device

# 如果显示unauthorized,需要在手机端授权

3. Python环境配置

# 创建虚拟环境
python -m venv ai_phone_env
source ai_phone_env/bin/activate  # Linux/macOS
ai_phone_envScriptsactivate  # Windows

# 安装核心依赖
pip install openai  # LLM API调用
pip install pillow  # 图像处理
pip install numpy  # 数值计算
pip install uiautomator2  # Android自动化
pip install adbutils  # ADB Python封装

# 可选:安装OCR增强
pip install paddlepaddle paddleocr  # 百度OCR
pip install pytesseract  # Tesseract OCR

核心代码实现(生产级)

下面是一个完整的AI操作手机框架实现,包含错误处理、重试机制、日志记录:

1. 屏幕捕获与UI解析模块

import adbutils
import base64
from PIL import Image
import io
import time

class ScreenCapture:
    """屏幕捕获与预处理"""
    
    def __init__(self, device_serial=None):
        self.device = adbutils.AdbClient(host="127.0.0.1", port=5037)
        if device_serial:
            self.device = self.device.device(device_serial)
    
    def capture(self, save_path=None):
        """捕获当前屏幕并返回PIL Image对象"""
        # 方法1:使用ADB screencap(速度快但可能压缩)
        screenshot_data = self.device.screencap()
        image = Image.open(io.BytesIO(screenshot_data))
        
        # 可选:转换为RGB模式(某些OCR需要)
        if image.mode != 'RGB':
            image = image.convert('RGB')
        
        # 保存(用于调试)
        if save_path:
            image.save(save_path, quality=95)
        
        return image
    
    def get_ui_hierarchy(self):
        """获取当前UI布局树(XML格式)"""
        xml_data = self.device.dump_hierarchy()
        return xml_data
    
    def find_element_by_text(self, text):
        """通过文本查找UI元素"""
        xml = self.get_ui_hierarchy()
        # 解析XML,查找包含指定文字的元素
        # 返回元素的坐标范围
        import xml.etree.ElementTree as ET
        root = ET.fromstring(xml)
        
        results = []
        for node in root.iter('node'):
            if text in node.get('text', ''):
                bounds = node.get('bounds')
                # 解析bounds格式:[left,top][right,bottom]
                import re
                match = re.search(r'[(d+),(d+)][(d+),(d+)]', bounds)
                if match:
                    left, top, right, bottom = map(int, match.groups())
                    center_x = (left + right) // 2
                    center_y = (top + bottom) // 2
                    results.append({
                        'text': node.get('text'),
                        'class': node.get('class'),
                        'center': (center_x, center_y),
                        'bounds': (left, top, right, bottom)
                    })
        
        return results

2. AI决策引擎(LLM集成)

import base64
import openai
import json
import re

class AIDecisionEngine:
    """AI决策引擎:将截图+指令转换为操作序列"""
    
    def __init__(self, api_key, base_url=None, model="gpt-4o"):
        self.client = openai.OpenAI(
            api_key=api_key,
            base_url=base_url  # 可选:使用代理或国内模型
        )
        self.model = model
    
    def analyze_screen(self, image, instruction):
        """分析屏幕截图,生成操作序列"""
        # 将图片转换为base64
        buffered = io.BytesIO()
        image.save(buffered, format="JPEG", quality=85)
        img_str = base64.b64encode(buffered.getvalue()).decode()
        
        # 构建提示词
        prompt = self._build_prompt(instruction)
        
        # 调用LLM
        response = self.client.chat.completions.create(
            model=self.model,
            messages=[
                {
                    "role": "user",
                    "content": [
                        {"type": "text", "text": prompt},
                        {
                            "type": "image_url",
                            "image_url": {
                                "url": f"data:image/jpeg;base64,{img_str}",
                                "detail": "high"
                            }
                        }
                    ]
                }
            ],
            response_format={"type": "json_object"},
            temperature=0.2  # 低温度保证稳定性
        )
        
        # 解析响应
        result = json.loads(response.choices[0].message.content)
        return result
    
    def _build_prompt(self, instruction):
        """构建提示词"""
        return f"""你是一个手机操作AI代理。你的任务是根据用户指令操作手机。

用户指令:{instruction}

请分析当前屏幕截图,生成一个操作序列来完成任务。

输出必须是一个JSON对象,格式如下:
{{
    "analysis": "对当前屏幕的分析",
    "actions": [
        {{
            "action": "click|swipe|input|wait|back|home",
            "x": 坐标x(仅click/input需要),
            "y": 坐标y(仅click/input需要),
            "text": "要输入的文字(仅input需要)",
            "direction": "up|down|left|right(仅swipe需要)",
            "distance": 滑动距离像素(仅swipe需要),
            "duration": 等待毫秒数(仅wait需要),
            "reason": "执行这个操作的原因"
        }}
    ],
    "task_complete": true/false,
    "next_instruction": "下一步建议(如果任务未完成)"
}}

注意:
1. 坐标必须基于图片的实际像素尺寸
2. 如果无法继续,请设置task_complete=true并说明原因
3. 每次只生成一个操作,不要生成整个序列
"""

3. 操作执行模块

class ActionExecutor:
    """操作执行器:将AI决策转换为ADB命令"""
    
    def __init__(self, device_serial=None):
        self.device = adbutils.AdbClient().device(device_serial)
    
    def execute(self, action):
        """执行单个操作"""
        action_type = action.get("action")
        
        if action_type == "click":
            x, y = action["x"], action["y"]
            self.device.click(x, y)
            return f"点击 ({x}, {y})"
        
        elif action_type == "swipe":
            direction = action["direction"]
            distance = action.get("distance", 500)
            # 获取屏幕大小
            size = self.device.window_size()
            start_x, start_y = size.width // 2, size.height // 2
            
            if direction == "up":
                end_x, end_y = start_x, start_y - distance
            elif direction == "down":
                end_x, end_y = start_x, start_y + distance
            elif direction == "left":
                end_x, end_y = start_x - distance, start_y
            elif direction == "right":
                end_x, end_y = start_x + distance, start_y
            
            self.device.swipe(start_x, start_y, end_x, end_y, duration=0.3)
            return f"滑动 {direction} {distance}像素"
        
        elif action_type == "input":
            text = action["text"]
            # 先点击输入框(假设坐标已提供)
            if "x" in action and "y" in action:
                self.device.click(action["x"], action["y"])
                time.sleep(0.3)
            # 输入文本
            self.device.send_keys(text)
            return f"输入文字: {text}"
        
        elif action_type == "wait":
            duration = action.get("duration", 1000) / 1000.0
            time.sleep(duration)
            return f"等待 {duration}秒"
        
        elif action_type == "back":
            self.device.back()
            return "按返回键"
        
        elif action_type == "home":
            self.device.home()
            return "按Home键"
        
        else:
            raise ValueError(f"未知操作类型: {action_type}")

4. 主控制循环

class AIPhoneAgent:
    """AI手机操作代理:完整任务执行框架"""
    
    def __init__(self, api_key, device_serial=None):
        self.capture = ScreenCapture(device_serial)
        self.engine = AIDecisionEngine(api_key)
        self.executor = ActionExecutor(device_serial)
        self.max_steps = 20  # 防止无限循环
        self.log_file = open("ai_agent_log.txt", "a", encoding="utf-8")
    
    def run_task(self, instruction):
        """执行完整任务"""
        self._log(f"开始任务: {instruction}")
        
        step = 0
        while step < self.max_steps:
            self._log(f"
=== 步骤 {step+1} ===")
            
            # 1. 捕获屏幕
            self._log("捕获屏幕...")
            screenshot = self.capture.capture(f"screenshot_step_{step}.jpg")
            
            # 2. AI分析决策
            self._log("AI分析中...")
            decision = self.engine.analyze_screen(screenshot, instruction)
            
            self._log(f"分析: {decision.get('analysis', 'N/A')}")
            
            # 3. 检查任务是否完成
            if decision.get("task_complete", False):
                self._log("任务完成!")
                break
            
            # 4. 执行操作
            actions = decision.get("actions", [])
            if not actions:
                self._log("AI未返回操作,任务可能无法继续")
                break
            
            action = actions[0]  # 每次只执行一个操作
            self._log(f"执行: {action.get('reason', 'N/A')}")
            
            try:
                result = self.executor.execute(action)
                self._log(f"结果: {result}")
            except Exception as e:
                self._log(f"错误: {str(e)}")
                # 重试或跳过
                break
            
            # 5. 等待界面响应
            time.sleep(1.5)
            
            step += 1
        
        if step >= self.max_steps:
            self._log(f"达到最大步骤 {self.max_steps},强制停止")
        
        self.log_file.close()
    
    def _log(self, message):
        """记录日志"""
        timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
        log_line = f"[{timestamp}] {message}"
        print(log_line)
        self.log_file.write(log_line + "
")

实战案例:自动刷短视频

下面是用上述框架实现的一个实战案例:自动刷抖音/快手,并自动点赞、评论:

def auto_scroll_short_video(instruction="打开抖音,刷10个视频,每个视频点赞并评论'好看'"):
    """自动刷短视频"""
    
    agent = AIPhoneAgent(api_key="your-api-key")
    
    # 步骤1:打开App(假设已经在主屏幕)
    # 这里需要先用传统自动化点击App图标
    # 或者使用Appium等工具启动
    
    # 步骤2:开始任务
    agent.run_task(instruction)
    
    # 扩展:添加更多智能判断
    # - 检测是否出现广告,自动跳过
    # - 检测视频内容,根据内容决定是否点赞
    # - 使用OCR识别评论区,生成更智能的评论

# 使用
if __name__ == "__main__":
    auto_scroll_short_video()

常见问题与解决方案

问题原因解决方案
ADB设备未授权手机未信任电脑手机端点击"允许USB调试"
截图黑屏App禁止截图使用MediaProjection API(需要悬浮窗权限)
坐标点击不准确屏幕分辨率变化使用UI布局树获取元素中心坐标
LLM响应慢网络延迟或模型负载高使用国内模型API(通义千问、文心一言)
操作失败率高缺少等待时间每个操作后增加1-2秒等待
被App检测为机器人操作过于规律添加随机延迟、随机滑动轨迹

高级技巧:提升稳定性与隐蔽性

  • 随机化操作:点击位置添加±5像素随机偏移,滑动速度随机化
  • 人类行为模拟:使用贝塞尔曲线模拟真实滑动轨迹
  • 多模态验证:结合OCR+图像识别验证操作结果
  • 异常恢复:检测ANR、崩溃对话框并自动处理
  • 批量任务队列:将多个任务加入队列,AI自动调度执行

相关资源推荐

AI操作手机是AI Agent技术的重要应用场景。通过本文的实战指南,你应该能快速搭建自己的AI手机操作代理,并实现复杂的自动化任务。如果遇到问题,欢迎在评论区交流讨论。

版权声明

本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论
883文章数 0评论数
作者其它文章