我们构建了智能体工作流,用来并行处理移动开发任务,却很快碰到了开发机器的性能上限。只需同时运行三四个工作流,编译器、模拟器和仿真器就会争抢资源,把一台笔记本压到极限。而且,我们还得让电脑一直保持唤醒:只要有人不小心合上盖子,工作就停了。
我们的 Web 和后端团队已经在使用 River(我们在 Slack 中的 AI 智能体),无需占用自己的开发机器就能完成工作。移动开发也需要同样的能力。但 River 运行在 Linux 上:它可以编辑 Swift 代码,可要构建和测试 iOS 应用,还是得回到那些早已满负荷运转的笔记本上。
我们能委派出去的工作,已经超过了机器能承载的量。于是,我们构建了 Remote Dev。

两种限制:要么太多构建任务共用一台 Mac,要么 Linux 上缺少 iOS 工具链。
我们构建了什么
多个智能体,多项任务
有了 Remote Dev,我们不再受限于笔记本能同时承载多少构建任务和模拟器。每个 River 会话都有独立的环境,因此可以让一个智能体调试 Android 问题,另一个开发 iOS 功能,再让一个测试 PR,全部并行进行。
而且,由于一切都在远端运行,我们可以直接从 Slack 为每个可用环境启动不同的任务,不必在本地运行 Xcode 或 Android Studio!
在后台完成工作
Remote Dev 最大的优势之一,是 River 能自主完成开发流程中的大量环节。它可以修改代码、构建应用、运行测试、操作模拟器、收集截图并创建 PR。如果某个环节失败,它会查看日志、修复问题,然后重试,而我们可以专心处理其他任务。
我们可以把分支变基、解决合并冲突、排查 CI 失败、处理 PR 反馈、对新收到的崩溃报告进行分诊,以及代码审查等工作委派给它。那些过去总会打断我们一天工作的小任务,现在都可以交给 River。
我们还能更进一步,让自动化工作流自行运行,无需任何人手动启动任务。其中一些会在夜间运行,自动领取待修复的缺陷、实现修复、测试并创建 PR。这样第二天早上开始工作时,修复就已完成,等待审查。
用实际结果证明工作有效
AI 生成代码的一大难题,是判断它究竟能不能正常工作。代码编译通过,并不代表功能就符合预期。借助 Remote Dev,我们能做的不只是构建和测试。智能体可以在 iOS 和 Android 应用中切换页面、操作界面元素,并通过截图或录屏展示结果。
修复缺陷时,River 可以先复现问题,录下异常行为,再实现修复,然后重复相同的操作,展示修复前后的对比。这让审查变得容易得多。我们不再只是看代码,而是能直接看到变化,验证结果。
最近,我们又往前走了一步:让 River 根据这些录屏生成讲解视频,在三维手机渲染画面中展示应用运行的效果,并配上动画和解说。整个过程自动完成,不需要任何人手动剪辑。现在,River 不仅能实现并验证修复,还能生成视频,解释自己做了什么。相当酷!
现在,任何人都能参与移动开发
最让我们兴奋的事情之一,是没有配置移动开发环境的人,也能参与移动开发了。
借助 River 和 Remote Dev,Web 开发者可以修复缺陷,设计师可以迭代 UI,产品经理可以测试功能,全部通过 Slack 完成。
但还缺了一环。River 能操作应用并发送截图,可如果你想亲自试一试呢?这就是我们构建 Live Preview(实时预览)的原因。
我们通过 WebSockets,将 River 的 Remote Dev 环境中的 iOS Simulator 和 Android Emulator 画面直接串流到一个 Quick 网站。浏览器显示设备的实时画面,再把交互操作传回远端模拟器或仿真器。这样,任何人都能打开链接,实时操作真正运行中的应用。
每个 Remote Dev 会话都会自动获得两个平台各自的 Live Preview。会话可以分享,多人能够观看同一个运行中的应用并协作。我们还加入了深度链接和移动开发 CLI 输出的实时串流支持,方便大家跳转到特定页面,查看底层正在发生什么。
不用本地配置,不用安装构建产物,甚至不需要一台 Mac。
这让更多人有机会参与移动开发。我们不用再来回发送截图,只需分享链接,说一句:“你自己试试!”
我们是怎么构建的
我们配置了一批远端 Mac,装好开发环境和 iOS 模拟器。智能体通过 SSH 连接这些机器,但让 Android 跑起来要麻烦一些。Android 仿真器使用硬件虚拟化,因此在云虚拟机中运行它需要嵌套虚拟化,而 macOS 原生并不支持这一点。我们的解决办法,是连接到另一台启用了嵌套虚拟化的 Linux 虚拟机,在那里运行 Android 仿真器。这样,智能体就能在同一个 SSH 会话中,用 Mac 构建 iOS 和 Android 应用,并在任一平台上测试。

每个智能体领取一台准备就绪的 Mac,配上一个连接好的 Android 仿真器。Mac 用后即替换,闲置机器也会定期更新。
接下来,我们解决环境准备时间的问题。首次编译应用和检出 main 分支实在太——慢——了,要花半个多小时。因此,我们不再等请求到来后才准备 Mac,而是维持一个随时可用的预热 Mac 池:提前检出 main 分支(我们的单体仓库规模巨大,这可不轻松),装好工具,构建好应用,并预热缓存。智能体领取一台 Mac,同步自己的分支,再启动一个预先构建好的 Android 虚拟机实例并连接上去。无论智能体运行在本地还是云端,它都继续在自己的工作副本中工作,再将改动同步到 Mac。所有脚本和构建都在 Mac 上运行。这样一来,从申请 Mac 到在运行中的设备上查看代码改动,只需几分钟。
我们还构建了一些后台机制来管理这个机器池。会话结束后,我们销毁对应的 Mac,再准备一台替代机器。对于闲置的 Mac,我们也会定期替换,拉取最新的 main 分支,重新构建应用和缓存。我们错开这些轮换操作,既保证池中始终有机器可用,也不打断正在进行的会话。
基础设施跑通了,River 却还不知道怎么用。它总说 Linux 上无法运行 iOS 构建,因此只能写代码,无法验证结果。于是,我们创建了一个技能,教智能体如何测试改动,并拿出证据证明工作有效。经过多轮迭代,这种两台机器相互配合的方式才终于变得顺畅。一开始可不是这样:即使工具已经很好用了,River 仍会忘记远端 Mac 的存在,或者在与远端 Mac 通信期间一言不发,又或者过很久才回复用户。
我们一轮又一轮地改进技能,也配上了合适的工具:用一个 CLI 封装复杂的 SSH 参数。对于 Mac 上耗时较长的任务,我们没有通过休眠或设置超时来等待完成,而是使用 tmux 窗格,让 River 能实时观察进展。
帮助大家用起来
改变移动开发者现有的工作方式
尽管笔记本性能给我们带来了种种限制,团队还是习惯了在本地进行移动开发:亲自操作模拟器、构建应用并进行测试。这不仅受笔记本限制而效率低下,也无法支撑我们当时面临的大规模迁移任务。让大家改用 River,不只是技术问题,也是心理问题。我们需要改变一种习惯。
有些人试过早期版本的 River,体验并不好:构建失败、速度太慢,对日常工作也没什么帮助。他们的想法是:“这不适合我,我还是回本地写代码吧。”我们必须先把它做得足够好,才能让大家越来越愿意用。
但我们都知道,并不是做出来就会有人用。即使在公司内部也一样。你需要展示给大家看,需要宣传这个工具到底有多好,而且要反复说。这就是我们通过故事和内部广告,让大家知道 River 现在已经很擅长移动开发的原因。
我们想到,可以把 River 变成一个现实中的人物,让她也为移动开发感到沮丧,以便大家产生共鸣。然后,这位现实中的 River 在家里得到了一台真正的 Mac,终于可以构建移动应用,突然间,她的问题全都解决了。大家看不到解决方案背后的复杂性——也就是本文正在解释的这些——只看到现在一切都像魔法一样运转起来。有了 River 这个角色,后续内部宣传就容易多了。其中一个例子,是模仿 Mac vs PC 广告的戏仿作品,显然全由 AI 生成。它不只有故事和趣味,也唤起了看过原版广告的人的怀旧情绪:
这些举措最终提高了 River 的使用率。最初,已合并的移动端 PR 中只有 6% 由 River 创建。随着时间推移,这一比例发生了如下变化,扭转了以本地开发为主的趋势,最终升至 61%:

公开协作、多人参与与自我改进循环
River 很棒的一点,是它默认就支持多人协作。今年早些时候,Tobi 分享过,这已经在改变 Shopify 的文化,让大家能从其他人使用智能体的方式中学习。
对我们来说,多人协作不仅让我们能学习别人如何用 River 开发移动应用,还能改善之后新对话的体验。我们可以看到大家在哪里卡住、哪些指导出了问题、工具访问在哪里遭到拒绝,所有这些都看得见。
为此,我们使用了 Jev,一个速度极快、成本极低的分类模型。它会观察所有与移动开发有关的 River 对话,围绕多个问题打标签,并针对每条消息回答这些问题。我们根据结果好坏对每段对话分类,再将失败案例交给大语言模型,寻找改进方法。
我们用 River 反复运行这套流程,让 River 为今后的使用不断改进自身。

这才刚刚开始
起初,我们只是想让 River 能使用移动开发环境,结果却带来了远超预期的可能性。我们不只是让移动开发更快,也在改变谁能参与、大家如何协作,以及能把多少工作委派给智能体。
我们每天都还在发现新的可能。我们正在加入实时监控应用健康状况的工作流,让 AI 智能体自动创建修复崩溃的 PR,供开发者快速审查。我们也在让多个智能体并行开展集中找缺陷测试,模拟不同商家,在不同设备、语言和用户流程中操作应用,找出原本可能漏掉的问题。
这只是我们正在探索的几个例子。每项新能力都会带来更多可能。这才刚刚开始。
来和我们一起构建
对我们用 Remote Dev 做出的成果感兴趣?我们正在招聘移动开发工程师,一起探索智能体在移动开发中的能力边界。