YouMind
登录

你需要一个软件工厂吗?

@addyosmani
英语2026年8月27日
277K
405
32
19
719

TL;DR

Addy Osmani 探讨了作为 AI 驱动开发可重复循环的“软件工厂”,强调了人类意图、验证预算和所有权的重要性,以防止技术债务和认知负债。

软件工厂是围绕软件工作的可重复循环。如果你正在构建一个软件工厂,足够好到可以发布的代码仍然需要人类的品味和所有权。我们将讨论这一点,包括你是否真的需要一个工厂。

如果是这样:

  • 你可能需要在前期让人类参与进来,以决定产品意图、系统设计(如果你在意的话)以及你的质量标准。
  • 要进行代码审查(灯火通明的工厂),但要刻意选择最需要它的地方。我发现你需要留意自动化反向压力失效的地方,或者需要做出可维护性权衡的地方。
  • 目标是让质量检查尽可能早且持续地进行。并非所有检查都必须如此,但这包括类型系统、自动化测试、突变测试、安全扫描器和架构规则检查工具。
  • 检查的数量不等于质量。你可能需要试验哪些检查能给你带来最佳的信噪比。准备好有意识地收紧或放宽你的约束条件。

你要构建你的工厂,使得人类品味的某些方面被编码到环境中,Agent 能提供其工作正确的证据,并且人类仍然“拥有”最终发布到生产环境的内容。

你真的需要一个软件工厂吗?

根据我的经验,使用你现有的编码工具就能取得惊人的进展! 例如,Claude Code 或 Codex、多个会话、包含验证和约束的良好规范。你甚至可以把一批 GitHub Issue 连同实现和人类参与的标准一起交给它们。Claude Code 的例程以及 Copilot/Codex 的云端 Agent 已经为你提供了定时或事件驱动的循环,而无需自定义基础设施。

当你需要可重复、一致的运行、在 Agent 之间交接工作、阻止两个会话处理同一个 Issue、保留证据以及在审查落后时暂停生产时,工厂才是有价值的。

Addy Osmani - inline image

所以我一开始说软件工厂是围绕软件工作的可重复循环。我们实际上可以看一个提示词,它演示了一个非常小的工厂循环:

在修改代码之前,请阅读 GitHub Issue #123 和仓库说明。

仅实现所述验收标准。不要修改身份验证、计费、迁移或现有的测试断言。在一个分支中工作,并保持差异易于审查。

运行 npm run lint、npm test 和 npm run build。如果某个必需的检查无法运行,请停止并解释原因。创建一个草稿 Pull Request,附上你已运行的检查、剩余的风险以及任何仍需要人类做出的决定。不要合并。

一个目标可以让这个过程持续进行,直到检查通过,并且我们可以每天早上轮询 GitHub Issue 以查找特定标签或审查开放的 Pull Request。分支保护可以强制执行合并边界,而人类可以通过选择哪些内容准备就绪、进行审查以及做出最终的合并决定等方式来保持参与。

当你需要一个事件驱动的工作队列(例如 Slack 触发器、GitHub Issue、Linear、待办事项列表)在隔离的云环境中运行,以处理分类、实现和测试,并需要一些明确的人工监督时,就添加一个软件工厂。有些工厂的循环以监控 Agent 监视生产环境并提交 Issue 进行再次分类而结束。

根据我的经验,当困难的部分在于让你的不同运行保持一致、在 Agent 之间交接工作、避免不同会话认领同一个 Issue、保留证据以及在人工审查落后时停止生产时,工厂就变得有用了。

解决这个问题的方法可能听起来有点无聊。例如,Warp 提到将每个传入的 Issue 分类为四种状态之一——准备实现、准备规范、需要信息、等待实现——而这个标签就是触发下一个 Agent 的信号。

Addy Osmani - inline image

这个标签一举多得:它是队列,是锁,并且由于一个会话只选取标记为“准备就绪”的内容,它也是人类可以搁置某些内容而无需永久拒绝的地方。

在工作流程方面,与仅使用 Claude/Codex 相比,有一些相似之处和不同之处:

  • 引导:Agent 需要方向修正,你可以提供输入并重新引导它
  • 通知:工厂如何报告自己被阻塞了。这可能是因为需求不明确、它开始做一些有风险的事情,或者它需要人类输入(引导)
  • 交接:将任务、其状态和上下文在云端工厂/另一个 Agent/人类审查者之间移动。良好的交接会跟踪发生了什么、还剩下什么要做以及为什么需要交接。

在一个好的工厂中,人类不仅仅局限于在最后审查和批准最终的差异。他们可以在早期塑造工作,在实现过程中引导它,通过交接来处理它,或者阻止它发布到生产环境。

验证是一个负责任的工厂花费大量时间的地方。我们稍后会详细介绍。

Addy Osmani - inline image

如果你决定确实需要一个软件工厂,构建它并不是唯一的选择。搭建基础设施来扩展工厂可能需要大量工作,你可能需要考虑购买与构建。 Factory.ai、Devin、Warp 和 HumanLayer 都提供这个循环中的部分功能。

我实际把注意力花在哪里

过去一年里,我日常的软件开发体验发生了很大变化。我一直在谈论越来越多地与 Agent 并行工作,朝着灯火通明的软件工厂迈进。很多人问我,这些东西到底意味着什么?你在构建什么?你在哪些项目上使用这些东西?很多是这样的:

Addy Osmani - inline image

所以在一个非常普通的日子里,我有一个更简单的灯火通明的软件工厂。我可以让任务在云端运行。其中一半的任务可能是在为我合作的小公司处理生产环境的客户端应用程序。它们会有真实的用户,真实的身份验证、支付、订阅,以及你需要小心的真正重大风险。你不能只是说,“哦,Agent,去做这个”,而没有测试、约束和质量检查。

我可以处理我的开源项目。我可以为我的书籍构建配套网站。我可以开发工具。我可以构建我自己的应用程序。这些都是我正在处理的非常非常不同类型的应用程序。有时它们唯一的共同点就是我用来处理它们的工具,对吧?也许我在做一个迁移。其他时候,我可能在做真正重大的功能开发。工作的影响范围也可能非常非常不同。

所以,当你开始思考如何达到一个我们越来越多地进行并行工作、努力提高速度、提高生产力、提高自主性的地方——这意味着让系统达到我们更信任它的程度——你确实需要考虑哪些地方绝对需要人类代码审查、人类输入。

其中很多将需要在前期完成,对吧?当你定义你的规范、需求时,产品设计会是什么样子?产品意图会是什么样子?然后你如何验证 Agent 已经正确地完成了工作?你如何验证它们没有破坏现有的系统?你如何确保它满足你的质量标准?

因此,生成代码不一定是你最需要担心的部分。只要有足够的上下文,Agent 就可以为我们编写实现、运行测试、检查失败并修改代码。我们需要达到一个状态,让我们觉得环境中已经编码了足够的人类品味,从而可以信任正在构建的东西,这样我们人类的注意力就可以集中在最需要的地方。

现在,有些人提出反对意见,说,“嘿,我不相信你可以就这样自动化掉这么多东西。” 这并不是说我们要自动化掉所有东西,对吧?但是考虑到正在生成的代码量,我认为让人类阅读所有代码是不现实的,尤其是很多时候我们并不是在建造火箭,对吧?我们在构建 UI,我们在构建全栈应用。

我们的判断力、我们的品味最好集中在最需要的地方。比如,系统中风险最高的部分是什么?我们需要在哪里应用人类的品味?这可能在前端,可能在系统的工作方式上。它不必是 100% 的代码。

我的认知带宽无法与 Agent 同步扩展

现实情况是,是的,我们现在可以并行启动数十、数百、数千个 Agent,但你自己的认知带宽却无法以同样的方式扩展。这可能会导致我之前谈过的认知或理解债务。

Addy Osmani - inline image

如果你回想一下仅仅五到十年前,工程社区中有很多关于上下文切换及其成本的讨论。我们会谈论人们多么讨厌在专注于一项任务时,同事或某人走到你的办公桌前。你需要很长时间才能重新进入心流状态,因为你必须重新跟上进度:我做到哪了?我在做什么?即使你脑子里还留有一点残余信息,仍然需要时间。

我们现在比以往任何时候都进行更多的上下文切换。在任何一天,如果我在软件工厂之外工作,我可能同时处理五到十个不同的项目,每个项目都有 Agent,或者同时处理一个项目上的五到十个不同的功能。可以说,我可以有五到十个不同的会话。

这意味着我必须能够跟上其中至少几个。如果我有信心已经足够好地定义了任务、定义了结果以及如何验证它是否完成得足够好,那么我有可能增加对某些任务的自主权。但也会有一些任务,我可能不一定有这种感觉,并且涉及更多风险或更多细微差别。我将不得不投入注意力。

考虑为你的审查者优化软件工厂。鉴于这些方法中的每一种仍然将其输出路由到一个人的注意力上,你应该问问工厂让你仍然需要做出的决定变得便宜了多少。

一个项目搞错的错误

我记得当我同时用我的 Agent 处理多个并行项目时,有几次我无意中做了些事情,比如,也许我正在开发一个 Web 应用,我想添加一个深色模式,所以我在脑子里想好了,好吧,这就是它需要的样子。但我错误地进入了另一个项目的会话,并开始输入相同的提示。

所以我开始为某个完全不需要深色模式的东西实现它。所以我可能会犯这种错误。我不想让我的软件工厂犯这种错误。

你需要真正从系统的角度来思考这个问题。你实际上是在尝试将一种软件工程文化、一种团队文化编码到一个系统中,以便它具有相同的行为,以便所有权归属于某个地方,以便仍然有人为发生的事情负责,并且你非常明确地思考这些事情。

当绿色具有误导性时

即使在这些系统中,你也要非常小心,对吧?我们很多人都见过,当你要求 AI 帮助你通过测试时,比如我们谈论的是编程测试、单元测试,它可以修改单元测试以满足条件,或者修改代码逻辑以通过条件。这并不意味着它实际上遵循了你的意图,以使功能行为和测试应该测试的内容保持一致,对吧?

Addy Osmani - inline image

仅仅因为一个软件工厂显示一切都是绿色的,并不意味着它实际上是绿色的,尤其是在你刚开始设置这些东西的时候。你需要投入大量注意力,确保你的检查、你的验证等等都以正确的方式设置。它们正在做你期望它们做的事情。你不想让它们产生误导。

你不想遇到这样的情况:你的测试说,“嘿,实际上,我已经更改了支持的身份验证提供商。” 你要求我添加 GitHub 作为身份验证提供商,但是,“嘿,我的 UI 只有三个位置,所以我删掉了其中一个。” 然后,“顺便说一句,那恰好是你的客户想要的一个。” 所以你只需要非常明确地说明你希望这些系统如何工作。

顺便说一句,安全性也非常重要。如果你的工厂读取不受信任的输入,比如 GitHub Issue/Slack 消息,它可能具有对抗性,并包含供应链攻击等问题。一些围绕软件工厂的产品,比如 Vercel Sandbox/AI ADK Factory,会在隔离的沙箱中运行它们的 Agent,只保留任务所需的密钥。这样,一个被攻破的运行就无法触及任务不需要的东西。你的防御最终是分层级的。

哪些旧项目值得重获新生?

我还认为,我们如今工作方式的一个重要部分是决定什么应该存在。如果你回想很多年前,在 AI 出现之前,有那么多被放弃的软件工程项目,那么多被放弃的周末项目、个人项目,它们之所以没有发布,是因为我们没有时间完成它们。我们没有精力优先考虑把它们推出去,因为它们对我们来说没那么重要,或者我们找不到时间。

现在,完成这些项目对我们来说相当简单,但同样的人类判断问题出现了。这些项目值得存在吗?它们应该发布吗?因为你把它们发布到世界上,即使只有五个用户,也许你也需要维护它。也许你现在有了一个想要维护的质量标准。

我知道这些年来我有过很多 GitHub 项目,现在有了 Agent,我做的第一件事就是让项目能够构建起来。因为,当然,你克隆它,现在它构建不起来了,因为所有的依赖都变了。一半的东西都过时了,或者到处都是安全漏洞,所以你必须更新它们。

然后你必须添加测试(如果你之前没有测试的话),这样你就知道,如果你以某种方式升级项目,或者将其迁移到更现代的语言或框架之类的东西,至少行为会保持不变。

然后你开始问自己,好吧,也许,一个愚蠢的例子,但也许我以前用 Twitter Bootstrap 做这个,但现在大家都在用 Tailwind 和 shadcn,所以我必须重新实现 UI。你会注意到,突然间这花了你更多时间,对吧?是的,Agent 可以更快地完成很多工作,但你现在必须考虑产品感觉、品味和所有这些因素。

你仍然会质疑,好吧,这是为谁做的?它有市场吗?是为我自己吗?是为其他人吗?如果我把它发布到世界上,考虑到现在任何人都可以像这样快速启动这些东西,它还会那么有趣吗?

所以我认为,这些事物是否值得存在这个人类问题?我们如何融入我们的品味和判断?我觉得这些东西仍然极其重要。这正是人类注意力这种稀缺资源真正发挥作用的地方。在过去,我们一天只有有限的时间。我们有会议。我们必须为设计和编码等事情预算时间。

现在我们有了 Agent 来帮助我们,我认为你真的必须非常明确地把时间花在哪里以及为什么。

当我构建一个示例工厂时发生了什么

所以我要谈谈那 82 分钟的工厂运行。人们问了我很长时间,“我该如何构建一个软件工厂?” 或者,“我习惯使用 Claude Code 或 Codex。我该如何将我的设置演变为使用软件工厂?”

所以我说的第一件事是,“你可能没问题。你的工作可能完全不需要工厂。” 但我确实想给人们提供一个可以参考的设置。所以我整理了一个名为 Factory 的仓库,你可以去看看。我还整理了一个演示应用和工作坊。

在过去的几年里,我用于很多事情的演示应用是一个电影应用。我是一个大影迷。我喜欢看电影。我一直在看电影,所以我有一个演示应用,它最初是一个非常简单的电影应用。我希望工厂能够实现一些功能。有几个不同的功能。我想要一个收藏功能。我希望它能够进行搜索,也许还想加入一个深色主题,诸如此类。

所以我让我的工厂开始处理这些事情。你可以查看实现。它的一个好处是实际上能捕捉到真正的问题。如果我只是要求它一次性实现,这些问题可能是我不会捕捉到的。

也许在大约 60 分钟的时候,我感觉,“哇,这进行得异常缓慢。” 我使用工厂询问我的工具,“为什么事情进展缓慢?” 它说,“这完全正常。所有的验证器仍在运行。”

你可能期望单个任务需要 10 分钟、15 分钟、20 分钟,但一旦你开始包含验证、重试、浏览器检查、人工审查以及任何这些额外的延迟,它们可能需要两到四倍的时间。

我确实认为这些可以累积起来,带来更好的质量和更好的系统信任度。从度量的角度来看,你可能会查看每个合并 PR 的成本和代码保质期等指标,作为理解债务的指标。

你还需要思考什么是有用的延迟,什么是工厂开销。在我的例子中,验证器捕捉到了一些真正的问题。有一点时间可能花在了生成我想要的证据上。其中一些是工厂运行的开销。我没有花任何时间优化它,但是一个只是运行大量你发现没有价值的检查的工厂,并不意味着它是一个高质量的工厂。

你想研究一下,对于任何重复的检查,它们是否无关紧要?它们是否嘈杂?它们是否真的让系统更安全?

验证需要预算

我思考验证预算的方式,基本上就是我们正在讨论的。我们在谈论一个验证预算。我以与历史上思考性能预算相同的方式来思考它。

Addy Osmani - inline image

有些类型的检查你可以在软件开发生命周期的早期运行,而有些检查非常重,但它们提供了巨大的价值,你会希望稍后运行它们。有一些快速的检查,例如,代码检查、类型检查。这些是相对快速的检查,你可以在早期运行。

我们完整的测试套件可以在草稿 PR 即将组合之前或之后运行。这可以包括突变测试、浏览器测试、安全检查等等。

我认为你不一定想用摘要来替换它们。你需要真正的测试,但你只需要确保在正确的地方为它们做预算,因为你不想减慢你的开发循环。我当然不想减慢我的开发循环。拥有快速的迭代循环对我来说很重要,但我也仍然想要那些检查和平衡。

当一次运行没有发布时

我上面写的很多内容都与检查有关。

在他们的软件工厂中,Vercel 将每个 Agent 运行标记为“成功”、“有缺陷”、“阻塞”或“手动”,并且只有“成功”才会发布到生产环境。其余的重新进入系统。我一直在以类似的术语思考运行。

Addy Osmani - inline image

这里的“有缺陷”意味着实现了错误的东西,或者可能没有完整的上下文,所以必须修复。“阻塞”意味着环境可能缺少凭证,所以你必须提供它。“手动”是一个边界,工厂可能还不能跨越。

这里的三件事中有两件可能有机械性的修复,最后一件是关于信任的。

虽然这种分类很好,但它没有向你显示成本。回到我用 TMDB 应用实现的工厂,没有拒绝的快速查找器花了 7 分钟。收藏功能,中间有两次拒绝和一次人类决定,花了 56 分钟。同一个工厂。所以我会将分类法与每个阶段的计时配对,否则你知道一次运行返回时有缺陷,却不知道发现这个缺陷花了你什么代价。我要修复的另一件事是边界处的交接:我的示例工厂停止了第一个 Issue 并将其移动到 factory:needs-info,这是正确的,但我不知道把我的答案放在哪里。一次手动运行不是在工厂停止时结束,而是在人类知道下一步该做什么时结束。

自主性不是一个单一的设置

几周前我写了一篇关于 Agent 自主性的文章,以及如何思考自主性,因为自主性不会是对每个项目都单一的设置。

验证为你赢得信任,并为你赢得授予 Agent 更多自主权的能力。所以,例如,如果我在处理一个非平凡的更改,但我设置了许多检查,一切都得到了正确验证,并且可能我自己也手动检查过了。下次我在同一个项目中做类似的任务时,也许我会觉得给 Agent 多一点自主权很舒服。

这就是你在构建这些软件工厂时需要考虑的事情。你的验证会随着风险而变化。你的目标是获得最佳的信噪比。你不仅仅是想有一个正在运行的大检查清单。

我不得不重新学习的功能

有一个功能我一直推迟,那天我同时使用多个 Claude 会话,同时处理几个不同的项目,每个项目同时处理几个不同的功能。Claude 实现了我正在处理的功能。看起来测试通过了。我没有在验证上投入太多思考,但测试通过了,所以我认为它有效。我合并了它。

这是一个收藏功能。我以为这实际上相当不错。我尝试在浏览器中检查它。看起来没问题,但几天后,我实际上回到了代码,因为我想做一些调整。

我并不想让我的 Agent 直接修改代码,因为它的工作方式有点微妙。点击图标时,它无法正确显示点击效果,所以我只想微调一下。我想了解它的工作原理,这样才能正确地指导我的 Agent。

我回到代码中,却无法向你解释这个功能是如何运作的。这个代码仓库是我的,对吧?我批准了那次改动。我理解其中大部分代码的运作方式,也理解仓库中很多部分的工作原理,但我的理解速度已经跟不上不断累积的代码量了。

我未能掌握的是,这个新增的功能实际上是如何工作的,UI 是如何运作的,以及它的效果是如何实现的。我不得不重新审视这个功能,一步步地问自己:“这是怎么工作的?我怎样才能理解它?”

并行工作对理解力的影响

当你进行并行工作时,它会放大这个整体问题,而在软件工厂中工作时,这种放大效应会更加明显。当你同时进行五到十个会话时,它们造成的远不止是审查量的问题。它们会创建多个心智模型,而这些模型在你处理其他工作时可能会逐渐冷却。

我们过去一直在讨论上下文切换带来的挑战,一旦聊天内容被压缩,你拒绝了一些方法,尝试了不同的方案,与 Agent 进行配对,你就很难记住会话中发生的所有事情。

你可以向上滚动,但随着压缩的发生,你无法看到所有内容,也无法将所有信息都记在脑子里。代码通常能保留所做的决定,但无法保留做出该决定的原因。

我认为这对你来说可能是一个有用的经验,重要的是,考虑让你的 Agent 实际存储关于其轨迹的信息,或者它解决问题方法的有趣经验,以便你以后可以回顾。

你可以决定是否将这些信息提交到代码仓库。你可以选择将其保存在本地,也可以选择与团队分享,但这样一来,以后就可以查阅这些信息。而不是依赖它可能存在于某个会话中,或者你以后可能还记得它。

它实际产生了什么?

@threepointone 和 @bentlegen 发布了一些关于软件工厂的观点和看法,我非常赞同:

Addy Osmani - inline image
Addy Osmani - inline image

人们很容易沉迷于执行的机制,优化这些机制,却忘记了它本该产生什么。如果你的工厂主要产出的是一个更好的工厂,那么你构建的软件,其产品就是它自身。

我认为投资于这个循环本身是好的,并且会产生复利。失败在于当循环闭合时,当工厂生产的一切都被工厂自身消耗,而外部没有人会注意到你是否关闭了它。我会用“拉动”这个测试来判断。必须有外部因素在要求改进。如果你说不出是谁在拉动,那你就是在做表面功夫。

所有权并未消失

这一切背后有一个更广泛的原则。

由人类实际键入的代码比例可能会大幅下降。但我认为,人类的所有权不必随之下降。

  • 仍然需要有人来选择问题。
  • 仍然需要有人来选择架构。
  • 仍然需要有人来设定质量标准。
  • 仍然需要有人来决定哪些验证信号值得信赖。
  • 仍然需要有人来决定证据是否足以发布。

而当最终的系统出现故障时,“是 Agent 写的”这个理由并不成立。这就是为什么我认为软件工程的未来最好描述为人类离开循环,而是 人类的判断力正在被重新定位。

我们应该将人们从循环中那些机器能够产生更强、更快、更确定信号的部分移除。同时,我们应该将人们集中在那些上下文、品味、风险和长期所有权最为重要的地方。

最好的软件工厂,其定义将不是它们能在多大程度上消除人类的参与。

它们的定义将是,它们能多么智能地 安置 人类的参与。

将人类的判断力置于上游,负责意图、系统形态和质量标准。在自动化反向压力变弱或后果变得主观的地方审查代码。尽可能早且持续地将每个确定性信号推入循环中。随着系统赢得或失去信任,有意识地收紧或放宽约束。

最终发布的代码,仍然必须有人来负责。足够好到可以发布的代码,仍然始于一个关心它是否应该存在的人。

一键保存

使用 YouMind AI 深度阅读爆款文章

保存原文、追问细节、总结观点,并在一个 AI 工作空间里把爆款文章沉淀成可复用笔记。

了解 YouMind
写给创作者

把你的 Markdown 变成干净的 𝕏 文章

图片上传、表格、代码块,往 𝕏 上手动重排太痛苦。YouMind 把整篇 Markdown 一键转成干净、可直接发布的 𝕏 文章草稿。

试试 Markdown 转 𝕏

更多可拆解样本

近期爆款文章

探索更多爆款文章