Opposable 发布手机智能体:让 Claude Code 等 Agent 直接操作 Android 与 iPhone
Phones are the last big body of software only people can use
Opposable 发布一款让 AI 智能体像人一样操作真实手机的工具,可打开应用、读取屏幕、输入并处理弹窗,Android 端基于无障碍服务,iPhone 端通过 Mac 以蓝牙键鼠加 USB 投屏绕开限制。
在20世纪70年代和80年代,世界上许多重要的软件都运行在IBM大型机上,只能通过3270终端使用,那是银行职员和航空公司代理整天敲打的绿色屏幕。这些应用程序无法让另一个程序与它们通信,因此当公司希望他们的新PC能与这些系统协同工作时,IBM推出了一种名为HLLAPI的接口,让PC程序能够读取终端屏幕上的内容并输入信息,就像职员一样。3270屏幕由带标签的字段而非像素组成,因此这些程序读取字段,几十年来,很大一部分业务集成都运行在为人设计的软件操作屏幕上。
我认为,每当大量软件只为人类操作而构建时,同样的事情就会发生:会出现一个层,代表程序操作这些屏幕,它一直发挥作用,直到合适的接口出现,而这可能需要很长时间。手机应用是当今最大的此类软件集合,也是大多数人每天使用的。我的银行、出租车、停车和包裹柜都是手机应用,没有代理可以使用的接口,而且每一个都将登录码发送到同一部手机。编码代理可以在从未见过的网站上找到路,但它们无法触及这些。Opposable是我们为手机打造这一层的尝试。它让代理或多或少像人一样使用真实手机,打开应用、读取屏幕、输入并处理中间弹出的任何内容。
在Android上,相当于那些字段的东西来自无障碍功能。2009年,Android 1.6添加了一个小框架,使名为TalkBack的屏幕阅读器能够向看不见的人描述其他应用的屏幕,并代表他们按下按钮,而我们的应用今天正是通过该框架来查找和点击东西。屏幕阅读器和代理对手机的需求几乎相同:用文字描述屏幕,以及无需瞄准像素就能按下按钮的方法。接下来是我们在此基础上构建时学到的东西,以及一些我对未来走向不太确定的猜测。
为什么手机比电脑更难
在笔记本电脑上,计算机使用在概念上很简单。代理截取屏幕截图,计算出点击位置并移动鼠标,操作系统对谁在移动它没有特别意见。手机的设计使每个应用都在自己的沙箱中运行,系统费尽心思阻止一个应用看到或触碰另一个应用,这也是手机从未遭遇Windows PC那种恶意软件的一大原因。我认为这种设计是正确的,但这确实意味着代理没有明显的接入点。
Android的一个入口是无障碍服务,即2009年那个框架的后代,如今也为使用开关或语音操作手机的人服务。持有该权限的应用可以读取其他应用的内容并在其中执行点击和手势,这也是代理所需要的。
iPhone 没有对应的接口,所以我们绕开了它。Mac 可以把自己伪装成蓝牙键盘和鼠标呈现给 iPhone,再开启 AssistiveTouch,iOS 就会把鼠标点击当作轻触,而屏幕画面则通过 USB 线回传到 Mac。我在另一篇文章里写了细节;在我们对 iPhone 17 Pro 的测试中,每一次轻触都落在了瞄准的位置。
智能体看到的是什么
第一个被证明至关重要的决定,是每一步向模型展示什么。截图是显而易见的选择,因为那是人看到的东西,也是桌面端计算机使用所围绕构建的,我们也是从那里开始的。它能用,但很慢,而且模型更擅长描述一张截图,而不是准确说出一个小开关在其中的位置,于是它们会点在偏几个像素的地方,什么也没发生,它们又花一步再截一张图来弄清原因。
无障碍服务免费提供了更好的东西,因为它已经知道屏幕上的每一个元素,连同它的标签、类型和位置,这正是 TalkBack 朗读出来的同一份信息。所以我们交给智能体一份带编号的列表,它回复类似“点击 12”而不是一对坐标。一屏文字只有几十行,而一张截图大约要一千个图像 token,所以每一步不仅更少出错,成本也更低。在智能体需要看照片或地图的情况下,截图仍然可用,而在我们的测试运行中它很少需要。
大部分速度提升来自应用与手机通信方式的两处改动。第一个版本为每个动作都打开一条到手机的新连接,然后固定等待半秒让屏幕稳定下来,于是我们改为保持一条连接常开,并等到屏幕真正停止变化,有时是 80 毫秒,有时是两秒。在我们用作基准的三项任务上,总时间从 140 秒降到 56 秒,与模型的往返次数从 62 次降到 18 次,而剩下的大部分是模型在思考,而不是手机。
打断
如果你观察自己用手机十分钟,你会发现其中很多事与你原本想做的事毫无关系。相机在你第一次打开时请求权限,某个应用想要你评分,某个网站想要你接受 cookie,而一条六位验证码在你正忙别的事时通过短信到来。人们处理这一切时毫无察觉,但一个没被告知这些的智能体会一遍又一遍地看着同一个屏幕,试图弄清它想要的按钮为什么不在那里。
我们花了很多时间让手机能够清晰地描述这些情况。当有东西遮挡应用时,元素列表现在会说明这一点,评分提示和更新提醒这类无害的提示会被自动关闭,一次性验证码会从消息和通知中提取出来,以便智能体可以继续它正在做的事情。权限对话框则有意留给智能体自行决定,因为授予权限是一个真正的选择。
在手机上完成更多工作
人们在手机上要求智能体做的大部分事情根本不需要大模型。设置闹钟、给联系人发短信、打开 Wi-Fi 或打开某个设置页面,每次都需要相同的几个步骤,所以应用现在可以自行完成大约四十项这样的操作,无需任何模型,并在之后检查屏幕以确认事情确实发生了。
当智能体通过 Opposable 在你的手机上做一件新事情时,这些步骤会依据屏幕上的文字而非像素位置被记录下来,你可以将它们保存为例程。下次手机自行在几秒内重放它们,因此大模型只需将一项任务弄清楚一次。
对于其他任何事情,有一个小型屏幕模型,大约二十亿参数,在手机本身上运行,通过查看屏幕来决定点击哪里。它的能力远不及 Claude,在陌生任务上它比我期望的要慢,但它无需连接即可工作,屏幕永远不会离开手机,而且在你合上笔记本电脑后它仍会继续运行。
当我们在笔记本电脑 CPU 上对该模型的单个步骤计时时,几乎一半的时间花在将截图转换为模型语言部分可以读取的内容上,而生成答案——即点击哪个元素——花费的时间最少。
那个阶段,即视觉编码器,与手机芯片每天为相机所做的工作非常接近。每部较新的手机都有一个神经处理器,其主要工作是让照片看起来更好,在 Galaxy S25 上,它运行我们的编码器大约只需四分之一秒,比笔记本电脑 CPU 快约十六倍。我们还没有在真实手机上端到端运行完整循环,每一步的其余部分仍然必须发生,所以我还不知道在那里完整的一步会花费多少。如果步骤的其余部分也能降下来,那么在手机上运行屏幕模型最终可能比将截图发送到服务器更便宜、更快速,但我们还没有那些数据。
支付,以及我们自己代码中的三个 bug
人们对 AI 智能体和银行应用在同一设备上感到紧张是合理的。从一开始,任何看起来像支付的东西都会暂停并在手机上询问所有者,带有批准和拒绝按钮,智能体所做的一切都会记录在手机上的日志中。上周有人问我们究竟如何判断一个屏幕是支付屏幕,当我回去检查时,发现该检查存在漏洞。
第一个版本只看被点击按钮上的标签。它能识别“Pay”、“Buy”、“Place order”和“Send money”,但一笔 25 欧元转账下方一个普通的“Confirm”却直接通过了,一个没有标签的按钮或滑动支付控件也是如此。我们把它改成读取整个屏幕,这样在显示金额且旁边有 total、amount 或 recipient 之类字样的屏幕上,确认类点击会先询问,而任何已知支付应用内的确认操作无论怎样都会先询问。
在测试这个修复时,我又发现了另外三个问题。审批请求是一条普通的 Android 通知,而既然智能体可以像任何人一样下拉通知栏,就没有什么能阻止它自行点击自己付款上的 Approve。在我修复这个问题时,我们的自动弹窗处理器在屏幕上某处看到了“update available”字样,便点击了它找到的第一个关闭按钮,而那恰好是一个待处理审批上的 Deny。还有,当手机通过 USB 连接到电脑且 Opposable 的控制开关关闭时,电脑上的工具会退回到通过调试连接来操控手机,这完全绕过了检查,于是我们测试页面上的一笔转账就直接通过了。
这三个问题都已修复,而且没有一个涉及模型行为不当。每一个都只是一段普通的管道代码,其编写前提是只有人才会碰通知栏,或者某条回退路径永远不会出问题。我怀疑手机智能体的大多数安全工作都会是这样:走遍一个操作可能经过的每一条路径,并确保机主的确认无法从其中任何一条路径触达。一旦你考虑到手机上的内容大多是别人写的文字,这就变得更加重要。智能体读到的每条短信、通知和网页都是输入,最终其中会有一条告诉它忽略自己的指令,把钱转到某个地方,所以我宁愿依赖智能体无法触达的检查,而不是依赖模型自己注意到。
大多数真实的资金转移最终也会落在智能体无法完成的认证上,比如指纹、银行应用自己的 PIN,或者在 iPhone 上,Face ID 加上双击侧边按钮。智能体可以完成一笔支付之前的全部二十个步骤,却仍然无法完成最后一步,所以对大多数支付而言,即使我们自己的检查漏掉了什么,最后一步仍然掌握在机主手中。
我认为这件事会走向何方
大型机的故事在 2010 年前后的个人理财领域有了一个更近的续集。银行不提供 API,所以 Mint 和 Plaid 通过用人们的密码登录并读取账户页面来连接他们的账户。银行不喜欢这样并试图阻止,但它一直有效,因为客户想要它,而在欧洲,监管机构最终要求银行提供正规的接口。在存在更好方式之前,读取屏幕就是这些应用获取数据的方式,这与 HLLAPI 为大型机所扮演的角色相同,而使用手机屏幕的智能体现在也处于类似的位置。
大多数应用除了为人设计的界面之外,不给智能体留下任何入口,而其中许多应用正是通过这个界面赚钱——来自广告,或者来自结账前弹出的那个优惠。有些应用会抵制,早期迹象已经出现:一些银行应用拒绝在虚拟手机上运行,Google 也要求你先注册一台虚拟手机,Play Store 才能在上面工作。与此同时,Android 和 iOS 都已经有了让应用直接向系统助手暴露操作的早期机制。我的猜测是,这两种方式将长期并存:想要智能体的应用使用正规接口,其他一切则回退到屏幕,就像 Web 在有了 API 之后很久仍然保留着网页一样。
Apple 和 Google 也会把智能体构建进它们的操作系统,那些大概会不错。但我们赌的是,人们已经有了自己喜欢的智能体,而且它未必是手机自带的那一个。如果你用 Claude、ChatGPT 或 Codex 工作,你会希望那个智能体也能使用你的手机。运行在你电脑上的智能体同样需要一部手机,理由和你一样:验证码发到那里,一半的服务也都在那里。
手机还成了证明你在网上是谁的东西。双重验证码和银行验证器应用都建立在这样一个假设上:拿着手机的人就是它的主人。一旦智能体拿着手机,这个假设就变弱了,我预计服务方会做出回应,把决定性的步骤转移到需要身体、指纹或人脸的东西上。在我看来这是健康的,因为它把工作和决策分开,就像支付审批那样。
在 Android 上让这一切成为可能的那个权限,原本是为残障人士存在的,而 Google 和应用开发者都有理由限制它。Android 已经让从 Play Store 之外安装的应用更难获得该权限,Google Play 也限制了哪些应用可以使用它。进一步收紧是很容易的,我认为我们不应该假装这种风险不存在。我们的理由建立在无障碍本身所依据的同一个理念上:这是你的设备,由你决定用什么来操作它——但我不能保证这个论点总能获胜。
一旦智能体成为真正占相当比例的用户,它们可能还会改变应用设计。许多移动界面设计都是在引导人,无论是稍微小了一点的取消按钮,还是退订需要点六次。智能体不会疲倦,也不会难为情,所以如果有足够多的人开始把这些流程委托出去,引导就会失效,一些筹码会回到手机主人手里。我们还不知道应用开发者会如何回应。
我们的思路
综合起来,这些就是我们构建时所依据的原则。手机应该尽可能自己完成更多工作,因为这能让你的屏幕保持私密、在无连接时也能继续工作,而且手机芯片在那些昂贵的部分上正变得非常擅长。任何智能体都应该能驱动它,因为用哪个智能体是你的选择。任何涉及资金流动的操作,最后一下都由你来点,而智能体绝不能通过任何途径触及那一下。智能体所做的一切都会被记录下来,所以你永远不必只听它说发生了什么。
这一切都还处于早期:除了 iPhone 和那一次神经处理器测量之外,我们所有的计时都来自模拟器,设备端模型比我想要的要慢,而且我们不断发现一些假设之所以成立,仅仅是因为有人在拿着手机。计算机使用之所以受到关注,是因为它让 AI 能够使用为人而非为其他程序构建的软件,而对大多数人来说,尤其是在一个家庭只有一部手机作为唯一计算机的国家,这些软件如今就生活在手机上。
如果你试用 Opposable 时它卡在了某个地方,我想知道是哪里。Android 应用在 getopposable.com 免费提供,iPhone 路线需要一台 Mac,我的邮箱是 hello@getopposable.com。
来源:Hacker News · getopposable.com