为什么软件工厂会失败:仅靠测试驱动工程是不够的
为什么软件工厂会失败:仅靠测试驱动工程是不够的
为什么软件工厂会失败:仅靠测试驱动工程是不够的
核心论点是,仅仅依赖 AI 编程代理(coding agents)和测试驱动工程(harness engineering)无法维持代码质量,因为模型对糟糕的设计缺乏惩罚机制,导致代码的可维护性随时间推移而下降。
软件工厂概念的演进
软件工厂的概念起源于 1968 年的一次 NATO 会议,那次会议还创造了“软件工程”一词。在 AI 出现之前,一个典型的工厂涉及:人类决定构建什么、在 Jira 等系统中跟踪工作、人类进行构建和测试、提交 pull requests 进行审查、针对失败进行循环、发布到生产环境、添加监控以及整合用户反馈。团队学会了将对齐工作前置——在规划和架构上投入时间——以减少返工并将审查时间从数小时缩短至数分钟。
为什么“无人值守”工厂会崩溃
移除人工审查会创建一个“无人值守”(lights-off)工厂,这在初期会加速交付,但最终会产生难以维护的代码,导致系统停机并需要昂贵的重写。作者的团队在 2025 年 7 月尝试了完全无人值守的方法,让代理处理来自 ticket 的所有中小型工作。几个月后,他们遇到了代理无法解决的棘手问题,网站宕机,用户愤怒,团队在挖掘了数周由代理生成的 spaghetti code 后,最终不得不从头开始重写。
模型无法从当前基准测试中学习可维护性
当今的编程代理基准测试仅奖励测试是否通过,不对架构质量提供信号,因此强化学习(RL)无法提高可维护性。例如,SWE-bench Multilingual 如果修复了报告的问题且没有破坏现有测试,就会给补丁打 1 分,但对于到处引入 try-catch 块、懒惰的类型转换(lazy type casts)或其他侵蚀代码库健康度的模式,并没有惩罚。正如作者所言,“侵蚀代码库可维护性是没有惩罚的。”
评估代码质量的新兴尝试
像 SWE-Marathon (Abundant AI)、DeepSWE (Datacurve) 和 Frontier Code (Cognition) 这样的项目尝试通过使用数小时的任务、变异测试(mutation testing)或检查代码质量规则的裁判模型(judge models)来判断可维护性。然而,这些评估仍然缺乏一个快速、可靠的 oracle(真值来源),供强化学习在大规模范围内改进设计决策。作者观察到,“如果一个模型能可靠地分辨好代码和坏代码,它一开始可能就会写出好版本,”但可维护性没有快速的 oracle,因此我们无法在 RL 过程中对其进行奖励。
重新引入“人机协同”规划
为了在不牺牲质量的情况下重新获得速度,团队在让代理编写代码之前,应该将人力重新投入到产品审查、系统架构、程序设计和垂直切片(vertical slices)中。作者提出了四个阶段:产品需求(定义用户痛点和成功标准)、系统架构(在服务、端点、schema 上达成一致)、程序设计(详细说明类型、方法签名、调用栈树、文件树差异)以及垂直切片(构建端到端的 tracer bullets 而不是水平层级)。这反映了 AI 之前的最佳实践,但利用 AI 加速每个步骤,同时在设计判断上保持人工参与。
实际杠杆:规划节省审查时间
在前期设计上花费约三十分钟可以将审查时间从数小时缩短至数分钟,在保持代码健康的同时实现 2-3 倍的净速度增益。作者引用的内部数据显示,一小时的规划会议可以将审查时间从六小时减少到二十分钟,因为规格明确的变更更容易让代理正确生成,也更容易让审查者验证。
真正的问题是坏的 Pull Request 太多,而不是 PR 太多
感知到的 PR 过载源于需要返工的低质量 AI 生成变更,而不是合法工作的量。正如一位评论者所说:“你不是 PR 太多,你是坏的 PR 太多。”优秀的 PR 是审查的享受;而 AI 一次性生成的 PR 通常需要 50% 的返工,给提交者和审查者都带来了智力和情感负担。
将约束理论应用于 AI 增强开发
模型擅长孤立的编码任务,但在跨领域的设计决策方面表现挣扎;在这些约束内进行优化意味着在规划、测试和监控中寻找杠杆,同时在架构判断上保持人工参与。作者最后的建议是:深入了解约束,通过与模型协作培养直觉,在约束范围内优化系统,寻找杠杆,并去读那该死的代码。
社区观点与反论
评论者提出了额外的因素和替代观点:
- 有人指出,大型产品仍然需要人工对每一次变更进行输入,而使用 AI 自动化进行重构、测试和 UI 变更的小型实验可以成功。“我们的核心产品规模太大,根本不适合它们……我们为轻量级代码重构、编写测试、UI 变更等使用了 AI 自动化,它们效果很好。” (@pdp)
- 另一人质疑了时间线,认为模型在 2025 年秋季/2026 年春季左右经历了实用性的阶跃,使得该时期之前的经验相关性降低。“难道现在大家不普遍认为模型在 2025 年秋季/2026 年春季左右经历了实用性的阶跃吗?” (@fishtoaster)
- 有条评论建议在作者对切片策略的描述中互换“垂直”和“水平”术语。“我谦虚地建议作者查一下‘垂直’和‘水平’的定义,并互换它们的术语 + 修复他们的视频 :) ” (@bavell)
- 关于 pull-request UX,有人评论说 GitHub 的 PR 页面很糟糕,并称赞了 Linear 的基础 PR 审查功能,该功能按主题对变更进行分组并添加评论。“这些天我认为,糟糕的 UX 真的没有任何借口。Linear……推出了一个基础的 PR 审查功能……立刻,心理负担减轻了许多……” (@rglynn)
- 几位用户呼吁更好的验证和基准测试,提议建立一个“MaintainabilityBench”,奖励那些在执行任务时能检测重复、建议新架构层或提升类型约束的模型。“想象一个‘MaintainabilityBench’,奖励那些在处理任务时能检测代码重复并进行重构,而不是敷衍了事地复制代码的模型……” (@cadamsdotcom)
- 一位评论者强调,构建软件不仅仅是向 AI 分配 ticket;人类对设计选择的判断仍然至关重要。“我认为在编码过程中会产生‘观点’。在某个时刻,作为人类的你必须想‘等等……如果我们在这里使用 Redis 呢?’” (@firasd)
- 另一人分享了一个成功案例:使用护栏(guardrails)、计划审查、基于浏览器的 QA、对抗性审查、单元测试、linter、类型检查器、提交后钩子、形式化方法追踪和明确的工程原则(功能核心、命令式外壳、使不可能的状态成为不可能、纯函数式风格)运行代理工厂八个月。“我还没有遇到 OP 提到的墙……我使用了大量的护栏……” (@iamwil)
- 另一种观点认为瓶颈不在于模型,而在于测试驱动工程(harness)——可观测性、回滚和意图验证。“随着编码代理从 Demo 转向生产环境,瓶颈通常不在模型,而是在它周围的测试驱动工程:可观测性、回滚和意图验证。” (@jkwang)
- 最后,有人警告不要将 AI 工厂视为“解决一切”的按钮,指出工厂仍然需要意图、护栏和管理,就像任何传统工厂一样。“软件工厂不是一个解决一切的按钮(即上帝)。在传统工厂中,事情会出错和失败。机器会受污染。挤压机会卡住。你仍然需要建立意图,定义你关心什么,定义护栏,当然还要管理工厂。” (@rapatel0)
这些社区见解强化了作者的结论:仅靠测试驱动工程是不够的;即使 AI 加速了软件开发的机械部分,维持代码质量仍需要刻意的人机协同设计、规划和审查。