我们如何建立一个软件工厂,推动 Astro 的 GitHub 问题数量降至零

发布于

(供稿中无引号的文字为编辑整理)

每个人都在谈论软件工厂:将 AI 代理组装成一个管道,可以独立生产工作软件,就像工厂将原材料转化为成品一样。人们对此是否真有可能、自动化的程度能走多远、以及人们演示的“循环”是否有实际价值,争论不休。也有人早已将其视为失败。

与此同时,还有一个更安静、更加忧虑的对话在进行:开源维护者们正在经历压力。AI 热潮使得生成问题、拉取请求和安全报告几乎变得免费,而维护者要花费巨大的精力去阅读所有这些内容。保持项目健康的老方法在这种数量面前变得岌岌可危。

每个人对这两个话题都有热烈的看法。我们认为,我们可以提供更为独特的内容:真正的结果。在过去几个月里,我们在 Astro 存储库上运行了一个自动化的问题整理管道。它读取传入的错误报告,在沙箱中重现这些问题,诊断根本原因,并为报告者发送预览版本以进行验证。其底层引擎发展为 [Flue](https://flueframework.com/),这是一个开放的框架,用于构建这种代理自动化,您也可以使用它来构建您自己的解决方案。

这并不是一次成功的尝试。但经过多次迭代,我们成功将未解决的问题从200多个减少到大约30个,并预计在下个月内将其降至零。这将是这个存储库在超过5年的历史中首次实现零未解决问题。

我们不是通过宣布“问题破产”、自动关闭冷门问题或忽略报告而达到这个目标的。我们的方法是自动化问题整理,利用一组独立的 AI 子代理在 GitHub Actions 内部运行。接下来是我们如何实现这一点的故事,以及您可能从中获得的见解。

## 从代理技能开始
年初时,我们专注于自动化开发的一个特定领域:问题整理。作为一个开源项目,手动处理问题可能是工作中最耗时、收益最少的部分。有时候,处理一个问题仅重现就可能需要几个小时,更不用说修复它了。这是一个自然而然(但常常被忽视)的自动化起点。

我们开始开发一种代理技能。这使我们能够作为维护者在本地开发和测试自动化,在我们自己的机器上运行代码测试。然后,我们可以在我们的代码库中的 GitHub Action 中运行相同的测试,以实现该问题整理工作流技能的完全重用。

问题整理技能精确镜像了我们在手动解决问题时所采取的步骤:
1. **重现**:克隆提供的重现存储库,以验证报告的问题。
2. **诊断**:对代码库进行工具化,并引入日志记录以确定错误的根本原因。
3. **验证**:审查相关的测试套件、代码注释和文档,以确定该行为是否确实为错误或是预期功能。
4. **修复**:将重现转换为失败的单元测试,通过架构指南识别适当的解决方案,并部署修复。

为了防止 LLM 在不存在错误的情况下强制解决方案,每个阶段都由一个独立的子代理执行。这些子代理通过将其发现编译到一个 **report.md** 文件中,按顺序传递信息。

## 将技能转化为自动化
在对问题整理技能进行初步内部测试后,我们的重点转向构建一个完全自动化的管道。我们特别希望将该逻辑直接集成到 GitHub 工作流中,确保完全透明,以便任何人都可以轻松审核代理的顺序推理和操作步骤。

随着我们将其连接,我们意识到整个管道实际上只是一个由问题标签驱动的状态机。每个新的提交以“需要整理”的标签开始,一旦用户确认修复,它就会转移到“修复已验证”。超出这些标签过渡的,管道自身不保持状态;它只是回读问题的现有评论,以判断给定问题的状态以及接下来应该发生什么。

从那里,流程自行运行。当代理找到修复方案时,管道利用 [pkg.pr.new](http://pkg.pr.new) 启动预览版本,并将发现的所有内容发送回问题:包括它所发现的总结、完整的日志以及安装预览的说明。原始报告者随后可以尝试在他们自己的项目中应用该修复,如果确认有效,自动化会根据该问题打开一个拉取请求。

## 从问题整理到框架
在构建这一切时,我们不断注意到其中并没有什么特定于 GitHub 的内容。响应事件、运行一系列独立的子代理,以及将它们的推理与它们被允许采取的行动分开——这只是一种工作流。可以从 Slack 消息、计划任务或 webhook 运行,一样能够有效工作。将这种认识概括为无论部署在哪里或驱动哪个模型都能以相同方式工作的运行时,最终就形成了 [Flue](https://flueframework.com/): 一个开放的、平台无关的框架,用于构建持久的代理和工作流。

## 代理自动化的好处
当我们首次推出这个自动化系统时,我们对于其有效性以及可能对开发者社区产生的负面影响的担忧是合理的。人们害怕依赖自动化的机器人响应会显得冷漠,造成我们作为维护者与用户之间的进一步隔阂。

但这种情况并没有发生。如果说有什么变化,我们现在与用户的互动更多了,只是在更有效的场所:
- 在 Discord 中直接与我们的社区成员互动。
- 积极参与 RFC 讨论并处理新的功能请求。
- 密切合作与贡献者,帮助将他们的想法融入框架中。

关于自动修复的质量,我们的核心理念是,我们的 AI 代理应该能够成功解决绝大多数传入的问题。当代理无法识别出正确解决方案时,我们视这种失败为代码库中潜在架构或文档问题的指示,指向以下三个领域:
- 不透明的抽象:如果代理不能解释组件之间的边界,人类开发者很可能也会在代码结构上遇到困难。
- 缺失文档:关键代码段缺乏明确的注释,解释了其实现背后的理由。
- 测试不足:代码库缺乏全面的测试覆盖,尤其是单元测试。

一个清晰的例子出现在一系列相关的热模块替换 (HMR) 错误中。问题整理机器人曾多次试图修改一个特定的 if 条件以解决问题。虽然这一更改修复了目标错误,但由于缺乏对该特定条件的测试覆盖,导致了其他地方的回归。一旦我们添加了描述该语句所控制的确切逻辑的注释,机器人就会自我调整,并停止在该领域尝试错误的修改。

每次我们追踪到这些失败并添加缺失的注释、测试或更清晰的边界时,机器人在该代码库的表现会显著改善,接下来的每个开发者也会感受到这种提升。

## 将工作流转变为 GitHub Action
最初,我们的整理逻辑直接嵌入在 Astro 的单一代码库中。这种耦合使得迭代变得困难;升级 Flue 或修改工作流就像在没有安全网的情况下对现有基础设施进行手术。为了克服这一点,我们将逻辑解耦到一个独立的、可以测试的存储库: [triagebot-action](https://github.com/withastro/triagebot-action)。这种隔离使我们能够引入自动化测试,确保在触及我们主要代码库之前的稳定性。

今天,这个操作能够为 Astro 的问题管理提供支持,并从那里扩展开来。其他几个团队也已采用它,有些是直接使用,有些则分叉构建自己的专为其项目量身定制的“工厂”。第二条路径才是重点:triagebot-action 年轻而且依然在积极发展,所以我们不是将其作为一个完成的产品分享,而是作为一个工作参考,您可以阅读、学习并加以改编。

这个操作的连接部分如下:

或者,将您自己的代理指向该存储库,让其阅读该设置,包括添加状态机所依赖的标签。

无论您采用哪种路径,其根本理念比我们的具体实现更重要:一个可持续的反馈循环,能让维护者集中精力于框架本身,而不是管理待办事项。代码是开放的。您可以分叉它、简化它,或者仅借用适合您项目的部分。

**想要构建类似这样的东西?深入阅读 [triagebot-action](https://github.com/withastro/triagebot-action) 的代码,看看它是如何工作的,或将其分叉作为您自己存储库自动化的起点。如果您正在更加严肃地构建基于代理的基础设施,这正是 Flue 的用武之地:深入了解 [Flue framework](https://flueframework.com/) 以构建您自己的解决方案。我们非常期待看到您构建的内容。欢迎在 [Astro Discord](https://discord.cloudflare.com/) 分享您的“工厂”故事。

---

原文链接:[点击查看](https://blog.cloudflare.com/astro-issue-triage/)

评论

暂无评论。

0.044573s