LayoutSee · 深度介绍

你的 AI 会写代码,
却连一个按钮都点不准

截图只能让它「看见」界面,View 树才能让它「摸到」控件。这是我做 LayoutSee 的原因。
一个 macOS 上的 Android 布局工作台 + MCP 服务:把真机视图树交给 Claude、Cursor、Comate,让 Agent 从「猜」变成「查」。

01先讲一个翻车现场

如果你试过让 Agent 操作真机,大概率见过这个画面。

任务很简单:「打开 App,搜索机械键盘,把第一个商品加入购物车」。

Agent 截了张图,模型盯着图看了三秒,说按钮在 (860, 2140),然后点了下去。屏幕上弹出了「猜你喜欢」的广告页。

为什么?因为就在两秒前,那个位置还是「加入购物车」,现在被一个运营弹窗盖住了。

真正可怕的是后半段:Agent 并不知道自己点空了。它继续截图,继续分析,继续一本正经地编下一步。

报错不可怕,可怕的是它以为自己成功了。

这不是模型不够聪明。把一张 1080×2400 的截图压缩成视觉 token 之后,那个 40×40 的关闭图标可能只剩十几个 token;模型再强,也没法从像素里凭空读出「这个控件叫 close,可点击,热区只有 24dp」。

02截图这条路,天生有三个坑

第一,坐标是猜的。 模型看图估像素,屏幕一缩放、分辨率一换、状态栏高度一变,坐标就漂。你以为是 10px 误差,实际点到了隔壁的 banner。

第二,界面是动的。 弹窗、骨架屏、运营位、键盘弹起、列表懒加载——你截的那一帧,永远只是过去。

第三,语义是缺的。 截图里没有 resource-id,没有父子层级,没有 clickable,也没有 bounds。模型只能从「长什么样」反推「是什么」,而这两件事在 UI 里经常对不上。

维度截图 + 视觉模型View 树 + MCP
元素身份靠识别,文案一改版就漂resource-id / 类名 / 层级,确定
坐标模型估,缩放即漂bounds 上报,ref 直点中心
遮挡判断基本靠猜诊断给出涉及节点与证据
上下文成本一张图几千 token,小字还看不清语义摘要默认 1200 token 预算
失败反馈常常「看起来成功了」显式错误码,过期就报错

于是所有人都在做同一件事:给模型更多截图、更多标注、更多 prompt,试图用视觉把结构「猜」出来。

但结构本来就在那里。

03Android 早就把答案放在那了

一行 uiautomator dump,就能拿到当前页面的 View 树 XML:每个节点的文本、resource-id、类名、坐标、是否可点击、父子关系,全都有。

那为什么大家不用?

因为原始 XML 是给机器看的,不是给模型看的:

所以真正的缺口从来不是「有没有 View 树」,而是:View 树离 Agent 能用的接口,还差一整个工程层。

04LayoutSee 就干这一件事

这两年,MCP 已经成了 Agent 接工具的事实标准。数据库、浏览器、文件系统都有了像样的接口,但轮到你手机里的 App,大多数方案还停在「截个图,让模型自己看」。

LayoutSee 补的就是这一块。

一句话:把 Android 运行时视图树,工程化成 Agent 能直接调用的 MCP 工具;顺便,给人类一张能看的工作台。

它也不是又一个 Appium 客户端:Appium 面向脚本和测试用例,要先写驱动逻辑;LayoutSee 面向 Agent 的即时决策——抓一次、找一次、点一次,不需要预先编排。同一套能力,人在工作台里也能直接用。

架构也不复杂:macOS 桌面端 + 本地 Core(Python,默认监听回环地址)+ 每台在线设备一个独立的 MCP 端点。手机通过 adb 接入,投屏走 scrcpy。Agent 和你在同一个 Core 上,看的是同一份快照。

LayoutSee 工作台:左边投屏,中间属性,右边 View 树,点哪儿查哪儿
工作台:左边投屏,中间属性,右边 View 树,点哪儿查哪儿。

05五步闭环:抓、读、找、点、验

这 12 个工具(9 读 3 写)不是为了凑数,它们刚好对应一个完整的操作闭环。

  1. 抓 —— capture_layout冻结页面、dump 视图树、截图、建索引,一次原子完成,返回 snapshotId。不是「先 dump 再截图」那种会错位的做法。
  2. 读 —— get_layout_summary / get_layout先看骨架,再按需深入。语义摘要是确定性生成的:同样的输入,永远同样的输出。实测一个 52 个节点的页面,压缩成 20 个可交互元素、1186 个 token。每个元素都带短 ref 和归一化边界(0–1 之间),换分辨率也不用重算。
  3. 找 —— find_element / query_xpath按文案、描述、resource-id 定位;XPath 直接在快照的原始 XML 上执行,返回 nodeKey。前者像人找东西,后者像工程师找东西,都给你。
  4. 点 —— tap / swipe / input_texttap 可以直接传 ref,Core 会取该节点 bounds 的中心点执行点击。不用你算坐标,也不给模型瞎猜的机会。
  5. 验 —— 再抓一次页面变了就重新抓,用新快照里的新 ref。拿旧 ref 去点会明确报 SNAPSHOT_STALE 或 REF_NOT_FOUND,而不是「假装成功」。

失败要显式。 这是给 Agent 做工具时最容易被忽略、也最重要的一条。

一次典型的调用长这样:

用户:把「加入购物车」点了,确认购物车角标 +1

Agent → capture_layout             → 52 nodes, snapshotId=snap-7a3e
Agent → find_element("加入购物车")   → ref=r_1f2e
                                     bounds=[0.00,0.85,1.00,0.92], clickable=true
Agent → tap(ref="r_1f2e")           → ok
Agent → capture_layout             → 购物车角标 3 → 4 ✓

你看,整个过程没有一次「我觉得大概在这个位置」。

06它还会顺手做个「体检」

diagnose_layout 检查六类问题:重叠、遮挡、越界、点击热区过小、文本截断、不可见但可交互。每条返回类型、严重程度、涉及节点、量化证据和建议,最多 50 条。

QA 说「这个按钮点不动」,以前你要复现、录屏、猜层级;现在跑一遍诊断,大概率直接告诉你:按钮被一个透明的 loading 遮罩盖着,遮罩的 nodeKey 是某某某。

布局智能:语义摘要与六类布局诊断
布局智能:语义摘要 + 六类布局诊断,问题的证据精确到节点。

有证据的排查,和靠感觉的排查,是两种工作。

07给 Agent 用,也给你用

很多「AI 工具」的问题是:为了机器好用,把人挤没了。

LayoutSee 反过来:人机共用同一份结构。

LayoutSee 投屏与操控
投屏与操控:画面即现场。

Agent 要的是接口,人要的是眼睛。两个都得有。

08边界,先说在前面

吹完功能,说点不好听的:

工具的价值是把「结构」这件事做扎实,不是替模型做所有判断。

09三分钟跑起来

  1. 下载并安装去官网下载页或 Releases 下 DMG:Apple 芯片选 arm64,Intel 选 x64。未签名包首次打开被拦,去「系统设置 → 隐私与安全性」点「仍要打开」。
  2. 装 adb,手机开 USB 调试
    brew install android-platform-tools
  3. 复制 MCP 配置打开设备工作台,进 MCP Tab,复制配置:
    {
      "mcpServers": {
        "layoutsee-android-3B161V012A600000": {
          "type": "sse",
          "url": "http://127.0.0.1:11663/mcp/android-3B161V012A600000/sse"
        }
      }
    }

粘进 Claude / Cursor / Comate(端口与设备名以界面实际给出的配置为准),再把 layout-see Skill 丢给它。第一句话可以这么问:

「读取当前页面,找出所有可点击但不是按钮的元素。」

然后看它第一次给你带回 resource-id、边界和 ref 的答案。

MCP 面板:每台设备独立端点,配置一键复制
MCP 面板:每台设备独立端点,配置一键复制。

10最后

过去两年,AI 学会了看图、学会了写代码、学会了用工具。

但它操作你的 App 时,还在靠猜。

截图是给眼睛看的,View 树是给手用的。 AI 已经长了眼睛,现在该给它一双手了。

如果这个小工具帮你少点了一次「猜」,欢迎去 GitHub 给个 Star;不好用就来开 Issue——最好带上快照和诊断证据,我们按证据聊。

LayoutSee · v22.6.1

macOS + Android 真机 · 12 个 MCP 工具 · 开源免费

致谢:设备接入与投屏能力基于 uiautomator2、scrcpy,接入层参考并二次开发自 uiautodev。