【GUI-Agent】阶跃星辰 GUI-MCP 解读---(4)---GUI-MCP 整体架构
【GUI-Agent】阶跃星辰 GUI-MCP 解读---(4)---GUI-MCP 整体架构
0x00 摘要
25年底,阶跃星辰升级发布了全新的AI Agent系列模型Step-GUI,包括云端模型Step-GUI、首个面向GUI Agent的MCP协议:GUI-MCP(Graphical User Interface - Model Context Protocol),这是首个专为图形用户界面自动化而设计的 MCP 实现,兼顾标准化与隐私保护。因此,我们就来解读这个MCP协议,顺便看看端侧Agent的实现架构。
本文是第四篇,主要是介绍GUI-MCP 整体架构。
因为是反推解读,而且时间有限,所以可能会有各种错误,还请大家不吝指出。
0x01 GUI-MCP
1.1 MCP
在Function Calling的框架下,每个既有系统都需要单独集成到应用中。每个组织或公司都有自己的API、认证方式、数据格式,开发者需要为每个组织或公司编写对应的函数实现。这就是MCP产生的原因:提供一个服务,可以让既有系统快速集成到LLM中。
MCP(Model Context Protocol)是一种用于规范大模型与外部能力交互方式的协议。如果说 Tools 解决的是“模型如何调用一个函数”,那么 MCP 解决的是“模型如何与一个长期存在、可复用的能力服务交互”。
MCP的核心是解决与既有系统的接驳问题,MCP的价值在于它提供了一套标准化的接驳协议,让不同的工具和数据源能够以统一的方式被LLM使用。本质上,MCP更偏重是一套接驳标准(只是在Function Calling的基础上,增加了一层JSON-RPC协议转换),而不是唯一的接驳方式。
或者说,MCP 更像是 API,Agent 只关心提交什么「参数」、得到什么「结果」。
1.2 需求
尽管大语言模型进展显著,其在 GUI 自动化中的应用仍因缺乏跨平台设备控制的标准化接口而受阻。现有方案往往平台限定,且与不同语言模型及设备集成需大量工程投入。一个强大的GUI模型训练出来后,如何让各种大模型都能方便、安全地使用它来控制设备?
为弥补这一缺口,StepFun团队借鉴了“模型上下文协议(MCP)”的思想,提出了 GUI-MCP(Graphical User Interface - Model Context Protocol),这是首个专为 GUI 操作任务设计的 MCP 实现。它像一个翻译器和安全过滤器,标准化了LLM与设备间的交互。
GUI-MCP 提供标准化工具包,无缝连接多种语言模型与多设备平台(Ubuntu、macOS、Windows、Android、iOS),使语言模型能通过统一协议控制移动与桌面设备,执行 GUI 操作任务。
1.3 差异化优势
GUI-MCP 的差异化优势如下:
- 针对移动设备控制的专门优化设备管理:
- GUI-MCP 提供了专门的工具来管理连接的移动设备,如
list_connected_devices()函数屏幕操作 - 专门设计了处理移动设备屏幕交互的工具,包括截图、点击、滑动等操作应用控制
- 针对移动应用的唤醒、控制和状态管理进行了优化
- GUI-MCP 提供了专门的工具来管理连接的移动设备,如
- GUI Agent 集成任务执行:
- GUI-MCP 通过
ask_agent()工具提供专门的 GUI 代理任务执行能力会话管理 - 支持任务会话的开始、继续和恢复,特别适合长时间的 GUI 操作任务交互处理
- 内置了对 INFO 操作的处理机制,允许代理在需要用户输入时暂停并等待反馈
- GUI-MCP 通过
- 移动设备特定功能状态检测:
- 集成了屏幕状态检测、设备方向检测等移动设备特有的功能多设备支持
- 支持同时管理多个设备,可以将任务分发到不同设备上
- 丰富的参数控制详细配置:
- 提供了丰富的参数来控制任务执行过程,如
enable_intermediate_logs、enable_intermediate_image_caption等错误处理 - 内置了对设备状态、屏幕方向等的检测和处理机制通用性与精确性的权衡可能牺牲通用性领域特定
- 提供了丰富的参数来控制任务执行过程,如
0x02 示例
以下是代码示例。这段代码是基于 fastmcp 库实现的异步客户端程序,核心功能是连接本地运行的 MCP服务,代码使 Client 异步连接到本地 MCP 服务器(http://localhost:8704/mcp),完成两个核心操作:
- 列出服务端支持的所有工具(
list_tools); - 定义了调用
ask_agent工具执行指定任务的异步函数;
整体采用 Python 异步编程范式(asyncio),适配 MCP 服务的异步通信特性。
import asyncio
from fastmcp import Client
client = Client("http://localhost:8704/mcp")
import json
from tqdm import tqdm
async def ask_agent(task: str):
async with client:
result = await client.call_tool("ask_agent", {"task": task, "reset_environment": False, "kill_app_when_awake": False, "max_steps": 1})
print(result)
# async
async def async_list_tools():
async with client:
tools = await client.list_tools()
print("Supported tools:\n", json.dumps(tools, indent=4, ensure_ascii=False))
asyncio.run(async_list_tools())
具体业务逻辑如下:
依赖导入与客户端初始化
import asyncio:导入 Python 内置的异步 I/O 库,是实现异步编程的核心依赖,用于管理异步任务、事件循环等。from fastmcp import Client:从fastmcp库导入Client类,fastmcp是适配 MCP 协议的客户端 / 服务端工具库,Client用于创建与 MCP 服务端通信的客户端实例。client = Client("http://localhost:8704/mcp"):创建 MCP 客户端实例,指定服务端地址为http://localhost:8704/mcp(本地 8704 端口的 MCP 服务接口)。import json:导入 JSON 处理库,用于格式化输出工具列表(美化打印)。from tqdm import tqdm:导入进度条库,但代码中未实际使用,属于冗余导入(可删除)。
调用 ask_agent 工具
以下是定义调用 ask_agent 工具的异步函数
async def ask_agent(task: str):定义异步函数ask_agent,接收一个字符串类型的参数task(表示要执行的任务)。async关键字标识这是异步函数,可在内部使用await调用其他异步操作。async with client::异步上下文管理器,自动管理客户端的连接生命周期(自动建立 / 关闭连接),避免手动处理连接的创建与释放,是fastmcp.Client推荐的使用方式。await client.call_tool(...)await:等待异步操作完成(此处是等待服务端返回调用结果),只能在异步函数内使用。client.call_tool:调用 MCP 服务端的指定工具,参数说明:- 第一个参数
"ask_agent":要调用的服务端工具名称(MCP 服务端需预先注册该工具)。 - 第二个参数(字典):调用工具的入参,包含 4 个关键配置:
"task": task:传递具体的任务内容(由函数参数task传入)。"reset_environment": False:调用工具时不重置运行环境(如 Agent 的上下文、运行的应用等)。"kill_app_when_awake": False:唤醒 Agent 时不终止已运行的应用。"max_steps": 1:限制 Agent 执行任务的最大步骤数为 1(仅执行一步操作)。
- 第一个参数
print(result):打印服务端返回的ask_agent工具调用结果。
列出服务端所有工具
以下是定义列出服务端所有工具的异步函数
-
async def async_list_tools():定义异步函数async_list_tools,无入参,用于获取并打印服务端支持的所有工具列表。 -
async with client:同样使用异步上下文管理器管理客户端连接。 -
tools = await client.list_tools():调用list_tools异步方法,获取服务端注册的所有工具信息(返回值通常是包含工具名称、描述、入参等的列表 / 字典)。 -
json.dumps(tools, indent=4, ensure_ascii=False):格式化 JSON 输出:
indent=4:缩进 4 个空格,让输出更易读。ensure_ascii=False:支持中文等非 ASCII 字符正常显示(避免被转义为\uXXXX格式)。
-
print(...):打印 “Supported tools:” 前缀 + 格式化后的工具列表。
执行异步任务
asyncio.run(...):启动 Python 异步事件循环,执行async_list_tools异步函数,是 Python 3.7+ 启动异步程序的标准方式。运行后会触发:连接 MCP 服务端 → 获取工具列表 → 格式化打印 → 关闭连接。
ask_agent函数仅定义未调用,若要执行,可将最后一行改为:asyncio.run(ask_agent("你的具体任务内容"))
0x03 差异
run_single_task.py(非MCP) 与 run_task_via_mcp.py 的差异如下:

详细对比分析如下。
流程和数据流的区别
-
run_single_task.py 的流程和数据流
- run_single_task.py 直接调用 evaluate_task_on_device 函数
- 创建 LocalServer 实例,直接与本地模型交互
- 数据流:用户任务 → LocalServer → ask_llm_anything → 设备执行 → 返回结果
- 任务直接在本地执行,没有中间层
-
run_task_via_mcp.py 的流程和数据流
- run_task_via_mcp.py 通过 client 连接到 MCP 服务器
- 通过 call_tool("ask_agent") 调用远程服务
- 数据流:用户任务 → Client → HTTP 请求 → MCP 服务器 → execute_task → LocalServer → ask_llm_anything → 设备执行 → 返回结果
- 任务通过 MCP 服务器间接执行
架构模式差异
- run_single_task.py 采用直接执行模式,客户端直接控制设备和模型推理
- run_task_via_mcp.py 采用服务化模式,通过 MCP 协议进行远程调用
设备管理差异
- run_single_task.py 直接调用 list_devices 获取设备列表,并选择第一个设备
- run_task_via_mcp.py 通过 MCP 服务器的 list_connected_devices 工具函数获取设备列表
服务器初始化对比
- run_single_task.py 直接创建 LocalServer 实例
- run_task_via_mcp.py 通过 HTTP 连接到已运行的 MCP 服务器
错误处理差异
- run_single_task.py 的错误处理在本地
- run_task_via_mcp.py 的错误处理分布在客户端和服务器端
任务执行函数对比
- run_single_task.py 使用 evaluate_task_on_device 直接执行。evaluate_task_on_device 在 run_single_task.py 中直接调用 LocalServer.automate_step
- run_task_via_mcp.py 通过 client.call_tool("ask_agent", …) 间接执行。run_task_via_mcp.py 中的调用链为:client.call_tool → Mcp 服务器的 ask_agent 函数 → execute_task → gui_agent_loop
0x04 GUI-MCP 整体架构
4.1 LLM 与 MCP 的交互模式
MCP 本质是「标准化能力调用协议 / 服务」,LLM 是「语义理解与决策核心」,Agent 是「统筹执行的主体」,
- Agent:是 “执行者 / 统筹者”,可发起请求,但不必然是必须的(模式 3 可无独立 Agent);
- LLM:是 “决策 / 语义核心”,负责理解意图、判断是否需要调用 MCP 能力;
- MCP:是 “标准化能力载体”,不做决策,只负责执行具体操作或封装 LLM 调用。
三者的角色组合决定了交互方式。
个人能想到的,LLM 与 MCP 的交互核心有 3 种模式,核心差异是「谁发起调用」和「MCP 的角色(LLM 网关 / 工具执行器)」 。这三种模式如下:
-
模式 1:Agent → LLM → MCP → 具体操作(LLM 驱动 MCP 执行工具)
- 核心逻辑:LLM 作为 “大脑” 解析 Agent 接收的用户指令,决策需要执行的具体操作(如 “打开计算器”“查询天气”),然后通过 MCP 协议调用对应的工具 / 服务执行操作,MCP Server 负责落地具体动作。
- 典型场景:智能助手(如语音助手、自动化 Agent)需根据自然语言指令执行物理操作 / 工具调用。
- 流程示例
Agent(用户指令:“计算 100+200”)→ LLM(解析意图:需调用计算器工具)→ MCP Client → MCP Server(执行计算器操作)→ 具体设备/工具(返回结果 300)→ MCP Server → LLM(整理结果)→ Agent(反馈给用户) -
模式 2:Agent → MCP → LLM(MCP 作为 LLM 调用网关)。即,Agent 调用 MCP 告知任务需求,再由 MCP 调用 LLM 完成规划的流程。这种架构结合了 Agent 的自主性、MCP 的协议标准化能力以及 LLM 的强大规划与推理能力。
- 核心逻辑:Agent 不直接对接 LLM 的异构接口,而是通过 MCP 协议调用统一的 LLM 能力,MCP Server 作为 “中间层” 封装不同 LLM 的调用逻辑。
- 典型场景:多客户端 Agent(如嵌入式设备、桌面程序)需调用 LLM,但不想适配每种 LLM 的原生 API。
- 流程示例
Agent(用户指令)→ MCP Client → MCP Server(解析协议,调用指定 LLM)→ LLM(生成响应)→ MCP Server(标准化响应)→ Agent -
模式 3:LLM 内置 MCP 能力(MCP 作为 LLM 的原生扩展),这是更深度的集成模式,MCP 能力被封装为 LLM 的 “插件 / 函数”,LLM 可直接调用 MCP 服务,无需外部 Agent 中转。
- 核心逻辑:MCP Server 注册的能力(如文件操作、设备控制)被接入 LLM 的函数调用体系,LLM 在生成响应时,可自主触发 MCP 调用。
- 典型场景:LLM 需直接执行工具操作(如 “帮我用 MCP 把文件 A 复制到文件夹 B”)。
- 流程示例
用户指令 → LLM(解析意图+触发 MCP 调用)→ MCP Server(执行文件复制)→ LLM(生成“操作完成”的响应)→ 用户
4.2 stepFunc GUI-MCP 的模式
stepFunc GUI-MCP 的模式类似第二种模式。MCP 在流程中作为对外服务接口层,介于外部客户端和内部核心执行逻辑之间,起到封装和暴露功能的作用。流程关系总结如下:
- 外部客户端(如 Chatbox)连接到 MCP 服务器 →
- MCP 服务器接收请求并调用相应工具函数 →
- MCP 后端实现处理具体业务逻辑,调用 gui_agent_loop →
- Agent 循环通过 LocalServer 与 LLM 交互得到动作指令 →
- 设备控制层(mobile_action_helper.py、pu_frontend_executor.py)执行具体操作。
这不是“纯 MCP”,而是 MCP + 内嵌 LLM 的混合架构,相当于把“规划+执行”封装在 MCP 内部。
4.3 系统架构层次
MCP 相关的系统架构层次如下:
-
外部接口层
- FastMCP 框架:提供 MCP 协议支持,实现标准化接口
- MCP Server:detailed_gelab_mcp_server.py 和 simple_gelab_mcp_server_withcaption.py 提供工具接口
- 工具定义:通过@mcp.tool装饰器定义可调用工具
- 工具接口:ask_agent、list_connected_devices、ask_agent_start_new_task、ask_agent_continue等
-
业务逻辑层(操作流程框架)
- 任务执行:
mcp_backend_implements.py中的execute_task函数处理核心逻辑 - 代理循环:
mcp_agent_loop.py实现 GUI 代理循环 - 状态管理:会话管理和任务状态跟踪
- 任务执行:
-
模型服务层
- LocalServer:
local_server.py提供本地模型服务 - LLM 交互:
ask_llm_v2.py实现与语言模型的通信 - 解析器:
parser_0920_summary.py处理动作解析
- LocalServer:
-
设备控制层
- 设备管理:
mobile_action_helper.py提供设备操作接口 - 动作执行:
pu_frontend_executor.py实现动作格式转换,执行具体动作 - ADB 接口:通过 ADB 与设备通信
- 设备管理:
4.4 数据流程图
整体数据流
- 任务输入:用户提供任务描述 → ask_agent 工具 → execute_task 函数
- 状态感知:设备截图 → 图像编码 → 模型输入消息
- 动作决策:LLM 推理 → 动作解析 → 设备操作指令
- 执行反馈:设备操作 → 状态更新 → 循环执行
详细数据流转
- 任务执行数据流
用户任务 → MCP Server → execute_task → gui_agent_loop → LocalServer → LLM 推理
-
会话管理数据流
- 会话创建:任务信息 → get_session → 会话 ID 生成
- 状态流转:截图 → 环境数据 → 模型输入 → 动作输出 → 设备操作
- 历史记录:动作序列 → 状态日志 → intermediate_logs
-
设备交互数据流
- 截图获取:capture_screenshot → 图像文件 → base64 编码
- 动作执行:解析动作 → act_on_device → ADB 命令 → 设备操作
数据流向总结:
- 外部请求:MCP客户端调用ask_agent,提供基本任务参数
- 参数处理:ask_agent处理参数后,传递给execute_task
- 配置加载:execute_task加载配置并创建LocalServer实例
- 执行循环:execute_task启动gui_agent_loop ,进入主执行循环
- 设备交互: gui_agent_loop通过LocalServer与LLM交互,获取操作指令并在设备上执行
- 结果返回:执行结果逐层向上返回给MCP客户端。

数据转换过程
-
图像数据转换
- 截图捕获:原始图像 → smart_open → 二进制数据 → base64 编码
- 图像处理:make_b64_url → 图像 URL → 模型输入格式
-
动作数据转换
- 格式转换:uiTars_to_frontend_action → 标准化动作格式
- 坐标转换:归一化坐标 → 固定坐标点 → 实际设备坐标
-
消息数据转换
- 输入构建:env2messages4ask → 多模态消息 → LLM 输入
- 输出解析:str2action → 动作对象 → 设备指令
特殊处理流程
-
INFO 动作处理
- 问题检测:检测到 INFO 动作 → reply_mode 判断处理方式
- 自动回复:auto_reply 函数 → LLM 生成回复
- 客户端处理:pass_to_client → 暂停执行等待用户输入
-
中间日志处理
- 日志启用:enable_intermediate_logs 控制中间日志记录
- 截图处理:enable_intermediate_screenshots 控制截图记录
- 图像说明:enable_intermediate_image_caption 控制图像说明生成
-
最终结果处理
- 最终截图:enable_final_screenshot 控制最终截图
- 最终说明:enable_final_image_caption控制最终图像说明
- 结果组装:各种数据 → return_log → 返回给用户
0x05 实现
5.1 关键数据结构
关键数据结构如下:
-
任务数据结构
- 任务参数:execute_task 函数参数包括任务描述、设备 ID、执行配置
- 会话信息:session_id、设备信息、任务状态
-
状态数据结构
- 环境数据:截图 URL、用户注释、设备状态
- 动作数据:动作类型、参数、坐标点、执行结果
- 日志数据:intermediate_logs、最终动作、执行结果
-
模型交互数据结构
- 输入消息:包含任务、历史、截图的多模态消息
- 输出动作:LLM 生成的动作指令和参数
- 配置参数:模型配置、解析器配置、执行参数
5.2 函数职责和层级关系
ask_agent、execute_task、gui_agent_loop 这三个函数构成了 GELab-Zero 系统的层次化架构,各自承担不同的职责。
函数职责和层级关系如下:
A[MCP层 - ask_agent] --> B[任务管理层 - execute_task]
B --> C[执行循环层 - gui_agent_loop]
详细数据流程如下:
- ask_agent(MCP 接口层)
- 职责:提供给外部 MCP 客户端的接口
- 输入参数:
- device_id: 目标设备 ID
- task: 要执行的任务描述
- max_steps: 最大执行步数
- session_id: 会话 ID(用于继续任务)
- reply_from_client: 客户端对 INFO 操作的回复
- 核心处理:
- 设置 reply_mode="pass_to_client"
- 根据是否有 task 决定是否重置环境
- 调用 execute_task 执行具体任务
- execute_task(任务管理层,注:论文中,execute_task 是高级MCP接口,但是实际上execute_task应该只是任务执行的中间管理层):
- 职责:任务执行的中间管理层,负责配置和初始化
- 输入参数:
- 所有来自 ask_agent 的参数
- reset_environment: 是否重置环境
- enable_*: 各种日志和截图选项
- reply_mode: INFO 操作处理模式
- 核心处理:
- 加载 MCP 服务配置 (mcp_server_config.yaml)
- 创建 LocalServer 实例
- 调用 gui_agent_loop 启动执行循环
- 返回执行结果
- gui_agent_loop(执行循环层)
- 职责:实际的任务执行循环
- 输入参数:
- agent_server: LocalServer 实例
- device_id: 设备 ID
- agent_loop_config: 代理循环配置
- 各种执行控制参数
- 核心处理:
- 初始化设备和屏幕
- 获取或创建会话 ID
- 进入主执行循环:
- 截图设备屏幕
- 调用 agent_server.automate_step () 获取下一个操作
- 处理 INFO 操作(根据 reply_mode)
- 在设备上执行操作
- 等待指定时间后继续循环
- 返回最终执行结果
依赖关系图如下:

5.3 模型分发
项目支持模型分发功能。架构设计允许:
- 同时使用本地模型和云端模型;
- 图像处理任务与任务规划任务使用不同模型;
- 本地模型处理图像理解任务(如图像摘要),低延迟、高隐私;
- 云端模型处理复杂任务规划和推理,推理能力强;
- 适用于本地模型图像理解性能优、云端模型推理规划更强的场景。
- 通过配置文件灵活指定各功能模块使用的模型;
- 支持混合部署策略,优化性能与成本。
5.3.1 项目架构层面的模型分发支持
模型配置分离
- 使用 model_config.yaml 统一管理不同模型
- 支持多模型提供者(本地、云端)
- 可定义不同 api_base 与 api_key 连接异构模型服务
模型调用接口统一
- ask_llm_anything 支持切换 model_provider
- 同一代码路径可调用本地或云端模型
具体配置如下:
agent_loop_config: {
# the gui agent protocol, e.g., parser_0922_summary
"task_type": "parser_0922_summary",
# the gui main model config
"model_config": {
"model_name": "gelab-zero-4b-preview",
"model_provider": "local",
"args": {
"temperature": 0.1,
"top_p": 0.95,
"frequency_penalty": 0.0,
"max_tokens": 4096,
},
# optional to resize image
"image_preprocess": {
"is_resize": True,
"target_image_size": [728, 728]
}
},
# the maximum steps for the agent loop
"max_steps": 400,
# the delay time after each action to next capture screenshot
"delay_after_capture": 2,
# debug mode if True will print more logs
"debug": False,
# reply_config:
# optional, the config for auto reply with llm
# if auto reply is enabled in the agent loop, if this config is not provided,
# the main model_config will be used for auto reply
# if provided, will use this config for auto reply
"reply_config": {
"model_config": {
"model_name": "gelab-zero-4b-preview",
"model_provider": "local",
"args": {
"temperature": 0.5,
"top_p": 0.95,
"frequency_penalty": 0.0,
"max_tokens": 512,
},
# optional to resize image
"image_preprocess": {
"is_resize": True,
"target_image_size": [728, 728]
}
}
},
# caption config:
# optional, the config for image captioning
# if image captioning is enabled in the agent loop, this config will be used
# to caption the image before sending to the model
"caption_config": {
"model_config": {
"model_name": "gelab-zero-4b-preview",
"model_provider": "local",
"args": {
"temperature": 0.5,
"top_p": 0.95,
"frequency_penalty": 0.0,
"max_tokens": 512,
},
# optional to resize image
"image_preprocess": {
"is_resize": True,
"target_image_size": [728, 728]
}
}
},
}
server_config : {
"mcp_server_port": 8704,
"log_dir": "running_log/server_log/os-copilot-local-eval-logs/traces",
"image_dir": "running_log/server_log/os-copilot-local-eval-logs/images",
"debug": False
}
5.3.2 功能模块层面的模型分发实现
在 mcp_agent_loop.py 中,图像摘要与任务规划可分离模型
调用代码位于 gui_agent_loop 中,
def gui_agent_loop(
if enable_intermediate_image_caption:
# to start a thread to caption the image while the agent is thinking
caption_result_container = {}
caption_thread = threading.Thread(
target=lambda: caption_current_screenshot( # 图像摘要
current_task=task,
current_image_url=image_b64_url,
model_config=agent_loop_config['caption_config'].get('model_config', agent_loop_config['model_config']),
result_container=caption_result_container
)
)
caption_thread.start()
# 忽略其他代码
server_return = agent_server.automate_step(payload) # 任务规划
图像处理模型
- caption_current_screenshot 生成图像摘要
- 可配置专属 caption_config 指定图像理解模型
具体摘要代码如下:
def caption_current_screenshot(current_task, current_image_url, model_config, result_container=None):
"""
Caption the current screenshot using the caption model specified in model_config.
"""
model_name = model_config['model_name']
model_provider = model_config.get('model_provider', 'eval')
messages_to_ask = [
{
"role": "user",
"content": [
{
'type': "image_url",
'image_url': {
'url': current_image_url
}
},
{
"type": "text",
"text": f"当前的任务是:{current_task}。\n请根据任务需求,详细描述出当前截图和任务相关的部分。如果有列表,请列出所有选项。"
},
]
}
]
response = ask_llm_anything(
model_provider=model_provider,
model_name=model_name,
messages=messages_to_ask,
args={
"max_tokens": 256,
"temperature": 0.5,
"top_p": 1.0,
"frequency_penalty": 0.0,
},
resize_config=model_config.get('image_preprocess', None)
)
if result_container is not None:
result_container['caption'] = response
return response
任务规划模型
- automate_step 主逻辑使用配置模型进行规划
- 通过 model_config 参数独立设置,与图像模型解耦
具体代码如下:
def automate_step(self, payload: dict) -> dict:
"""
Automate a step in the Copilot service.
"""
model_name = model_config['model_name']
model_provider = model_config.get('model_provider', 'eval')
args = model_config.get('args', {
"temperature": 0.1,
"top_p": 1.0,
"frequency_penalty": 0.0,
"max_tokens": 512,
})
response = ask_llm_anything(
model_provider=model_provider,
model_name=model_name,
messages=messages_to_ask,
args=args
)
action = parser.str2action(response)
5.3.3 配置文件中的模型分发支持
多模型配置
- mcp_server_config.yaml 定义 agent_loop_config
- 支持 model_config 与 caption_config 分别指定模型
- agent_loop_config.model_config:主任务规划
- caption_config.model_config:图像理解与摘要
灵活模型选择
- execute_task 中通过 agent_loop_config['caption_config'].get('model_config', agent_loop_config['model_config']) 实现图像处理模型可选配置
- 未单独配置 caption_config 时,回退到主模型配置
豆包手机的模型使用
从 豆包手机 - 技术分析篇 摘录豆包手机的使用如下,我们互相印证:
记忆系统架构采用了“云端理解” + “本地存储” + “向量检索”的方式。涉及到一个云端模型和若干本地Embedding模型:
云端模型“InternVL3-2B”:这是个Image-Text-to-Text模型,大小为2B。输入是文本或图像,输出文本。在豆包全局记忆中负责理解上传的图像和文字,并输出文本形式的结构化记忆摘要。
本地识别模型:主要有三个本地负责初步处理的识别模型。1,orc_service:负责orc识别,提取截图中的文字。2,on_screen_ner模型:负责在记忆存储时,识别屏幕中的实体。3,ner_name,负责在记忆检索时,识别用户查询中的实体。这里的实体是指如“人名”,“地名”,“时间”等关键词汇,这些词汇将用于向量搜索。
本地Embedding模型:有三个本地Embedding模型负责将文字或图像映射到可检索的向量空间:
- memory_text_embedding_v2:这个模型负责纯文本语义空间的映射,其输入包括orc识别的文字,两个实体模型提取出的内容,embedding_v2负责将他们映射到文本空间中合适的位置。embedding_v2在存储和检索时都会被调用。每次调用耗时约15-20ms。
- clip_image_embed:负责将图像映射到图像空间。其输入是图像,输出是该图像在图像空间中的向量表示。这个模型仅会在记忆存储时被调用,对应截图记忆的情况。每次调用耗时约280-290ms。
- clip_text_embed:负责将文本映射到图像空间。其输入是文本,输出是该文本在图像空间中的向量表示。这个模型仅会在检索时被调用,使用的场景是用文字搜图像的情况(比如:搜索我保存的那张猫的图片)。
5.4 会话状态管理
-
会话状态映射
- 会话 ID:session_id 维护任务执行状态
- 历史记录:intermediate_logs 记录执行过程
- 状态同步:确保抽象状态与设备实际状态同步
-
执行控制
- 步数控制:
max_steps参数控制执行步数 - 环境重置:
reset_environment参数控制是否重置设备环境 - 执行模式:
reply_mode参数控制 INFO 动作处理方式
- 步数控制:
5.5 参数验证机制
5.5.1 输入验证
action_assertion 函数验证:
- 验证action字典包含action_type键
- 验证action_type在允许的操作类型中
验证必需参数的存在性和类型正确性
- 坐标范围验证:所有坐标值必须在 0-1000 范围内坐标值必须为整数类型
5.5.2 任务验证
-
execute_task函数验证:验证task和session_id不能同时提供验证device_id在连接的设备列表中 -
gui_agent_loop函数验证:验证reply_mode为允许的值之一验证max_steps不超过配置的最大值
5.5.3 操作执行约束
-
环境约束
- 设备状态检查:每次操作前检查屏幕是否开启,操作前确保设备已初始化检查设备连接状态
reset_environment逻辑:为 True 时按 Home 键重置到初始状态为 True 时重新启动目标应用
-
执行约束
- 步骤限制:最大步骤数由
max_steps参数控制实际最大步骤为max_steps与配置文件中默认值的最小值 - 时间延迟:每步操作后有固定延迟时间截图捕获后有捕获延迟时间
- 步骤限制:最大步骤数由
浙公网安备 33010602011771号