超越提示词:KubeStellar 如何利用 AI 智能体实现 81% 的 PR 采纳率

0 阅读9分钟

\n\n本文介绍了作者利用 AI Agent 开发 KubeStellar 控制台的经验。他提出“AI 代码库成熟度模型”,强调核心不在于模型,而在于围绕代码构建的测量与反馈闭环,最终实现 81% 的 PR 采纳率。

译自:Beyond prompting: How KubeStellar reached 81% PR acceptance with AI agents

作者:Andy Anderson

在使用编程智能体构建 KubeStellar 控制台的过程中,令人惊讶的不是模型能力的大小,而是周围代码库必须承担的大量繁重工作。

去年 12 月中旬,我开始从零开始构建 KubeStellar 控制台。这是一个用于 Kubernetes 的多集群管理仪表盘,属于云原生计算基金会(CNCF)沙箱项目 KubeStellar 的一部分。技术栈后端是 Go,前端是 React 和 TypeScript,打包使用 Helm。没有团队。只有我和两个在并行终端会话中运行的 AI 编程智能体。

前两周是这个领域里每个人都会描述的“蜜月期”。代码从智能体中涌现的速度快到我来不及阅读。我原本计划花费三天时间的工作,在两个小时内就完成了。我在脑子里记下了一份一直想构建的功能列表,然后一个接一个地把它们叫出来实现。

接着,挫折感来袭了。

构建失败的方式变得难以追踪。前一天的架构选择被悄悄覆盖。范围在未经要求的情况下不断扩大。智能体不断修改我并未指定的外部文件,而连锁反应是最糟糕的部分——修复了一个问题,结果另外三个地方又坏了。我开始花更多的时间在回滚上,而不是在审查上。承诺的 10 倍效率提升开始让人感觉像是一种负资产,我决定放弃整个方案。

这种从兴奋到极度沮丧的转变轨迹似乎是普遍存在的。业界通常的建议是给智能体更多的自主权:让它运行更久,触达更多文件,并进行自我修复。根据我的经验,这往往会让失败模式变得更糟,而不是更好。杠杆作用的方向恰恰相反。AI 辅助代码库的智能不在于模型本身,而在于代码库围绕它构建的循环。如果你想让智能体做更多,周围的代码就必须测量更多。

四个月过去了,KubeStellar 控制台现在的状态非常好。目前有 63 个 CI/CD 工作流,32 个夜间测试套件,十二个分片的覆盖率达到了 91%。在 82 天的时间里,PR 采纳率稳定在 81% 左右。社区 Bug 报告从提交到合并修复大约需要 30 分钟。功能需求在大约一小时内就能以 Pull Request 的形式落地。这些都不是更好模型的结果。改变的是代码本身学会了测量什么。

五个紧密的循环让我走到了这一步。我将它们视为我称之为“AI 代码库成熟度模型”的台阶——辅助级(Assisted)、指令级(Instructed)、测量级(Measured)、自适应级(Adaptive)和自维持级(Self-Sustaining)。我将按它们出现的顺序逐一介绍,因为我认为这个顺序是无法重排的。

1. 写下你不断纠正的内容(指令级)

成本最低、可能回报最高的干预措施,就是将你个人的偏好外部化。我首先在代码库根目录下创建了一个 CLAUDE.md,接着为 Pull Request 规范创建了 .github/copilot-instructions.md 文件。接下来是一份卡片级开发指南,记录了我拒绝 AI 生成 PR 的首要原因。

那一份指南最终涵盖了我大约 90% 的拒绝标准。开发过程变得更加一致。智能体不再重复同样的错误。我不会称之为测量——在那个阶段,我仍然依靠直觉——但它过滤掉了足够的噪声,使得标准化的测量成为可能。

2. 将测试视为信任层,而不只是正确性层(测量级)

这是最关键的转变。自主工作流的测试不同于人类工作流的测试。这是智能体判断自己是在让系统变好还是变坏的唯一信号。

在四周的时间里,我增加了 32 个夜间测试套件,并将十二个并行分片的覆盖率推到了 91%。这些套件涵盖了合规性、性能、空值安全(nil safety)、可访问性、国际化和视觉回归。与此同时,我开始将每个类别的 PR 采纳率记录到 auto-qa-tuning.json 中。事实证明,该文件是后续所有工作的核心支柱。

覆盖量很重要,广度也很重要。但几乎让我功亏一篑、也是我要向尝试此道的任何人发出最严厉警告的,是确定性。

“在人类工作流中,不稳定的测试只是个烦恼。但在自动化工作流中,它会对整个信任模型造成缓慢且无声的侵蚀。”

一个关于拖放功能的 Playwright 端到端测试 通过率大约为 85%。在人类工作流中,这是可以忍受的;你重新运行一下,然后继续。但在测试结果决定是否合并的自动化工作流中,85% 成功率的测试就是一场灾难。好的 PR 被随机拦截,而差的 PR 却被放行。我花了三天时间研究这一个测试,结果发现是 CI 环境中的动画完成计时问题。这个教训具有普适性:你无法在不可靠的信号之上构建自动化。在人类工作流中,不稳定的测试只是个烦恼。但在自动化工作流中,它会对整个信任模型造成缓慢且无声的侵蚀。

3. 在能够测量之前不要自动化(自适应级)

有了采纳率记录后,自动化变成了一个更安全的提议。自动 QA 开始每天运行四次,涵盖八层质量检查。决定系统专注于哪类工作的轮换权重开始根据数据进行自我调整。可访问性 PR 的采纳率为 62%,因此其权重上升到 0.93。算子类(Operator-category)PR 的采纳率仅为 8%(129 个关闭的 PR 中只有 11 个被合并),因此该权重降为零,CI 周期被重新分配。

围绕这个核心,还有几个循环也闭合了:

  • 分流程序每 15 分钟扫描四个仓库。
  • PR 监控器每 60 秒轮询一次构建状态。
  • 错误恢复工作流使用指数退避算法处理卡住的智能体。
  • 一个 GA4 查询每小时针对生产分析运行一次,在用户报告之前就为错误峰值提交 GitHub Issues。

“没有测量的自动化不是成熟——它是大规模的失败。”

所有这些的模式都是一样的:先测量,后自动化。颠倒顺序就是自主系统失控的原因。没有测量的自动化不是成熟——它是大规模的失败。

4. 让代码库成为操作手册(自维持级)

在某个时间点——我也说不清具体是哪一天——系统不再需要我参与其中就能运作。它的行为由其产物决定:指令文件、测试、工作流规则以及采纳率历史。社区成员在任何时间开启 Issue,这些 Issue 在我起床之前就已经被分流、分配、修复、测试并排队等待审查。

有一个案例体现了这种转变。4 月份,一位用户提交了一个 Bug,报告称当 Pods 困在 ImagePullBackOff 状态时,集群却被标记为“健康”。在我查看之前,系统已经给出了回答:集群健康反映的是基础设施健康(节点就绪、API 可达性),这在架构上与工作负载健康是分开的。这并不是 Bug。这只是 Kubernetes 的思维模型与仪表盘显示内容不完全匹配。这个设计决策已经编码在测试、健康检查逻辑和文档中;智能体能够解释它,因为代码库已经“知道”了它。

这,比任何吞吐量数字都更能代表“代码即模型”在实践中的真实样貌。

5. 询问“为什么”,而不是“做什么”

一个提示词习惯产生了不成比例的效果。我不再说“修复这个 Bug”,而是开始问:“你为什么没发现这个?”前一种表达方式产生的是一个补丁。后一种则往往会产生根因分析,并作为副作用,生成一个新的测试、指令或规则,从而封死一整类类似的失败。

命令得到的是一系列孤立的修复。提问则会产生复利。久而久之,正是这些提问将代码库变成了自改进系统,如果你是从零开始,它们也是最初产生指令文件的源头。

这对维护者和领导者意味着什么

如果你正在领导工程团队,请停止优化你所使用的模型。模型是一个商品化组件,更换模型只是一个周末的工作。重建周围的反馈系统则需要一个季度的工作。差异化在于智能基础设施:指令文件、测试套件、指标和工作流规则。

对于开源维护者来说,这直接解决了 CNCF 社区对话中不断浮现的职业倦怠问题。如果一个代码库能够编码足够的维护者判断力,使得智能体可以处理分流、生成 Pull Request 并向用户解释设计决策,那么社区就可以主要通过提交 Issue 来引导项目。

维护者变成了系统的架构师,而不是日常操作员。对于 KubeStellar 控制台来说,这并非假设。它现在就在运行。它是否能扩展到单人维护的沙箱项目之外,还需要更广泛的社区去测试。我真的很想知道答案。

大多数团队仍处于第一个循环中,即编写 Prompt 和审查输出。那是每个人的起点。重点不是冲向最后一个循环。重点是察觉哪个循环实际上阻碍了你,然后去闭合下一个循环。

代码库承载了我学到的东西。测试捕捉到了我脑子里记不住的东西。而仍然属于我的——我认为这部分永远属于我——是决定什么值得构建,对什么说不,以及好的产品应该是什副样子。全 工智能