Replay.io 自愈软件循环两周开出 152 个 PR,80 个经复现验证后合并
What our experimental self-healing software loop shipped in two weeks
Replay.io 在 9 月 18 日至 10 月 1 日于自有仓库试运行由 Fullstory、Replay QA、Obvious 三层组成的自愈循环,共开出 152 个 PR,全部非人工编写,其中 80 个经复现验证后由工程师合并,覆盖 124 个 bug 中的 76 个。
我们在9月18日至10月1日期间进行了一次试点测试,测试了一个由三个独立服务拼凑而成的自愈循环,全部在我们自己的代码库内。这个循环开启了152个拉取请求,其中没有一个是由人类编写的。其中80个是经过验证的修复,由我们团队中的某个人直接合并,无需额外测试。
三个产品,五次交接,一个人工决策
循环的三层各自做它擅长的一件事。Fullstory是生产监控层:它观察真实会话并在出现问题时发出标记。Replay QA在循环的两端承担两项不同的工作。Obvious编写修复。然后由一个人审查PR和QA报告,并决定是否合并。按设计,这是唯一的人工步骤。

- 检测(Fullstory):从真实生产会话中浮现信号。
- 诊断(Replay QA):复现问题,从录制中找出根因,并提交一个包含严重性、证据和bug ID的GitHub issue。
- 修复(Obvious):在
fix/qa-issue-N上开启一个PR,包含原因、变更内容和权衡,通过Fixes #N链接。 - 验证(Replay QA):探索PR预览以查找回归,然后针对它复现原始bug:对于前端变更,重放原始会话;对于后端变更,独立复现。
- 合并(工程师):唯一的人工决策。issue自行关闭。
从录制中复现bug并证明修复消除了该bug,两次使用同一个机制。第二次使用正是这个实验变得有趣的地方。
开启152个,合并80个,验证80个
十四天,一个代码库,没有手写代码。以下是全部152个拉取请求的最终去向。

全部80个合并的PR都附带了针对该PR复现的原始bug,并显示该bug已消失。其中46个是前端变更,通过重放发现该bug的会话来验证。另外34个涉及后端,Replay QA在其中独立复现了问题。
这些PR之下是124个不同的bug。其中76个现已在main上修复,且每个修复都经过了验证。这相当于每天修复五个多bug,而没有人编写代码。124个中有18个需要多次尝试,因为当PR被关闭或QA失败时,循环会再开启一个。一个Segment PII泄露尝试了四次。

27个未合并即关闭的PR大多是那些被取代的尝试,而非直接拒绝。前三天清理完积压后,合并速度与新PR的开启速度保持同步。关于范围的一点说明:152个PR中有7个没有关联的QA bug。它们是后续跟进,主要是循环在修复自己早期某个PR上的CI。
这样的循环擅长什么
124个bug,按类型分组。这张图表中的两件事改变了我们对这个问题的看法。

性能问题占循环修复的所有问题的43%。这涵盖了过大的负载、以no-cache方式提供的API响应以及请求瀑布。有一个响应在每次查看项目时都会发送约975KB的旅程创作树。像这样的bug会在待办事项中搁置一年,因为没有任何一个人负责它们,而且它们从来都不是最紧急的事情。循环不在乎它们是否无聊。
安全漏洞的复现最为清晰。安全漏洞往往以明确无误的方式失败,因此证明修复也同样明确无误。修复包括GET /api/projects在未经身份验证的情况下以200状态码返回私有项目列表;未经身份验证的项目读取返回完整记录,包括owner_id;以及/api/auth-me(包含电子邮件和Auth0 id)在约132秒后从CDN缓存中提供过期数据,尽管有no-store。

证明修复的两种方式
验证是针对修复的诊断:针对PR复现原始bug并证明它已消失。Replay QA如何复现取决于PR更改了什么。

无论哪种方式,审查PR的工程师都不需要相信模型对其自身修复的描述。每次合并都附带了针对更改复现的原始故障,并证明其已消失。
生成从来都不是困难的部分。循环在两周内产生了152个PR。使其中80个可合并的是证明,这就是生成拉取请求的循环与工程师真正会合并的循环之间的区别。
已经有人指出了缺失的一环
在撰写本文时,我们寻找了是否有人描述过使这项工作得以实现的阶段。我们找到的最接近的是Augment开发者体验负责人Chris Kelly在9月10日为LeadDev撰写的关于构建软件工厂的指南中的一句话:
验证器部署到隔离实例,执行受影响的行为,并发布可检查的证明——日志、截图、可重放的跟踪。
—— Chris Kelly,Augment · LeadDev,2026年9月10日
我们想论证,该列表中的第三项所做的工作远超其位置所暗示的。
工厂已经有了日志和截图。它没有可重放的跟踪,而正是这一产物将报告结果的验证器与交出人类或第二个代理可以审问的东西的验证器区分开来。我们阅读了已发布的代理软件工厂描述,包括Cloudflare、Vercel、Builder.io、Augment、OpenAI和Uber的。大多数根本没有复现或诊断阶段。在少数有的当中,Kelly的是我们发现的唯一一个说明了该阶段应该产生什么的。
据我们所知,他描述的也是今天没有人交付的东西。Vercel的文档从另一面直截了当地指出了同一堵墙:调查可以在实现开始前复现故障,但对于需要浏览器的bug,每个浏览器会话都在有人在场的情况下运行,无人值守的运行则回退到记录的发现。
我们所知道的唯一硬数据来自Google的自动程序修复团队,他们测量了这一问题的两个方面(arXiv:2502.01821)。

复现是他们所测量的最高杠杆输入,而重建复现测试正是失败的环节。在后续工作中,他们指出自家工程师在使用已部署系统时,要求将复现测试包含在 AI 生成的补丁中,因为正是这一点让他们愿意信任它。
我们的两周是同一发现的一个小而具体的版本。对于 46 个前端修复,无需重建任何东西:发现 bug 的会话在发生时就被记录了下来。对于 34 个后端修复,这个循环做了 Google 所测量的更难的事,并独立复现了故障。这个教训比“智能体现在能修 bug 了”更狭窄,也更有用。自愈循环的好坏,取决于它能否第二次复现故障。
我们接下来要做什么
我们正在开发一个自愈循环,它将做到设置无摩擦,并且能在你自己的软件工厂循环中运行,这样你就能看到同样的结果。
如果你想参与 beta 测试,请告诉我们你的软件工厂情况,我们会与你跟进。
来源:Hacker News · replay.io