@addyosmani: https://x.com/addyosmani/status/2079442194449232227
摘要
Addy Osmani 的这篇文章探讨了将软件工厂视为规模化代理循环的概念,区分了有人类监督的明工厂和没有人类监督的暗工厂,并强调了理解与设计循环、调控机制和工厂结构的重要性。
查看缓存全文
缓存时间: 2026/07/21 06:42
软件工厂:亮灯与暗灯
软件工厂是大规模运行的受约束循环。你可以让人类参与循环(亮灯工厂):用判断力和专注力换取速度和易出错性。或者你可以忽略人类(暗灯工厂),让那些智能体自主规划、构建并交付代码,而无需任何人仔细阅读细节。但是,如果人们停止阅读,他们就会停止理解你的软件。你现在最艰难的任务是知道要构建哪些检查机制,以及授予多少自主权。
软件工厂这个概念可以追溯到鲍勃·贝默1968年的论文《程序生产的经济学》。半个世纪以来,许多人梦想着一个世界,其中软件是一种可重复、可量化的生产过程(类似于在工厂中冲压汽车零件),而不是个人孤立的工艺。从历史上看,这个梦想通常(尽管并非普遍)未能实现,部分原因在于冲压思想的难度。
但在过去两年里,情况发生了巨大变化,以至于现在重新审视这个古老的梦想是合理的。而且,由于一些细微之处很容易被忽略,因此值得精确地定义到底什么才是真正的新变化,以及哪些可能是伪装成新机遇的重蹈覆辙的陷阱。
HumanLayer 的联合创始人 @dexhorthy 最近在 AI Engineer World’s Fair 上做了一个精彩的演讲,名为 “Harness Engineering is not Enough: Why Software Factories Fail.” 关于这个话题,值得一看。
循环是原子。工厂是规模化的循环。
结构就是一切,一切都始于小的单元。整个栈实际上是三个概念层层叠加:循环、约束框架和工厂。
一个循环是一个代理重复执行单一任务:收集上下文、采取行动、检查结果,并再次执行直到满足某个条件。它是代理工作的最小单元,其上的所有东西都只是循环堆叠循环。
循环工程的关键在于,你不再逐轮提示代理,而是设计一个自动为你提示它的小型系统。
约束框架是围绕循环的围墙:它运行在沙箱,能接触到的工具,在运行之间存续的记忆,以及决定“完成”含义的门槛。循环是行为;约束框架是该行为运行的环境。
给一个裸模型不加约束框架,它会高兴地永远运转下去。约束框架是围绕它的一切,使其运行有用且安全。
软件工厂是同时运行多个受约束的循环,由一个工作队列供应,并通过一个审查关口排放到生产环境,由人类从上层掌控全局。它不是一个更大的智能体;它是由循环构成的组织架构图。
最终的范式转变是从编写代码转向构建和运行编写代码的工厂。工作的单元向上移动一层,变为循环、约束框架以及它们之间的流动,而不是单个代码差异。
循环 → 约束框架 → 工厂。工厂不是更智能的智能体;它是许多受约束循环输入一个审查关口,并由人类拥有外部循环。工厂,如图所示
Dex 花最多时间展示的那张幻灯片非常精彩,因为它是一个清晰的接线图,将原本显而易见的循环可视化了出来。以下是我对它的理解:
工厂是一个闭环:意图和生产信号输入一个队列,约束框架进行构建,自动检查并通过审查关口部署,监控将生产环境状态转化为信号。意图来自工程领导层的愿景,并直接来自工程师,进入待办事项队列。由事件和用户请求驱动的信号也驱动同一个队列。
约束框架只是从队列中选取一个项目并为其构建变更的东西。在约束框架之外,我们可以看到所有为了使变更安全到足以进入生产环境而需要的自动检查。这些自动检查同时运行,毫不费力,无需工程师有意识地参与,这要归功于CI、测试、静态分析和各种扫描。这里的唯一决策点是审查关口。批准后,变更被部署到生产环境并监控,监控数据反馈回最初启动循环的信号。
总的来说,图中的每个框几乎都是零成本:生成、测试、扫描。它们都以微不足道的成本大规模运行。只有一个昂贵的框被证明顽固地抗拒规模化,那就是审查关口。那个闪亮的琥珀色盒子是“判断力”,也是关于我们能否让开发更快、更频繁的争论的核心所在。
为什么称之为“暗”
暗工厂是在物理上关灯运行的,因为车间里只有机器,而机器不需要光线来看东西。暗软件工厂也是同样的做法:交付代码时没有任何人类阅读过,仅由其他机器验证。
这个比喻借鉴自制造业。它的起源是物理的而非数字的,源于那些关灯并由机器人完成工作的设施。日本的发那科自2001年以来就一直运行这种关灯工厂;小米在2024年也开设了自己的高度自动化的暗工厂。它们的共同点是产品在组装和交付过程中没有任何人类阅读过它。当“阅读”这个行为从流程中移除时,“暗”就出现了。
我借用这个概念不是为了它的氛围或者作为侮辱。尽管这个词听起来有点吓人,但这里的“暗”只是一个简单的物理类比:原始的工厂车间,但没有光。在软件中,车间就是变更集。无论是谁编写了变更集,谁审查了它,谁交付了它,这些人类都不在了,剩下的只是一个仅由构建它的机器验证的变更集。
这是一件出奇容易的事情,至少一开始如此。容易是因为缺失的审查步骤阻碍了一切。它的缺失让你觉得团队的垂直吞吐量突然且急剧地提高了。感觉就像突破了音障。尽管看似容易,但要在这些暗流程中生存下来却比看起来更难,因为其中隐藏着各种代价。
约束框架工程还不够
编排、沙盒原型设计和工具调用(模型与世界和彼此交互)的约束框架将变得越来越强大和有效。然而,在长期维护代码库质量以及通过增量变更来保持质量方面,存在模型固有的失败风险,而且我认为有充分理由相信,仅靠模型最终将在与理解债务的斗争中失败。
理解债务是指现有代码量与任何人类仍然理解的代码量之间不断扩大的差距。暗工厂不会偿还这笔债务;它会尽可能快地积累债务,而测试始终保持绿色。
这是一个重要的区别,因为模型在某些任务上表现良好。但对于任何不是对代码库小部分进行即时变更的任务,尤其是在复杂的棕地系统中,仅靠模型的自动化编码面临无法逾越的障碍。绿地应用、周末玩具项目和副项目都有一个共同点:几个月的开发周期通常足以让事情正常运转,或至少接近正常。
但是,一个已经开发了十年或更久的企业系统是另一种猛兽;它必须在专业环境中以专业的速度进行维护。项目进行到三到六个月时,你已经在未读代码中苦苦挣扎了。那种环境,特别是生产代码所施加的约束,会让即使是强大的智能体也表现不佳,这与开发周末玩具的开发者所享受的“vibe-coding”形成鲜明对比。
Dex 从经验中报告说,这是一个重大失败,以至于需要痛苦的逐行手动调试才能定位。这源于一个完全自动化的代码工厂运行了大约四个月,期间没有任何人类查看所写的代码。这种体验背后是两种相互冲突的指标之间的权衡。一个是最大化令牌利用率,这是我们目前视为进步的指标。另一个,它暗中最小化的是任何人类参与者在该时刻仍然理解的系统量。
暗工厂真正擅长的,是在测试保持绿色的同时,快速消耗全新的代码。最终的清算,当它来临时,不会是戏剧性的“一切突然崩溃”的时刻。它会是安静且迟到的。
暗和亮是同一个流水线,只是灯光放在不同的地方。亮灯版本不仅仅是在末尾重新添加审查——它还将人类判断力前移到设计和架构阶段。瓶颈从来不在生成环节
软件工厂的根本约束不是我们能产出多少代码:而是我们能多快验证它。
反压是一条规则:你只能给一个循环与其可以廉价且可靠地验证的程度相匹配的自主权,一分一毫都不能多。验证,而不是生成,才是工厂的真正约束。
因为无限的生成能力与有限且不可扩展的人力注意力之间存在持续的紧张关系,核心问题是廉价生成与有限的审查之间的差距。看看漏斗:只要代表验证的瓶颈没有扩大,它就会堵塞。正如Dex指出的,数量本身不是问题:我们真正遭受的是糟糕Pull Request的过剩。当你有高数量但缺乏可信的关卡时,制造出的缺陷是不可避免的。这又回到了反压:自主权不能扩展到超出可以廉价且可靠地验证的范围。
第二个问题在于,为什么改进模型不应该自动缩小它所能生成的内容与可以验证的内容之间的差距。在架构良好的系统上进行训练,可以说比通过简单测试更困难:请记住,衡量架构卓越性的代价函数不是以秒甚至分钟为单位,而是以月或年为单位。整齐的梯度在功能上无法计算,因此一个期望对复杂设计决策进行清晰、即时评估的系统,不可能在好的例子上进行训练。
生成是一个宽阔的嘴巴;验证是狭窄的瓶颈。加速嘴巴只会加深瓶颈处的堆积。
重新亮灯
亮灯工厂是同一个流水线,但在判断力存在的地方保持灯光亮着。智能体仍然完成大部分构建工作,但在交付之前有一个人类阅读产出,并且在任何错误决策代价高昂的地方,灯都亮着。
亮灯版本不是把审查附加到末尾,而是将人类判断力的点前移,移到产品、设计和架构上,在智能体开始一个循环之前。
那前期的一小时带来的好处是减少了实施时间。它将漫长而令人沮丧的代码审查转变为对两百行计划的快速阅读。你在决策被构建之前就能审查它,这样以后你就不必在两千行生成的代码中追踪,去弄清楚那个决策到底是什么。有些决策代价高昂且影响持久,你希望在成本累积之前就让人类及早参与。当然,即使你提前花了时间,有时你还是需要查看差异。
你可能会觉得这听起来不够光鲜。你是对的。安全网由我们一直知道但大多忽略的、极其普通的架构实践组成:良好的类型和方法签名,让错误在编译时而不是在生产中被捕获;测试接缝,我们可以固定行为并使变更可观测;布局代码,让下一个读者(无论是人类还是模型)知道在哪里找到他们关心的东西;保持调用栈短小且易读;保持组件边界清晰,这样变更就不会有巨大的影响范围;依赖注入,以便我们可以替换一个部分。这些都不是新东西。我们一直说我们在乎好的架构。但现在我们使用了自动化编码智能体,这个架构终于发挥了第二个作用,作为一个廉价且难以伪造的安全网,来捕捉智能体将犯的错误。
那个安全网必须存在于模型之外,因为模型不会提供它。那些感觉最有能力的编码智能体(包括Claude Code和Codex等)是针对它们自己的约束框架和工具进行强化训练的:它们精通所有工具和行话,但不擅长长期可维护性之类的东西。我们一直谈论的有意架构是捕捉那种债务的工具,我们在其中投入的资金就是我们买回自主权。
将其与安全的基础设施结合起来,就有一些紧密、低风险的循环可以无人值守运行。Horthy在最近的一篇文章中描述了一个:一个夜间GitHub Actions定时任务,它只修复一种反模式(一个lint违规或一个不必要的可选属性),提交,并自行打开一个小型Pull Request,这样团队醒来时会看到一个稍微好一点的代码库和一个足够短的、可以阅读的差异。但对于风险足够高的循环,你不想冒醒来看到认证系统、计费引擎或公共API契约被破坏的风险。在那里保持灯光亮着,相信一个有判断力并对系统有实际工作知识的人会捕捉到错误。
什么能让一个循环争取到暗灯资格
这条规则无论你称之为反压、验证还是灯光开关,都适用。
一个循环只有在以下条件下才能赢得完全自动化的地位:检查是廉价的、高频率运行的,并且依赖于某种不容易被伪造的东西。绿灯/红灯判断器、类型关卡、属性测试,以及搭配真实评分规则的审查智能体,都符合条件。你还需要判断器能够立即给出答案,并且不会随时间漂移。当完成不仅能被你证明,也能被机器证明时,你就达到了自动化。
短循环比长循环更容易验证。Dex的经验法则:一个智能体在3到10步内表现良好,超过20步就开始丢失思路。原因是上下文累积:智能体拖得越多,就越容易偏离。当循环很短时,验证它是廉价的。庞大复杂的循环在角落里隐藏错误,这另一种说法是它们从未赢得过关灯资格。
保持亮灯则相反。如果一个错误答案代价高昂,并且只有人类能发现,那么就需要审查循环。无法被测试捕获的微妙生产bug、巨大的影响范围、以及将决定一年或更长时间工作的决策,都属于这种情况。在这些情况下,你的注意力才是真正的产品——那个代价高昂、必不可少的。
危险在于忘记切换每个开关,而把它们全部设置为相同模式。全部暗灯,你四个月后就得拆除一切。全部亮灯,没人能及时完成审查,你就会陷入巨大的瓶颈。困难而需要技能的工作是决定每个开关放在哪里。
循环、图还是状态机?
你应该阅读 @DavidKPiano 的 “State machines in 2 minutes”
当你给智能体一个任务时,你很可能要围绕它构建一个图,无论你把这个图称为有限状态机还是一组条件链接的服务调用。这是一种框架,软件不仅仅是遵循一些抽象规则,而是遵循结构化的工作流:每个节点是一个明确的步骤,节点之间的每条边是一个明确的条件。
这听起来需要很多结构,但大部分已经在任何软件中存在了,因为任何代码都可以表示为控制流图。所以唯一真正的创新是:一个坚持自主权的智能体实际上只是在走一个特定的图,它的自由被限制在一个节点内部。而这里人们忘记的部分是,
相似文章
Factory 2.0:从编码智能体到软件工厂(3分钟阅读)
Factory宣布其使命进入下一阶段:软件工厂,一个互联的、以智能体为原生的系统,用于端到端软件开发全生命周期,现已与大型企业投入生产。
@addyosmani: https://x.com/addyosmani/status/2074927530482835916
Addy Osmani 讨论了在代理工程中“掌控外循环”的概念,强调了人工智能代理系统中的人类问责制、质量检查、裁决和可答复性。
@matanSF: https://x.com/matanSF/status/2066578088184680920
Factory 发布 Factory 2.0,从编码代理演变为端到端、代理原生软件工厂,实现组织范围内的自主软件开发,具有模型独立性和自主智能。
@omarsar0: https://x.com/omarsar0/status/2068008743153832264
这篇文章解释了从手动提示编码助手到设计自动循环来提示它们的转变,详细说明了这些循环是什么、它们的历史演变以及在生产中构建它们所需的组件。
@jasonzhou1993: https://x.com/jasonzhou1993/status/2067937943545897143
循环工程是一种系统设计实践,让AI代理自主决定工作内容、执行并迭代,通过构建跨领域复合的外循环来超越手动提示。文章解释了两层代理框架,以及如何在循环间共享工件以促进累积学习。