1. 项目概述:Open-AutoGLM 技术架构解析
Open-AutoGLM 是一个将智能手机作为"可视化GUI环境"的自动化代理框架。它的核心创新点在于将传统的UI自动化测试工具与多模态大模型相结合,构建了一个完整的"感知-决策-执行"闭环系统。这个框架最吸引我的地方在于它巧妙地将设备控制、屏幕理解和AI决策三个独立领域的技术栈融合成了一个有机整体。
在实际应用中,这个框架可以完成诸如"帮我发微信红包给张三200元"、"在美团外卖点一份宫保鸡丁"等需要多步骤交互的复杂任务。与传统的基于规则或坐标点击的自动化工具不同,Open-AutoGLM通过大模型的视觉理解和逻辑推理能力,实现了对手机界面的语义级操作。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心架构与实现原理
2.1 系统分层设计
整个系统采用典型的分层架构,从上到下分为:
- 设备交互层:通过ADB/HDC协议与手机建立连接
- 状态感知层:获取屏幕截图和当前应用上下文
- 模型服务层:处理多模态输入并生成决策指令
- 动作执行层:将抽象指令转换为具体设备操作
这种分层设计使得每个模块都可以独立演进。例如更换模型服务提供商时,只需确保接口兼容,其他层代码几乎不需要修改。
2.2 核心工作流程
系统运行时会持续执行以下循环:
- 通过ADB获取当前屏幕截图(PNG格式)
- 解析当前前台应用信息(包名、Activity等)
- 构建包含文字描述和图像的多模态提示
- 将提示发送给大模型并获取响应
- 解析模型输出的结构化指令
- 将指令转换为ADB命令并执行
- 等待下一轮状态采集
这个循环会一直持续,直到模型输出finish()指令或达到最大迭代次数。
3. 关键技术实现细节
3.1 设备控制技术栈
Android设备控制主要依赖ADB(Android Debug Bridge)协议。框架中对常用操作进行了高级封装:
python复制class AndroidController:
def get_screenshot(self):
# 使用adb screencap命令获取屏幕截图
subprocess.run(["adb", "shell", "screencap", "-p", "/sdcard/screen.png"])
subprocess.run(["adb", "pull", "/sdcard/screen.png", "local.png"])
return Image.open("local.png")
def tap(self, x, y):
# 执行点击操作
subprocess.run(["adb", "shell", "input", "tap", str(x), str(y)])
对于HarmonyOS设备,则使用HDC(HarmonyOS Device Connector)协议,接口设计类似但底层命令有所不同。
3.2 多模态提示构建
系统提示(system prompt)的设计尤为关键,它需要:
- 明确可用的动作类型及其参数格式
- 定义任务完成的判定条件
- 包含常见问题的处理策略
一个简化的提示模板如下:
code复制你是一个手机操作助手,可以执行以下动作:
- do(action="Tap", element=[x,y]) 点击屏幕坐标
- do(action="Swipe", start=[x1,y1], end=[x2,y2]) 滑动操作
- do(action="Type", text="内容") 文本输入
- finish(message="结果") 任务完成
当前任务:{user_task}
请先思考要做什么,然后输出<think>...</think>,最后在<answer>中给出要执行的动作。
3.3 模型响应解析
模型输出通常包含思考过程和执行指令两部分:
code复制<think>
需要先打开微信,然后点击"+"图标,选择"红包"功能
</think>
<answer>
do(action="Launch", app="com.tencent.mm")
</answer>
框架使用AST(抽象语法树)安全地解析这些指令,避免直接eval带来的安全风险:
python复制def parse_action(action_str):
try:
# 使用ast.literal_eval安全解析
action_dict = ast.literal_eval(action_str[3:-1]) # 去掉do()外壳
return Action(
type=action_dict["action"],
params={k:v for k,v in action_dict.items() if k != "action"}
)
except (SyntaxError, ValueError) as e:
raise InvalidActionError(f"无法解析动作: {action_str}") from e
4. 模型服务集成方案
4.1 云端API集成
对于使用云端模型服务的情况,框架设计了一个通用的OpenAI兼容接口:
python复制class OpenAIClient:
def __init__(self, api_key, base_url="https://api.openai.com/v1"):
self.client = OpenAI(api_key=api_key, base_url=base_url)
def chat_completion(self, messages, model="gpt-4-vision-preview"):
response = self.client.chat.completions.create(
model=model,
messages=messages,
stream=True
)
return response
这种设计使得可以轻松切换不同的模型提供商,只要它们支持相同的API接口。
4.2 本地模型部署
对于需要离线运行的场景,框架支持通过vLLM或SG-lang部署本地模型:
-
vLLM部署:适合拥有NVIDIA GPU的环境
bash复制
python -m vllm.entrypoints.api_server \ --model mistralai/Mixtral-8x7B-Instruct-v0.1 \ --dtype half \ --gpu-memory-utilization 0.9 -
SG-lang部署:更适合CPU或边缘设备
bash复制
./server -m ../models/mistral-7b-instruct-v0.1.Q4_K_M.gguf \ -c 2048 \ --port 8080
本地部署时,只需将API endpoint指向本地服务地址即可:
python复制client = OpenAIClient(api_key="none", base_url="http://localhost:8080/v1")
5. 上下文管理与多轮对话
5.1 对话历史维护
为了实现连贯的多步操作,框架维护了一个对话上下文:
python复制class Conversation:
def __init__(self, system_prompt):
self.messages = [{"role": "system", "content": system_prompt}]
def add_user_message(self, content, image=None):
msg = {"role": "user", "content": content}
if image:
msg["images"] = [image]
self.messages.append(msg)
def add_assistant_message(self, content):
self.messages.append({"role": "assistant", "content": content})
这种设计使得模型能够记住之前的操作步骤,做出更连贯的决策。
5.2 长上下文处理策略
随着对话轮次增加,上下文会不断膨胀。框架实现了多种优化策略:
- 关键信息摘要:定期用模型生成对话摘要
- 滑动窗口:只保留最近N条消息
- 分层存储:将历史操作记录存入数据库,只在提示中引用关键信息
6. 性能优化与工程实践
6.1 响应延迟优化
在实际使用中,我发现几个关键优化点:
-
截图压缩:将截图从PNG转换为JPEG,质量设置为75%,体积可减少80%
python复制def compress_image(img): buffered = io.BytesIO() img.save(buffered, format="JPEG", quality=75) return base64.b64encode(buffered.getvalue()).decode() -
流式处理:模型响应采用流式接收,可以边生成边解析
python复制for chunk in response: delta = chunk.choices[0].delta.content if delta: buffer += delta if "</answer>" in buffer: return parse_complete_action(buffer) -
操作预判:对于连续点击操作,可以预先加载下一个可能的点击位置
6.2 错误处理与重试机制
可靠的自动化系统需要完善的错误处理:
-
超时控制:每个步骤设置合理超时
python复制@retry(stop_max_attempt_number=3, wait_fixed=2000) def safe_adb_command(cmd, timeout=5): return subprocess.run(cmd, timeout=timeout, check=True) -
状态验证:执行操作后检查预期变化
python复制def verify_tap(x, y): before = get_screenshot() tap(x, y) after = get_screenshot() return not image_similar(before, after) -
异常恢复:当检测到应用崩溃时自动重启
7. 安全与权限考量
7.1 设备访问安全
- ADB授权管理:自动处理USB调试授权
- 权限最小化:只请求必要的shell权限
- 操作沙盒:在隔离环境中执行高风险命令
7.2 模型指令安全
-
指令白名单:只允许预定义的安全操作
python复制ALLOWED_ACTIONS = {"Tap", "Swipe", "Type", "Launch", "Finish"} def validate_action(action): if action.type not in ALLOWED_ACTIONS: raise SecurityError(f"禁止的操作类型: {action.type}") -
参数范围检查:验证坐标是否在屏幕范围内
-
敏感操作确认:对于发送消息等操作要求二次确认
8. 扩展与定制方案
8.1 自定义动作扩展
开发者可以通过继承基类来添加新动作类型:
python复制class ScrollAction(Action):
TYPE = "Scroll"
def execute(self, device):
device.swipe(
self.params["start_x"],
self.params["start_y"],
self.params["end_x"],
self.params["end_y"]
)
# 注册新动作类型
ActionRegistry.register(ScrollAction)
8.2 领域特定优化
针对不同应用可以定制专用提示词。例如微信操作提示:
code复制你正在操作微信,特别注意:
1. 红包功能在"+"→"红包"
2. 聊天列表向右滑动可标记为已读
3. 发送图片前需要先点击"+"→"相册"
8.3 多设备协同
框架架构支持扩展为多设备控制:
python复制class MultiDeviceController:
def __init__(self, devices):
self.devices = devices
def distribute_task(self, task):
# 根据设备能力分配任务
for device in self.devices:
if device.can_handle(task):
return device.execute(task)
9. 实际应用案例
9.1 电商比价自动化
实现自动打开多个购物App,搜索同一商品并比较价格:
- 依次打开淘宝、京东、拼多多
- 在每个App中搜索目标商品
- 解析商品页面获取价格信息
- 汇总比较结果
9.2 社交媒体管理
自动化执行:
- 定时发布预设内容
- 自动回复常见评论
- 分析互动数据生成报告
9.3 无障碍辅助工具
为视障用户提供:
- 屏幕内容语音播报
- 语音指令操作系统
- 智能界面导航
10. 开发实践建议
经过多个项目的实践,我总结出以下几点经验:
- 逐步验证:先手动构造几个典型场景的提示-响应对,确保模型理解基本操作
- 日志详尽:记录完整的决策过程,便于问题排查
- 测试覆盖:为每个动作类型编写单元测试
- 性能基线:建立关键指标的基准值(如单步耗时)
- 用户反馈:设计机制让用户可以纠正错误操作
一个实用的调试技巧是在本地保存每个步骤的截图和模型响应:
python复制def debug_step(step, screenshot, prompt, response):
step_dir = f"debug/step_{step}"
os.makedirs(step_dir, exist_ok=True)
screenshot.save(f"{step_dir}/screen.png")
with open(f"{step_dir}/prompt.txt", "w") as f:
f.write(prompt)
with open(f"{step_dir}/response.txt", "w") as f:
f.write(response)
11. 常见问题与解决方案
11.1 模型不理解界面元素
现象:模型无法正确识别可操作元素
解决:
- 在提示中添加更详细的界面描述
- 提供相似界面的few-shot示例
- 使用OCR提取文字信息辅助定位
11.2 操作执行后状态未更新
现象:点击后界面无变化
解决:
- 增加操作后延迟
- 实现变化检测机制
- 添加显式等待条件(如等待某元素出现)
11.3 复杂任务中途迷失
现象:多步操作后模型忘记初始目标
解决:
- 定期重申任务目标
- 使用子任务分解
- 维护任务堆栈跟踪进度
12. 架构演进方向
从工程角度看,Open-AutoGLM架构还可以进一步优化:
- 分布式执行:将Agent部署在边缘设备,减少延迟
- 混合决策:结合规则引擎与模型决策
- 主动学习:从用户纠正中持续改进
- 视觉编码器:专用模型提取屏幕特征
- 操作记忆库:建立可复用的操作模式库
一个有趣的扩展方向是引入强化学习来优化决策策略:
python复制class RLPolicy:
def __init__(self):
self.q_table = defaultdict(float)
def select_action(self, state):
# 基于学习到的策略选择动作
return max(self.actions, key=lambda a: self.q_table[(state, a)])
def update(self, state, action, reward):
# 更新Q值
self.q_table[(state, action)] += 0.1 * (
reward + 0.9 * max(self.q_table[(new_state, a)] for a in self.actions)
- self.q_table[(state, action)]
)
这种架构演进将使系统能够从经验中学习,逐步减少对提示工程的依赖。
