


























MAI-UI是阿里通义实验室发布的一项重磅研究成果:是一个旨在 重塑人机交互方式 的“基础图形用户界面(GUI)智能体”,和阶跃星辰的思路非常类似,因此我们可以互相印证。
MAI-UI的信息如下:
https://arxiv.org/pdf/2512.22047
https://github.com/Tongyi-MAI/MAI-UI
MAI-UI的MCP工具使用的两大好处为:
MAI-UI是原生设备-云协作系统,阶跃星辰也是端-云协同,豆包应该也是类似方式。

MAI-UI也使用MCP来应对现实挑战。
ask_user 动作:当指令模糊时(如“把最近的文件发给他”,缺收件人和文件),MAI-UI会主动暂停,生成一个提问动作,向用户请求澄清。mcp_call 动作:MAI-UI可以调用外部工具(通过Model Context Protocol, MCP)。例如,比较两个地址的开车时间,不需要在地图App里手动输入,直接调用“高德地图API”即可;在手机上查询GitHub提交历史,也只需一个API调用。下图为MCP的动作空间。

两类核心Agent如下:
| Agent | 文件 | 任务 | 输出协议 |
|---|---|---|---|
| MAIGroundingAgent | src/mai_grounding_agent.py | UI 元素定位(单步) | <grounding_think>.</grounding_think> |
| MAIUINavigationAgent | src/mai_navigation_agent.py | 多步移动端GUI导航,支持ask_user与mcp_call |
整体架构图如下:

关键约束如下:

为什么 MAI-UI 要把 MCP 拉进来?这是为了解决 GUI Agent 的三个老大难
| 问题 | 纯 GUI 路径的痛点 | MCP 给出的解法 |
|---|---|---|
| 效率 | 查个公交路线要点 5-10 屏 | 一次 mcp_call("amap_route", ...) 直接拿结构化结果 |
| 能力天花板 | 模型识别能力 / 屏幕信息有限,长链路任务容易掉链子 | 把 "查询、计算、第三方业务" 外包给确定性 API |
| 数据敏感性 / 设备-云协同 | 端上小模型搞不定的专业任务必须走云 | MCP 调用本身就是云侧能力的入口;与 README 里 "Device-Cloud Collaboration" 同源 |
这就是 “Agent-user interaction and MCP augmentation :enabling agent to interact with user and use MCP tools to complete the task"。
MAI-UI 并不是MCP的实现方,而是MCP的消费方一它把外部MCP 工具的能力以“额外动作“的形式注入到prompt
里,让模型在合适的时候选择直接调工具,而不是去点屏幕。
MCP是给GUIAgent加一条“绕过屏幕“的快捷通道。
分工具体如下图,三者同级共存于同一个动作集合,由模型自主判断该用哪个。

代码中实现如下:
<tool_call>{"name":"...", arguments*:{...}}</tool_call>;下图是一次完整MCP往返的完整时序。
关键三步:模型吐 tool_call ──► 外层调真实 MCP ──► 结果作为纯文本 mcp_response 回灌下一步
predict。Agent 本身不执行网络调用,只负责传话。
要点:

问题的本质:GUI路径 VS API路径的“步数 × 单步成本“差距
GUI路径里,每一步都包含一次完整的多模态推理:
单步GUI 成本 = encode(截图)= 几千vision token
+ encode(history_n张历史截图)
+ 模型decode(<thinking>+<tool_call>)
+ 客户端反归一化坐标 + 真机点击 + 等待UI渲染 + 重新截图
而MCP调用一次的成本如下:
单次MCP成本 = encode(MCP返回JSON字符串)几十~几百token
+ 模型decode下一个动作
+ 客户端走HTTP拿结构化结果(确定性、毫秒级)
量纲上压缩比通常是10× -100× —因为一张手机截图的视觉token数 ~= 几千;而一段JSON文本 = 几百。
MCP之所以能把长UI操作压缩成少量API调用,核心是用“低成本、确定性、结构化“的文本通道替换“高成本、概率性、像素级“的视觉通道 ----- 而MAI-UI刚好通过统一tool_call语法 + 文本回灌mcp_response + 工具schema一次性渲染这三件事,从而让这种压缩在工程上自然成立、不需要额外特化的代码路径。
比如,mai_naivigation_agent.py的_build_messages():每一步都把最近history_n张截图重新base64后塞回messages。
纯GUI路径下messages体积膨胀
step 0: [sys, img0] ──► ~3k tok
step 1: [sys, img0, assto, img1] ──► ~7k tok
step 2: [sys, img0, asst0, img1, asst1, img2] ──► ~10k tok
step 3: [sys, img1, asst1, img2, asst2, img3](滑窗) ──► ~10k tok
对应公式:纯GUI完成任务N_ui × C_vision,N_ui 大、C_vision 也大,乘积爆炸。
而把同一段流程换成“GUI+MCP"以后,具体如下:
GUI+MCP路径下messages体积
step 0: [sys+MCP_tools_decl,img0]
step 1: ◄── tool_call:amap_route(...) ← 模型一次决定走MCP
step 2: [..., user(text=mcp_response_json)] ← 外层把JSON灌回
◄── tool_call:open("Notes")
step 3: [...,img_after_open_notes] ← 才需要再来一张截图
step 4: ◄── tool_call:type("行程已规划")
要点:
任务:“帮我规划:现在去招商银行取钱,再去城西银泰城;公交地铁;总时长 < 2h;把计划写进笔记App。
step 1 打开高德 screenshot ●
step 2 点搜索框 screenshot ●
step 3 键入"招商银行" screenshot ●
step 4 选最近一家 screenshot ●
step 5 点"路线" screenshot ●
step 6 切到"公交" screenshot ●
step 7 设起点 screenshot ●
step 8 读屏判断时长 screenshot ●
step 9 返回,再搜下一段 screenshot ●
step 10 ...重复5-8.. screenshot ●●●●
step 14退出高德 screenshot ●
step 15打开笔记 screenshot ●
step 16 新建 screenshot ●
step 17 输入标题 screenshot ●
step 18输入内容 screenshot ●
step 19保存 screenshot ●
__________________
~19步 x ~10k vision tok = ~190k tok
~19次模型RTT
+真机渲染等待19次
step 1 mcp_call("amap_route",
{"from":"阿里云谷",
"to":"招商银行",
"constraints":{"radius_km":4,"mode":"transit"}})
text-only ○
step 2 mcp_call("amap_route",
{"from":"招商银行",
"to":"城西银泰城",
"mode":"transit"})
text-only ○
step 3 open("Notes") screenshot ●
step 4 click(新建) screenshot ●
step 5 type(标题) screenshot ●
step 6 type(正文-把两段路线 JSON 拼起来) screenshot ●
step 7 click(保存) screenshot ●
__________________
7 步;仅 5 张截图
≈ 5 × 10k + 2 × 0.5k = ~51k tok
+ 2 次 HTTP RTT
+ 真机渲染等待 5 次
节省:步数 19→7 (-63%),视觉 token 190k→50k (-73%),决策延迟同比下降。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。