惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

L
LangChain Blog
V
V2EX
爱范儿
爱范儿
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Martin Fowler
Martin Fowler
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Apple Machine Learning Research
Apple Machine Learning Research
WordPress大学
WordPress大学
有赞技术团队
有赞技术团队
宝玉的分享
宝玉的分享
Last Week in AI
Last Week in AI
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
罗磊的独立博客
小众软件
小众软件
Vercel News
Vercel News
博客园 - 司徒正美
阮一峰的网络日志
阮一峰的网络日志
V
Visual Studio Blog
J
Java Code Geeks
P
Proofpoint News Feed
MongoDB | Blog
MongoDB | Blog
B
Blog
美团技术团队
量子位

博客园_首页

Plist 二进制格式 Milvus 和 PGVector,哪个更好? OpenClaw 已过时?在 VS Code 中运行 Hermes Agent! 第30篇文章:一个大三计科生的自白 Manim如何在数学公式中完美显示中文? Docker 部署 RocketMQ 5 并发编程核心概念辨析 C#事务处理最佳实践:别再让“主表存了、明细丢了”的破事发生 CLI 是什么?为什么大厂突然集体卷命令行? 【从0到1构建一个ClaudeAgent】协作-自主Agent UIImageView 设置图片不生效的原因排查 最小二乘问题详解20:无先验约束下的增量式SFM自由网平差 痞子衡嵌入式:大话双核i.MXRT1180之XIP应用里借助MU实现可靠Flash IAP的方法 AI Chat 封装, SemanticKerne.AiProvider.Unified 已发布 Windows下右键编辑js文件无法打开记事本——在注册表中使用环境变量 在后台服务中使用 Scoped 服务,为什么总是报错? H200 安装驱动并使用sglang启动模型 wireshark 抓包Trap上报告警内容 我用 AI 辅助开发了一系列小工具(2):图片压缩工具 [A Primer On MC and CC] 2.1 Memory Consistency 1 - 指令重排序和 SC 模型 Oracle数据库SCN推进技术详解与实践指南 玩转控件:封装个带图片的Label控件 Claude Code 4.7 真正该升级的不是模型,而是你的工作流 前端小白一句话,AI 帮我做了个颜值拉满的桌面媒体播放器。当代码不再是门槛,一句话编程就是现实。 5. WorkBuddy: 小龙虾的灵魂三件套,让你的小龙虾不只是工具 SQLite 分片方案实战:三种分片策略的深度对比 告别简陋 UI!一款基于 Fluent Design 和基于 WinUI 的开源免费、现代化的 Avalonia UI 控件库 关于二进制排列组合枚举的总结 AI开发-python-LangGraph框架(3-27-LangGraph从零实现大模型智能决策工作流) ElasticSearch主分片和副本分片概念详解
【GUI-Agent】阿里通义MAI-UI 代码阅读(1)--- 总体
罗西的思考 · 2026-05-06 · via 博客园_首页

【GUI-Agent】阿里通义MAI-UI 代码阅读(1)--- 总体

0x00 摘要

MAI-UI是阿里通义实验室发布的一项重磅研究成果:是一个旨在 重塑人机交互方式 的“基础图形用户界面(GUI)智能体”,和阶跃星辰的思路非常类似,因此我们可以互相印证。

MAI-UI的信息如下:

https://arxiv.org/pdf/2512.22047

https://github.com/Tongyi-MAI/MAI-UI

0x01 特色

MAI-UI的MCP工具使用的两大好处为:

  • 将冗长的UI操作压缩为少量API调用;
  • 将传统桌面工作流(如GitHub提交查询)带入手机。

1.1 端云协同

MAI-UI是原生设备-云协作系统,阶跃星辰也是端-云协同,豆包应该也是类似方式。

  • 本地轻量Agent:常驻设备端,负责处理大多数任务,并扮演“轨迹监控员”的角色。
  • 云端强大Agent:当本地监控员发现任务执行出现偏差(如卡住、操作错误),且当前不涉及敏感隐私数据时,会触发向云端Agent的切换。
  • 关键创新:本地模型经过专门训练,不仅会执行任务,还会判断是否偏离目标,并在切换时生成一个“错误摘要”发给云端,帮助云端快速理解问题、接手完成。

MAI-UI-0.2

1.2 应对挑战

MAI-UI也使用MCP来应对现实挑战。

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

下图为MCP的动作空间。

MAI-UI-0.3

1.3 核心Agent

两类核心Agent如下:

Agent 文件 任务 输出协议
MAIGroundingAgent src/mai_grounding_agent.py UI 元素定位(单步) <grounding_think>.</grounding_think>{"coordinate":[x,y]},坐标基于 SCALE_FACT0R=999 归一化
MAIUINavigationAgent src/mai_navigation_agent.py 多步移动端GUI导航,支持ask_user与mcp_call .<tool_call>{json}</tool_call>,多轮带历史截图

1.4 整体架构图

整体架构图如下:

阿里GUI-1

关键约束如下:

  • src/内为扁平导入(from base import),调用方需把 src/插入sys.path;
  • requirements.txt(agent 客户端)与evaluation/grounding/requirements.txt(评测,含 vLLM/torch)两套独立;

1.5 评测流程图

阿里2

0x02 MCP在MAI-UI中的作用

为什么 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加一条“绕过屏幕“的快捷通道。

2.1 MCP与GUI操作的分工

分工具体如下图,三者同级共存于同一个动作集合,由模型自主判断该用哪个。

阿里3

2.2 实现

代码中实现如下:

  • 实例化 Agent 时把 工具清单(JSON-Schema 风格的列表)通过mcp_tools=[...]传进来;
  • Agent 用 Jinja2 把这份清单渲染进 system prompt的 ##MCP Tools区块;
  • 模型在某一步输出<tool_call>{"name":"...", arguments*:{...}}</tool_call>;
  • 客户端外层负责真正去调那个 MCP服务(项目本身不内嵌MCP客户端 / 不内嵌网络层)
  • 拿到结果后,把字符串结果塞到下一步 obs[mcp_response*],Agent 在_build_messages 时把它作为新的 user 消息追加。

2.3 一次完整MCP往返的时序

下图是一次完整MCP往返的完整时序。

关键三步:模型吐 tool_call ──► 外层调真实 MCP ──► 结果作为纯文本 mcp_response 回灌下一步
predict。Agent 本身不执行网络调用,只负责传话。

要点:

  • 模型对 GUI 动作和 MCP 调用使用同一种输出语法(都是<tool_call>{name,arguments}</tool_call>),客户端通过 name 是否在 mcp_tools 里来分流;
  • 工具调用的真正执行完全在仓库之外,让你想接什么 MCP 服务(高德地图、12306、淘宝、企业内网工具)都行,只要能给出 JSON-Schema 描述并自己接通网络。

阿里4

2.4 MCP如何把长的UI操作压缩为少量的API调用?

2.4.1 问题的本质

问题的本质: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文本 = 几百。

2.4.2 为什么MAI-UI恰好让这种“压缩“是天然成立的?

MCP之所以能把长UI操作压缩成少量API调用,核心是用“低成本、确定性、结构化“的文本通道替换“高成本、概率性、像素级“的视觉通道 ----- 而MAI-UI刚好通过统一tool_call语法 + 文本回灌mcp_response + 工具schema一次性渲染这三件事,从而让这种压缩在工程上自然成立、不需要额外特化的代码路径。

GUI

比如,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"以后,具体如下:

                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("行程已规划")

要点:

  • _build_messages里如果某TrajStep没有携带新screenshot而携带mcp_response,只追加一段纯文本user 消息,不会追加图片,这一步视觉token增量=0,只多几十~几百文本token。
  • mcp_tools列表只在system prompt里渲染一次,由Jinja2的[%if tools%} 控制;不会每步重发。
  • 模型用同一种<tool_call>语法统一表达GUI动作与MCP调用,所以decode 长度量级一致一压缩完全靠“省掉了一连串需要看屏幕的中间步”。

2.4.2 一张直观对比图

任务:“帮我规划:现在去招商银行取钱,再去城西银泰城;公交地铁;总时长 < 2h;把计划写进笔记App。

A. 纯 GUI 路径(无 MCP)
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次
B. GUI + MCP 路径
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%),决策延迟同比下降。

0xFF 参考

从豆包手机谈起:端侧智能的愿景与路线图

阿里发布MAI-UI,一个“活”在屏幕里的全能AI助手!手机真能全自动了?