九凤
Loop Engineering:让 AI Coding 持续正确

Loop Engineering:让 AI Coding 持续正确

AI 编程真正的难点,不是让模型写出一次正确代码,而是让正确目标、正确实现、独立验证和经验改进持续发生。这是「vibe coding 工程化」系列第一篇:为什么需要 Loop,它改变了什么,以及什么时候不值得用。

Vibe Coding

「vibe coding 工程化」系列第一篇。本篇是科普:讲清楚 为什么需要 Loop、它改变了什么、 什么时候值得用。具体的施工单字段、门禁配置和脚本细节,留给后面几篇。

单次生成能力由模型决定,长期交付质量由工程系统决定。

这句话是我做了几个月 AI Coding 之后最实在的体会。模型一年比一年强,但**「这次写对了」和「这个项目一直是对的」之间,隔着的东西跟模型没什么关系**。

一、AI Coding 的真实问题

先说清楚:不是模型不会写代码。它写得很好。

问题出在别处,而且只在任务变大之后才出现。

目标会漂。 你让它加个限流,它顺手把注册接口、两个重置接口一起改了——因为「这些看起来也该限」。改得不算错,但那不是你要的这一轮。等你发现时,diff 已经跨了三个模块,你分不清哪些是本轮该做的。

上下文会丢。 长任务里,前天定的架构语义,今天的会话已经不记得了。它会重新推理一遍,推出一个同样合理但不一样的结论。

它会自圆其说。 这是最要命的一条。同一个模型既实现又自审,你问它「这样对吗」,它会用刚才生成代码的同一条推理链回答你「对」。自审在这里是同义反复,不是检查。

你看不懂它在干什么。 一个跨模块的任务跑到第三天,你想知道「现在到哪了、下一步为什么是它」,得去读它的输出——而它的输出永远是自信、完整、看起来很有道理的。

这四条有个共同点,值得单独说:

它们都不报错。

不会编译失败,不会测试变红,不会有任何一个工具跳出来说「等一下」。小任务里你依赖的那套反馈——编译器、测试、类型检查——在这些问题面前全部沉默

它们不是「AI 不够好」的产物。恰恰相反,是 AI 足够好的产物:它写得太通顺了,通顺到每一行都看不出破绽。

人的错误通常带语气。一个人写「据某某确认」的时候,心里多少有一丝犹豫,那丝犹豫会渗进文字里。AI 的错误没有语气。

二、什么是 Loop Engineering

先说它不是什么:不是让两个 AI 无限互相聊天,也不是无限重试

它是一套闭环交付方法:

        权威文档(需求 / 架构 / 方案)
                    │
                    ▼
      ┌──►  ① 目标对齐:本轮施工单
      │             │
      │             ▼
      │     ② 分阶段实施(执行方)
      │             │
      │             ▼
      │     ③ 机器验证:范围门禁 + 测试
      │             │
      │             ▼
      │     ④ 独立审查(另一方,只读真实 diff)
      │             │
      │      ┌──────┴──────┐
      │      │             │
      └──────┤ 有问题      │ 通过
        再来一轮           ▼
                   ⑤ 证据收口(冻结 diff/测试/结论)
                          │
                          ▼
                   ⑥ 经验反馈 → 规则演进

关键在那个回箭头

它不是「写完 → review 一下 → 合并」的流水线,是一个逼近过程。这个区别不是修辞,我有数据。

一次审查为什么不够

一份架构设计,交给独立审查方,连着跑了五轮:

轮次发现的 MAJOR说明
第 1 轮6 条红线冲突、设计与代码矛盾、未决事项被定稿…
第 2 轮5 条全是新的
第 3 轮4 条全是新的
第 4 轮4 条全是新的
第 5 轮4 条全是新的

23 条实质问题,49 分钟,没有一条重复。

这才是「为什么必须是 Loop」的答案。修完第一轮那 6 条,第二轮冒出 5 条全新的——因为第一层被清掉之后,第二层才暴露出来。

而且越往后越深。第 1 轮的问题在文档层面就能看出来(红线冲突、术语不一致);第 5 轮的问题得把方案在脑子里跑起来才看得见——比如「候选领取的 CAS 冲突被错误地等同于候选耗尽」,那是并发语义,第 1 轮根本轮不到它。

如果只审一遍,你会拿到一份修好了 6 个问题、还剩 17 个的设计,而且你会以为它通过了。

三、为什么普通 Prompt 不够

很多人的第一反应是:这些在 prompt 里说清楚不就行了?「不要越界」「不要自己下结论」「测试要覆盖真实路径」。

不够,原因有三个。

Prompt 表达期望,不表达约束。 「请不要越界」和「机器真的阻止越界」是两件事。前者是一句话,后者是一道会返回非零退出码的门禁。

长会话里指令权重会衰减。 开头那句「只改这三个文件」,到第 40 轮对话时,跟当前上下文里的一百件事在争夺注意力。它没有忘记,它只是不再是最重要的那句

执行方无法验证自己是否遵守了约束。 你可以让它自查,但那还是同一条推理链。

所以 Loop 做的事是:把关键约束从「文字提醒」提升为机器边界——路径白名单变成 diff 门禁,「必须测试」变成命令退出码,「不能自己批准」变成另一个不共享推理链的审查方。

一条经验:凡是有代码机制的约束,修完就不再犯;凡是靠文档、靠记性的,会一直犯。 我自己就栽过——一条规则上午刚写进文档,下午写新内容时照样违反,两小时后才发现。

四、角色分工

Loop 里有四个角色,边界很清楚:

角色负责不负责
目标优先级、架构语义、风险接受、发布授权逐条转发两个 AI 的输出、替 AI 判断代码细节
Claude按施工单实施、跑测试、汇报进度、按 findings 修复自审批准、扩大范围、擅自提交或部署
Codex读真实 diff 独立审查、给机器可读的结论替代编译器、决定产品风险
Harness路径范围、危险操作、证据完整性的机器边界判断复杂业务语义

这里最重要的一条:Claude 的解释和进度汇报是线索,不是证据。

它说「测试通过了」不算数,命令的退出码才算数。它说「这个之前定过」不算数,翻出当时的决议记录才算数。

可信链条只有这几样:

权威文档 + 真实 diff + 命令退出码 + 独立审查 + 冻结证据

五、五个核心对象

用生活化的话讲,Loop 里只有五样东西:

1. 权威文档 —— 图纸 需求、架构、方案。它回答「为什么做、目标长什么样」。它不记录每次工具怎么跑的。

2. 施工单(Task Packet)—— 本次派工单 这一轮唯一的目标是什么、允许动哪些文件、验收标准是什么、哪些明确禁止。 它是执行会话的唯一主线指针——执行方跑偏了,拿它对一下就知道。

3. 范围门禁(Guard)—— 工地围栏 只管「你有没有走出这块地」,不管「你在这块地上盖得好不好」。它不判断业务语义,只比对路径。

4. 审查提纲(Review Prompt)—— 这次验收重点看什么 不是把全部历史复制一遍,是「这一轮最关键的问题是什么」。

5. 证据包(Run Evidence)—— 竣工资料 当时的 HEAD、diff、门禁结果、测试输出、审查结论。三个月后有人问「为什么这么设计」,你翻这个,而不是翻聊天记录。

六、一次任务怎么流动

举个简化的例子。

架构师定规矩:异步请求失败后,必须沿一个固定的候选序列依次重试,不能随便挑。

写施工单:本轮唯一目标是实现这个重试序列;允许动路由器和状态机两个文件;验收标准是正常、失败、回退三条路径都有测试;明确禁止改动计费相关代码。

Claude 实施:写代码,跑测试。正常路径过了,失败路径过了,回退路径也过了。它汇报:完成。

门禁比对:真实 diff 只碰了允许的两个文件。通过。

Codex 独立审查:它拿到的是真实 diff,不是 Claude 的自述。它发现——并发条件下,两个 worker 可能同时认领同一个候选,造成双提交。测试没覆盖这个,因为测试是单线程跑的。

Claude 只修这个:不顺手重构,不「既然改到这里了不如把那个也优化一下」。修完,跑回归。

审查通过,证据收口:冻结这一刻的 diff、测试输出、审查结论。这一轮结束。

注意这里发生了什么:测试全绿,门禁通过,执行方汇报完成——但代码有一个并发缺陷。 抓住它的不是更严格的测试要求,是一个没参与生成、只读真实 diff 的第二方。

七、Loop 带来了什么

没有 Loop使用 Loop
主线目标随对话漂移,diff 跨了三个模块才发现施工单声明唯一目标,门禁比对真实 diff
验证执行方说「测试通过了」命令退出码 + 独立审查读真实 diff
缺陷暴露时机上线后commit / deploy 之前
并发/回退/安全问题单线程测试测不出来独立审查方按语义反推
换会话靠聊天记录,前天定的今天忘了施工单 + 证据包,跟会话无关
三个月后问「为什么这么设计」翻聊天记录,翻不到翻证据包:当时的 diff、测试、结论
经验留在某个人脑子里沉淀成规则,跨项目复用

最实在的一条:缺陷在 commit 之前暴露。上面那 23 条 MAJOR,如果没有这道缝,其中相当一部分会变成线上问题,或者变成三个月后没人敢动的「当初就是这么设计的」。

八、Loop 不是什么

这一节比上一节重要。大部分把流程搞砸的人,是搞错了这几条。

不是项目管理看板。 它不追踪谁在做什么、进度百分之多少。主线状态还是以你原有的计划和台账为准。

不是所有改动都要走的审批流程。 改个文案也要写施工单、拉审查——那是自残。

不是让 AI 完全自治。 恰恰相反,它把人的裁决点收窄并固定:只在架构语义、风险接受、发布边界上做决定,其余交给机器边界。

不是用文档数量衡量质量。 连续两轮只在改规则、改提纲、改台账,没有代码增量——那不是流程严谨,那是空转

不是 Codex 审查越多越好。 审查只剩措辞和排版问题时,继续审是浪费。

不是替代测试、架构师和生产责任人。 独立审查不是编译器,它不能替你跑测试;它也不决定产品风险——那是人的活。

九、成本和适用边界

Loop 是有成本的,而且成本不小。所以要分强度:

强度适用最小做法
快速处理读代码、查 bug、明确的小修、低风险单文件改动直接干完 + 跑针对性验证。不写施工单,不拉审查
标准 Loop跨文件、架构实现、重要设计、多 agent 接力一个施工单、一次门禁、必要测试、一次独立审查
严格 Loop集群写操作、数据/模型、安全、发布、不可逆迁移标准 Loop + 环境授权、回滚证据、人工风险裁决

判断不清时用标准 Loop。但出现下面这些信号,应该降低强度而不是继续加文档:

  • 改动可以在一个低风险文件内完成;
  • 连续两轮只改规则、提纲、台账,没有代码增量;
  • 审查只剩措辞和排版问题;
  • 流程建设时间开始接近实际实现时间。

最后这条是硬线。流程的成本必须明显小于它防住的损失,否则它就是个仪式。

十、Loop 怎么自我进化

这是我认为最容易被忽略、也最关键的一层。

一个很自然的冲动是:每发现一次流程问题,就往规则里加一条。三个月后你会得到一份没人读的规则集——而没人读的规则等于没有规则

所以规则的晋升要走这条路:

实践中发现问题
      ↓
先进轻量收件箱(只记事实,不当场立规矩)
      ↓
周期性聚合:这个问题重复出现了几次?
      ↓
达到阈值 → 才考虑升级为通用规则
      ↓
规则可测试、可衡量,且**允许降级和退役**

核心边界是:问题自动发现,规则人工晋升。

这里有个我自己踩到的坑,值得说:收件箱本身也会出问题。我的收件箱跑了一段时间后,里面 96% 的记录是「护栏正常拦了一次」——那不是问题,那是护栏在按设计工作。真正的信号被埋在噪音里。

记录「系统正常」等于制造噪音,而噪音会让人学会无视这个收件箱,连真信号一起无视。这个坑我会在后面单独写一篇。

十一、怎么判断 Loop 是否健康

不看文档数量。看这些:

  • 执行方大部分时间在实现和验证,而不是在维护流程文档;
  • 人只处理真正的架构、风险和发布裁决,不做二传手;
  • 审查能抓住跨文件、并发、回退和安全问题——如果它只会挑错别字,那这道缝没起作用;
  • 每个阶段的进度能用一句业务语言说清
  • 普通操作不反复弹确认
  • 规则建设时间明显小于交付时间
  • 相同的问题越来越少——重复问题经过聚合才进规则,规则也允许退役。

长期做不到,优先缩小阶段、降低强度、修正施工单,而不是继续加约束文本。

结尾:从「生成代码」到「持续正确」

回到开头那句话。

单次生成能力由模型决定。 这一年模型进步得非常快,而且还会更快。

长期交付质量由工程系统决定。 这部分不会因为模型变强而自动变好——恰恰相反,模型越强,它的错误越通顺、越自洽、越没有语气,也就越需要一道不共享推理链的缝

那条被抓住的假授权是 Claude 写的,抓住它的是 Codex。但真正起作用的不是哪个模型更聪明——换成两个 Claude、或者两个 Codex,只要中间那道缝还在,效果一样。

人类团队几十年前就懂这个道理,所以有 code review,所以有「作者不能 approve 自己的 PR」。Loop 只是把同一条规矩,搬到一个写得更快、更自信、也更没有语气的作者身上。

它写得越好,这道缝就越必要。

Loop 的价值,是把偶然的正确变成可重复的正确。


下一篇:施工单到底怎么写——一份好的施工单和一份没用的施工单差在哪,以及为什么「允许修改范围」这一栏比「目标」那一栏更重要。