跳到正文
Shopify Engineering·· 21 天前精选AI 评分72

Shopify 打造 Remote Dev 架构,为 AI 智能体提供移动端远程开发环境

We gave AI agents a mobile dev environment

AI 导读

Shopify 工程团队开发了 Remote Dev 架构,让其 Slack AI 智能体 River 能在远程环境独立完成 iOS 与 Android 应用的代码构建、真机模拟与测试。

推荐理由

原文拆解了将移动端编译与模拟器解耦到远程机群的架构方案,为团队规模化落地智能体开发提供了工程参考。

正文 · AI 翻译

我们搭建了智能体工作流来并行处理移动端开发任务,但开发机很快就吃不消了。仅仅运行三四个工作流,编译器、模拟器和仿真器相互争抢资源,就能让一台笔记本电脑的性能直接见顶。而且电脑还必须一直保持唤醒状态,谁要是手滑合上笔记本屏幕,正在跑的任务就全停了。

前端和后端团队此前已经用上了集成在 Slack 里的 AI 智能体 River,干活时完全不占本地机器的资源。移动端也需要类似的方案。但 River 运行在 Linux 上:它虽然能编辑 Swift 代码,可构建和测试 iOS 应用时,还是得回到那些早就卡爆了的笔记本上。

我们下派任务的速度,已经远远超过了机器实际跑任务的能力。于是,我们打造了 Remote Dev。

两大限制:要么是一台 Mac 承载了太多构建任务,要么是 Linux 上缺少 iOS 工具链。

我们的解决方案

多智能体并发,多任务并行

有了 Remote Dev,笔记本能跑多少个构建和模拟器再也不是瓶颈。每次 River 会话都会分配到一个独立的环境,我们可以让一个智能体在 Android 上调试 Bug,另一个在写 iOS 功能,还有一个在测试 PR,所有任务完全并行。

而且因为所有任务都在远端运行,我们直接在 Slack 里就能向各个可用环境分发不同任务,本地连 Xcode 或 Android Studio 都不用开!

后台全自动运行

Remote Dev 最大的优势之一,就是 River 能够自主接管大部分开发流程。从编写改动、构建应用、运行测试,到操作模拟器、截取屏幕截图,再到提交 PR,它全都能搞定。中途要是出了问题,它还会查看日志、排查修复并重试,我们则可以专心做别的事情。

分支变基(rebase)、解决合并冲突、排查 CI 失败、修改 PR 反馈意见、分类处理崩溃日志、代码审查——以往这些频繁打断我们思路的琐事,现在都可以甩给 River 处理。

甚至连手动启动任务的步骤都可以省掉。我们设置了全自动工作流,有些任务在夜间静默运行,自动抓取 Bug、编写修复代码、执行测试并提交 PR。第二天一早我们上班时,修复代码已经写好,直接等待审查就行了。

有凭有据,成果自证

AI 生成代码最棘手的问题之一,就是如何确定它真的管用。代码能编译通过,并不代表功能逻辑符合预期。有了 Remote Dev,我们能做到的远不止构建和跑测试。智能体可以在应用中来回跳转、与界面元素交互,并在 iOS 和 Android 设备上录下屏幕操作或截图作为佐证。

修复 Bug 时,River 可以先复现问题并录下异常行为,随后实施修复,最后重走一遍相同步骤展示修复前后的对比。这让代码审查变得轻松很多——我们不用干啃代码,直接看界面改动就能验证效果。

最近我们还更进一步,为 River 增加了根据这些录屏自动生成演示视频的功能。视频里应用会呈现在 3D 手机模型中,配有动画演示和旁白解说。全程全自动生成,根本不需要人工剪辑。也就是说,现在的 River 不仅能写代码、做验证,还能自己出个视频讲解自己干了什么。可以说相当酷了!

任何人现在都能参与移动端开发

最让我们兴奋的一点,是让那些没有配置移动端开发环境的人也能参与移动端开发。

有了 River 和 Remote Dev,Web 开发者可以修复 Bug,设计师可以迭代 UI,产品经理可以测试功能——这一切只需通过 Slack 就能完成。

但之前还少了一块拼图。River 虽然能操作应用并发送截图,但如果你想亲自上手体验呢?这就是我们打造实时预览(Live Preview)的原因。

我们通过 WebSocket,把 iOS 模拟器和 Android 模拟器的画面从 River 的 Remote Dev 环境直接推流到 Quick 网页端。浏览器不仅能实时显示设备画面,还会将用户的交互操作回传给远程模拟器。这样一来,任何人只需点开一个链接,就能实时操作真正运行中的应用。

每个 Remote Dev 会话都会自动为双平台生成专属的实时预览。会话支持共享,多个人可以同时围观并在同一个运行中的应用上协同操作。我们还加入了深度链接(Deep Link)和移动端命令行实时推流支持,方便用户直接跳转到特定页面,并排查底层运行情况。

无需本地配置,无需安装构建包,甚至连 Mac 都不需要。

这让更多人能够参与到移动开发中来。大家不再需要来回发截图,而是直接甩过去一个链接:“你自己上手试试!”

实现原理

我们搭建了一批配置好开发环境和 iOS 模拟器的远程 Mac 机器池。智能体通过 SSH 连接到这些机器,但让 Android 跑起来要棘手得多。Android 模拟器依赖硬件虚拟化,要在云端虚拟机里运行就需要嵌套虚拟化,而 macOS 原生并不支持这一点。为了绕开这个限制,我们改为连接一台启用了嵌套虚拟化、独立运行的 Linux 虚拟机中的 Android 模拟器。通过这套架构,智能体只需在同一个 SSH 会话中,就能在一台 Mac 上同时完成 iOS 和 Android 的构建,并在对应平台上进行测试。

One session. Both platforms.

每个智能体都会认领一台配有 Android 模拟器的待命 Mac。Mac 使用完毕后会被替换,闲置的机器也会定期刷新。

接下来我们要解决的是环境准备耗时问题。最初,应用的首次编译和主分支检出耗时极长,超过 30 分钟。因此,我们不再等请求来了才临时准备 Mac,而是维护一个处于“温热”待命状态的 Mac 资源池:提前检出主分支(这可不容易,毕竟我们的单一代码库规模极其庞大)、装好工具、构建好应用并备好缓存。智能体认领一台 Mac 后,同步自己的分支,并启动预先构建好的 Android 虚拟机实例挂载上去。无论智能体是在本地还是云端运行,它都会在自己的工作区中继续工作,并把代码变动同步到 Mac 上,随后所有的脚本和构建任务都在 Mac 上执行。这样调整后,从申请 Mac 到在真机模拟环境中看到代码生效,耗时直接缩短到了几分钟。

为了调度这个资源池,我们还在后台做了一些支撑工作。会话结束后,我们会销毁对应的 Mac 并准备替代机器;对于闲置的 Mac,我们也会定期轮换,拉取最新的主分支代码,重新构建应用和缓存。整个轮换过程采用错峰方式,确保资源池随时可用,且不会中断正在进行的会话。

底层基础设施虽然跑起来了,但 River 压根感知不到。它总是坚称 iOS 构建无法在 Linux 上运行,结果就是只管写代码,却没法验证。于是我们做了一项技能,教智能体如何测试自己的改动并证明工作成果。经过多轮迭代,这两台机器才实现了天衣无缝的协同。但起初并非一帆风顺:即便工具一应俱全,River 还是动不动就忘了远端 Mac 的存在;与远端 Mac 通信时也一声不吭,或者过了很久才给用户回复。

经过反复迭代,我们不断优化这项技能,并配齐了趁手的工具——比如用一个 CLI 封装掉复杂的 SSH 参数;针对 Mac 上耗时较长的任务,我们没有采用休眠或设置超时等待,而是利用 tmux 窗格让 River 能够实时查看进度。

推动大家用起来

改变移动端开发者的日常工作方式

尽管现有的笔记本电脑性能受限,团队以往还是习惯在本地做移动端开发:开着真实的模拟器操作、构建应用、亲自测试。受限于笔记本性能,这种模式不仅效率低下,在面对我们手头庞大的迁移任务时也根本无法规模化运作。推动大家改用 River,不仅是个技术挑战,更是个心理关卡。我们必须打破既有的习惯。

有些同事试用过早期版本的 River,体验并不理想:构建老失败、速度慢,根本应付不了日常工作。大家心里都想:“这东西不适合我,我还是回本地写代码吧。”要让大家真正用起来,我们必须先把体验做到极致。

但大家都明白,光把工具做出来,别人不会自动找上门来,内部推广也是如此。你得亲自展示,得去布道这个工具有多好用,而且要反反复复讲。因此,我们借助故事包装和内部广告,让大家意识到 River 在移动端开发上已经今非昔比了。

我们萌生了一个想法:把 River 拟人化为一个现实中的打工人,为搞不定移动端开发而抓狂,以此引发大家的共鸣。接着,现实中的 River 家里添置了一台真正的 Mac,终于能顺利构建移动应用,所有烦恼瞬间烟消云散。大家看不到这套方案背后的复杂细节(也就是我们在这篇文章里拆解的内容),他们只看到一切忽然变得神奇般顺畅。River 的人设立起来后,后续的内部宣传就轻松多了。下面就是一个例子——内容显然全由 AI 生成,恶搞了经典的 Mac vs PC 广告。这不仅增添了故事性和趣味性,还让看过原版广告的同事们狠狠怀旧了一把:

这番努力最终推动了 River 的普及。起初,由 River 创建且最终合入的移动端 PR 仅占 6%。随着时间推移,这一比例彻底扭转了本地开发的局面,最终一路攀升至 61%:

River's share of PRs

公开构建、多人协同与自我进化循环

River 的一大亮点在于原生支持多人协同。今年早些时候,Tobi 分享过这种模式如何潜移默化地重塑了 Shopify 的文化,让大家能够相互观摩并学习别人驾驭智能体的方法。

对我们而言,这项多人协作功能不仅让我们了解到其他人如何在移动端用 River 写代码,还能帮助我们持续优化后续会话的体验。用户在哪里卡壳、引导在何处走偏、工具调用何时被拒——所有细节都一览无余。

为此,我们采用了速度极快且成本极低的分类模型 Jev。它会监测移动端上的所有 River 会话,打上多重问题标签,并对每条消息进行标记。我们会根据最终成效对每次对话进行分类,并将失败案例输入大语言模型,借此发掘改进方案。

我们借助 River 持续迭代这一流程,让 River 能够自我完善,更好地服务后续的使用场景。

River iterating

这还只是开始

最初,我们只是想让 River 能够接入移动端开发环境,但最终释放出的潜能远超预期。我们不仅让移动端开发变得更加高效,更改变了谁能参与贡献代码、团队如何协同工作,以及我们能将多少任务托付给智能体。

而且,我们每天都在发掘新的可能。我们正在引入能够实时监控应用健康状态的工作流——AI 智能体会在发生崩溃时自动提交 PR 修复代码,随时供人工快速审查。此外,我们还利用多个智能体并行展开捉虫测试,在不同设备、语种和业务流程中模拟各类商家,以揪出那些容易被遗漏的问题。

这些还只是我们正在探索的一部分场景。每一项新能力的落地,都会开启更多可能。这仅仅是个开始。

加入我们,共同打造未来

对我们在 Remote Dev 上取得的成果感到心动?我们正在招聘移动端工程师,一起拓宽智能体在移动开发领域的应用边界。

来源:Shopify Engineering · shopify.engineering