这几个月,我每天跟 Codex 说的话比跟人说的话多。
早上开一个任务,让它改个接口。下午再开一个,让它修个 Bug。每开一次新任务,就写一段新的 prompt,把需求讲一遍,把上下文喂一遍,把约束条件重复一遍。
我那时候觉得我在用 AI。回头看,是 AI 在用我。
如果你做过类似的事,能理解这种感觉:你以为你在指挥,但每次协作都是临时工模式。签一次约,干一次活,验一次收。下次还要从头签。
这就是 prompt 模式的底层逻辑——一次性契约。不管你写了多长、多详细的 prompt,任务做完之后,这份契约就过期了。下次开新任务,重新签。
最近,我把这件事换了一种做法。
不写更好的 prompt。写循环。
代码能跑,不等于敢上线
先说一组数据。
字节跳动今年在火山引擎 Force 大会上公布了他们内部用 AI 写代码的情况。TRAE 团队超过 90% 的代码由 AI 生成,AI 代码贡献率一年涨了 6 倍,Token 消耗涨了 5 倍。
这些数字在讲一件事:AI 写代码这件事已经在生产环境里大规模跑起来了。
但另一组数据更值得关注。
字节跑了 900 次实验,结论是:主流 Coding 模型生成的代码,正确率能到 80% 以上。但「可交付性」——不用人改、直接能上线的比例——只有 40 到 60 分。 十段代码里,八段能跑通。但能直接上线的,四五段。
中间差的那三四十分,不是代码写得烂。是测试没跑、CI 挂了、依赖对不上、边界情况没覆盖、性能不达标。
字节的做法,是在 AI 输出外面加一层 Harness——自动化测试、CI/CD、代码规范检查、质量门禁。Harness 本身不是什么新概念,test harness 这个术语在软件工程里用了很多年。它做的事一直很明确:提供一个自动化的验证环境,判断代码能不能交付。
加了 Harness 之后,可交付性从五六十分拉到八十分。
这组数据讲的不只是字节。它讲清楚了一件事:AI 输出的质量,和 AI 输出能不能用,是两回事。从「能跑」到「敢上线」,中间差的是一整套验证体系。
代码有 Harness,Agent 更需要
Harness 是给代码用的。Loop 是给 Agent 用的。
一个 Agent 执行任务的过程,不是「收到指令 → 一次输出 → 结束」。它是连续做决策:读文件、理解上下文、写代码、跑测试、看结果、调整方向、再写代码。每一步都可能偏。
你把任务丢给 Agent,等它跑完回来告诉你「做好了」。你打开一看,前半段都对了,中间偏了一下,后面的全跑歪了。而且你还不知道是从哪一步开始偏的。
Harness 的思路搬过来,逻辑一模一样:不要在最后验收,在每一步之后都设验证。
Loop 就是 Agent 的 Harness。
Cobus Greyling 在他的 loop-engineering 仓库里给了一套完整的 primitives:自动化调度、工作树隔离、Skills 注入、子 Agent 分派、状态持久化。每一个 primitive 解决的都是 Agent 执行过程中的一个可靠性问题。
dhakalnirajan 的 LOOPS.md spec 走得更远,直接把 Agent 的工作拆成三个角色——Planner 做规划、Generator 做执行、Evaluator 做评估。角色严格分离,谁写什么、谁评什么,全在 YAML 里定义。他甚至还给了一套评分 rubric:Design 占 30%、Craft 占 30%、Functionality 占 40%,总分低于阈值直接打回。 这些框架在讲同一件事:你不再盯着 Agent 干活。你设计一套规则,让它自己盯自己。
怎么写 Loop:9 条规则
最近我把从写 prompt 改成写 loop,落地方式很轻。
每个 Codex 的项目文件夹里放一个 loop.md,定义了 Codex 执行任务时要遵守的循环规则。同时,在每个 ChatGPT 的 project 资料里也放了一份写 loop 的要求——ChatGPT 每次给 Codex 生成任务的时候,按这些规则来,并且在ChatGPT 的自定义指令里也加了一条:所有 Codex 任务都按 loop 写。
loop.md 里是 9 条。能展开的展开。
1. 写循环,不写单次愿望
最基础的一条,也是最容易被「效率」这个借口绕过去的。
不要写「实现这个功能」。写「实现 → 自测 → 修 Bug → 再测 → 直到测试全过」。
一次只给一个目标。完成之后自己判断要不要进入下一轮。不通过就再来一轮。
单次 prompt 赌的是 AI 一次性输出的质量。但 AI 输出本身就波动。你今天写一段 prompt 让它改五个文件,可能完美完成,也可能漏改两个。你不会提前知道。
Loop 不赌。把「赌一把」拆成「跑三轮」。三轮里总能发现问题。
看起来慢了。但你算一下:一轮做到 80 分然后你接手修,和三轮做到 95 分你只验收,哪个省时间,你做过的都清楚。
2. 先谈合同,再动手
需求丢过去,让它直接写,这是 prompt 模式的条件反射。
Loop 的规则是:接到任务,先别写代码。先复述一遍你理解了啥、要改哪些文件、不改哪些文件、执行计划是什么。我看一眼,方向对了,动手。方向偏了,改两句话再动。
花两分钟对齐方向,省掉的可能是半小时的返工。
同样的规则,Cobus Greyling 管它叫 Contract Negotiation——Agent 在生成代码前,先输出理解和计划,获得确认再执行。
不确认就上手写的 Agent,就是在赌你的 prompt 没有任何歧义。你的 prompt 有过没有歧义的时候吗?
3. 角色分开:规划、执行、评估、记录
让同一个 AI 评估自己写的代码,结果就是永远满分。
所以拆开。
规划归 ChatGPT。执行归 Codex。评估也归 Codex,但它不能拍脑袋说「完成了」——它得把测试跑一遍,把结果写出来,自己判断过没过。
记录也归它。每轮结束在 loop.md 下面写一行:做了什么、结果是什么、下一步是什么。
dhakalnirajan 的 LOOPS.md 里 Planner / Generator / Evaluator 的拆分看起来重,但核心理念是对的——同一个人不能既写代码又判卷子。这个原则放在人身上是常识,放在 Agent身上却被很多人跳过去了。
4. 状态写磁盘,不赌上下文窗口
Loop 跑了好几轮,状态存哪?
很多人的做法:存聊天记录里。上一轮做了什么、发生了什么,靠上下文窗口记住。下一轮翻回去看。
赌上下文窗口有三个问题:窗口一长,AI 容易忘;任务一复杂,关键信息被淹没;一旦开新对话,状态全丢。
我的要求:每轮跑完,把关键状态写进磁盘。就几行——做了什么、测试结果、还剩什么、下一轮优先处理什么。
下一轮启动时,ChatGPT 先读这个文件,再生成 Codex 任务。不管上下文多长、不管中间隔了多久、不管你在不在同一个对话窗口里——状态在磁盘上,不会丢。
5. 主观任务也要评分
自动化测试能判对错,代码风格检查能判规范。但有些东西没法自动化:可维护性怎么样、模块边界清不清晰、有没有过度设计。
「主观的没法自动化,就算了」——很多人到这里就不往下想了。
但算了的结果是:Loop 里只有硬指标能触发重做,软指标永远被放过。跑一段时间,代码能跑,但没法改。
loop.md 里加了一个评分段:可维护性、可读性、模块边界清晰度。每一项 1 到 5 分。不要求精确,但要打。低于 3 分的,自动进下一轮优化。
不准没关系,总比没有好。有个不准的分数在,AI 至少知道自己还需要看一遍。
6. 调试读日志,不靠感觉
Loop 跑完,Codex 说「搞定了」。
搞没搞定,不能靠它一句话。
每轮结束输出一段结构化日志:做了什么、改了哪些文件、测试跑没跑、结果怎么样、有没有 Warning。你只用读这一小段。不用在几百行终端输出里翻。
日志这件事,说出来像废话——谁不知道要看日志?但真的做 loop 的时候,人很容易跳过这一步。因为 loop 跑完看到结果是绿的,就默认过程也是绿的。
7. 允许循环重启
Loop 跑偏了怎么办?
不是硬修。重启。
什么时候重启:上下文明显跑偏了、AI 陷入死循环了、连续三轮没有实质性进步。
重启不是认输。重启的意思是,有时候重新开始比坚持错误方向要快。
这条规则写进 loop.md,主要是给自己看的。人不愿意重启,因为「已经跑了两轮了,沉没成本」。但你回头想想:已经跑了两轮还在错,不就是该重启的证据吗?
8. 每轮结束写 next bottleneck
不管这轮成了还是败了,跑完之后写一句:当前最大的瓶颈是什么。
可能是某个模块测试覆盖率不够,可能是依赖版本太老,也可能是需求描述本身有歧义。
next bottleneck 不是写给 AI 的。是写给下一次你自己的。下次打开这个项目,先看这一行,先把它解决掉,再往下跑。
很多项目的 loop 跑不顺,不是因为某一条规则没写好,是因为一直被同一个瓶颈卡住。不被同样的问题卡第二次,就是 next bottleneck 的价值。
9. 定期删掉旧 harness
Loop 跑了之后,loop.md 里积了很多东西。有些规则是应对当时某个问题写的。问题解决了,规则还在。
旧规则跟新需求冲突的时候,loop 会卡。AI 不知道该听哪条。
每个月扫一遍 loop.md,删掉已经不适用、已经过时、已经跟现有项目结构冲突的规则。这件事不紧急,但时间长了不删,loop 会越来越重,跑得越来越慢。
代码里的 dead code 你不删,不影响功能,但影响下次改动的效率。loop 里的旧规则,一模一样。
你还在环里
写 loop,最大的感受不是技术上的。是心态上的。
写 prompt 的时候,你觉得你在把一件事「交给」AI。交给它,你就不管了,等结果。
写 loop,你知道你在把一件事「委托」给 AI。委托的意思是你还在环里,只是位置变了——从操作者变成设计者。
你不再被 AI 的工作节奏拉着走。你在设计它怎么工作。在什么节点验证,在什么情况下重启,在什么时候喊你。