循环不值钱,能自证的循环才值钱:聊一聊 Loop Engineering
先给自己那篇打个补丁
我在《也聊聊 AI Harness》里写过一个递进:Prompt 让 AI 答得更好,Context 让 AI 更懂现场,Harness 让 AI 进入系统。当时我把 Loop 放在 Harness 的第一种形态里,讲的是"做事、观察结果、修正策略"循环起来,系统就会长记性。
隔了一段时间再看,那篇有个明显的空档:我把"循环起来"讲成了目的。
但循环本身其实一文不值。一个会自己转的循环,和一个每转一圈都能拿出独立证据证明自己没跑偏的循环,中间隔着的不是工程量,而是"这东西能不能放着不管"的分水岭。前者你还是得盯着——那它没替你省掉任何东西,你只是把敲 prompt 换成了盯进度条;后者才配叫系统。
所以这篇是那篇的补丁:Loop 是 Harness 里最难、也最容易做成花架子的那一块。
从驾驶位挪到设计位
过去我跟 agent 的关系,是我敲一轮 prompt、读一轮返回、再敲下一轮。链路里每一步都要人判断、确认、再推进,人必然是瓶颈——这也是为什么 Prompt 和 Context 再怎么优化,天花板都摆在那儿:它们优化的是"人一次次驱动 AI"这个动作,没动结构。
挪一格过去,我要做的事变成:设计一个会自己找活、执行、验证、记账、定下一步的东西,让它去驱动 agent。
但挪到设计位,不等于人退场。恰恰相反,人退到了更要命的位置上——什么算做完、拿什么证明做完、哪条线绝对不许碰、花多少钱算超。这几件事 agent 替我定不了,也不该替我定。我不定,它就会用它自信的猜测替我填上。
说白了:模型决定这套东西的上限,我的架构决定它的下限。 模型每半年跳一级,prompt 措辞里抠出来的优势,下一个版本就抹平了。但"状态存在哪、怎么证明完成、什么时候必须停"这三层,模型升级到明年也长不出来——它们不在模型里,在模型外面。
这个道理我早就见过
想通这层之后我有点恍惚,因为这不是新东西——我做前端工程治理时就撞过一模一样的墙:规范写在文档里、周会上念叨,没用;真正生效的那一下,是把它变成 CI 里一条会让流水线变红的检查。口头约定不算约定,写进流水线才算——不是因为人不自觉,而是没有强制校验点的约定,一定会在压力下漂移,而且没人会在漂移当天发现。
Loop 里发生的事一样,只是漂移得更快:第 1 轮讲清楚的约束,到第 47 轮悄悄不见了。
做 Hybrid 首屏那阵是同一个教训的另一个版本:没有量化就没有优化。先让每一段耗时变成可比的数字,才谈得上定卡口、守住不劣化。
换到 AI 上就是一句话:给 loop 一个它作不了弊的裁判。 我不是从 AI 这边推出这个结论的,我是在别处被教育过之后,认出了它。
验证是整件事的灵魂
我在 Harness 那篇里写过"单个 AI 自评很容易高估自己",当时只当成用多 agent 的理由带过。现在我觉得那句话被我写轻了——因为最危险的不是 agent 失败,是它把没做对的事讲得像做完了。
失败是可见的,我会去修。假完成是不可见的——它带着"✅ 已完成"进入下一轮,污染后面所有决策。而且循环跑得越顺、报表越绿,我越不会去看。
验证怎么做,我现在想清楚了四条。
一、裁判必须是硬信号,不能是模型的意见。 优先用天然成立的确定性信号:类型检查、lint、测试、运行时报错、退出码。这些东西不看模型脸色。已经有 tsc 了,就别再让模型"帮我检查类型对不对"——拿概率性的东西复述确定性的东西,纯亏。主观任务就找可信工具造 ground truth、定一个能返回数字的指标——只有数字才能套阈值。而阈值一旦定下就死守:放行一次"就差一点点",这道闸门以后就都是摆设。
二、写的和验的,不能是同一个。 拆成两个角色:builder 只管写和改;checker 拿掉全部写权限,在独立上下文里跑——它不该看见 builder 一路自我说服的心路历程,只能看见结果和证据。最关键的是,checker 得有真的判不过的权力,判了不过循环照样往下走,它就是个吉祥物。我在 Harness 那篇里提过生成和评估拆开,当时觉得是可选项,现在觉得是必选项——自评等于没评,永远 A+。
三、禁止它去改记分牌。 这条想到的时候后背有点凉:我给了 agent 硬 gate,又给了它"必须让 gate 变绿"的目标——那"把代码改对"和"把 gate 弄绿"就是同一道题的两个解,后者往往更省事。删断言、标 skip、加 || true、把真实失败判成 flaky……每一招都能让仪表盘变绿。它不是坏,它是在解我给的题,题给窄了它就从窄处钻出去。所以硬 gate 和"不许动记分牌"的约束必须成对出现——只给 gate 不给约束,等于告诉它考试必须及格,却不说不许改分数。
四、验证得分场景。 能用工具判断的别交给模型,这是默认档;Web 的东西必须真用浏览器像用户那样点过、看控制台、截图存证——我做过几年 Hybrid 容器,太清楚"代码看起来对"和"端上真的对"能差多远;数据任务要 dry-run、备份、跑完回读条数;实在没有硬 gate 的,找个独立评委打分,不完美,但比自评强得多。
整个循环长这样:
不知道何时该停的循环,只是烧钱的死循环
"跑到 token 烧完"不是停止条件,那叫失控。
真正的退出条件,必须是 agent 自述之外、能被外部硬信号检查的东西:测试过了、build 成功了、任务卡挪到 Done 且流水线是绿的。凡是要读 agent 的总结才能判断"做完了没",都不算。
退出条件可能永远不满足,所以还得叠硬停兜底:
- 最大轮数,我的体感是 5 到 20,看任务。
- token / 时间 / 预算上限。
- 连续两次栽在同一个失败上,立刻停——精准命中"原地打转"这个最常见的浪费模式。
- 某次修复让原本通过的检查挂了,立刻停——它开始拆东墙补西墙了。
然后是任务书。我现在强迫自己写全四栏——终态、证据、不可破坏的约束、允许花的预算,少一栏就当这个任务还没想清楚。拿我这个博客的场景写一版:
# 终态
所有 MDX 文章的 frontmatter 字段齐全且格式合法;
pnpm build 通过;新增文章在 /posts 列表和 feed.xml 里都出现。
# 证据
1) `node scripts/check-frontmatter.js` 退出码 0
2) `pnpm build` 退出码 0,且 public/feed.xml 里能 grep 到新文章 slug
3) 浏览器打开 /posts/<slug>,截图,控制台无 error
# 约束(不可破坏)
- 不许改 theme.config.jsx、next.config.mjs、styles/main.css
- 不许为了让检查通过而删字段、放宽校验、加 skip 或 || true
- 不许改动任何已发布文章的正文
- 需要改构建流程或依赖版本 → 停下来问我
# 预算
- 最多 15 轮;同一个校验错误连续 2 轮没修好即停
- 单轮最多改 5 个文件
- 撞任一上限 → 停,列出剩余失败项,交人工写的时候有个意外的体感:凑齐四栏的过程,本身就是在逼我把话说清楚。 好几次写到"证据"那栏卡住了——说明我压根没想清楚怎么算做完,那这个任务现在就不该交给循环。任务书与其说是给 agent 的指令,不如说是给我自己的体检。
上下文是工作台,不是档案室
这条我以前一直做错:什么都往 context 里塞。
得把工作状态和推理上下文分开。上下文只放当前这一步要用的材料——它是工作台,台面就那么大。长期状态写到磁盘上:进度账本结构化地记当前目标、已完成、改过哪些文件、决策及理由、验证结果、下一步;然后下一轮先读账本,再读代码——顺序别反,先读代码就又开始靠猜了。
长循环还得配一份常驻的高层说明(愿景、架构约定这类),每轮重读,对抗目标漂移:
状态告诉它"现在在哪",说明告诉它"要去哪"。
缺前者,每轮从零重启;缺后者,每轮都往稍微偏一点的方向走,偏移会累积。
这也接回 Harness 那篇最想说的原则:不允许长期做一次性工作。 现在我会补一句——固化下来的东西必须放在会被强制重读的地方,否则它跟写在周会纪要里的规范没区别。
什么时候压根不该做循环
这条放在靠后,但其实该最先想——它拦掉的成本,比前面所有技巧带来的都多。
我给自己的标准,是从 Harness 那篇的"手动跑过 3 到 10 次就该固化"长出来的,加了两个前提:
这件事我手动做烦了,且每次的判断标准都一样,且我能写出一条命令来判断它对不对。
- 做烦了——一次性的事,设计循环的功夫早就自己做完三遍了。
- 标准一样——标准每次都要现想的,那是判断题不是执行题。循环擅长"有唯一正确答案、只是要试很多次"的事;判断题循环一万轮,也只是把一个主观判断重复一万遍。
- 能写出判断命令——写不出来就意味着没有裁判,没有裁判的循环,等于让一个会撒谎的实习生自己给自己签字验收。
还有个隐性前提:token 烧得起。循环的本质是拿算力换人力,试错、回滚、重跑都是浪费。每一轮都心疼 token,就会忍不住去干预——那又回驾驶位了。
起步的顺序,比起步本身重要
真要动手,顺序不能反:
手动还没跑稳就上自动化,是循环翻车最常见的原因。 这句我敢说得肯定,因为工程治理已经教育过我一遍:你没法自动化一个自己都还没做对的流程,只会把做错的姿势自动化,然后错得更快、更多、更难查。
这个顺序还顺便回答了"从哪儿下手":从你已经手动做烦了、且每次都做得对的那件事下手。 烦,说明值得;每次都对,说明裁判已经存在,只是还长在你脑子里,把它挪到磁盘上就行。
还不成熟的地方
得诚实说:上面这些讲得头头是道,大部分是我的设计判断,不是跑出来的经验。
我目前有几个能跑的最小闭环——写、检查、修、重跑,直到过或撞上限,这个博客的发文流程算一个。但真正的 builder / checker 拆分基本没做过,独立上下文的对抗验证没做,让它自己开 PR、关任务卡这种"接进真实环境"的部分也没接上。
几个还没想透的:
- 验证的成本可能比想象中高。 硬 gate 好定的场景,往往本来就有测试;而最想让 AI 接管的脏活——改老代码、对齐设计稿、处理线上数据——恰恰最难造 ground truth。有可能"能不能自动验证"这一条,就把循环的适用面卡得比想象中小得多。
- 技能文件自我迭代那层没实践过。 让外循环去观察、改进技能文件听着很美,但谁来验证这次改进是改进、不是漂移?目前能接受的折中是外循环只提建议、人来点头——但这样我的 review 带宽就成了新的天花板。
- "哪些点值得叫醒我"很主观。 定太密,人还是瓶颈;定太松,发现时已经跑偏二十轮。这个度只能一个场景一个场景试。
等真把某个循环跑到能拿出账来算——比如每个被接受的改动平均花多少钱——再回来写一篇有数字的。
最舒服的那个失败,是我不再有观点
最后说个比烧钱严重得多的风险。
循环跑顺之后,有两件事会悄悄发生。一件是某天要去 debug 一个我"拥有"、但从来没读过的系统。另一件更隐蔽:我不再对产出有观点了,它给什么我收什么——因为一路绿灯,因为看起来都对,因为很久没被它坑过了。
第二件最舒服,也最危险。
回头看,前面所有机制——硬 gate、独立 checker、停止条件、状态落盘、任务书四栏——都是在防这一件事。它们不只是让循环跑得对,更是让我在不逐行盯着的情况下,依然真的知道它在干什么:gate 是我的眼睛,账本是我的记忆,任务书是我的判断力。这三样落到磁盘上,我才敢不看;没落却也不看了,那不叫自动化,叫撒手。
所以我对"提效"的理解又降了一档:以前觉得提效是"让 AI 干得更多",现在觉得是"让我能放心地不看它干"。而"放心"两个字的全部重量,都压在验证和停止条件上——不在循环,更不在 prompt。
循环是拿来跑的,但它凭什么停、凭什么算数,得我来定。
设计位看着比驾驶位轻松,其实责任更重。交出去的是手上的活,不是脑子里的判断——方向盘可以给它,仪表盘得留着。
2026 © Lizhenyui.