你需要一个软件工厂吗?
软件工厂是围绕软件工作的可重复循环,但达到可发布标准的代码仍需人类的品味与所有权——人类判断应被重新定位到意图、系统设计与质量门槛的上游,而非被完全移除。

软件工厂是围绕软件工作的可重复循环。如果你正在构建软件工厂,达到可发布标准的代码仍需人类的品味与所有权。我们将讨论这一点,包括你是否需要现在就建工厂。
如果是这样:
- 你可能需要人类在前期介入,决定产品意图、系统设计(如果你在意的话)以及你的质量标准。
- 进行代码审查(灯火通明的工厂),但要有的放矢地用在最需要的地方。我发现你要警惕自动化反向压力失效的地方,或是需要做出可维护性权衡的地方。
- 力求质量检查尽可能早且持续地进行。并非所有检查都必须如此,但这包括类型系统、自动化测试、变异测试、安全扫描器以及架构规则的检查都在范围内。
- 检查数量 ≠ 质量。你可能需要试验哪些检查能给你最佳的信噪比。准备好有意识地收紧或放宽你的约束。
你希望构建你的工厂,使人类品味的某些方面被编码到环境中,代理提供其工作正确的证据,而人类仍然“拥有”最终进入生产环境的内容。
你真的需要软件工厂吗?
根据我的经验,使用现成的编码工具链,你就能走得很远!比如Claude Code或Codex,配合多个会话、包含验证和约束的良好规格说明,甚至可以把一批GitHub问题连同实现标准和人工介入标准一起交给它们。Claude Code的例程以及Copilot/Codex的云端代理,已经能提供定时或事件驱动的循环,无需自定义基础设施。
当你需要可重复的一致运行、在代理之间交接工作、防止两个会话处理同一问题、保留证据以及在审查落后时暂停生产时,软件工厂才值得投入。

所以,我一开始就说软件工厂是围绕软件工作的可重复循环。我们实际上可以看一个提示词,它演示了一个非常小的工厂循环:
在修改代码前,阅读GitHub问题#123和仓库说明。
仅实现规定的验收标准。不要修改认证、计费、迁移或现有测试断言。在分支中工作,并保持差异可审查。
运行npm run lint、npm test和npm run build。如果某项必需检查无法运行,停止并解释原因。打开一个草稿拉取请求,附上你运行的检查、剩余风险以及仍需人类做出的任何决定。不要合并。
一个目标可以让这个循环持续进行,直到检查通过,我们可以每天早晨轮询GitHub问题以查找特定标签,或审查打开的拉取请求。分支保护可以强制执行合并边界,人类可以通过选择哪些内容准备就绪、进行审查并做出最终合并决定等,保持在循环中。
当你需要一个事件驱动的工作队列(例如 Slack 触发器、GitHub 问题、Linear、待办事项)在隔离的云环境中运行,以处理分类、实施和测试,并需要一些明确的人工监督时,可以添加一个软件工厂。有些工厂的循环末端会有一个监控代理,观察生产环境并提交问题,这些问题会再次进入分类流程。
根据我的经验,当难点在于让你的不同运行保持一致、在代理之间交接工作、避免不同会话认领同一问题、保留证据,以及当人工审查落后时停止生产时,工厂就会变得有用。
解决这个问题的方法可能听起来有点枯燥。例如,Warp 提到将每个传入的问题分类为四种状态之一——可实施、可规范、需信息、待实施——而这个标签就是触发下一个代理的信号。

这个标签一举多得:它既是队列,也是锁,而且由于会话只拾取标记为“就绪”的内容,它也是人工可以暂时搁置事项而不必永久拒绝的地方。
在工作流程方面,与仅使用 Claude/Codex 相比,有一些相似之处和不同之处:
- 引导:代理需要纠正方向时,你可以提供输入并重新引导它
- 通知:工厂如何表示受阻。这可能是因为需求不明确、它开始了有风险的操作,或者需要人工输入(引导)
- 交接:在云工厂/另一个代理/人工审查者之间移动任务、其状态和上下文。良好的交接会跟踪已完成的事项、剩余的工作以及为何需要交接。
在一个好的工厂中,人工不仅仅局限于在最后审查和批准最终的差异。他们可以在早期塑造工作,在实施过程中引导它,通过交接推进它,或者阻止它发布到生产环境。
验证环节是负责任的工厂投入大量时间的地方。我们稍后会详细讨论这一点。

如果你确实决定需要软件工厂,构建它并非唯一选择。搭建基础设施以扩展工厂规模可能工作量巨大,你可能需要考虑是购买还是自建。Factory.ai、Devin、Warp 和 HumanLayer 都在销售这个循环中的某些部分。
我实际把注意力放在哪里
过去一年里,我日常的软件开发体验发生了很大变化。我一直在谈论越来越多地与代理并行工作,朝着实现“灯火通明”的软件工厂迈进。很多人问我,这些到底意味着什么?你在构建什么?你在哪些项目上使用这些东西?很多是这样的:

所以在一个非常普通的日子里,我有一个更简单的“灯火通明”软件工厂。我可以有在云端运行的任务。其中一半任务可能是在为与我合作的小公司处理生产级客户端应用。这些应用会有真实用户,会有真实的身份验证、支付、订阅,以及需要谨慎对待的真实重大风险。你不能只是说,哦,代理,去干这些事,而没有测试、约束和质量检查作为保障。
我可以投入到我的开源项目中。我可以为我的书籍搭建配套网站。我可以开发各种工具。我也可以打造自己的应用程序。这些项目都是截然不同的应用类型,而我正在同时进行着。有时,它们唯一的共同点就是我用来处理它们的工具,对吧?也许我在做一次迁移,而另一些时候,我可能在进行真正繁重的功能开发。这些工作的影响范围也可能大相径庭。
因此,当你开始思考如何达到一个越来越频繁进行并行工作的状态时,我们正努力提升速度、提高生产力,并增强自主性——这意味着要让系统达到一个我们更信任它的水平——你确实需要考虑哪些地方绝对需要人工代码审查和人工输入。
其中很多工作将需要在前期完成,对吧?当你定义规格说明和需求时,产品的设计会是什么样子?产品的意图又会是什么样子?然后,你如何验证代理确实正确完成了工作?你如何确保它们没有破坏已有的系统?你如何确保它达到你的质量标准?
因此,生成代码本身未必是你最需要担心的部分。只要有足够的上下文,代理就能为我们编写实现、运行测试、检查失败并修改代码。我们需要达到一个状态,让环境中蕴含足够的人类品味,从而能够信任正在构建的东西,这样我们的人类注意力就能集中在最需要它的地方。
现在,有人提出反对意见,说:“嘿,我可不信你能把这么多东西都自动化掉。”这并不是说我们要把所有东西都自动化,对吧?但考虑到生成的代码量,我认为让人类全部阅读并不现实,尤其是在很多时候我们并不是在造火箭,对吧?我们是在构建用户界面,是在构建全栈应用。
我们的判断力和品味应该集中在最需要的地方。比如,系统中最有风险的部分是什么?哪里需要运用人类的品味?这可能是在前端,也可能是在系统运作方式上。不必覆盖百分之百。
我的认知带宽无法与智能体同步扩展
现实是,是的,我们现在可以同时启动几十个、几百个、甚至上千个智能体,但你自己的认知带宽却无法以同样的方式扩展。这可能会导致我之前提到过的认知或理解债务。

如果你回想一下,就在五到十年前,工程界曾大量讨论过上下文切换及其成本。我们会谈到人们多么讨厌在专注于任务时,有同事或其他人走到你桌前打断你。之后你需要很长时间才能重新进入心流状态,因为你必须重新跟上思路:我做到哪儿了?我在做什么?即使你脑中还有些残留记忆,仍然需要时间。
我们现在比以往任何时候都更频繁地进行上下文切换。在任何一天里,如果我在软件工厂之外工作,我可能同时与智能体一起处理五到十个不同的项目,或者在一个项目上同时推进五到十个不同的功能。可以说,我可以同时进行五到十个不同的会话。
这意味着我必须能够至少掌握其中几项。我有可能在信任自己对任务定义得足够清晰、明确了预期结果以及如何验证其完成质量的前提下,增加某些任务的自主权。但也会有一些任务,我可能并不那么放心,它们涉及更多风险或更微妙的细节,我必须投入关注。
考虑为你的审查者优化软件工厂。鉴于每种方法最终都将输出汇聚到一个人的注意力上,你应该思考,这个工厂在多大程度上降低了你仍需做出的决策的成本。
一个错误项目的失误
我记得当我和我的代理们同时处理多个并行项目时,有时我会不小心犯下这样的错误:比如,我在开发一个网页应用,想添加深色模式,心里已经有了大致的构想。但我不小心进入了另一个项目的会话,并输入了相同的提示。
于是我开始为一个完全不需要深色模式的东西实现它。我可能会犯这样的错误,我不希望我的软件工厂也犯类似的错误。
你需要真正从系统的角度来思考这个问题。你实际上是在尝试将软件工程文化、团队文化编码进一个系统中,使其具备同样的行为模式,让所有权归属明确,确保有人对结果负责,并且你对自己如何思考这些方面非常明确。
当绿色具有误导性时
即便在这些系统中,你也需要格外谨慎,对吧?我们很多人都见过这样的情况:当你让AI帮你通过测试时——比如编程测试或单元测试——它可能会修改单元测试以满足条件,或者改变代码逻辑来通过测试。但这并不意味着它真正遵循了你的意图,以实现功能行为与测试本应验证的内容之间的对齐,对吧?

仅仅因为软件工厂显示一切正常(绿色),并不意味着实际就是正常的,尤其是在你刚开始搭建这些系统的时候。你需要投入大量注意力,确保你的检查、验证等环节都设置得当,它们确实在做你期望它们做的事情。你不希望它们产生误导。
你不希望出现这样的情况:测试显示“嘿,实际上,我已经更改了支持的认证提供商。你让我添加GitHub作为认证提供商,但我的界面只够放三个位置,所以我去掉了其中一个。顺便说一句,那恰好是你们的客户真正想要的一个。”所以,你需要非常明确地规定你希望这些系统如何运作。
另外,安全性也极其重要。如果你的工厂读取了不可信的输入,比如GitHub问题或Slack消息,这些输入可能带有对抗性,并包含供应链攻击等问题。一些软件工厂产品,如Vercel Sandbox/AI ADK Factory,会在隔离的沙箱中运行其代理,仅持有任务所需的机密信息。这样,即使某个运行被攻破,也无法触及任务不需要的资源。你的防御最终会形成分层结构。
哪些旧项目值得重获新生?
我还认为,如今我们工作的一大部分在于决定什么应该存在。回想多年前,在人工智能出现之前,有那么多被遗弃的软件工程项目,那么多被搁置的周末项目和个人项目,它们之所以未能发布,是因为我们没有时间完成它们。我们没有精力去优先考虑将它们推出,因为它们对我们来说并不那么重要,或者我们找不到时间。
现在,完成这些项目对我们来说相当容易,但同样的人类判断问题也随之而来。这些项目值得存在吗?它们应该被发布吗?因为一旦你将它们公之于众,即使只有五个用户,也许你就得维护它们。也许你现在有了一个想要维持的质量标准。
我知道,多年来我有过许多GitHub项目,现在有了智能代理,我做的第一件事就是让项目能够构建起来。因为,当然,你克隆下来后,它现在无法构建,因为所有依赖都变了。一半的东西已经过时,或者到处都有安全漏洞,所以你必须更新它们。
然后,如果你没有测试,你还得添加测试,这样你至少能知道,如果你以某种方式升级项目,或者将其迁移到更现代的语言、框架或类似的东西,行为至少会保持不变。
接着你开始问自己,嗯,也许一个很傻的例子,但也许我当年用的是Twitter Bootstrap,而现在大家都在用Tailwind和shadcn,所以我必须重新实现用户界面。你会发现,突然间这花费了你更多时间,对吧?是的,智能代理可以更快地完成很多工作,但你现在不得不考虑产品感、品味以及所有这些因素。
你还在质疑,嗯,这是为谁做的?它有市场吗?是为我自己吗?还是为别人?如果我把它推向世界,既然现在任何人都能这么快地生成这些东西,它还会一样有趣吗?
所以我认为,这些事物是否值得存在的人性化问题,以及我们如何融入自己的品味和判断,我觉得这些仍然极其重要。这正是人类注意力这一稀缺资源真正发挥作用的地方。在过去,我们一天只有有限的时间。我们有会议,必须为设计和编码等事项预算时间。
现在有了代理来帮助我们,我认为你必须非常明确地知道你把时间花在了哪里,以及为什么。
当我构建一个示例时发生了什么
所以我要谈谈那82分钟的工厂运行。人们已经问我相当长一段时间了,你知道,“我如何构建一个软件工厂?”或者,“我习惯用Claude Code或Codex,我如何将我的设置升级到使用软件工厂?”
所以我一直在说的第一件事是,“你可能没问题。你的工作可能完全不需要工厂也能很好。”但我确实想给人们一个参考设置,让他们可以查看。所以我整理了一个名为Factory的仓库,你可以去看看。我还整理了一个演示应用和工作坊。
过去几年里,我常用的演示应用之一便是一款电影应用。我是个超级电影迷,热爱观影,几乎无时无刻不在看电影。因此,我有一个演示应用,起初它只是一个非常简单的电影应用。我希望这个工厂能够着手实现一系列功能。有几个不同的功能点:我想要一个收藏功能,可能还需要搜索功能,或许还要加入深色主题,诸如此类。
于是,我让我的工厂开始处理这些事务。你可以查看具体的实现过程。其中一个好处是,它确实捕捉到了实际问题。这些问题如果我只是要求一次性实现,可能根本不会发现。
大约在60分钟的时候,我感觉:“哇,这进展得异常缓慢。”我通过工厂询问我的测试框架:“为什么事情进展得这么慢?”它回答说:“这其实完全正常。所有验证器仍在运行中。”
你可能预期单个任务需要10分钟、15分钟或20分钟,但一旦开始包含验证、重试、浏览器检查、人工审查等额外延迟,它们可能需要两到四倍的时间。
我确实认为,这些额外步骤能够累积起来,提升系统的质量和信任度。从度量的角度看,你可能会关注诸如每个合并的PR成本、代码寿命等指标,这些可以作为理解债务的度量。
你还需要思考什么是有效延迟,什么是工厂开销。在我的案例中,验证器确实捕捉到了一些实际问题。部分时间可能花在了生成我想要的证据上,有些则是工厂运行的开销。我并没有花太多时间去优化它,但一个只是运行大量你并不觉得有价值的检查的工厂,并不意味着它就是高质量的。
你想研究的是,对于任何重复的检查,它们是否无关紧要?它们是否带来噪音?它们是否真的让系统更安全?
验证需要预算
我思考验证预算的方式,基本上就是我们正在讨论的。我们谈论的是一个验证预算。我以历史上思考性能预算的同样方式来思考它。

在软件开发生命周期的早期,你可以运行某些类型的检查,而有些检查虽然非常繁重,但提供的价值巨大,你会希望稍后再运行它们。有些快速检查,比如代码风格检查、类型检查,这些相对较快的检查可以在早期运行。
我们的完整测试套件可以在草拟拉取请求之前或之后更接近时运行。这可以包括变异测试、浏览器测试、安全检查和类似的内容。
我认为你不一定想用简单的摘要来替代这些。你需要真正的测试,但只需确保在正确的地方为它们做预算,因为你不希望拖慢开发循环。我当然绝不想拖慢我的开发循环。快速的迭代循环对我来说很重要,但我也希望保留那些检查和平衡。
当一次运行未能交付时
我上面写的大部分内容都涉及检查环节。
在他们的软件工厂中,Vercel 标记 每次代理运行为“成功”、“有缺陷”、“受阻”或“手动”,且只有“成功”会进入生产环境。其余则重新进入系统。我也一直在以类似的术语思考运行。

这里的“有缺陷”意味着实现了错误的东西,或者可能没有完整的上下文,因此需要修复。“受阻”意味着环境可能缺少凭据,所以你必须提供它。“手动”是一个边界,工厂可能还不允许跨越。
这三项中的两项可能有机械性的修复,而最后一项则关乎信任。
虽然这种分类很好,但它没有显示成本。回到我用TMDB应用实现的工厂,无拒绝的快速查找器耗时7分钟。收藏夹,有两次拒绝和中间一次人工决策,耗时56分钟。同一个工厂。所以我会将分类与每个阶段的计时配对,否则你只知道一次运行返回时有缺陷,却不知道发现这一点的代价。我要修复的另一件事是边界处的交接:我的示例工厂停止了第一个问题并将其移至factory:needs-info,这是正确的,但我不知道把答案放在哪里。手动运行并非在工厂停止时结束,而是在人类知道下一步该做什么时才结束。
自主性并非单一设置
几周前,我写了一篇关于代理自主性的文章,探讨如何思考自主性,因为自主性不会成为每个项目的单一设置。
验证能带来信任,也让你有能力赋予代理更多自主权。因此,举例来说,如果我在处理一项非平凡的变更,但已设置多项检查,一切都能正确验证,或许我还亲自手动检查过。下次在同一项目中执行类似任务时,我可能会更放心地给代理多一点自主权。
这就是你在构建这些软件工厂时需要考虑的事情。你的验证会随着风险而变化。你的目标是获得最佳的信噪比。你并不只是想运行一个庞大的检查清单。
我不得不重新学习的特性
有一个特性我一直推迟处理,当时我正同时使用多个Claude会话,同时处理几个不同的项目,每个项目又涉及几个不同的功能。Claude已经实现了我正在开发的那个功能。测试看起来是通过的。我当时没有在验证上花太多心思,但测试通过了,所以我认为它没问题,就合并了。
这是一个收藏功能。我当时觉得它其实还不错。我尝试在浏览器中查看,看起来似乎没问题,但几天后,我实际上回到了代码中,因为我想对这个功能做一些调整。
我不想直接让代理进行修改,因为它的工作方式很微妙。你点击图标时,它不会在点击时显示正确的效果,所以我想自己微调一下。我想理解它是如何工作的,这样才能正确指导我的代理。
我回到代码中,却无法向你解释这个功能是如何运作的。这个仓库是我的,对吧?我批准了那次更改。我理解其中很多部分是如何工作的,仓库的大部分我也懂,但我的理解并没有跟上不断累积的代码步伐。
我没能吸收的是,这个新增功能实际上是如何工作的,UI 是如何运作的,以及它对 UI 的影响是如何实现的。我不得不重新做这个功能,并一步步地思考:“这是怎么工作的?我该如何理解它?”
并行工作对理解的影响
当你进行并行工作时,它会放大这个整体问题,而在软件工厂中做这件事时,这种影响会更加显著。当你同时进行五到十个会话时,它们带来的问题远不止审查量增加那么简单。它们会形成多个心智模型,而当你专注于其他工作时,这些模型可能会逐渐冷却。
我们历来讨论过上下文切换的挑战,而一旦聊天被压缩,你拒绝某些方法,尝试不同的方案,与代理配对时,你将很难记住会话中发生的所有事情。
你可以向上滚动,但随着压缩的发生,你不会拥有所有内容,也无法将所有信息都记在脑中。代码往往保留了所做的决定,但并未保留做出该决定的原因。
我认为这对你来说可能是一个有用的学习点,在重要的情况下,考虑让代理存储关于其轨迹的信息,或者它如何处理问题的有趣经验,以便你以后可以回顾。
这可以是你决定提交到仓库的东西,也可以不提交。如果你想,可以保留在本地,也可以与团队分享,但之后可以查阅。而不是依赖它可能存在于某个会话中,或者你之后可能记得它。
它实际产出什么?
@threepointone 和 @bentlegen 发布了一些关于软件工厂的观点和看法,我深表赞同:


人们很容易被做事的机制所吸引,优化机制,却忘了它本该产出的东西。如果你的工厂主要产出的是更好的工厂,那你构建的软件产品就是它自身。
我认为投资于这个循环是好的,而且它会复利增长。失败在于当循环闭合时,工厂产出的一切都被工厂自身消耗,而外部没有人会注意到你是否关闭了它。我会采用的测试是“拉动”。外部必须有某种东西在要求改进。如果你说不出是谁在拉动,那你就是在打磨。
所有权并未消失
这一切背后有一个更广泛的原则。
人类亲手键入的代码比例可能会大幅下降。但我认为,人类的所有权不必随之减少。
- 仍有人选择要解决的问题。
- 仍有人选择架构方案。
- 仍有人设定质量标准。
- 仍有人决定哪些验证信号值得信赖。
- 仍有人判断证据何时足以交付。
而当最终系统出现故障时,“是代理写的”并不能成为借口。这就是为什么我认为软件工程的未来不应被简单描述为人类退出循环。相反,人类判断正在被重新定位。
我们应当将人类从那些机器能够产生更强、更快、更确定性信号的环节中解放出来。同时,我们应当将人类集中到那些情境、品味、风险与长期所有权最为关键的地方。
最优秀的软件工厂,其定义将不在于它们多大程度上消除了人类参与。
而在于它们如何明智地安排这种参与。
将人类判断力保留在意图、系统形态和质量标准的上游环节。在自动化反向压力变弱或后果变得主观的地方审查代码。尽可能早且持续地将每个确定性信号注入循环中。随着系统赢得或失去信任,有意识地收紧或放宽约束。
最终发布的代码,仍必须有人为之负责。足以发布的优秀代码,其起点仍是某个在乎它是否应当存在的人。