"I don't prompt Claude anymore. I have loops running that prompt Claude and figuring out what to do. My job is to write loops." — Boris Cherny
「我已经不再亲自 prompt Claude 了。我有一堆循环在跑,它们去 prompt Claude、弄清楚该做什么。我的工作,就是写循环。」——Boris Cherny
Over the last months I have watched more and more people build something on top of coding agents that feels meaningfully different from just using a coding agent. Some of this happens on top of Pi which is cool to see for sure! The pattern is the same everywhere though: work is put into a queue of sorts, a machine picks it up, attempts it, stops, and then some harness decides whether that was actually the end.
最近几个月,我看到越来越多人在 coding agent 之上搭一种东西——它跟「使用 coding agent」有着实质的不同。其中一些就搭在 Pi 之上,看着当然高兴!不过模式到处一样:工作被放进某种队列,一台机器领走它、尝试它、停下,然后某个 harness 决定:这真的是终点吗?
If not, the harness continues the same session, injects another message, starts a fresh session with modified context, or sends the task to another machine. The task stays alive beyond the point where the model by itself would normally have said: "I am done."
如果不是,harness 就继续同一个 session、注入下一条消息、带着改过的上下文开一个全新 session、或者把任务发到另一台机器。任务活得比模型自己本来会说「我做完了」的那个时刻更久。
I think about that type of loop more than I want to admit.
这类循环在我脑子里盘旋的次数,比我想承认的要多。
There is already an agent loop inside every coding agent. The model calls a tool, incorporates the result, calls another tool, reads a file, edits a file, runs tests, and eventually produces some answer. That loop is one we have been quite familiar with for a long time. The other loop is the harness level loop: the loop outside the agent loop. That loop is also not new. We have been doing versions of this since early Claude Code days, but that loop is becoming ever more present in agentic engineering and in recent weeks it has started to dominate the Twitter discourse.
每个 coding agent 体内本来就有一条 agent loop:模型调工具、吃进结果、再调下一个、读文件、改文件、跑测试,最终产出某个答案。这条循环我们早就熟透了。另一条循环是 harness 层的循环:agent loop 之外的 loop。它也不新(ghuntley 的 Ralph)——Claude Code 早期我们就在做它的各种变体——但它在 agentic 工程里的存在感越来越强,最近几周甚至开始统治 Twitter 上的话语。
I Am Not Good At This Yet · 我还没玩转这个
My current status is that I have not had much success with this way of working for code I deeply care about which turns out to be quite a lot of code.
我的现状是:对那些我真正在乎的代码,这种工作方式没帮我做成什么——而仔细一想,这样的代码其实相当多。
Part of that is taste and part of it is control. I attempt to set a high bar for what I want code to look like, and I want to understand the code I ship. Under pressure, or in a discussion with another human, I want to be able to explain what the system does without first having to ask a clanker to explain it to me. Now there is obviously a question if this desire to understand the code is one that I will still have a few years from now. For now I have not moved past the point of comprehension being important to me.
一部分是品味,一部分是控制。我对自己想要的代码样子设了很高的门槛,而且我想理解我发布的代码。有压力时、或跟另一个人讨论时,我要能直接解释这个系统在干什么——而不是先让 clanker 给我解释一遍。当然有个问题:几年后我是否还会有「想理解代码」这个愿望。至少现在,我还没跨过「理解对我重要」这道坎。
Given this desire, there is something I lack with my experience of code written without me paying attention, particularly from loops. Present-day models tend to produce code that is too defensive, too complex, too local in its reasoning. They avoid strong invariants. They add fallbacks instead of making bad states impossible. They duplicate code, invent bad abstractions, and paper over unclear design with more machinery. Worse though: I so far see very little progress of this improving. If anything, on that front it feels to me that we might even be making steps in the wrong direction. At least for my taste, present-day hands-off harnesses like Claude Code with ultracode produce worse code than what we were producing last autumn. That's because Claude Code, with Fable for instance will be working uninterrupted on a problem for thirty minutes or more, when previously the process would have been much more human in the loop.
抱着这个愿望,我对「不在我注视下写出的代码」——尤其是循环产出的代码——始终缺了点什么。当下的模型倾向于产出**太防御、太复杂、推理太局部**的代码。它们回避强不变量;它们加 fallback,而不是让坏状态不可能存在;它们复制代码、发明糟糕的抽象、用更多机器去糊住不清晰的设计。更糟的是:我至今几乎没看到这方面的进步。甚至可以说,在这个维度上我们可能正在倒退。至少对我的品味而言,如今像 Claude Code with ultracode 这样的放手型 harness,产码质量比去年秋天更差——因为 Claude Code(比如带着 Fable)会不打断地闷头干半小时以上,而从前这个过程里人的参与要多得多。
Furthermore it's well understood that models tend to observe some local failure and add a local defense. Karpathy mentioned how they are "mortally terrified of exceptions". In systems with important invariants, especially persisted data formats or core infrastructure, the right fix is not "handle every malformed case." The right fix is to make the malformed case unrepresentable or impossible to write in the first place. Yet even with a lot of manual steering, that type of code does not come out of LLMs naturally, and even if the code comes out naturally like that, they will still attempt to handle now impossible errors.
此外大家都很清楚:模型倾向于看见局部失败就加局部防御。Karpathy 说过它们「对异常抱有致命的恐惧」。在带有重要不变量的系统里——尤其是持久化数据格式或核心基础设施——正确的修法不是「接住每一个畸形情形」,而是让畸形情形一开始就**无法表示、无法写入**。可即便人工使劲掰,这类代码也不会从 LLM 手里自然长出来;就算长出来了,它们还是会试图去处理那些如今已不可能发生的错误。
When you take that behavior and you put it behind loops, you tend to amplify it. If each iteration adds another small defense, the system slowly becomes less understandable while appearing more robust. The more hands-off you are, the more that happens. It also teaches really bad practices when tools like this are given to juniors without clear guidance. Because if you ask them, why they are doing all that, they will convincingly argue their case.
把这种行为放进循环里,你会把它放大。如果每次迭代都加上一层小防御,系统就在「看起来更健壮」的同时慢慢变得愈难理解。你越放手,这发生得越多。把这类工具不加清晰指导就交给 junior,还会教出很坏的实践——因为你去问他们为什么要做这一切,他们会令人信服地论证自己的做法。
Where Loops Work · 循环在哪里奏效
At the same time, it would be dishonest to pretend the loop pattern does not work because it already works astonishingly well in some domains.
但同时,装作循环模式不管用是不诚实的——它已经在一些领域运转得惊人地好。
Porting code one of them. There are already impressive examples of large automatic porting efforts, including the reported work around moving parts of Bun from Zig to Rust. I have used it with success myself to port MiniJinja to Go. Performance explorations are another case where this works beautifully. A machine can try experiments, benchmark them, discard failures, and keep searching. Security scanning fits naturally too and so does almost any type of research: asking a system to explore a complex problem space and report back without necessarily committing lasting code. One thing that many of these have in common is that they either do not generate new code, but transform code that already exists, or they produce code that intentionally does not have a long shelf life. They either produce proof of concepts or ideas, surface findings or are more akin to mechnical transformation.
代码移植就是之一。大规模自动移植已经有 impressing 的先例,包括把 Bun 的一部分从 Zig 移到 Rust 的报道;我自己也成功用它把 MiniJinja 移植到了 Go。性能探索是另一处——机器可以做实验、跑基准、丢弃失败、继续搜索。安全扫描也天然合适,几乎所有类型的研究都合适:让系统探索一个复杂的问题空间然后汇报,而不必提交长寿的代码。这些东西的共性是:**它们要么不生成新代码、只变换已有代码,要么产出的代码刻意短命**。它们产出概念验证或点子、浮现发现,或者干脆就是机械变换。
I believe that loops that produce artifacts without necessity of longevity or that create some form of clearly verifiable mechnical translation matters more than the general ability of a harness to mechanically measure a goal. Many successful applications of loops use another LLM as a judge or as an orchestrator. The mechnical translation case can be verified with a binary test case, but it can also be judged by an LLM instead!
我认为,「产出无需长寿命的产物、或创造某种可清晰验证的机械翻译」的循环,比「harness 能否机械度量目标」这个通用能力更关键。循环的许多成功应用都是拿另一个 LLM 当裁判或编排者。机械翻译可以用二元测试用例验证,但同样可以让 LLM 来判!
Claude Code, for instance, is increasingly good at creating entire experimental workflows that it will then execute. Sure, the code it produces is slop, but that's more the fault of the model than the harness not being a good judge on if a step in the workflow resulted in a net improvement or completion.
比如说,Claude Code 越来越擅长搭建整套实验性工作流然后自己去执行。没错,它产出的代码是 slop,但这更多是模型的锅,而不是 harness 不会判断「工作流里的这一步是否带来了净改进或完成度」。
The harness just needs some signal that lets it continue. It does not have to be objective or binary, it just has to be useful enough to drive another iteration.
harness 只需要一个能让它继续下去的信号。它不必客观、不必二元——只要足以驱动下一次迭代就够。
I absolutely love loops already that take the boring parts out of my day to experiment and measure and to give me ideas.
对于那些把我日常里「做实验、跑度量、找灵感」的无聊部分拿走的循环,我已经爱得不行。
Software As Organism · 软件即生命体
On the other hand using that same looping methodology to write lasting code does not yet sit well with me. The metaphor I like to reach for is one of moving from software as a deterministic machine to software as an organism.
但另一面,用同一套循环方法学去写长寿代码,我至今无法安然接受。我喜欢用的隐喻是:我们正从「软件作为确定性机器」滑向「软件作为生命体」。
I became a software engineer in an enviornment that encouraged me to understand the machine. There was always a layer you could peel off to deepen your understanding. Machines that did not exhibit deterministic observable behavior were maybe accepted, but generally seen as not exactly optimal. Software architecture-wise, I saw it as desireable to push further towards more determinism rather than less. Likewise the ability to understand the code has been an undeniable goal. In practice not always possible we still took pride in writing code so that it became possible even for new engineers to navigate complex code bases through clever architecture. On well designed systems there were always engineers that knew where the invariantes lived, which parts were load-bearing and which changes were safe. Ideally all of that was also well documented. Where that understanding was lacking, it was generally regarded as something to improve upon.
我入行时的环境鼓励我去理解机器。永远有一层可以剥开、让理解更深一层。不表现出确定性可观察行为的机器也许会被接受,但一般被视为不够优化。在软件架构上,我认为应该向更多确定性推进而不是更少。同样,「能理解代码」是不可否认的目标。实践中不总能做到,但我们仍然以这样的写码为荣:凭聪明的设计,让新工程师也能导航复杂的代码库。设计得好的系统上,总有一些工程师知道不变量住在哪、哪些部分是承重墙、哪些改动是安全的。理想情况下这些还有良好的文档。哪里缺了这种理解,哪里就被视为有待改进。
Obviously that ideal has always been strained. Many software systems, especially very successful ones had periods where engineers on the team were able to keep them clean. Large software systems are not infrequently too big, too dynamic and too dependent on external services to fit into anyone's head. Even without LLMs we already diagnose distributed systems somewhat like doctors in that we observe symptoms, form hypotheses, "order more tests", try some remedies, and observe again.
显然这个理想从来都是紧绷的。很多软件系统——尤其是非常成功的那些——都有过团队工程师能把它们保持干净的时期。大型软件系统经常大到、动态到、依赖外部服务到装不进任何人的脑子。就算没有 LLM,我们诊断分布式系统也已经有点像医生了:观察症状、形成假设、「加做检查」、试些疗法、再观察。
Yet with LLMs we're pushing much further in that direction and much quicker. We use them to write the code and we also use them for diagnosis and remedy. There are plenty of engineers that already live in a world in which the first step after the occurrence of a production issue is followed by having a clanker read logs, propose root causes and proactively put up a patch. The resulting patch is then often picked up by another machine that reviews, sometimes even landing it on main without any human supervision.
而 LLM 把这个方向推得远得多、快得多。我们用它们写代码,也用它们做诊断与治疗。已经有大量工程师活在这样一个世界里:生产事故出现后的第一步,是让 clanker 读日志、提根因、主动挂补丁;然后补丁常由另一台机器审查,有时甚至不经任何人监督就落进 main。
Obviously that is powerful and I cannot deny that it sounds appealing. But giving in to that idea, particularly with less and less human oversight means accepting that we may no longer understand the whole system in the same way. We treat it, we monitor it, we stabilize it, but we do not necessarily comprehend it.
显然这很强大,我无法否认它听起来诱人。但向这个想法投降——尤其是在人的监督越来越少的情况下——意味着接受:我们可能不再以同样的方式理解整个系统。我们治疗它、监控它、稳定它,但我们不一定理解它。
I have no doubts that for some software, that is okay. Not every line of code deserves human authorship and worse code might have been written in the past.
我毫不怀疑,对某些软件来说,这样挺好。不是每一行代码都配得上人类亲手书写,过去写出的更糟的代码也多得是。
But do I want all software to be authored this way?
但我想让所有软件都这样被写出来吗?
You Cannot Quite Opt Out · 你无法完全退出
What's very uncomfortable is that opting out of this fully machine-driven future may not be an option.
非常不舒服的一点是:完全退出这个机器驱动的未来,可能不是一个选项。
Security is the clearest example today. Even if you do not use loops to build your software, other people will use loops against your software. Attackers will run machines continuously and even if it's not attackers, then security researchers will and some of that automated work will throw up dust but also find real issues. And both the signal and the noise will come your way at a volume that makes it almost impossible to deal with unless you yourself throw a machine at the problem.
安全就是今天最清晰的例子。**即便你不用循环构建你的软件,别人也会用循环攻击你的软件。**攻击者会让机器连轴转;就算不是攻击者,安全研究者也会——那些自动化工作扬起的灰尘里也会翻出真问题。而信号和噪音都会朝你涌来,量大到除非你自己也往问题上扔一台机器,否则几乎没法应付。
Daniel Stenberg's post about curl's summer of bliss is a good example of the pressure maintainers are already under. As far as I know, AI does not play a tremendous role in the core development of curl today. Yet despite all of this, maintainers are overwhelmed by reports, most of which are now AI-generated ones.
Daniel Stenberg 那篇讲 curl「summer of bliss」的文章,是维护者正承压的好例子。据我所知,AI 在 curl 的核心开发里 today 并不扮演巨大角色。然而尽管如此,维护者还是被报告淹没了——其中大部分现在是 AI 生成的。
If attackers and reporters loop, defenders will eventually need to loop too to keep up. Maybe not to write patches directly, maybe just to triage and reproduce and pressure will increase.
如果攻击者和报告者都在循环,防御者最终也不得不循环起来才能跟上。也许不是直接写补丁,也许只是分诊和复现——压力只会涨。
The same is true competitively as some teams will out-build others through raw speed. Some projects will suddenly move faster because a tiny group figures out how to orchestrate machines effectively. Some startups will do with five people what used to require fifty. Some people might literally put a machine against your product in a loop and ask it to "make it like the other one." And if their users are happy, does it really matter?
竞争维度同理:有些团队会靠纯粹的速度盖过别人。有些项目会突然变快,因为一小撮人搞明白了如何有效编排机器。有些创业公司用五个人干过去五十个人的活。有些人可能字面意义上地对你的产品架一台机器跑循环,命令它「把它变得像另一个」。而如果他们的用户挺满意,这真的重要吗?
Not all software will be equally affected. Some domains will punish sloppiness and demand trust and responsibility, but a lot of software lives in a world where raw speed, quick experimentation, and vast coverage matter enormously.
不是所有软件都会被同等波及。有些领域会惩罚草率、要求信任与责任,但大量软件活在一个原始速度、快速实验、覆盖面压倒一切的世界里。
Building New Dependencies · 建立新的依赖
The scariest part to me is that we become dependent on these new machines in new ways. Software has always depended on tools. I remember the time when I had to pay for compilers. These new tools are a flashback to times where creating software came with real costs. But now it's no longer a one-time payment, it's a constant dependency. Not just a dependency on a filled wallet, but also a cognitive dependency.
对我来说最可怕的部分是:我们正以新的方式依赖这些新机器。软件从来都依赖工具——我还记得要为编译器付费的年代。这些新工具像是闪回到「创造软件伴随真实成本」的时期。但现在这不再是一次性付费,而是一种持续的依赖。不只是钱包的依赖,还是认知的依赖。
If a codebase is produced by loops, reviewed by loops, patched by loops, and kept alive by loops, what happens when you no longer have access to the same class of systems? What happens when some trade restrictions take away access to the most powerful models? What if just the cost becomes unbearable? What if you and your team just lose the last remaining ability to understand the code without using the machine?
如果一个代码库由循环生产、由循环审查、由循环修补、由循环续命——那你不再能访问同类系统时会怎样?某些贸易管制拿走最强模型的访问权时会怎样?如果仅仅是成本变得无法承受呢?如果你和你的团队就是失去了「不用机器也能理解代码」的最后一丝能力呢?
We may create codebases that are not merely hard to maintain by humans, but that assume machine participation as part of their maintenance model. This is already happening! It's not happening everywhere, and it might not even be happening in ways that are seen as problematic, but we see more and more of it. People more and more merge code they cannot fully explain. People lose their ability to create issue reports or discuss things in chat, without augmenting or rephrasing their messages with the context provided by a clanker. Too many people increasingly rely on a machine to summarize or contextualize it. More and more do I encounter people who converse with me through the indirection of an LLM.
我们可能造出这样的代码库:不只是「人类难以维护」,而是**把机器参与当作其维护模型的一部分**。这已经在发生!不是到处都在发生,甚至未必以被视为问题的形式发生,但我们看到得越来越多。人们越来越多地合并自己无法完整解释的代码。人们正在失去不借助 clanker 提供的上下文来增强、改写措辞,就写不出 issue 报告或在聊天里讨论问题的能力。太多人越来越依赖机器来总结或语境化。我遇到「隔着一层 LLM 跟我对话」的人,越来越多。
Again, maybe that is not even going to be wrong, but it's a massive change to how we did things.
再说一遍:也许这甚至不会是错的。但这对我们过去的做事方式,是一场巨变。
Future Harnesses · 未来的 harness
I have little doubt that this is where things are going but going there will require us to do something about our tooling everywhere, and not just in the coding agents.
我几乎不怀疑事情正走向那里。但走到那里,要求我们对各处的工具做点什么——而不只是在 coding agent 里。
Just orchestrating more loops won't be enough. Better visualizations of changes or orchestration or agents will not restore our understanding. Either we need to find clever ways to jolt the human back into the loop and make the changes of the loops legible long term, or we need to find better ways to compose these ever more complex systems.
光编排更多循环是不够的。更好的变更可视化、编排可视化、agent 可视化,都换不回我们的理解。要么我们得找到聪明办法把人震回回路里、让循环的变更长期保持可读;要么我们得找到更好的方式去组合这些日益复杂的系统。
This is also where my thinking about the role of Pi is changing. Pi has been cautious, and I think that caution is good. I do not want a future where every interaction turns into an uncontrolled swarm of machines making changes I cannot follow. I would not want Pi to become an unmaintainable mess in an effort to win the race towards software that writes itself and I would not want Pi to promote this type of engineering either. At the same time Pi is a harness and harnesses are at the center of people running these new types of experiments.
**这也是我对 Pi 的角色定位正在改变的地方。**Pi 一直谨慎,我认为这种谨慎是好的。我不想要这样一个未来:每次交互都变成一群机器的失控蜂群,做着跟不上的改动。我不想让 Pi 为了赢下「软件自写」的竞速变成一团不可维护的烂泥,也不想 Pi 去推销那种工程学。但同时,Pi 是一个 harness,而 harness 正处在人们跑这类新实验的震中。
Task queues for coding tasks, orchestration of agents, subagents, durable sessions will matter more and more. Even those of us who have their reservations and are not blindly embracing loops will have to start doing those experiments. We need to, because we need to understand how to make this future bounded and survivable.
面向编码任务的队列、agent 编排、subagent、durable session——这些会越来越重要。**连我们这些有保留、不盲目拥抱循环的人,也得开始做这些实验了。**我们必须做,因为我们需要理解如何让这个未来有界、可存活。
Controlling Loops · 驾驭循环
As you can read from this post, I'm very uneasy about this future. Not cause of fear, but because of caution given experiences with this technology so far.
如你所见,我对这个未来非常不安。不是因为恐惧,而是基于对这项技术迄今的体验而来的谨慎。
Adopting the idea of harness loops means that the harness decides when work is finished. In the agent loop, the model eventually says "done" and I review. Even before that, I usually steer along the way. I am involved and I enjoy learning along the way. In the harness operated loop I'm not sure what my role even is. Even the "done" signal loses all meanings and just becomes communicated to yet another machine that judges. My role is reduced to that of a messenger.
采纳 harness loop 意味着:由 harness 决定工作何时完成。在 agent loop 里,模型最终说「做完了」,我来审。在那之前,我通常一路 steering。我参与其中,享受沿途学习。而在 harness 驱动的循环里,我甚至不确定我的角色是什么。连「done」这个信号都失去了全部意义——它只是被传达给下一台做判断的机器。**我的角色被降格为一个信使。**
Today I do not like much of the code that I see from systems built that way and neither do I enjoy interacting with too much of software built with AI assistence. Looping is powerful but it removes responsibility more and more, and it at least today very much encourages us to give in to the machine.
今天,我不喜欢这类系统产出的代码的大部分,也不太享受与太多 AI 辅助构建的软件打交道。循环很强大,但它把责任一点点卸掉,而且至少在今天,它非常鼓励我们向机器投降。
And yet I have no doubts that this looping future is going to be our future despite the fact that I presently resent it. I already see astonishingly small teams building at impossible speed and I see codebases turning more and more into obscure and confusing organisms that can only be diagnosed by more machines. Those codebases are simultaniously useful and messy.
然而我毫不怀疑:这个循环的未来就是我们的未来——尽管我此刻厌恶它。我已经看到小得惊人的团队以不可能的速度构建,看到代码库越来越变成晦涩费解的生命体,只能靠更多机器来诊断。那些代码库同时是有用的和混乱的。
So I guess I'm coming to terms with that the question is not whether we will loop because clearly we will. Maybe the question is that in a future of loops, how do we don't abdicate judgment, how we can retain rules of good engineering, how we can ensure that responsible human can continue to supervise, how we need to re-think how we architect code to retain sanity along the way.
所以我想我正在接受:问题已经不是「我们会不会循环」——显然会。问题也许是:在循环的未来里,我们如何不放弃判断,如何保住好工程的规则,如何确保负责任的人能持续监督,以及我们需要怎样重新思考代码架构,才能在这一路上保住理智。