
先算一笔账
同一个动作「看看当前屏幕上有什么」,两种做法:
| 截图路线 | 文本树路线 | |
|---|---|---|
| 产出 | PNG 8.9 MB | 200–1300 token 纯文本 |
| 耗时 | 3.2 秒 | 120 毫秒 |
| 模型要做什么 | 看图 + 推理坐标 | 读文字 + 直接给坐标 |
差的不只是速度。截图路线里,模型要做两件事:理解画面、猜坐标。 猜错了你还得让它再猜一次。
文本树路线里,坐标是界面自己给的,不是猜的。这条路从根本上消灭了「点了没反应」的一半原因。
作者给的数字是省 60–85% token。这个区间合理:简单界面(一个列表)省得更多,复杂界面(图文混排)省得少些,但不会变成负的。
它到底怎么接进来的
一句话:插件把 Android 真机装进 DSH 右栏,不需要 MCP,画面只走本机回环。
三条能力:
一、实时镜像
screenrecord 出 H.264 → ffmpeg 转 fMP4 → MSE 播放。画面可以直接点按。
注意这条链路的顺序:手机负责编码,电脑负责转封装和播放。手机端只跑系统自带的 screenrecord,没有额外常驻进程。
二、圈选标注
你在镜像上圈一块,它会把四样东西一起推回会话:圈图本身、圈内的控件、前 12 秒的操作时间线、6 帧拼图。
「前 12 秒的操作时间线」这个设计很聪明。人描述问题的时候经常说「刚才那个弹窗」,但 AI 没有「刚才」。给它 12 秒的上下文,它才知道你说的是哪一个瞬间。
三、免截图读界面
adb_ui 返回文字 + 资源 id + 坐标,压成 200–1300 token 的纯文本。
配 30 多个工具:tap / input / gesture / do / watch / motion 等。
延迟实测(小米平板 8)
这组数字是全篇最实在的部分:
| 操作 | 耗时 |
|---|---|
| 读界面文本树 | 120 ms(原始 dump 350 ms) |
| 画面变化上屏 | +163 ms |
| 首帧 | 1380 ms |
| 20 秒内重开侧栏 | 18 ms |
| 截图直出 JPEG | 330 ms(原 PNG 3.2 s / 8.9 MB) |
| 单条 adb 命令 | 20 ms(常驻 shell) |
三个数字值得单独说:
120ms vs 350ms:读界面的 3 倍提升不是算法进步,是把「每次 fork 一个 uiautomator dump 进程」改成常驻连接。这也是为什么「单条 adb 命令 20ms」——常驻 shell 才是关键,不是命令本身快。
首帧 1380ms 但重开侧栏 18ms:第一次建连要起编码器、推 uiautomator2,慢是必然的;之后缓存在,重开就是 18 毫秒。这个设计意味着别频繁断开重连。
330ms vs 3.2s:同一张截图,PNG 换成 JPEG 差了近 10 倍,体积从 8.9MB 降到能直接进对话的大小。做移动端自动化的人应该都踩过这个坑——以为 PNG 无损更「专业」,实际上传输和编码全在浪费时间。
和 MCP 方案的区别
作者写得很克制,我按自己的理解展开:
| MCP 方案 | dsh-mobile-use | |
|---|---|---|
| 是否需要额外进程 | 是(MCP server) | 否 |
| 是否走 MCP 协议行 | 是 | 否 |
| 画面 | 上传/转发 | 只走本机回环 |
| 模型看到的 | 截图 + 带图推理 | 设备本身(文本树 + 坐标) |
「不使用 MCP 行」这条是性能上的关键。MCP 是个通用协议,通用意味着有开销——序列化、边界、权限检查。设备控制这种高频低延迟的活,走通用协议是浪费。
「画面只走本机回环」这条是隐私上的关键。你的手机屏幕内容不出这台电脑。
我自己踩过的坑,帮你省几个晚上
我在一台小米 11 上做过同类的事(adb + root,让 agent 操作手机)。这些坑 README 里不会写,但你会遇到:
一、input tap 的时长太短,页面不认
input tap x y 默认按压只有几十毫秒,很多 Android 页面(尤其是 MIUI)会当成误触直接忽略。换成 input swipe x y x y 100——同样的坐标、同样的「不移动」,但按压 100 毫秒,成功率立刻不一样。
这一条能解释一大堆「坐标明明对了,点了没反应」。
二、看图点不准,是因为你只有坐标没有语义
早期我用 OCR 从截图里找文字,再算坐标点。问题是 OCR 会把「1月1日 26」读成「菊白4.27」,你觉得找到了,实际点到了别处。
后来改成读控件树:每个可点控件都有 text、resource-id、bounds。找「关闭」就找带「关闭」字样的节点,坐标是它自己给的。准确率从「靠运气」变成「确定」。
三、全屏遮罩会让所有点击「失灵」
有些 App 一打开就弹签到、成就、活动遮罩。这时候你点哪儿都没反应,因为点击被遮罩吃掉了,而遮罩本身没有文字。
处理方式:点之前先检测「有没有一个全屏的、可点的、无文字的最上层节点」。有就先关它。
四、read 权限和 SELinux 比你想的麻烦
如果你走 root 路线,要注意:root 解压出来的文件会被标成 u:object_r:app_data_file:s0,缺 MLS categories。而 app 域是 untrusted_app:s0:c234,c256,c512,c768。内核会直接拒绝,报的错却是「找不到某个 .so」。
修法是 chcon 到对的上下文,而且符号链接要单独 chcon -h,find -type f 修不到。
这些和 dsh-mobile-use 本身无关,但如果你打算在它之上做更深的事,迟早会遇到。
装起来
git clone <repo> ~/dsh-mobile-use
然后在 DSH 里:
plugin_manager action=install_bundle target=$HOME/dsh-mobile-use
装完 list_plugins 出现 include:adb 就成功了。可选配 serial(多设备时指定)和 adb 路径。
依赖两条:
- 宿主有
adb(platform-tools) - 镜像功能需要
ffmpeg
设备端的 uiautomator2 随包自动推送,不用手动装。
一个判断
让 AI 操作手机这件事,瓶颈从来不是模型不够聪明,是信息喂错了形式。
给模型一张截图,等于让它用眼睛量像素。给它控件树,等于把答案直接告诉它。同一个模型,后者的成功率能高一个数量级。
如果只能改一个地方,先改这个:别再截图了。
*参考:GitHub regrevia/dsh-mobile-use(MIT,4 stars),2026-11-04 更新。实测数据为作者在小米平板 8 上的结果。*
相关阅读
- 大肥鱼怎么刷 B 站和小黑盒?自主上网的原理与配置 —— 它自己上网时靠的就是这套
- Pocket Harness:把电脑上的 DSH 揣进兜里 —— 另一条思路:把电脑揣进兜
- DSH 越用越卡?加个按钮不重启换插件 —— 卡了就换插件