# Software Factories, Light and Dark
**作者**: Addy Osmani
**日期**: 2026-07-21T05:43:47.000Z
**来源**: [https://x.com/addyosmani/status/2079442194449232227](https://x.com/addyosmani/status/2079442194449232227)
---

A software factory is harnessed loops at scale. You can run the loop with humans in it (light factory): trading judgment and concentration against speed and breakage. Or you can ignore the humans (dark factory) and let those agents scope, build and ship code, without anyone really reading the details. But if people stop reading, they'll stop understanding your software. Your hardest job now is knowing which checks to build and how much autonomy to delegate.
This idea of the software factory is a term that dates back to Bob Bemer's paper, "The economics of program production" given in 1968. For half a century, many have dreamed of a world in which software is a repeatable and instrumentable production process (analogous to stamping out car parts in a factory) rather than the isolated craft of individuals. Historically, this dream has generally (although not universally) fallen flat, in part because of the difficulty of stamping out ideas.
But in the last two years, things have changed dramatically enough that now it makes sense to take a fresh look at the old dream. And since some subtleties can easily be glossed over, it's worthwhile to be somewhat precise about exactly what is really new and different, and what may be recurring traps, dressed up as new opportunities.
@dexhorthy, co-founder of HumanLayer recently gave a great talk at AI Engineer World's Fair called "Harness Engineering is not Enough: Why Software Factories Fail." worth checking out on this topic.

## The loop is the atom. The factory is the loop at scale.
Structure is everything, and it all starts with small units. The whole stack is really three concepts layered on top of each other: the loop, the harness, and the factory.
A loop is one agent doing a single job on repeat: gather context, take an action, check the result, and go again until some condition is met. It is the smallest unit of agentic work, and everything above it is just loops stacked on loops.
The point of loop engineering is that you stop prompting the agent turn by turn and instead design the small system that prompts it for you.
A harness is the walls around a loop: the sandbox it runs in, the tools it can reach, the memory that survives between runs, and the gates that decide what "done" means. The loop is the behavior; the harness is the environment that behavior runs inside.
Hand a raw model no harness and it will happily spin forever. The harness is everything around it that makes it useful and safe to run.
A software factory is many harnessed loops running at once, fed by a queue of work and drained through a review gate into production, with humans owning the whole thing from above. It is not a bigger agent; it is an org chart made of loops.
The final paradigm shift is moving from writing code to building and running the factory that writes it. The unit of work shifts up a level, to the loop, the harness, and the flow between them, rather than the individual code diff.

Loop → harness → factory. A factory isn't a smarter agent; it's many harnessed loops feeding one review gate, with a human owning the outer loop. The factory, drawn
The central slide Dex spent most time on was brilliant because it's a clarifying wiring diagram that visualizes what otherwise is an obvious loop. Here's my take on it:

The factory is a closed loop: intent and production signals feed a queue, the harness builds, automated checks and review gate it, deploy ships it, monitoring turns prod back into signals. Intent flows from the vision of engineering leadership, and directly from engineers, into a queue of things to be done. Signals driven by incidents and user requests drive the same queue.
The harness is just the thing that picks an item from the queue and builds a change for it. Beyond the harness, we can see all the automated checks required to make changes safe enough to let into production. These automated checks run at once, effortlessly, without any conscious involvement from engineers, thanks to CI, tests, static analysis, and scanning of all kinds. The only decision point here is the review gate. After approval, changes are deployed and monitored in production, with monitoring data feeding back into the signals that kicked the loop into motion to begin with.
By and large, every box in this diagram is almost zero cost: generation, tests, scanning. They all run at scale for negligible cost. There is only one expensive box that proves stubbornly resistant to scaling, and that's the review gate. That shiny amber box is "judgment", and where the crux of the argument about whether we can make development faster and more frequent resides.
## Why we call it "dark"
A dark factory runs with the lights physically off, because the only things on the floor are machines and machines don't need light to see. A dark software factory is the same move: code ships that no human has read, verified only by other machines.
The image is borrowed from manufacturing. Its origins are physical rather than digital, rooted in facilities where the lights are turned off and the work is carried out by robots. FANUC in Japan has been running lights-out factories of this sort since 2001; Xiaomi, in 2024, opened a heavily automated dark factory of its own. What these have in common is a product assembled and shipped without a single human having read any of it. The "dark" comes in when that act of reading is removed from the process.
I'm not borrowing the concept for its vibe or as an insult. For all its creepy buzz, "dark" here is a simple physical claim: the original factory floor, but without light. In software, the floor is the diff. Whoever wrote the diff, whoever reviewed it, whoever shipped it, those humans are gone, and what remains is a diff verified only by the machines that built it.
This is a surprisingly easy thing to do, at least at first. It's easy because that missing review step gets in the way of everything. Its absence makes your perception of your team's vertical throughput seem suddenly and radically higher. It feels as if you've broken the sound barrier. For all its apparent ease, it's harder than it seems to survive those dark workflows, with all their buried costs.
## Harness engineering is not enough
The harness of orchestration, sandboxed prototyping, and tool calling as models interact with the world and each other will become increasingly powerful and effective. However, there's an inherent in-model failure in trying to keep up with codebase quality over the long game and through additive changes, and I think there's good reason to believe that models alone will ultimately lose that battle against comprehension debt.
Comprehension debt is the widening gap between how much code exists and how much any human still understands. A dark factory doesn't pay it down; it takes it on as fast as it can, with the tests green the whole way.
This is an important distinction because models do well at some tasks. But for anything that isn't an immediate change to a small part of a codebase, especially in a complex brownfield system, model-only automated coding faces an insurmountable obstacle. Greenfield apps, weekend toys and side projects are alike in that a few months of development cycles is usually enough to get things in working order, or at least close enough.
But an enterprise system that has been under development for a decade or more is a different beast; it has to be maintained, in a professional environment at a professional pace. Three to six months into a project, you're already drowning in unread code. That kind of environment, and especially the constraints enforced by production code, would make even a powerful agent do poorly, all of it in contrast to the vibe-coding enjoyed by developers working on weekend toys.
Dex reports from experience that this is a major failure, so much so that it required painstaking manual debugging to pinpoint. This came from running a fully automated code factory for about four months, during which no human looked at the code that was written. Underlying the experience is a tradeoff between two conflicting metrics. One is maximizing token utilization, the number we currently treat as progress. The other, which it quietly minimizes, is the amount of the system any human participant still understands at any moment.
Where the dark factory truly shines is in its ability to burn through pristine code while the tests stay green. The ultimate reckoning, when it comes, will not be a dramatic "it all goes sideways" moment. It will be quiet and late.

Dark and lit are the same pipeline with the lights in different places. The lit version doesn't just re-add review at the end - it moves human judgment upstream to design and architecture, too. The bottleneck was never generation
The fundamental constraint in a software factory isn't how much code we can churn out: it's how quickly we can verify it.
Back pressure is the rule that you can only hand a loop as much autonomy as you can cheaply and reliably verify, and not one inch more. Verification, not generation, is the real constraint on a factory.
Because unbounded generation capacity is in perpetual tension with the finite, non-scaling resource of human attention, the core problem is the gap between cheap generation and bounded review. Look at the funnel: as long as the neck representing verification doesn't widen, it's going to back up. As Dex points out, volume alone isn't the problem: what we're really suffering from is a surplus of bad PRs. When you've got high volume without trustworthy gates, manufactured defects are unavoidable. This is just back pressure again: autonomy can't expand beyond what can be cheaply and reliably verified.
The second-order problem is why improving the model shouldn't automatically close the gap between what it can generate and what can be verified. Training on well-architected systems is an arguably more difficult proposition than passing simple tests: remember, the cost functions measuring architectural excellence aren't measured in seconds or even minutes, but in months and years. Tidy gradients are functionally impossible to compute, so a system expecting crisp, instant evaluation of complex design decisions isn't going to be trained on good examples.
Generation is a wide mouth; verification is the narrow neck. Speeding up the mouth just deepens the pile at the neck.
## Turning the lights back on
A lit factory is the same pipeline with the lights left on where judgment lives. The agents still do most of the building, but a human reads what comes out before it ships, and the lights stay on wherever a wrong call is expensive.
The lit version doesn't tack review onto the end but moves the point of human judgment upstream, to the product, the design, and the architecture before an agent starts a loop.
One great thing about that upfront hour is that it leads to fewer implementation hours. It turns a long, frustrating code review into a quick read of a two-hundred-line plan. You get to review a decision before it's built, so later you aren't chasing through two thousand lines of generated code to find out what the decision even was. Some decisions are expensive and long-lived enough that you'd want a person in on them early, before the cost compounds. Of course, there are still times you look at diffs, even when you've spent time up front.
You might be thinking that all sounds unglamorous. You're right. The safety net is made up of perfectly ordinary architectural practices we've always known about and mostly ignored: good types and method signatures so that mistakes are caught by the compiler instead of in production; test seams where we can pin behavior and make change observable; laying out the code so the next reader, human or model, knows where to find the thing they care about; keeping call stacks short and legible; keeping component boundaries well defined so a change doesn't have a huge blast radius; and dependency injection so we can swap out one piece for another. None of it is new. We've always said we care about good architecture. But now that we're using automated coding agents, that architecture is finally doing a second job as a cheap and hard-to-fake safety net against the mistakes the agent will make.
That safety net has to live outside the model, because the model won't supply it. The coding agents that feel most capable, Claude Code and Codex among them, are reinforcement-trained against their own harness and tools: fluent with all the tools and idioms of the trade, but not with things like long-term maintainability. The deliberate architecture we've always talked about is the tool that catches that debt, and the investment we make in it is us buying back our autonomy.
Put that together with safe infrastructure, and there are some tight, low-risk loops you can run unattended. Horthy described one in a recent post: a nightly GitHub Actions cron that fixes exactly one anti-pattern, a lint violation or a needlessly optional prop, commits, and opens one small pull request, all on its own, so the team wakes up to a slightly better codebase and a diff short enough to read. But for loops with high enough stakes, you don't want to risk waking up to a broken auth system, billing engine, or public API contract. Keep the lights on there, and trust that a person with judgment and a real working knowledge of the system will catch the mistake.
## What earns a loop the dark
This rule applies whether you call it back pressure, verification, or the light switch.
A loop can earn itself fully automated status only if the check is cheap, runs at high frequency, and relies on something that can't be easily faked out. Green-or-red oracles, type gates, property tests, and a review agent coupled with a real rubric all fit. You also need the oracle to answer immediately and not drift over time. When done can be proven not just by you but by a machine, you've reached automation.
Short loops are easier to verify than long ones. Dex's rule of thumb: an agent holds up for three to ten steps, then starts losing the thread past twenty. The reason is context accumulation, the more the agent drags along, the more likely it is to wander off. When a loop is short, verifying it is cheap. Sprawling loops hide mistakes in the corners, which is another way of saying they never earned lights-out status.
Keeping the lights on is the opposite case. A loop needs to be reviewed if a wrong answer is expensive and only a person can catch it. Subtle production bugs that can't be caught by tests, large blast radii, and a decision that's going to shape the work of a year or more all qualify. In those cases, your attention is the actual product, the costly, essential one.
The danger is forgetting to flip each switch and just setting all of them to the same mode. All dark, and you're stuck tearing everything down four months later. All lit, and no one can get reviews done in time and you're stuck in a gigantic bottleneck. The hard, skilled job is deciding where to put each switch.
## Loops, graphs or state machines?
You should read "State machines in 2 minutes" by @DavidKPiano
When you hand an agent a task, you're probably going to build a graph around it, whether you call that graph a finite state machine or a set of conditionally-linked service calls. It's a framing where the software isn't just following some abstract rules but a structured workflow: every node is an explicit step, and every edge between nodes is an explicit condition.
That sounds like a lot of structure, but most of it is already there in any software, since any code can be expressed as a control-flow graph. So the only real novelty is that an agent insisting on autonomy is really just walking around a particular graph, and its freedom is constrained to the inside of a node. And here's the part people forget, which Dex wrote down a year ago: software was always going to have that structure. There's a reason we used to draw programs as flow charts.
The genuinely new move was trying to throw the diagram away, leaning on a loop where the model picks the path tool call by tool call, until it declares itself done. That felt like liberation, right up until it met a ten-year-old codebase, and the discipline everyone is now rediscovering, owning your control flow, is really just walking the graph back around the loop. So the question of whether we should shift from loops back to graphs is almost an admission that we needed the flowchart all along.
Here's what it looks like in practice. Take a bug to fix. As a pure loop, you sit down and think: figure out what's wrong, change some code, run the tests, see what happens, and if that round doesn't kill the run, loop back and start again. The whole journey is decided as you go, which problem you chase, the exact code you change, which tests you run and in what order, whether you run tests at all, and whether you try again or declare victory.
As a graph, the first thing you do is map out what should happen. Reproduce the bug or go ask for more information, find the cause, try a fix, run the tests, and let a failing run route back to the fix while a passing one goes on to review, where only an approval reaches done. The agent is still clever inside each box; it just can't wander off the paths you sanctioned. Santi laid this out with a diagram that makes the difference obvious.
The real appeal of that graph, of course, is that it's back pressure drawn as a diagram. You give up some of the agent's freedom and get mandatory checks and legible failure points in return, so when a run dies you can point at the node that killed it. It's the same instinct behind Dex's blunt line that most so-called agents aren't very agentic at all, "mostly deterministic code, with LLM steps sprinkled in at just the right points." And this isn't just an artifact of how people happen to be building things right now: you can see the pattern in LangGraph and LlamaIndex Workflows, in Jerry Liu's hybrid workflow-graph-over-agents with an outer loop that grows parts of the graph as it runs, and in David Khourshid's reminder that this is really just state machines and the actor model turning up in new clothes.
One clarification, because the term is badly overloaded: when I keep calling this a graph, I don't mean a knowledge graph. I mean a predefined directed graph of how the work should flow, conditional edges and all, giving the loop a shape you can actually trust.
## Where the human actually goes
Notice that the person never left the factory. They moved.
I think engineers need to increasingly own the outer loop. The agents can investigate a bug, write up the diagnosis, implement a fix, run the tests, and write up a report. That's the execution of the inner loop, and they can do it as efficiently as anyone. But that was never the job. The bits you own are what I'd call the outer loop: decide whether it's the right way to address the problem, verify that the diagnosis and implementation are sound, approve the change, and carry the consequences of being wrong. The boundary between the two loops is evidence, the diffs, the tests, the logs, and a brief explanation that connects them. Types, seams, and rubrics make it possible to oversee all this without doing a lot of work for every change.
It's useful to put it this way: you're not down on the line writing changes any more; you're up at the end of the production line designing it and guarding the gate. There's a lot you can do to make the model better and the harness more capable, but I've observed that identifying problems that are expensive in the long term is not typically something you can automate away. The core thing that's still the job is to exercise human judgment better than any flow of paper and computing power.
Robots are fine operating in the dark, but humans need to see what they're doing. If everything on the factory floor is dark, and you can't see anything, and you can't even find the light switch, that's where the danger is.
Pangram scored this article as 100% human written.
## 相关链接
- [Addy Osmani](https://x.com/addyosmani)
- [@addyosmani](https://x.com/addyosmani)
- [145K](https://x.com/addyosmani/status/2079442194449232227/analytics)
- [Bob Bemer's](https://en.wikipedia.org/wiki/R._W._Bemer)
- [@dexhorthy](https://x.com/@dexhorthy)
- ["Harness Engineering is not Enough: Why Software Factories Fail."](https://youtu.be/htM02KMNZnk?t=27219)
- [loop engineering](https://addyosmani.com/blog/loop-engineering/)
- [the factory](https://addyosmani.com/blog/factory-model/)
- [FANUC in Japan has been running lights-out factories of this sort since 2001](https://en.wikipedia.org/wiki/Lights_out_(manufacturing))
- [comprehension debt](https://addyosmani.com/blog/comprehension-debt/)
- [Dex's rule of thumb](https://github.com/humanlayer/12-factor-agents/blob/main/content/factor-10-small-focused-agents.md)
- [your attention is the actual product](https://addyosmani.com/blog/human-is-the-expensive-part/)
- [State machines in 2 minutes](https://x.com/DavidKPiano/status/2079209887158989231)
- [@DavidKPiano](https://x.com/@DavidKPiano)
- [Dex wrote down](https://github.com/humanlayer/12-factor-agents)
- [outer loop](https://addyosmani.com/blog/own-the-outer-loop/)
- [scored](https://www.pangram.com/history/d151077c-b4ca-4277-a2fe-75e6cb282f06)
- [Upgrade to Premium](https://x.com/i/premium_sign_up)
- [1:43 PM · Jul 21, 2026](https://x.com/addyosmani/status/2079442194449232227)
- [145.2K Views](https://x.com/addyosmani/status/2079442194449232227/analytics)
- [View quotes](https://x.com/addyosmani/status/2079442194449232227/quotes)
---
*导出时间: 2026/7/21 17:38:10*
---
## 中文翻译
# 软件工厂:光明与黑暗
**作者**: Addy Osmani
**日期**: 2026-07-21T05:43:47.000Z
**来源**: [https://x.com/addyosmani/status/2079442194449232227](https://x.com/addyosmani/status/2079442194449232227)
---

软件工厂就是大规模运行的受限循环(harnessed loops)。你可以让人类参与其中来运行这个循环(光明工厂):用判断力和专注力换取速度,同时承担出错的风险。或者你可以忽略人类(黑暗工厂),让智能体自行界定范围、构建并发布代码,没有人真正阅读细节。但如果人们停止阅读,他们就会停止理解你的软件。如今你最艰难的工作,就是知道该构建哪些检查机制,以及该下放多少自主权。
软件工厂这个概念可以追溯到 Bob Bemer 在 1968 年发表的论文《程序生产的经济学》。半个世纪以来,许多人一直梦想着一个软件生产成为可重复、可度量的过程的世界(类似于在工厂里冲压汽车零件),而不是孤立的个人手艺。从历史上看,这个梦想大多(虽然并非全部)落空了,部分原因在于“冲压想法”实在太难。
但在过去两年里,情况发生了足够剧烈的变化,现在值得重新审视这个古老的梦想。而且,由于一些微妙之处很容易被忽略,因此有必要准确地说明:究竟什么是真正的新事物和新变化,哪些又可能是披着新机会外衣的老陷阱。
HumanLayer 联合创始人 @dexhorthy 最近在 AI Engineer World's Fair 上做了一场精彩的演讲,题为《Harness 工程还不够:为什么软件工厂会失败》,这个话题值得一听。

## 循环是原子。工厂是大规模的循环。
结构就是一切,一切都从小的单元开始。整个技术栈实际上是三个层层叠加的概念:循环(loop)、挽具(harness)和工厂(factory)。
循环是一个智能体重复执行单一任务:收集上下文、采取行动、检查结果,然后再次循环,直到满足某个条件。它是智能体工作的最小单元,其上的一切都只是循环叠加循环。
循环工程的要点在于:你不再逐轮给智能体写提示词,而是设计一个小系统来替你提示它。
挽具是围绕循环的围墙:它运行所在的沙箱、它能调用的工具、在多次运行之间保留的记忆,以及决定什么才算“完成”的门控。循环是行为;挽具是行为运行于其中的环境。
把一个原始模型交出去而不带任何挽具,它会永远欢快地空转下去。挽具就是围绕它的一切,使它的运行既有用又安全。
软件工厂是许多同时运行的受限循环,由一个工作队列供料,经过审查门排入生产环境,而人类在上方掌控全局。它不是一个更大的智能体;它是一张由循环构成的组织架构图。
最终的范式转变,是从编写代码转向构建和运营那个编写代码的工厂。工作的单元上移了一级——变成了循环、挽具以及它们之间的流转,而不是单个的代码差异。

循环 → 挽具 → 工厂。工厂不是更聪明的智能体;它是许多受限循环汇入同一个审查门,而人类掌控着外层循环。工厂示意图
Dex 花最多时间讲解的那张核心幻灯片非常出色,因为它是一张清晰的接线图,把原本显而易见的循环可视化了。以下是我的解读:

工厂是一个闭环:意图和生产信号汇入队列,挽具进行构建,自动化检查和审查门把关,部署将其发布,监控则把生产环境转回信号。意图来自工程领导层的愿景,也直接来自工程师,汇入待办事项队列。由事故和用户请求驱动的信号也汇入同一个队列。
挽具只是从队列中取出一个条目并为其构建变更的东西。在挽具之外,我们可以看到让变更足够安全、可以进入生产环境所需的全部自动化检查。这些自动化检查依靠 CI、测试、静态分析和各种扫描工具同时运行,毫不费力,无需工程师有意识地参与。这里唯一的决策点是审查门。批准之后,变更被部署到生产环境并接受监控,监控数据又回流到最初启动这个循环的信号中。
总体而言,这张图中的每一个方框几乎都是零成本的:生成、测试、扫描,它们都能以可忽略不计的成本大规模运行。只有一个昂贵的方框顽固地抗拒规模化,那就是审查门。那个闪亮的琥珀色方框是“判断”,而关于我们能否让开发更快、更频繁的争论,其核心正在于此。
## 为什么我们称之为“黑暗”
黑暗工厂在物理上是关着灯运行的,因为车间里只有机器,而机器不需要光就能“看见”。黑暗软件工厂也是同样的操作:发布的代码没有任何人类读过,只由其他机器进行验证。
这个意象借自制造业。它的起源是物理世界而非数字世界,植根于那些关掉灯光、由机器人完成工作的设施。日本的 FANUC 自 2001 年以来一直在运行这类“关灯工厂”;小米在 2024 年开设了一家高度自动化的黑暗工厂。它们的共同点是:产品被组装并出厂,却没有一个人类读过其中任何部分。当“阅读”这一行为从流程中被移除时,“黑暗”便降临了。
我借用这个概念不是为了它的氛围,也不是作为一种侮辱。尽管“黑暗”这个词带着令人不安的意味,但在这里它只是一个简单的物理性说法:原本的工厂车间,但没有灯光。在软件领域,车间就是 diff。无论是谁写了 diff,谁审查了它,谁发布了它——这些人都已不在场,留下的是一个仅由构建它的机器验证过的 diff。
这是一件出奇容易做到的事,至少一开始是这样。之所以容易,是因为缺失的审查步骤妨碍着一切。它的缺席让你对团队垂直吞吐量的感知突然且急剧地飙升。感觉就像你突破了音障。然而,尽管看似轻松,要在那些黑暗工作流中存活下来,承担其中所有被埋藏的成本,却比看起来要难得多。
## 仅靠框架工程是不够的
随着模型与世界及彼此互动,编排、沙盒原型设计以及工具调用的框架将变得越来越强大和有效。然而,从长远来看,通过增量变更来跟上代码库质量,存在一种模型固有的失败倾向,而且我们有充分的理由相信,仅靠模型最终将在与理解债的对抗中落败。
理解债是指存在的代码量与任何人仍然理解的代码量之间不断扩大的差距。黑暗工厂不会偿还这笔债;它以尽可能快的速度累积这笔债,而测试全程保持绿灯。
这是一个重要的区别,因为模型在某些任务上确实表现出色。但对于任何并非对代码库一小部分进行即时变更的事情,尤其是在复杂的棕地系统中,纯模型的自动化编码面临着不可逾越的障碍。绿地应用、周末玩具和副项目的共同之处在于,几个月的开发周期通常足以让事情正常运转,或者至少足够接近。
但一个已经开发了十年或更久的企业系统则是另一回事;它必须在专业环境中以专业节奏进行维护。项目进行到三到六个月时,你就已经淹没在未读的代码中了。这种环境,尤其是生产代码所强加的约束,会让即使强大的智能体也表现不佳,这一切都与开发周末玩具的开发者所享受的凭感觉编程形成鲜明对比。
Dex 根据经验报告说,这是一个重大失败,以至于需要 painstaking 的手动调试才能定位问题。这来自运行一个完全自动化的代码工厂约四个月的经历,在此期间没有任何人查看所编写的代码。这段经历的背后是两个相互冲突的指标之间的权衡。一个是最大化 token 利用率——我们目前将其视为进展的数字。另一个则是它在悄悄最小化的指标:任何人类参与者在任何时刻仍然理解的系统比例。
黑暗工厂真正大显身手的地方,在于它在测试保持绿灯的同时快速吞噬原始代码的能力。最终的清算,当它来临时,不会是一个戏剧性的“一切崩溃”的时刻。它将是安静而迟来的。

黑暗工厂与灯火通明的工厂是同一条流水线,只是灯放在了不同的位置。灯火通明的版本不只是在最后重新加上审查——它还将人类的判断上游推进到设计和架构环节。瓶颈从来不是生成
软件工厂的根本约束不是我们能产出多少代码:而是我们能以多快的速度验证它。
背压是一条规则:你只能给一个循环赋予你能廉价且可靠地验证的自主权,一分一毫也不能多。验证而非生成,才是工厂的真正约束。
因为无限的生成能力与有限的、无法扩展的人类注意力资源处于永恒的张力之中,核心问题就是廉价生成与有限审查之间的鸿沟。看看这个漏斗:只要代表验证的瓶颈口不扩大,它就会积压。正如 Dex 指出的,数量本身不是问题:我们真正遭受的是糟糕 PR 的过剩。当你拥有高数量却没有可信的关卡时,人为制造的缺陷就不可避免。这又是背压:自主权不能扩展到能被廉价且可靠验证的范围之外。
二阶问题在于,为什么改进模型不应自动缩小其生成能力与可验证能力之间的差距。在架构良好的系统上进行训练,可以说比通过简单测试更困难:请记住,衡量架构卓越性的成本函数不是以秒甚至分钟来计算的,而是以月和年为单位。整齐的梯度在功能上是不可能计算的,因此一个期望对复杂设计决策进行清晰、即时评估的系统,不会在好的示例上得到训练。
生成是一张宽嘴;验证是狭窄的瓶颈。加快嘴的速度只会加深瓶颈处的堆积。
## 重新点亮灯光
灯火通明的工厂是同一条流水线,只是在判断存在的地方保留了灯光。智能体仍然完成大部分构建工作,但在代码发布之前,会有人阅读它产出的内容,而且只要错误决策代价高昂的地方,灯光就会一直亮着。
灯火通明的版本不是把审查附加在末端,而是将人类判断的节点上游推进到产品、设计和架构环节——在智能体开始循环之前。
提前投入的那一个小时的一大好处是,它减少了后续的实施时间。它把漫长而令人沮丧的代码审查变成了一次对两百行计划的快速阅读。你可以在决策被实现之前对其进行审查,这样以后就不必在两千行生成的代码中追根溯源,去弄清那个决策到底是什么。有些决策成本高昂且影响长远,你需要让人在早期、在成本累积之前就参与其中。当然,即使提前花了时间,仍有些时候需要查看 diff。
你可能会觉得这一切听起来毫无魅力。你说得对。这张安全网是由我们一直都知道却大多忽视的、再普通不过的架构实践构成的:良好的类型和方法签名,让错误被编译器捕获而不是在生产环境中暴露;测试接缝,让我们可以固定行为并使变更可观察;合理组织代码,让下一个读者(无论是人还是模型)知道去哪里找他们关心的东西;保持调用栈简短清晰;保持组件边界清晰定义,使变更不会产生巨大的影响范围;以及依赖注入,让我们可以把一个组件换成另一个。这些都不是新鲜事物。我们一直声称在意好的架构。但现在我们开始使用自动化编码智能体,这些架构终于承担起了第二份工作——作为一道廉价且难以伪造的安全网,防范智能体将会犯下的错误。
这张安全网必须存在于模型之外,因为模型不会自己提供它。那些看起来最能干的编码智能体,包括 Claude Code 和 Codex 在内,都是针对它们自身的框架和工具进行强化学习训练的:对这一行的所有工具和惯用手法运用自如,但在长期可维护性之类的事情上却不然。我们一直谈论的这种有意为之的架构,正是捕捉这类技术债务的工具,而我们在这方面的投入,就是在赎回我们的自主权。
把这些与安全的基础设施结合起来,就有一些紧凑、低风险的循环可以无人值守地运行。Horthy 在最近的一篇文章中描述过一个例子:一个每晚运行的 GitHub Actions 定时任务,修复恰好一个反模式——一个 lint 违规或一个不必要的可选 prop——然后提交并开启一个小型 pull request,全部自动完成,团队醒来时会看到一个稍微好一点的代码库,以及一个短到足以读完的 diff。但对于风险足够高的循环,你不会想冒险醒来时发现认证系统、计费引擎或公共 API 契约已经坏了。让那里的灯一直亮着,并相信一个有判断力、对系统有真正实际了解的人会抓住错误。
## 什么能让一个循环配得上熄灯
无论你称之为反压(back pressure)、验证,还是那个电灯开关,这条规则都适用。
一个循环只有在检查廉价、高频运行,且依赖某种难以轻易造假的东西时,才能获得完全自动化的资格。绿/红判定器、类型门控、属性测试,以及配备真实评分标准的审查智能体,都符合条件。你还需要判定器能立即给出答案,且不会随时间漂移。当"完成"不仅能由你证明,还能由机器证明时,你就达到了自动化。
短循环比长循环更容易验证。Dex 的经验法则是:智能体能撑住三到十步,超过二十步就开始迷失方向。原因在于上下文的累积——智能体拖着的东西越多,就越可能跑偏。当循环很短时,验证它就很廉价。 sprawling(铺开式)的循环把错误藏在角落里,换句话说,它们永远不配获得熄灯资格。
保持开灯则是相反的情况。如果一个错误答案代价高昂、且只有人才能抓住它,那么这个循环就需要被审查。测试无法发现的微妙生产环境 bug、巨大的影响范围,以及将塑造一年以上工作的决策,都符合条件。在这些情况下,你的注意力才是真正的产品——昂贵而不可或缺的那个。
危险在于忘记为每个开关分别做出判断,而是把它们全部设为同一模式。全部熄灯,四个月后你就得推倒重来。全部开灯,没人能及时完成审查,你就会陷入巨大的瓶颈。困难而有技术含量的工作,是决定每个开关放在哪里。
## 循环、图还是状态机?
你应该读一读 @DavidKPiano 的《State machines in 2 minutes》
当你把一个任务交给智能体时,你很可能要在它周围构建一个图,无论你把这个图称为有限状态机,还是一组按条件连接的服务调用。在这种框架下,软件不再只是遵循某些抽象规则,而是一个结构化的工作流:每个节点都是显式的一步,节点之间的每条边都是显式的条件。
这听起来像是很多结构,但其中大部分已经存在于任何软件中了,因为任何代码都可以表示为控制流图。所以唯一真正的新颖之处在于:一个坚持自主的智能体,其实只是在某个特定的图上游走,而它的自由被限制在节点内部。而人们忘记的那一点,Dex 一年前就写下来了:软件本来就一直会有这种结构。我们过去把程序画成流程图是有原因的。
真正的新动作是试图扔掉那张图,依赖一个由模型在每次工具调用之间选择路径的循环,直到它自己宣布完成为止。这感觉像是一种解放,直到它撞上一个有十年历史的代码库。而如今所有人都在重新发现的那个纪律——掌控自己的控制流——其实就是把图重新画回循环周围。所以,"我们是否应该从循环转回图"这个问题,几乎就是在承认:我们一直都离不开那张流程图。
下面是实际操作中的样子。假设要修一个 bug。作为纯粹的循环,你坐下来思考:找出哪里出了问题,改一些代码,跑测试,看看结果如何,如果这一轮没有让整个运行中断,就回到开头重新开始。整个旅程是边走边决定的——追哪个问题、具体改哪些代码、跑哪些测试、以什么顺序跑、是否要跑测试、以及是再试一次还是宣布胜利。
而作为图,你做的第一件事是把应有的流程画出来。复现 bug 或去询问更多信息,找到原因,尝试修复,跑测试,让失败的运行回流到修复环节,而通过的则进入审查,只有获得批准才算完成。Agent 在每个框内仍然很聪明,只是不能偏离你许可的路径。Santi 用一张图把这个区别讲得清清楚楚。
这张图真正的吸引力,当然是把背压画成了图表。你放弃 agent 的一部分自由,换来的是强制检查和清晰可见的失败点,这样当一次运行挂掉时,你能指出是哪个节点杀死了它。这与 Dex 那句直白的论断背后的直觉如出一辙:大多数所谓的 agent 根本没有多少 agentic 的成分,“基本上是确定性代码,只是在恰当的位置点缀了 LLM 步骤。”而且这不仅仅是人们现阶段构建方式的偶然产物:你可以在 LangGraph 和 LlamaIndex Workflows 中看到这种模式,在 Jerry Liu 的混合工作流-图-基于-agent 的方案中看到——它带有一个会在运行中不断生长出图的一部分的外层循环,也可以在 David Khourshid 的提醒中看到——这其实只是状态机和 actor 模型换了个新马甲又出现了。
需要澄清一点,因为这个术语被严重滥用了:我一直说这是图,指的不是知识图谱。我指的是一个预定义的有向图,描述工作应该如何流转,包含条件边等,给这个循环一个你真正可以信赖的形状。
## 人到底在哪里
请注意,人从来没有离开过工厂。他们只是换了位置。
我认为工程师需要越来越多地掌握外层循环。Agent 可以调查一个 bug,撰写诊断,实现修复,跑测试,并撰写报告。这是内层循环的执行,它们可以做得和任何人一样高效。但这从来都不是工作的全部。你真正拥有的部分是我所说的外层循环:判断这是否是解决该问题的正确方式,验证诊断和实现是否可靠,批准更改,并承担出错带来的后果。两个循环之间的边界是证据——diff、测试、日志,以及一段将它们串联起来的简短说明。类型、接缝和评分标准让你无需为每次更改做大量工作就能监督这一切。
这样说会更有用:你不再站在流水线上写更改了;你在生产线末端设计它并守着大门。你可以做很多事情让模型更好、让工具链更强大,但我观察到,识别那些长期代价高昂的问题通常不是可以自动化掉的事情。仍然属于工作的核心,是比任何纸流和算力都更好地运用人类判断。
机器人在黑暗中运作没问题,但人类需要看清自己在做什么。如果整个车间一片漆黑,你什么也看不见,甚至连灯的开关都找不到,那才是危险所在。
Pangram 将这篇文章评为 100% 人类撰写。
## 相关链接
- [Addy Osmani](https://x.com/addyosmani)
- [@addyosmani](https://x.com/addyosmani)
- [145K](https://x.com/addyosmani/status/2079442194449232227/analytics)
- [Bob Bemer 的](https://en.wikipedia.org/wiki/R._W._Bemer)
- [@dexhorthy](https://x.com/@dexhorthy)
- [“Harness 工程还不够:为什么软件工厂会失败。”](https://youtu.be/htM02KMNZnk?t=27219)
- [循环工程](https://addyosmani.com/blog/loop-engineering/)
- [工厂](https://addyosmani.com/blog/factory-model/)
- [日本的 FANUC 自 2001 年以来一直在运行这类熄灯工厂](https://en.wikipedia.org/wiki/Lights_out_(manufacturing))
- [理解债务](https://addyosmani.com/blog/comprehension-debt/)
- [Dex 的经验法则](https://github.com/humanlayer/12-factor-agents/blob/main/content/factor-10-small-focused-agents.md)
- [你的注意力才是真正的产品](https://addyosmani.com/blog/human-is-the-expensive-part/)
- [两分钟讲状态机](https://x.com/DavidKPiano/status/2079209887158989231)
- [@DavidKPiano](https://x.com/@DavidKPiano)
- [Dex 写下了](https://github.com/humanlayer/12-factor-agents)
- [外层循环](https://addyosmani.com/blog/own-the-outer-loop/)
- [评为](https://www.pangram.com/history/d151077c-b4ca-4277-a2fe-75e6cb282f06)
- [升级到 Premium](https://x.com/i/premium_sign_up)
- [2026年7月21日 下午1:43](https://x.com/addyosmani/status/2079442194449232227)
- [145.2K 次浏览](https://x.com/addyosmani/status/2079442194449232227/analytics)
- [查看引用](https://x.com/addyosmani/status/2079442194449232227/quotes)
---
*导出时间: 2026/7/21 17:38:10*