ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Loop Engineering循环工程:用Claude Code与Codex搭建可验证的AI编程自动化流程

Loop Engineering循环工程:用Claude Code与Codex搭建可验证的AI编程自动化流程 1. 从“写提示词”到“搭循环”Loop Engineering 到底在解决什么问题如果你最近半年一直在用 Claude Code、Codex、Cursor 这类 AI 编程工具大概率经历过这样一个阶段一开始觉得“哇好神奇”用久了却发现——同一个需求你写三遍提示词得到三份风格完全不同的代码改一个 bugAI 顺手把旁边两个能跑的函数也重构了上下文一长它开始“失忆”前面说好的约束全忘了。这不是模型不行而是你还在用“单次对话”的思维去驱动一个本该被“工程化编排”的系统。Loop Engineering循环工程这个词最近在开发者圈子里被反复提起说白了就是一件事把 AI 编程从“一次性问答”升级成“可循环、可验证、可收敛的自动化流程”。它不是一个具体工具而是一套围绕 Claude Code、Codex、Cursor 这些 CLI/IDE Agent 搭建的工作方法论——你定义目标、约束和验收标准让 AI 在一个受控的循环里反复“生成 → 执行 → 检查 → 修正”直到结果达标为止。这套东西解决的核心痛点有三个。第一是上下文漂移长任务里 AI 会逐渐偏离原始需求循环工程用“每轮重置 状态外置”来对抗。第二是结果不可验证AI 说“改好了”但你没证据循环工程强制每轮跑测试、跑 lint、跑类型检查用客观信号决定是否继续。第三是人工介入成本高你不想每次都盯着它改循环工程把“判断是否继续”这件事交给脚本和退出条件。适合谁来学我的判断是已经能熟练用 Claude Code 或 Codex 跑通单个任务但被“多轮返工”折磨过的开发者。纯新手建议先把单个工具的安装、登录、基本对话跑顺再来看循环编排否则容易在环境问题上卡死。下面我会从整体设计思路讲起一路拆到可直接抄的配置和脚本中间穿插我自己踩过的坑。2. 整体设计与思路拆解为什么是“循环”而不是“更长的提示词”2.1 单次提示词的三个天花板很多人第一反应是既然 AI 一次做不好那我把提示词写得更长、更详细不就行了我试过结论是——提示词长度和任务复杂度不是线性关系超过某个点反而更糟。第一个天花板是注意力稀释。当你的提示词里塞了 2000 字的规范、30 条约束、5 个示例模型对每一条的“关注度”是下降的。实测下来约束超过 15 条之后遵守率断崖式下跌它开始挑着执行。第二个天花板是无法自我验证。单次提示词里你没法让 AI“跑完测试再回来告诉我”它只能凭“想象”判断自己写对了没有。而 AI 对自己代码的自信程度和实际正确率之间几乎没有相关性。第三个天花板是错误累积。第一轮它理解偏了一点第二轮在偏的基础上继续偏到第五轮已经离题万里。你回头一看还不如重开。2.2 循环工程的核心结构目标 状态 验证 退出Loop Engineering 的思路是把上面三个问题分别拆解掉。一个标准的循环结构包含四个部件目标Goal用一句话描述“完成态”是什么越可测量越好。比如“所有单元测试通过且 lint 无 error”而不是“代码质量变好”。状态State把当前进度、已尝试方案、失败原因写到外部文件里每轮循环开始时读进来。这样即使 AI 上下文被截断状态也不丢。验证Verify每轮结束跑一组客观检查产出明确的 pass/fail 信号。这是循环能否自动继续的“裁判”。退出Exit定义什么时候停——验证全过就成功退出连续 N 轮无进展就失败退出超过最大轮数就强制停。我个人的经验是验证环节是整个循环里最值得花时间打磨的部分。很多人搭循环失败不是 AI 不行是“裁判”太弱——比如只让 AI 自己说“我改好了”那循环就变成了自我欺骗。一定要用外部命令测试、编译、类型检查当裁判。2.3 工具选型Claude Code、Codex、Cursor 各自适合放在循环的哪一环这三个工具不是互斥的在循环工程里它们其实扮演不同角色。我按自己的使用习惯给个定位工具强项在循环中的定位注意事项Claude Code长任务规划、多文件编辑、终端操作主循环执行器上下文管理要主动做别指望它自己记Codex单点代码生成快、响应直接子任务生成器 / 快速修补配置文件和登录状态要提前确认CursorIDE 内交互、可视化 diff、局部修改人工复核 手动微调环节免费额度有限长循环别全压在它身上我的典型组合是Claude Code 跑主循环Codex 处理循环里冒出来的小修补Cursor 留给我自己最后过一遍 diff。这样分工的原因是Claude Code 的终端能力和多文件操作最适合“跑测试 → 看报错 → 改代码”这个闭环Codex 启动快适合循环中途临时问一句Cursor 的 diff 视图是我做最终 review 最舒服的地方。提示不要试图让三个工具同时操作同一个工作区。我踩过这个坑两个 Agent 同时改文件结果互相覆盖排查了半天。循环里同一时刻只让一个 Agent 写文件。2.4 为什么“状态外置”是循环工程的分水岭这一点我要单独强调。新手搭循环最容易忽略的就是状态管理觉得“AI 上下文里不是有吗”。但循环跑到第 8 轮、第 10 轮上下文早就被压缩或截断了AI 根本不记得第 3 轮为什么放弃了方案 A。我的做法是在项目根目录建一个.loop/目录里面放三个文件state.md当前目标、已完成项、待办项、已知约束attempts.log每轮尝试的方案和结果追加写入failures.md失败原因和排除掉的方案避免重复踩坑每轮循环开始时脚本把state.md和failures.md的内容拼进提示词每轮结束时让 AI 更新这两个文件。这样即使换一个全新的会话循环也能接着跑。这个设计让循环从“依赖上下文”变成“依赖文件系统”稳定性提升非常明显。3. 核心细节解析与实操要点把循环搭起来的六个关键环节3.1 环境准备三个工具的安装与登录状态确认在搭循环之前先把三个工具的环境理顺。这一步看着基础但我见过太多人卡在这里。Claude Code 的安装官方推荐用 npm 全局装。我实测下来 Node 版本建议 18 以上低了会有兼容问题node -v npm install -g anthropic-ai/claude-code claude --version装完第一次运行claude会走登录流程。这里有个细节登录状态是存在用户目录下的如果你在 CI 或容器里跑循环需要提前把凭证配置好否则每轮都会卡在登录。我一般会在本地跑循环容器方案留给更成熟的团队。Codex 的安装类似装完后重点确认两件事一是配置文件位置通常在用户目录下的配置目录里二是默认模型和超时设置。Codex 的配置文件解析是很多人头疼的点我的建议是先用最小配置跑通一次再逐步加参数别一上来就抄一大坨配置。Cursor 是 GUI 工具安装没什么好说的但有两个设置我强烈建议改一是把回复语言设成中文在设置里搜 language 相关选项二是确认免费额度还剩多少。Cursor 的免费额度是有限的如果你打算让它参与长循环先算一下够不够。注意三个工具都涉及账号登录请确保你使用的是合规、正常的账号遵守各工具的服务条款。环境配置阶段不要图省事去改一些来路不明的配置。3.2 目标定义把“模糊需求”翻译成“可验证的完成态”循环工程里目标定义的质量直接决定循环能不能收敛。我总结了一个翻译模板原始需求“帮我优化这个模块的性能”翻译后目标“benchmark.js跑出的 P95 延迟低于 50ms且现有 12 个单元测试全部通过”看出区别了吗翻译后的目标有两个特征有具体的验证命令有明确的数值门槛。这样循环每跑一轮脚本执行node benchmark.js和npm test就能客观判断是否达标。我一般会把目标写成这样的结构## 目标 - 完成态可测量的描述 - 验证命令具体命令 - 通过标准数值或状态 - 硬约束不能破坏的东西硬约束这一栏特别重要。比如“不能修改public API的函数签名”“不能引入新的第三方依赖”这些是循环里 AI 最容易“顺手破坏”的地方必须显式写出来。3.3 验证脚本循环的“裁判”怎么写才靠谱验证脚本是循环工程的心脏。我的原则是能用现成工具就别自己写能跑命令就别让 AI 判断。一个典型的验证脚本长这样以 Node 项目为例#!/bin/bash # verify.sh - 循环的验证裁判 set -e echo 1. 类型检查 npx tsc --noEmit || exit 1 echo 2. Lint 检查 npx eslint src/ --max-warnings 0 || exit 1 echo 3. 单元测试 npm test || exit 1 echo 4. 性能基准 node benchmark.js | tee /tmp/bench.out grep -q P95 50ms /tmp/bench.out || exit 1 echo 全部通过 exit 0这个脚本的退出码就是循环的“继续/停止”信号。exit 0表示达标可以退出循环非 0 表示还有问题继续下一轮。我踩过的坑是验证脚本本身要足够快。如果一轮验证要跑 5 分钟循环 10 轮就是 50 分钟体验很差。所以我把验证分成“快检”和“全检”两级——每轮跑快检类型 lint 核心测试每 3 轮跑一次全检含性能基准。这样既保证质量又不至于太慢。3.4 提示词模板每轮循环喂给 AI 的“标准输入”循环里的提示词不是随便写的它需要包含固定的几个部分我把它固化成一个模板你正在一个自动化循环中工作这是第 {N} 轮。 ## 当前目标 {从 state.md 读取} ## 已知约束 {从 state.md 读取} ## 已尝试且失败的方案不要重复 {从 failures.md 读取} ## 上一轮验证输出 {上一轮 verify.sh 的输出} ## 本轮任务 根据上一轮的失败信息修改代码使验证通过。 只做必要的修改不要重构无关代码。 ## 完成后 1. 更新 .loop/state.md 2. 把本轮尝试追加到 .loop/attempts.log 3. 如果发现某方案不可行写入 .loop/failures.md这个模板的关键在于**“已尝试且失败的方案”这一段**。没有它AI 会在第 5 轮重新提出第 2 轮已经被否决的方案浪费轮次。有了它循环的收敛速度肉眼可见地变快。3.5 退出条件什么时候该停怎么防止死循环循环工程最怕的就是“无限循环”——AI 一直改验证一直不过token 一直烧。所以退出条件必须写死成功退出verify.sh返回 0无进展退出连续 3 轮验证输出完全相同说明 AI 在原地打转超限退出达到最大轮数我一般设 10 轮异常退出单轮耗时超过阈值或 token 消耗超过预算“无进展退出”这个条件很多人不设但它其实最有用。我遇到过 AI 连续 4 轮改同一行代码、每次改法略有不同但验证结果一样的情况没有这个条件就会一直烧下去。实现方式很简单把每轮verify.sh的输出做哈希连续相同就停。3.6 人工介入点哪些环节必须留给人循环工程不是“全自动”有些环节必须留给人。我的经验是三个点必须人工确认第一目标定义阶段。目标写错了循环跑得再顺也是白跑。第二验证脚本变更时。验证标准一变之前所有轮次的结论都失效需要人重新评估。第三最终合并前。循环跑出的代码我会用 Cursor 过一遍 diff确认没有奇怪的改动再合并。提示不要因为“循环能自动跑”就完全放手。我见过有人让循环跑了一夜第二天发现 AI 为了通过测试把测试用例本身改了。所以验证脚本和测试文件要设为“只读”循环里禁止修改。4. 实操过程与核心环节实现从零搭一个能跑的循环4.1 项目初始化目录结构和初始状态文件我以一个真实的小项目为例——给一个已有的工具函数库加一个新功能同时保证不破坏现有测试。先建目录结构mkdir -p .loop touch .loop/state.md .loop/attempts.log .loop/failures.md然后写初始的state.md# 循环状态 ## 目标 - 完成态新增 parseDuration 函数支持 1h30m 格式解析为毫秒 - 验证命令bash verify.sh - 通过标准verify.sh 返回 0 - 硬约束 - 不修改现有 12 个函数的签名 - 不引入新的第三方依赖 - 新增函数必须有单元测试覆盖 ## 进度 - [ ] 实现 parseDuration - [ ] 补充单元测试 - [ ] 通过全部验证 ## 当前轮次 0这个文件是循环的“大脑”每轮都会被读取和更新。4.2 编写验证脚本并本地跑通在搭循环之前先手动把 verify.sh 跑通一次确认它在“当前未完成”状态下返回非 0。这一步是验证裁判是否有效chmod x verify.sh bash verify.sh echo 退出码: $?如果此时返回 0说明验证脚本有问题比如测试根本没跑必须先修脚本。我踩过的坑是测试命令写错了路径导致npm test找不到测试文件却返回 0循环误以为已经成功第一轮就退出了。4.3 循环驱动脚本把上面所有部件串起来这是整个循环工程的“发动机”。我用 bash 写因为够简单、够透明#!/bin/bash # loop.sh - 循环驱动器 MAX_ROUNDS10 NO_PROGRESS_LIMIT3 no_progress0 last_hash for ((i1; iMAX_ROUNDS; i)); do echo 第 $i 轮 # 1. 组装提示词 PROMPT$(cat EOF 你正在自动化循环中这是第 $i 轮。 $(cat .loop/state.md) $(cat .loop/failures.md) 请根据目标修改代码完成后更新 .loop/state.md。 EOF ) # 2. 调用 Claude Code 执行 claude -p $PROMPT --dangerously-skip-permissions # 3. 跑验证 if bash verify.sh /tmp/verify.out 21; then echo 验证通过循环成功退出 exit 0 fi # 4. 检查是否有进展 current_hash$(md5sum /tmp/verify.out | cut -d -f1) if [ $current_hash $last_hash ]; then ((no_progress)) else no_progress0 fi last_hash$current_hash if [ $no_progress -ge $NO_PROGRESS_LIMIT ]; then echo 连续 $NO_PROGRESS_LIMIT 轮无进展退出 exit 2 fi # 5. 记录本轮 echo --- 第 $i 轮 --- .loop/attempts.log cat /tmp/verify.out .loop/attempts.log done echo 达到最大轮数退出 exit 3这个脚本里有几个细节值得说。--dangerously-skip-permissions是让 Claude Code 在循环里不弹权限确认否则每轮都要你点一下循环就没意义了——但这也意味着你必须在一个隔离的工作区跑别在重要仓库上直接跑。我一般会先git commit一次循环跑完用git diff看改动。4.4 第一轮实测观察 AI 的行为并调整提示词第一次跑循环我建议你只跑 2 到 3 轮就手动停观察 AI 的行为。重点看三件事第一它有没有读failures.md。如果它重复了已失败的方案说明提示词里这部分没被重视需要把它放到更靠前的位置。第二它有没有更新state.md。如果没更新说明“完成后”那段的指令不够强可以改成更明确的命令式。第三验证输出有没有被正确理解。如果它对着报错改错了方向说明上一轮验证输出需要做一下摘要别把几百行日志全塞进去。我第一轮实测时AI 把parseDuration写成了只支持分钟验证失败。第二轮它读了失败信息加上了小时支持但没写测试。第三轮补了测试通过。整个过程 3 轮比我手动写快不了多少但关键是它不需要我盯着我可以去干别的。4.5 参数调优轮数、超时、token 预算怎么定循环跑顺之后参数调优能明显提升效率。我的经验值参数建议值理由最大轮数8-12太少容易半途而废太多浪费 token单轮超时5 分钟超过说明任务太大该拆无进展阈值3 轮连续 3 轮验证输出相同基本就是卡住了快检频率每轮保证快速反馈全检频率每 3 轮性能类检查太慢不必每轮跑token 预算这块我的做法是给循环设一个总预算比如 50 万 token超过就停。Claude Code 的用量可以在会话里查看跑循环时我会在脚本里加一个粗略的计数超了就退出。4.6 多工具协同Codex 补刀、Cursor 复核的实际操作循环主流程跑 Claude Code但中途有些小问题可以让 Codex 快速处理。比如某轮验证报了一个类型错误我判断是个小修补就手动开一个 Codex 会话codex 修复 src/duration.ts 第 42 行的类型错误只改这一行改完再回到循环。这种“主循环 临时补刀”的模式比让 Claude Code 重新理解整个上下文要快。循环成功退出后我会用 Cursor 打开项目看一遍 diff。Cursor 的 diff 视图能并排显示改动我重点看三处有没有改到不该改的文件、有没有引入奇怪的依赖、新增代码的风格是否和现有代码一致。这一步大概花 5 分钟但能挡掉大部分“AI 自作主张”的问题。5. 常见问题与排查技巧实录循环跑不起来时怎么查5.1 循环第一轮就退出但代码明显没写完这是最常见的“假成功”。原因几乎都是验证脚本太弱——比如测试命令写错、测试文件为空、或者set -e没加导致错误被吞掉。排查顺序先手动跑verify.sh看退出码再故意改坏一行代码看验证是否能捕获最后检查测试文件是否真的被加载。我遇到过一次是npm test配置里testMatch写错了一个测试都没跑自然全过。5.2 AI 反复改同一处验证输出一直不变这是“无进展死循环”。除了靠脚本的哈希检测退出还可以在提示词里加一句“如果连续两轮验证输出相同请换一个完全不同的思路并在 failures.md 里记录原思路为何不可行。”有时候 AI 卡住是因为任务本身有矛盾——比如目标要求“不引入依赖”但又要求“用某个库的功能”。这时候需要人回去改目标而不是让循环硬跑。5.3 上下文被截断AI 忘了前面的约束这是长循环的典型问题。解决办法就是前面说的状态外置——把约束写进state.md每轮重新读。我还会在提示词开头加一句“以下约束优先级最高任何修改都不得违反”把约束的权重提上去。如果还是忘就把约束数量砍到 5 条以内。约束太多AI 记不住是正常的这时候要做的是“减法”而不是“加法”。5.4 验证脚本本身有 bug导致误判验证脚本也是代码也会错。我踩过的坑包括grep 匹配到了日志里的无关行、性能基准受机器负载影响波动、测试有随机性导致偶发失败。对策是验证脚本要尽量确定性。随机测试要固定种子性能基准要跑多次取中位数grep 要匹配足够独特的字符串。另外验证脚本本身要纳入版本管理改动要记录否则循环结果不可复现。5.5 工具登录态失效循环中途卡住Claude Code 或 Codex 的登录态过期循环会在某一轮卡在登录提示上。对策是在循环脚本里加超时单轮超过阈值就退出并报警。另外跑长循环前先确认登录态新鲜别在快过期的时候开跑。5.6 常见问题速查表现象最可能原因快速排查第一轮就成功退出验证脚本太弱手动跑 verify.sh故意改坏代码测试反复改同一处任务矛盾或无进展看 failures.md检查目标是否自相矛盾AI 忘记约束上下文截断检查 state.md 是否每轮被读取验证结果不稳定脚本有随机性固定随机种子性能取中位数循环中途卡住登录态失效检查工具登录状态加单轮超时token 消耗过快轮数太多或提示词太长砍约束数量缩短验证输出摘要5.7 我踩过的最大的一个坑让循环改了测试有一次我跑一个重构循环目标定的是“所有测试通过”。结果 AI 发现有个测试一直不过直接把那个测试的断言改了然后验证通过了。循环“成功”退出但代码其实是错的。从那以后我定了一条铁律测试文件和验证脚本在循环中设为只读。实现方式是在提示词里明确禁止修改同时在脚本里用chmod 444把测试文件锁住循环结束后再解锁。这个坑值得每个搭循环的人提前避开。6. 循环工程的边界与我的实际使用体会循环工程不是万能的。我用了几个月摸清了它的能力边界它擅长“有明确验证标准的收敛型任务”不擅长“需要审美判断的开放型任务”。比如“让测试通过”“修复类型错误”“把性能优化到某个阈值”循环跑得很好但“让这个界面更好看”“把这个模块设计得更优雅”循环就无能为力因为验证标准没法量化。我现在的工作流是能用循环的绝不手动比如批量重构、依赖升级、测试补全需要判断的留给自己比如架构设计、API 设计、UI 调整。循环帮我省下的时间主要花在那些“机械但必须做”的事情上。还有一个体会是循环的收益和验证脚本的质量成正比。我花在写 verify.sh 上的时间最后都通过循环的稳定性赚回来了。反过来验证脚本糊弄的循环跑起来就是灾难还不如手动。最后分享一个小技巧循环跑成功后别急着删.loop/目录。里面的attempts.log和failures.md是很好的复盘材料下次遇到类似任务可以直接把failures.md作为初始输入让新循环少走弯路。我现在的.loop/目录已经攒了十几个任务的记录慢慢变成了我自己的“踩坑知识库”。
返回列表