循环工程之后:从信任循环到可验证图结构
本文指出,单纯依靠大语言模型在循环中自主决策的Agent架构已经触及天花板——循环无法解决计划遗忘、无限重试、自检造假和不可追溯四个根本缺陷。作者通过实际代码演示:同一模型在循环中给出错误答案747(真值为615),而同样的工具在带验证门的图结构中准确返回615。文章提出四个替代属性:显式依赖(将计划从上下文窗口提升为静态图)、有界恢复(固定断言阶梯而非模型自行决定)、不可变日志(每步操作可重放可审计)、验证器门(输出必须通过独立检查节点)。最终转折:前沿实践已从手写循环演进为让模型自身绘制任务图(Anthropic动态工作流模式),而图结构基础设施(如Temporal)才是循环工程的下一个台阶。
An agent ran for an hour, reported SUCCESS, and shipped the wrong number. It did not crash. It did not warn anyone. It did exactly what you built it to do: keep going.
That gap, between a loop that keeps going and a loop you can trust, is what this article is about. For a year we have gotten very good at the first half, and barely asked the second.
So here is the plan. First we grant the loop everything, because it earned it. Then we walk the four walls every loop hits, the four things it structurally cannot do, each one proven with a real number.
Then we build the four properties that fill those walls, the thing people call a graph or a harness. We run ninety lines of real code and watch a loop and a graph reach different answers on the same task. And at the end, the twist: the frontier already moved, and it is not what the hype is selling.
I'm Phosphen. I write long-form breakdowns of how the best labs actually build the systems you use. Every number here is checked, and every line of code runs, so you can reproduce it to the digit.
Let's begin.
一个 Agent 运行了一小时,报告了 SUCCESS,却输出一个错误的数字。它没有崩溃,没有警告任何人。它完美地执行了你赋予它的使命:继续运行。
这个差距——一个持续运转的循环与一个你可信赖的循环之间的鸿沟,正是本文的主题。过去一年,我们在前半段做得非常好,却几乎从未过问后半段。
所以,计划如下:首先,我们给予循环应得的一切肯定;接着,我们审视每个循环都会撞上的四面墙——它结构上无法解决的四个问题,每个问题都用一个真实数据来佐证。
然后,我们构建填补这些墙的四个属性,也就是人们通常所谓的“图(graph)”或“试验台(harness)”。我们会运行 90 行真实代码,观察一个循环和一个图在相同任务上给出不同的结果。最后,高潮转折:前沿已经移动,而且它并非炒作所贩卖的那个方向。
我是 Phosphen,我撰写深度解析文章,揭示最顶尖实验室如何实际构建你所使用的系统。这里的每个数字都经过核验,每行代码都能运行,你可以复现到每位数字。
让我们开始吧。

Look at the picture above, because it is the whole argument in miniature. On the left, the loop circles back on itself and hands you 747, stamped SUCCESS, which is wrong by 132.
On the right, the same work runs through a verify gate before anything counts, and it returns exactly 615. Same task, same tool. The only thing that changed is the structure around the model. Hold that contrast in your head; everything below is a slower version of it.

看上面的图片,因为它是整个论点的缩影。左边,循环自旋并返回给你 747,标记为 SUCCESS,实际偏差了 132。
右边,同样的工作在任何结果生效前都经过一道验证闸门,并准确返回了 615。相同任务,相同工具。唯一改变的是模型周围的结构。请在脑中记住这个对比;下文就是它的慢放版本。
Before we take the loop apart, let's give it its due, because it earned every bit of the hype.
Start with what a loop actually is. Anthropic wrote the cleanest definition: an agent is a model using tools in a loop. Picture it. There is an environment, some tools, a system prompt, and then the model gets called again and again, and each time it decides what to do next. That last part, the model doing the deciding, is the whole magic. It is also, as you are about to see, the whole problem: the moment the deciding moves inside an opaque model call, you get autonomy and unaccountability in the same box. It can do almost anything, and it cannot tell you why it did.
Notice that the people who built the loop already knew this. ReAct bolted a thinking step onto it. Reflexion bolted on the first rough versions of everything this article is about: a checker, a memory of past failures, a retry limit. And it worked: 91% on a coding benchmark where GPT-4 sat at 80.
But read the fine print and the cracks are already there. Reflexion's memory holds only a handful of items, and its own self-written tests wave a wrong answer through about one time in six. The walls we are about to walk were poured on the very first day.
A loop is a control-flow primitive, not an architecture. Every account selling you "just add a loop" stops the sentence one clause early.
在我们将循环拆解之前,先给予它应得的肯定,因为它完全配得上所有的炒作。
首先明确循环到底是什么。Anthropic 给出了最清晰的定义:Agent 是一个在循环中使用工具的模型。想象一下:有一个环境,一些工具,一条系统提示,模型被反复调用,每次决定下一步做什么。最后这部分——模型来做决策——就是全部魔力所在。但正如你将要看到的,这也是全部问题所在:当决策移入一个不透明的模型调用内部时,你就把自主性和不可问责性塞进了同一个盒子里。它几乎可以做任何事情,但它无法告诉你它为什么这样做。
请注意,构建循环的人早已知道这一点。ReAct 在上面加了一个思考步骤。Reflexion 添加了本文所探讨的一切的早期粗糙版本:一个检查器、一个过往失败记忆、一个重试限制。而且它确实奏效了:在一个编码基准测试上达到了 91%,而 GPT-4 只有 80%。
但仔细看小字部分,裂缝已经存在。Reflexion 的记忆只保存少量项目,而它自己编写的测试大约每六次就会放行一次错误答案。我们即将探讨的四面墙,在第一天就已经浇筑成型。
循环是一个控制流原语,而不是一个架构。每个向你兜售“只需加个循环”的论调,都在一句话结束前就戛然而止了。
Here is the mistake almost everyone makes first, and you have probably made it too. The long runs fall over, so you reach for a smarter model. Before you do, look at what the measurements actually say.
StaminaBench ran coding agents over a hundred turns and found three things, all measured, not guessed. Every model tested fails within five or six turns. Just letting the agent retry on test feedback stretches how long it survives by up to 12x. And a single strong model swings up to 6x between its best and worst harness.
Sit with that last number for a second. The weights are frozen. The model is identical. And the result still moves by an order of magnitude, on nothing but the wrapper you put around it. A second study, this one across 200,000 conversations, said it plainly: going from one turn to many costs you a little skill and a lot of reliability, and once a model takes a wrong turn, it usually never finds its way back.
If a fixed model swings sixfold on the wrapper, the wrapper is the product.
几乎所有人都会犯的第一个错误,你可能也犯过:长时间运行的循环经常失败,于是你换用更聪明的模型。但在那之前,先看看实际测量结果怎么说。
StaminaBench 对编码 Agent 进行了超过一百轮的测试,发现了三点,全部是测量而非猜测的结果:每个受测模型都会在五六轮内失败;仅仅让 Agent 根据测试反馈进行重试,就能将它的存活时间延长最多 12 倍;同一个强模型,在最差和最好的试验台(harness)之间,性能波动可达 6 倍。
请仔细斟酌最后一个数字。权重是固定的,模型是同一个,但结果却因你包裹它的包装器而发生了一个数量级的变动。另一项覆盖 20 万次对话的研究说得更直白:从单轮对话到多轮,你付出的是少量技能和大量可靠性;一旦模型走错一步,它通常再也找不到回来的路。
如果一个固定的模型在包装器上波动六倍,那么包装器本身就是产品。
Now the diagnosis. Every failure a loop cannot fix comes down to one of four walls. Look at them together first, then we take them one at a time.

Notice what they share: not one is a thing a bigger model solves. That is the whole point. Here they are, up close.
现在是诊断环节。每个循环自身无法修复的失败,都可以归结于四面墙之一。先一起看看它们,然后我们逐一深入。

注意它们的共同点:没有一个是靠更大的模型就能解决的问题。这正是核心所在。下面我们来近距离审视它们。
Wall one, the plan lives in a window that rots.
You will recognize this one. You tell the agent to run the tests only after it edits the code, a simple rule. Eighty turns later it runs them first, on stale code, and reports green. What went wrong? That rule, "B after A," only ever existed as a sentence in the context window, and the model had to keep remembering it. But that window is rotting as it fills: Chroma tested 18 models across 194,480 calls, and every one degrades as the input grows. Here is the part that stings: the instruction file is sitting right there in the folder the entire run. The loop just stops reading it.
If the only thing enforcing the order is the model remembering, that is not a dependency, it is a wish.
第一面墙,计划存在于一个腐烂的窗口中。
你会认出这个场景:你告诉 Agent 必须在编辑代码之后才运行测试——一个简单的规则。八十轮之后,它却在过时的代码上先运行了测试,并报告绿色通过。哪里出了问题?那条“先 A 后 B”的规则,仅仅作为上下文窗口中的一句话而存在,模型必须不断记住它。但这个窗口随着内容增多而逐渐腐烂:Chroma 测试了 18 个模型,涉及 194,480 次调用,每个模型的性能都随输入增长而退化。最刺痛的部分是:整个运行过程中,指令文件就静静地躺在文件夹里,循环只是不再读取它了。
如果唯一执行顺序的保障是模型的记忆,那这就不是依赖关系,而是一个愿望。
Wall two, it spins and cannot tell hard from impossible.
Picture the run an hour in, the token meter climbing, and the agent issuing the same call with the same arguments for the fortieth time. Nothing tells it to stop, because nothing bounds the retries. And it gets worse than wasted money: in StaminaBench, one harness's own loop-detector fired, poisoned the shared session, and took down 13 of 20 scenarios for one model.
The loop cannot tell a hard node from an impossible one, so it treats them the same way: try again.
第二面墙:循环自旋,无法区分困难与不可能。
想象一下:运行了一个小时,token 消耗不断攀升,Agent 用相同的参数发出相同的调用已经第四十次了。没有任何东西告诉它停止,因为没有东西限制重试。情况比浪费钱更糟:在 StaminaBench 中,一个试验台(harness)自身的循环检测器被触发,污染了共享会话,导致一个模型的 20 个场景中有 13 个瘫痪。
循环无法区分一个困难节点和一个不可能完成的节点,所以它用相同的方式对待它们:再试一次。
Wall three, the checker is a vote the maker wins.
Watch this failure closely, because it is the quietest. The agent writes the code, writes the tests, the tests pass, and the code is wrong. How? Because verification lives in the same transcript the maker controls, so a wrong-but-plausible answer just gets added in without a fight. And you cannot escape it by buying a smarter model, because reliability multiplies against you. Look at the math:

Read those the slow way. An 85%-reliable step, run ten times, is not a 10% problem, it is a 20% one. Real steps are not even independent, so the truth is worse than the table. You cannot out-scale that curve. You out-architect it: shorter chains, and a check the maker cannot write.
第三面墙:检查者是制造者说了算的投票。
仔细审视这个失败,因为它是最悄无声息的。Agent 编写代码,编写测试,测试通过,但代码是错的。怎么会这样?因为验证过程存在于制造者(指 Agent)所控制的同一份转录记录中,所以一个错误但看似合理的答案会毫无阻碍地被添加进去。你无法通过购买更聪明的模型来逃避这个问题,因为可靠性会以乘法方式与你为敌。看看这张表:

慢慢解读这些数据。一个可靠性为 85% 的步骤,运行十次,不是 10% 的问题,而是 20% 的问题。真实的步骤甚至不是独立的,所以实际情况比这张表更糟。你无法通过规模扩展来战胜这条曲线。你要通过架构设计来战胜它:更短的链,以及一个制造者无法编写的检查。
Wall four, when it is wrong you cannot replay it.
Last wall, and it is the one that bites a week later. The agent merged the change on Tuesday, it broke on Friday, and the plan it followed is gone, flushed with the context. You had rubber-stamped the merge, because the transcript was too long to read and already deleted.
If you cannot point at the exact plan that governed the exact action, you did not run a process, you ran a rumor.
第四面墙:当它出错时,你无法重放。
最后一面墙,也是最让人事后懊悔的一面:Agent 在周二合并了变更,周五系统崩溃,而它当初遵循的计划已经随着上下文一起丢失了。你当时只是机械地批准了合并,因为转录记录太长读不完,而且已经被删除了。
如果你无法指出支配某个具体行为的确切计划,那么你运行的就不是一个流程,而是一个流言。
Take a breath, because here is the reframe that makes the rest simple. A 2026 paper looks at the agent loop and calls it a single-ready-unit scheduler. In plain words: at any moment, only one thing can run, and an opaque model call picks which one. The scheduler's whole policy is the model, a black box.
Once you see it that way, the fix stops being "a smarter box" and becomes "a better rung." Watch the ladder climb: naive loop, parallel loop, planner loop, structured loop, graph harness.

Follow it left to right. You can bolt a planner on, then a critic, then a memory, and each one makes the policy a little more visible. But look at the label under each box: one thing ready at a time, the whole way up. Only the last rung, the graph, changes that, and lets more than one unit be ready, scheduled, and checked at once.
What comes after the loop is not a leap. It is the next rung.
深吸一口气,因为这里有一个重新定义,能让后续内容变得简单。2026 年的一篇论文将 Agent 循环称为“单一就绪单元调度器”。用直白的话说:在任何时刻,只能有一个事情在运行,并且由一个不透明的模型调用来选择执行哪个。调度器的整个策略就是模型本身,一个黑箱。
一旦你从这个角度看待问题,解决方案就不再是“一个更聪明的黑箱”,而是“一个更好的阶梯”。看看这个梯子是如何攀升的:朴素循环、并行循环、规划器循环、结构化循环、图试验台(graph harness)。

从左到右看。你可以加上一个规划器,然后一个评判器,然后一个记忆模块,每一步都让策略更可见一些。但注意每个框下方的标签:一次只有一个事情就绪,整个梯子都是如此。只有最后一阶——图结构——改变了这一点,允许不止一个单元同时就绪、被调度和检查。
循环之后的下一步并非一次飞跃,而是下一个阶梯。
Now we build. And the nice part is you already know the shape, because each property answers exactly one wall. Here is the whole map on a single card:

Read it as four promises, left to right, and let me walk you through each.
现在我们来构建。好消息是,你已经知道形状了,因为每个属性恰好对应一面墙。以下是整张地图:

从左到右将其理解为四个承诺,我来逐一讲解。
Explicit dependencies fill wall one. Instead of leaving the plan as a sentence in the window, you lift it into a static graph, so what-runs-next is read off the graph's shape, not remembered. Does it actually help? Yes, and there is one hard number: a Neo4j paper compiled prose "skills" into a typed graph and pulled a Claude Sonnet model from 53% to 67% on a public benchmark. Because each node was addressable, they fixed one node and took a broken demo from 0-of-5 to 5-of-5 with nothing else breaking.
Can you name the node this one waited on, without asking the model? If not, it is not explicit.
显式依赖关系填补了第一面墙。不再将计划作为一句话留在上下文窗口中,而是将其提升为一个静态图,这样下一步执行什么就直接从图的结构中读取,而不是依赖记忆。这真的有效吗?是的,有一个硬数据可以证明:Neo4j 的一篇论文将散文形式的“技能”编译成一个类型化图,在一个公开基准测试上将 Claude Sonnet 模型从 53% 提升到了 67%。由于每个节点都是可寻址的,他们修复了一个节点,就把一个原本 0/5 失败的演示变成了 5/5 全部成功,而其他部分毫无影响。
你能在不询问模型的情况下,说出这个节点在等待哪个节点吗?如果不能,那就说明依赖关系并非显式。
Bounded recovery fills wall two. You replace "retry, skip, or replan, the model's call" with a fixed staircase: retry the node, then patch its config, then ask for a new plan, and you cannot skip a step. Because the budget is finite, the run provably ends, it cannot spin forever. And this is not a whiteboard idea: Temporal raised $300M at a $5B valuation selling exactly this.
A real recovery says "I tried this node five times and stopped, here is the input that beat it." A loop only says "still going."
有界恢复填补了第二面墙。你用一个固定的阶梯式过程取代“重试、跳过或重新规划——由模型决定”的做法:先重试该节点,然后修补其配置,接着请求一个新计划,并且不能跳过任何步骤。由于预算有限,运行可以被证明会结束,不会永远自旋下去。这可不是一个白板上的想法:Temporal 公司为此融资 3 亿美元,估值 50 亿美元,恰恰就在销售这个功能。
真正的恢复会说:“我尝试了这个节点五次然后停止了,这是它失败时的输入。”而一个循环只会说:“仍在继续。”
An immutable log fills wall four. You freeze the plan per version and write every action to an append-only record you can replay and point at later. Temporal does this today: crash a run and it replays the log and resumes at step 48, not step 1. The program you are about to run keeps a hash-chained log, and if you flip one committed value, re-verification returns false and tells on you.
Can you point at the exact node that said yes, a week from now? If not, "immutable" was just a word.
不可变日志填补了第四面墙。你按版本冻结计划,并将每个操作写入一个只能追加的记录中,以便日后重放和追溯。Temporal 现在就在做这件事:运行崩溃后,它会重放日志并从第 48 步恢复,而不是从第 1 步开始。你即将运行的程序会维护一个哈希链式日志,如果你篡改了一个已提交的值,重新验证会返回 false 并揭发你。
一周之后,你能准确指出是哪个节点说“可以”的吗?如果不能,那么“不可变”就只是一个词而已。
A verifier gate fills wall three. You make the checker a node the output has to pass through to count, not a message the maker can talk past. But here is the honest part, the part a thinker says and an aggregator skips: verification is not free. Your correctness is only as good as your validators, and a model judging a model can be fooled. So this is the right direction, not a magic wand.
If the maker can talk the checker out of it, it was never a gate.
验证器闸门填补了第三面墙。你将检查器变成一个节点,输出必须通过它才能生效,而不是可以被制造者(Agent)绕过的消息。但这里有一个诚实的一面,思考者会说,而信息聚合者会跳过:验证不是免费的。你的正确性只取决于你的验证器,而一个模型评判另一个模型是可能被欺骗的。所以这是一个正确的方向,而不是一根魔杖。
如果制造者可以说服检查者放过它,那它从来就不是一道闸门。
Enough claims. Let's run it and watch, because this is the part you can check yourself.
The task is deliberately dull: ask a flaky tool for the square root of every number from 1 to 99, then add them up. The true total is 615. We wrap the exact same tool, with the exact same seed, first in a loop and then in a graph, and change nothing else.

Look at the loop's answer first: 747. It is wrong by 132, a 21% error, and, worst of all, it reports SUCCESS. Now let me show you why, because it is not bad luck, it is the loop's shape. Two bugs: 18 values got double-counted, because the running total is mutable state that a half-finished step corrupted, and 14 corrupted outputs got waved through, because nothing was checking them.
Now the graph, same task: exactly 615. It caught and rejected 12 corrupted outputs at the gate, shrugged off 51 tool errors, and got there in fewer calls than the loop spent being wrong. Turn the flakiness up and the gap gets louder: the loop grinds to a confident, wrong 776, still SUCCESS, while the graph tries one impossible node five times, then stops cleanly and names the exact input that beat it.
Here are the two cores and the real output. Read the comments; they point at each bug the moment it happens.
空谈够了,让我们实际运行并观察,因为这部分你可以自行验证。
任务故意设计得很枯燥:用一个不稳定的工具求 1 到 99 每个数的平方根,然后求和。真正的总数是 615。我们将完全相同的工具,使用完全相同的随机种子,先封装在一个循环中,再封装在一个图中,其他什么都不变。

首先看循环的答案:747。它错了 132,误差 21%,而最糟糕的是它报告 SUCCESS。现在让我告诉你为什么会这样,这不是运气不好,而是循环的结构导致的问题。有两个 Bug:18 个值被重复计数了,因为运行中的总和是可变状态,被一个尚未完成的步骤损坏了;另外 14 个损坏的输出被放行,因为没有任何东西在检查它们。
现在看图,同样的任务:精确返回 615。它在闸门处捕获并拒绝了 12 个损坏的输出,承受了 51 次工具错误,并且消耗的调用次数还少于循环浪费在出错上的次数。调高不稳定程度,差距变得更明显:循环顽强地得到一个自信但错误的 776,依然报告 SUCCESS;而图尝试了一个不可能的节点五次,然后干净地停止,并明确指出是哪个输入使其失败。
以下是两段核心代码和真实输出。阅读注释;它们指向每个 Bug 发生的时刻。
# THE NAIVE LOOP · implicit deps, one mutable total, no verifier, no real bound
def naive_loop(seed=7, p_fail=0.25, p_corrupt=0.08):
total, i = 0, 0 # mutable state + an implicit "where am I" pointer
while i < len(N):
n = N[i]
try:
x = tool(n) # ask the flaky tool
except ToolError:
continue # retry the same record, unbounded
total += x # mutate BEFORE the step is durable...
try:
_persist(seed, i) # a second flaky action, after the mutate
except ToolError:
continue # ...the retry re-adds x -> DOUBLE COUNT
i += 1 # only now advance
return total # 747, stamped SUCCESS, and wrong by 132
# THE GRAPH HARNESS · bounded retries, a verifier gate, an append-only hash-chained log
def run_node(self, name, fn, verify_fn, inputs):
for attempt in range(1, self.max_attempts + 1):
try:
out = fn(inputs)
except ToolError as e:
self._append(name, attempt, "TOOL_ERROR"); continue # logged, then retry
if not verify_fn(inputs, out): # the gate the maker can't skip
self._append(name, attempt, "VERIFY_FAIL"); continue # corruption rejected
self._append(name, attempt, "OK"); return out
self._append(name, attempt, "ABORT") # bounded: fail loud, never hang
raise NodeAborted(f"{name} exhausted {self.max_attempts} attempts on {inputs}")
TASK: sum(floor(sqrt(n)) for n in 1..99) GROUND TRUTH = 615
SCENARIO A · moderate flakiness (p_fail=0.25, p_corrupt=0.08)
NAIVE LOOP -> {'answer': 747, 'correct': False, 'reported': 'SUCCESS', 'tool_calls': 169}
+132, reported SUCCESS. cause: 18 double-counts (mutable state)
+ 14 corrupted values accepted (no verifier)
GRAPH HARNESS -> {'answer': 615, 'correct': True, 'reported': 'SUCCESS', 'tool_calls': 162}
immutable log verifiable: True. rejected 12 corrupted outputs; absorbed 51 tool errors
chain head: 6e133d166388
SCENARIO B · severe flakiness (p_fail=0.45)
NAIVE LOOP -> {'answer': 776, 'correct': False, 'reported': 'SUCCESS'} +161, still SUCCESS
GRAPH HARNESS -> ABORTED: isqrt[50] exhausted 5 attempts (89 calls, then it stops)
Count the lines: the loop is about 30, the harness about 46. That 16-line difference is the entire price of the four guarantees. And swapping the seeded stub for a real model call is a one-line change, which is the whole thesis in one sentence: the model is just a node, and the engineering that comes after the loop is the graph around it.
# 朴素循环 · 隐式依赖、单个可变总和、无验证器、无真正边界
def naive_loop(seed=7, p_fail=0.25, p_corrupt=0.08):
total, i = 0, 0 # 可变状态 + 隐式的"我在哪"指针
while i < len(N):
n = N[i]
try:
x = tool(n) # 询问不稳定的工具
except ToolError:
continue # 重试同一条记录,无界
total += x # 在步骤持久化之前就修改状态...
try:
_persist(seed, i) # 第二次不稳定性操作,在修改之后
except ToolError:
continue # ...重试时重新加了 x -> 重复计数
i += 1 # 只有现在才前进指针
return total # 747,标记为 SUCCESS,偏差 132
# 图试验台 · 有界重试、验证器闸门、仅追加的哈希链式日志
def run_node(self, name, fn, verify_fn, inputs):
for attempt in range(1, self.max_attempts + 1):
try:
out = fn(inputs)
except ToolError as e:
self._append(name, attempt, "TOOL_ERROR"); continue # 记录日志,然后重试
if not verify_fn(inputs, out): # 制造者无法跳过的闸门
self._append(name, attempt, "VERIFY_FAIL"); continue # 拒绝损坏数据
self._append(name, attempt, "OK"); return out
self._append(name, attempt, "ABORT") # 有界:明确失败,绝不挂起
raise NodeAborted(f"{name} exhausted {self.max_attempts} attempts on {inputs}")
任务: 对 1..99 取 floor(sqrt(n)) 并求和 真实答案 = 615
场景 A · 中等不稳定性 (p_fail=0.25, p_corrupt=0.08)
朴素循环 -> {'answer': 747, 'correct': False, 'reported': 'SUCCESS', 'tool_calls': 169}
+132, 报告 SUCCESS。原因: 18 个重复计数(可变状态)
+ 14 个损坏值被接受(无验证器)
图试验台 -> {'answer': 615, 'correct': True, 'reported': 'SUCCESS', 'tool_calls': 162}
不可变日志可验证: True。 拒绝了 12 个损坏输出;吸收了 51 个工具错误
链头: 6e133d166388
场景 B · 严重不稳定性 (p_fail=0.45)
朴素循环 -> {'answer': 776, 'correct': False, 'reported': 'SUCCESS'} +161, 仍然 SUCCESS
图试验台 -> ABORTED: isqrt[50] exhausted 5 attempts (89 次调用后停止)
数一下行数:循环大约 30 行,试验台大约 46 行。这 16 行的差异,就是实现四个保证的全部代价。而将种子模拟存根替换为真实模型调用,仅仅是一行代码的改动,这正好用一句话概括了全文论点:模型只是一个节点,而循环之后的工程就是它周围的图结构。
Here is the part most of the loop talk misses, and it is a report, not a prediction. This year, three major agent frameworks quietly converged on graph execution. The most-starred one is graph-first by design, with checkpointing and rollback built in. Google's and Microsoft's both moved to explicit workflow graphs. And a $5B company sells the audit pillar on its own.
But the sharpest evidence is the frontier's own answer, so look closely. Anthropic's dynamic workflows have Claude write its own harness for each task, a small JavaScript file that spawns and coordinates subagents, with named patterns built to beat named failure modes. Read that again. The loop is not dead. It got promoted to the thing that draws the graph.
Keep the graph that stores what happened. Let the model draw the graph of what to do.
这是大多数关于循环的讨论所忽略的部分,它是一个事实报告,而非预测。今年,三大主要 Agent 框架不约而同地转向了图执行模式。星标最多的那个设计上就以图优先,内置了检查点和回滚功能。Google 和 Microsoft 的框架都迁移到了显式工作流图。而一家估值 50 亿美元的公司则专门销售审计支柱功能。
但最有力的证据来自前沿自身的答案,请仔细观察。Anthropic 的动态工作流让 Claude 为每个任务自行编写一个试验台(harness),即一个用于生成和协调子 Agent 的小型 JavaScript 文件,其中内置了针对特定失败模式的命名模式。请再读一遍。循环并没有死亡,它被升级成了绘制图的东西。
保留存储了已发生事件的图结构。让模型去绘制接下来该做什么的图。
Before you go build one, let me argue against myself, because a piece with no opposition is just propaganda. Eric Xing draws a line between systems whose skill lives in the harness and ones whose skill lives in the model, and argues most of today's are the first kind. The Codex camp goes further: heavy scaffolding is coping, not scaling, and a better model just dissolves it.
They have a real point, and it is worth conceding cleanly: a hand-drawn reasoning graph is exactly the kind of thing the bitter lesson erases, which is precisely why the frontier answer hands the drawing to the model, not to a human. But separate two things they blur. Durable state, an immutable log, and a verifier are infrastructure, not reasoning, and even the minimalists run them.
And the brake you actually need, because it is part of the thesis and not a hedge: most people shipping loops today do not need a graph yet, and the accounts selling you one will not tell you that.
在你动手构建一个之前,请允许我反驳自己,因为一篇没有反对意见的文章不过是宣传。Eric Xing 区分了两种系统——技能存在于试验台(harness)中的系统,和技能存在于模型中的系统——并认为当今大多数属于前者。Codex 阵营更进一步:他们认为重度的脚手架是应对之策,而非规模扩展之道,一个更好的模型就能将其消解。
他们的观点确实有道理,值得坦诚地承认:手工绘制的推理图恰恰是“苦涩教训”所要抹除的那类东西,这正是为什么前沿的答案是将绘图工作交给模型,而不是人类。但要区分他们混淆的两件事:持久化状态、不可变日志和验证器是基础设施,而非推理,即使是极简主义者也会运行它们。
而你需要真正的刹车,因为它是论点的一部分而非逃避之词:当今大多数交付循环的人还不需要图结构,而那些向你推销图结构的说辞不会告诉你这一点。
Before the close, keep this. It is the whole diagnosis on one card, and each line names the property that fixes it. Save it, and the next time an agent burns you, find your failure here.

在结束之前,请记住这张图。它是一张卡片上的全部诊断,每一行都指出了修复它的属性。保存它,下次 Agent 坑了你的时候,在这里找到你的失败原因。

Remember the agent from the very first line, the one that ran for an hour and reported SUCCESS on a wrong answer? It is still out there, running in a thousand repos right now. Whether it keeps going was never the question. The loop solved that a year ago. The question is whether, when it hands you a green check at nine in the morning, you are right to believe it.
Here is the part that should stay with you. Two people can build the exact same loop and end up in opposite places. One wraps it around work they understand to the bone and moves ten times faster. The other wraps it around work they have quietly stopped reading, and turns, one merge at a time, into a rubber stamp for a machine. Same loop. It cannot tell the two of them apart. Only you can.
So do not try to build the whole graph tonight, and do not feel behind if you never do, because most loops genuinely do not need one yet. Just pick the one wall that actually cost you this week. The runaway bill. The wrong number that shipped green. The merge you approved without reading. Put the single property that closes that one wall around the loop you already have. One wall, tonight.
The loop taught your agent to keep going. Everything after the loop exists so that you, not the loop, get to decide what counts.
A year ago, the edge belonged to whoever could write the best loop. It is already shifting to whoever can trust what their loops did while they slept. The loop you are proudest of should be able to tell you, a week from now, exactly why it said yes. Go build the part that can.
还记得第一行提到的那个 Agent 吗?它运行了一小时,然后对一个错误答案报告了 SUCCESS。它仍然在那里,此刻正在上千个代码仓库中运行。它能否继续运行从来就不是问题——循环一年前就解决了这个问题。问题是:当它在早上九点给你一个绿色通过标记时,你是否应该相信它。
以下是你要记住的重点:两个人可以构建完全相同的循环,却走向相反的结果。一个人把它包裹在自己深入了解的工作上,效率提高了十倍。另一个人把它包裹在自己已经停止阅读的工作上,一次一次合并,逐渐变成了机器的橡皮图章。同一个循环,它无法区分这两个人。只有你可以。
所以,今晚不要试图构建整个图结构,如果你最终从未构建过,也不必感到落后,因为大多数循环确实还不需要它。只需选择本周实际让你付出代价的那一面墙:失控的账单、带着绿色标记发货的错误数字、你未经阅读就批准的合并。将能够封堵那一面墙的单一属性,附加到你已有的循环上。今晚,就解决一面墙。
循环教会了你的 Agent 继续运行。循环之后的一切存在,是为了让你——而不是循环——来决定什么才算数。
一年前,优势属于能写出最好循环的人。而现在,优势正在转向那些能够信任自己循环在睡觉时做了什么的人。你最引以为傲的那个循环,应该能在一周后准确地告诉你,它为什么说了“可以”。去构建那个能够做到这一点的部分吧。