如果你最近在折腾 AI Agent八成已经见过这样的场面模型答错了你让它“再试一次”结果它换了个姿势又错一遍或者它明明已经写出一版差不多的答案却因为缺少一个“自我检查”的步骤交上来一份漏洞百出的结果。我自己的项目里也反复出现这类问题后来才发现问题不在某一个模型调优上而在于整个 Agent 的执行流程里缺了真正有用的循环设计。Loop Engineering中文可以叫“循环工程”。它研究的不是编程语言里的 for/while而是智能体在真实任务中反复迭代、自我修正、逐步逼近目标的那套机制。这篇教程会从最基础的概念讲起带你把 Agent 内部最常见的几种循环模式拆开揉碎然后用一个虚构但足够真实的项目“稿文助手”走完从设计到落地的全流程。不管你之前是用现成框架搭过 Agent还是自己写过几行调度代码这篇的内容都能直接抄作业。1. 先把“循环工程”这个说法翻译成人话1.1 不是什么新技术而是一种必要的工程视角我第一次听到 Loop Engineering 这个词是在和一位做智能体架构的同行聊天时。他没有给我看任何新框架而是指着他屏幕上一段调度代码说“Agent 好不好用很大程度取决于这个循环设计得好不好。”这句话点醒了我。过去我们写 Agent总把注意力放在选什么模型、写什么提示词上但现实是一个单次调用模型的结果十有八九不够用。真正让 Agent“看起来聪明”的是它在一次不成之后怎么修正在修正之后怎么判断能不能停。这整个反复运行的回路就是循环工程要管的事。打个比方你让一个实习生写一份活动方案。如果只扔一句话就等着收结果大概率得到一版他自己都看不下去的草稿。但如果你告诉他——先列提纲写完初稿后自己查一遍错别字再把方案对照预算重新审一遍——最后给你的东西质量就会完全不一样。这套“先做、再查、再改、再判”的结构化流程就是人类世界里的循环工程。1.2 循环工程的范围不只是让模型多试几次很多人以为给 Agent 加个“如果失败就重试”的逻辑就是循环工程。这太窄了。循环工程至少包含四层内容循环结构设计整个任务应该拆成几个阶段每个阶段是大模型完成还是由普通代码完成评估机制每次循环结束后拿什么标准判断结果“够好了”谁来当裁判终止策略什么时候必须停止最大次数是多少出现哪些信号要提前中断状态管理每一轮产生的结果和反馈如何传给下一轮过程中哪些信息要保留哪些要丢弃单纯的重试只是四层中最浅的一层。真正的循环工程是把这个系统设计的每个环节都考虑进去让 Agent 在“能跑”的基础上做到“跑得快、跑得稳、结果可复现”。1.3 循环工程在什么场景下是刚需不是所有 Agent 场景都需要复杂的循环。如果你只是问模型“今天是几号”一次调用就够了。但下面这几类任务缺乏循环设计基本做不出可用结果长文档撰写一篇五千字的技术方案一次生成必然有逻辑断层和事实错误。代码修复与优化改完代码必须编译、跑测试再根据报错信息做二次修改。复杂信息抽取从乱糟糟的网页里抽字段第一次抽不准需要结合校验规则重抽。结构化输出生成模型输出 JSON 偶尔会坏需要循环性地修复格式。我在某公司做内部工具时遇到过很典型的例子同样是让模型写营销文案A 项目组只做单次调用用户反馈像在读万金油B 项目组加了两轮“先写后审”循环整体质量明显高出一个档。差的不是模型是循环。2. 拆解一个最小循环回路的关键构件2.1 没有“万能循环”但有“通用构件”任何循环工程都可以抽象成四个构件执行器、评估器、工作内存、控制器。理解这四样东西的职责再看任何复杂架构都会很轻松。执行器Executor真正干活的组件。它可能是一个大模型调用也可能是一段脚本负责产出当前迭代的结果。评估器Evaluator判断当前结果好坏的组件。它可以是规则如“JSON 能否被解析”、另一个模型打分、外部测试工具的通过率甚至是人工确认。工作内存Memory每一轮执行完把有用的结果、错误信息、中间状态记录下来供下一轮参考。控制器Controller决定循环是否继续。它握着一组终止条件比如最大迭代次数、质量阈值、总预算上限。你可以把控制器类比成燃气灶上的自动熄火装置执行器是炉火评估器是感温探头工作内存是锅里的菜——没有哪一样可以随便省掉。2.2 循环回路必须显式定义终止条件新手最容易犯的错就是只定义“继续条件”不定义“终止条件”。比如写“如果质量分低于 0.8 就继续迭代”乍一看没毛病但实际运行时一旦质量分卡在 0.75 上不去循环就会一直空转烧掉大量 token 才被外部超时机制掐断。我比较习惯的做法是同时设置三类终止条件终止条件类型示例目的质量达标评估分 0.85正常结束数量上限最多迭代 5 轮防止死循环资源上限累计 token 不超过 3 万控制成本三者的优先级按“数量/资源上限 质量达标”处理。即便质量还没达标只要迭代次数够了就必须停止并返回“当前最优结果警告信息”。这在生产环境里非常重要。2.3 评估器是循环质量的分水岭同样的循环结构用不同的评估器结果可能天差地别。我做过一次对照实验用三种评估方案去迭代优化同一批文案。方案 A让模型自己打分“请按 1-10 分评估你的输出”方案 B用一套自定义规则检查字数范围、是否有错别字、是否包含指定关键词方案 C用一个独立的强模型做评分独立的 prompt不暴露写作模型结果很有意思方案 A 几乎永远给自己打 8 分以上循环很快就停了但产出没有明显提升方案 B 稳定但上限低因为规则只能识别“格式合格”判断不了“文采好不好”方案 C 效果最好但成本和延迟最高。没有完美的评估器。工程上最务实的选择是“规则为主、模型为辅”先把能用代码判断的都交给代码比如格式、长度、必含字段、编译结果剩下主观部分再交给模型评分。这么设计既控制成本又保留质量判断能力。3. 三种高频循环模式的工程实现3.1 模式一自我反思循环自我反思循环是最基础也最容易见效的模式。它的核心动作是执行一轮 → 要求模型针对自己的输出挑毛病 → 根据毛病重新执行一遍。工程实现上我会把“反思”和“重写”拆成两次独立的模型调用而不是在同一个 prompt 里既要求输出又要求反思。原因很简单模型同时处理两件事每件都容易做不精。分开后反思 prompt 里明确要求“列出最多 5 个具体问题不要修改原文”重写 prompt 里再带上“上一版的问题清单”以及“请针对问题逐项修改”的要求。伪代码大致长这样def self_reflect_loop(task, max_rounds3): result generate(task) for i in range(1, max_rounds 1): feedback reflect_on(result, task) # 只提问题不产出新内容 if is_good_enough(feedback): break result generate(task, previous_resultresult, feedbackfeedback) return result在实测中这个模式对“文案优化”“报告润色”“代码注释补全”这类任务特别有效。前两轮提升明显第三轮以后边际效益就非常低了因此我这里把 max_rounds 默认值设为 3而不是 10。3.2 模式二计划-执行-反馈循环比自我反思更进一步的是把循环从“改输出”升级成“改计划”。典型流程是模型先制定任务计划比如分三步走。按计划逐步执行。每一步执行完后把结果反馈给计划层。如果某一步结果不理想模型被允许修改后续计划。这种模式适合任务步骤多、中间结果相互依赖的场景。比如写一篇技术调研报告第 1 步收集资料第 2 步写大纲第 3 步填充正文第 4 步统一风格。用自我反思循环只能改正文改不了“大纲本身就有问题”这件事而计划-执行-反馈循环允许你在第 3 步发现资料不足时回头把第 1 步补跑一遍。需要特别提醒的是这个模式下工作内存的设计会变复杂。你必须把“原始任务”“当前计划”“已执行步骤的结果”“下一步要做什么”这四类信息分开存储否则模型很快就把上下文搅成一团。3.3 模式三多 Agent 协作循环多 Agent 协作循环本质上是把评估器和执行器从同一个模型上下文里剥离出来让一个 Agent 产出、另一个 Agent 审查、第三个 Agent 做最终裁决。我实现过一个轻量版本一个“写手 Agent 一个编辑 Agent 一个决策 Agent”。写手负责生成初稿编辑负责挑刺并给出修改建议决策 Agent 判断“是否采纳编辑意见、是否继续循环”。这和前面两种模式最大的区别在于写手不再兼任评估员避免了“自己看自己永远顺眼”的问题。代价也很明显多了一次以上的额外模型调用成本几乎翻倍而且三个 Agent 的提示词必须仔细对齐否则会出现“写手听不懂编辑意见”的糟糕情况。我不建议小项目一开始就上多 Agent先把自我反思循环跑通收益通常会更高。4. 保姆级实战从零搭建一个“稿文助手”最小项目4.1 项目目标与需求拆解这个实战项目的虚构背景是我想做一个内部用的“稿文助手”输入一个主题输出一篇两千字左右、结构清晰、有一定文采的科普性文章。产品要求有两点第一文章不能有明显的常识错误第二整体结构要包含引言、正文分层、结尾三个部分。如果只做一次模型调用文章往往形似而神不似。于是我把需求拆成三个子问题如何保证结构完整如何保证内容质量如何控制成本答案就是一套带“结构校验 质量打分”的循环工程实现。4.2 环境准备与依赖说明这是教程项目不依赖任何框架只需要一个能调用大模型接口的 Python 环境。我这里以“某模型 API 的本地封装”举例你换成自己手头可用的任何供应商接口都可以。依赖库就两个openai仅示范不限于该供应商和json。在编写代码前先约定两条内部规范所有模型调用的 temperature 固定为 0.7。所有模型输出都要求是纯文本不额外包 Markdown。4.3 循环结构设计与代码实现我先把整个循环定义清楚第一轮根据主题直接生成初稿。 第二轮用规则检查结构缺哪部分就补哪部分。 第三轮含以后让模型自评内容针对评分低的部分重写。终止条件结构校验通过且自评分大于 7 分或者最大轮数达到 4 轮。下面是核心代码我尽量保持精简import json def call_llm(prompt, modeldefault): # 这里替换成你的模型调用代码 # 返回字符串文本 return 模拟的模型输出文本 def generate_draft(topic): prompt f请围绕“{topic}”写一篇2000字左右的科普文章要求包含引言、至少3个正文小节、结尾。 return call_llm(prompt) def check_structure(article): required_sections [引言, 正文, 结尾] result {} for section in required_sections: result[section] section in article return all(result.values()), result def self_score(article, topic): prompt ( f请评估下面这篇文章的质量输出JSON字段包括score(0-10)和issues(数组)。\n f文章主题{topic}\n文章内容{article[:1500]} ) resp call_llm(prompt) try: data json.loads(resp) return float(data[score]), data.get(issues, []) except Exception: return 5.0, [评估输出格式异常] def rewrite_article(article, topic, issues): issues_text .join(issues) if issues else 无特别问题请整体润色 prompt ( f请根据以下问题修改文章保留原文章优点仅改动需要改的部分。\n f问题清单{issues_text}\n主题{topic}\n原文{article} ) return call_llm(prompt) def run_loop(topic, max_rounds4): article generate_draft(topic) history [] for round_idx in range(1, max_rounds 1): ok, structure_detail check_structure(article) score, issues self_score(article, topic) history.append({ round: round_idx, structure_ok: ok, score: score, issues_count: len(issues) }) if ok and score 7.0: return article, history, success if round_idx max_rounds: return article, history, max_rounds_reached combined_issues issues[:] if not ok: combined_issues.append(结构不完整请补全引言、正文、结尾) article rewrite_article(article, topic, combined_issues) return article, history, unexpected这版代码没有考虑 Token 用量限制实际项目里你可以在call_llm外面套一层计数器设置每次循环最多消耗多少 Token。4.4 实测效果与一个典型的运行日志我拿主题“为什么睡眠不足会影响工作效率”跑了一次运行日志如下轮次结构是否完整自评分主要问题处理动作1否6.2正文只有两节缺少结尾触发结构补全2是6.8引言例子与主题关联弱针对性重写引言3是7.1无达标返回结果日志能很清楚地告诉我们真正花时间的是第二轮第一轮和第三轮的差异主要在结构而不是文采。如果我把 max_rounds 设为 2这篇稿子会因为结构不完整而退出循环所以建议这部分至少留到 3 轮给人留缓冲。4.5 成本估算参考以当前常见的模型定价区间来估算一次完整循环大约消耗 6000 到 9000 token。如果每 token 的成本在中低区间算下来每篇稿子的模型成本约为零点几元人民币如果换成更强的模型成本会明显上升但换来的是自评分更快达标、循环轮数下降。在真实预算敏感的场景下我一般会给文本类任务设置每篇稿子的成本上限超过了就自动改为“降级模式”——即停止自评分重写直接把当前最优结构版本返回给用户。这种方法简单粗暴但很有效。5. 循环工程最容易翻车的五个坑5.1 坑一迭代越多结果越差的“劣化漂移”有一天我调一个文案生成 Agent发现第二轮结果比第一轮差第三轮比第二轮更差。起初我以为是模型抽风后来看了中间过程才明白模型在“反思”阶段过度聚焦于挑小毛病比如某个词不够华丽、某个句式不顺结果把原本自然平实的文案改成了浮夸堆砌的八股文。解决方法有两条。一是约束反思范围在反思 prompt 里明确写“除非是事实错误或明显的逻辑断裂否则不要为换词而换词”二是引入“回退机制”把上一轮的结果也存进工作内存只有在新一轮的评分不低于上一轮 0.2 分时才接受新版本否则沿用旧版本继续迭代。5.2 坑二死循环或近似死循环只要终止条件写得够严密真正的死循环其实很少但“近似死循环”很常见每一轮都有变化但分数始终在 6.9 到 7.1 之间波动一直触达不到 7.0 的达标线直到用完所有预算。我在 2.2 节里说的“双重上限”就是为此设计。另外还有个实用技巧把达标阈值设成区间而不是一个点。比如“score 7.0 达标”可以改成“score 6.85 且连续两轮没有下降即视为达标”。这个小改动至少帮我省了不少 Token。5.3 坑三评估标准错位——裁判打分依据和任务目标不一致早前我在某个项目里让模型做“内容合规检查”结果它反复给一篇文章打低分原因是“语言风格不够幽默”。而任务目标根本没有幽默要求。这就是典型的评估标准错位。要解决它需要在评估 prompt 里显式声明“评估维度”第一是准确性第二是结构完整性第三是与主题的相关性。然后让模型按维度分别打分并给出依据而不是只给一个笼统的分数。这能让评估者意见更容易被理解重写阶段也更容易抓重点。5.4 坑四上下文污染与工作内存失控循环越深历史消息越冗长。模型要处理的上下文里既有原始任务、上一版全文又有一堆“第 3 轮你觉得这个比喻不够好”之类的杂音。结果就是模型被无关细节带偏越改越偏。经验做法是工作内存里只保存三类信息——最新版本的全文、本轮要处理的问题清单、原始任务约束。其余历史版本和过程评价一律不进主上下文。如果非要保存完整历史应该放到专门的存储里通过检索按需取用而不是一股脑塞给模型。5.5 坑五成本预估缺失被账单吓一跳有一次我开了多 Agent 协作循环跑一批文章跑完才发现总消耗比预想的高了 8 倍。查了一下是因为我在循环里忘了加成本统计模块某个子任务在不知不觉中反复循环了十几轮。后来我给每个子项目都加了“预算仪表盘”用一行代码在每次模型调用前累计请求次数和 Tokens并且同步输出到日志。这一步不复杂但能救命。建议你在任何循环工程实现里都把成本统计作为第一优先级的基建。6. 循环做完了怎么判断它到底值不值6.1 三个核心度量指标循环工程不是“有循环就好”它和任何技术决策一样需要可量化的评估。我常用的指标有三个质量提升量循环前后评估分的差值相对提升率。如果 3 轮循环只提升 0.1 分基本可以判定这个循环低效。边际效益第 N 轮相比第 N-1 轮的质量增量。一轮的增量如果小于零点几分说明这条循环已经逼近收敛点。成本效率比质量提升总量除以总 Token 消耗。这是我在内部做技术选型时最看重的比值。6.2 什么时候该削弱循环如果你的业务场景是海量碎片化文本比如每天处理上千条短评论那么复杂的 4 轮循环就不合适。这种场景更适合“单次生成 一次规则校验”顶多加一轮修复。我之前做过一次测算对短文本做自我反思循环预期质量提升只有 0.2 分但成本翻了 2.5 倍延迟翻倍。明显不划算。循环不是越强越好而是要和业务里的“单位文本价值”匹配。6.3 网格化调参的经验值如果让我给一套相对通用的初始参数大概是这样参数建议初值取值范围调整逻辑最大轮数42-8写作任务 4 足够代码修复可 5-6质量达标分7.06.5-8.0越高越贵规则校验必选结构/格式/黑名单用代码兜底评估模型温度0.20-0.4要稳定不要发挥回退阈值0.20.1-0.3防止劣化漂移这个表不是万能公式但可以作为你第一次调参的起点。之后根据具体任务去改动比从零摸索省力很多。7. 进阶从单循环走向多级循环系统7.1 阶段性循环与全局循环大部分任务只适合“单循环”也就是整个任务只有一个迭代回路。但当任务真的很大比如写一本书、开发一个完整功能模块单循环就撑不住了。这时候我会拆成多级循环。举一个虚构的例子某“智能排课系统”项目里我把排课任务拆成了三层循环。第一层是“生成课表”模型基于教师、班级、教室生成一版课表。第二层是“冲突检测循环”检测同一教室是否被两节课占用同一教师是否同时上两门课检测到冲突就回到第一层局部调整。第三层是“资源利用优化循环”在冲突清零的前提下计算教室闲置率低于阈值就再次调整课表。这三层循环不是嵌套关系而是串行关系。第一层跑完进入第二层第二层收敛后再进入第三层。如果直接做成一个超大循环评估器会很难写因为冲突要单独计算、资源效率又是另一个维度。7.2 循环的自我评估与自适应终止再往后走还可以让控制器学习历史数据。比如统计同一个任务类型在不同轮数下的质量分布曲线下次运行时如果发现自己的进度曲线和历史达标曲线明显偏离就可以提前终止或增加轮数而不是永远用固定的 4 轮。这个能力我目前只在少数项目里实验过收益不确定但方向值得关注。对大多数读者来说先把固定参数的循环跑熟比追求自适应要重要得多。7.3 人工介入点设计循环工程不是“全自动机器”在关键节点保留人工决策反而更高效。比如在最终输出前加入一个“抽取关键事实供人工复核”的步骤不让人工看全文只看三五个关键数字和结论。这一步能大幅降低模型幻觉对项目的影响而且很便宜。我的习惯是在循环退出之后、结果交付之前用一行代码生成“关键事实清单”单独输出。这样即使模型在细节上编造了什么人工也能快速发现而不是通读全文去找错。8. 最后再分享一点我对循环设计的真实感受项目做多了以后我越来越觉得 Loop Engineering 的核心不在于“让模型多跑几轮”而在于给“跑”这件事设计一套清晰的指挥规则。模型能不能生成好内容这件事存在随机性但循环工程能让这个随机性变得可控、可度量、可收敛。每次调循环参数我脑子里都会过一遍这个循环是在帮用户减少返工还是在帮模型自我感动如果答案是后者我会立刻把循环删掉。我自己现在做新 Agent 项目时会先写一版没有循环的“直出版本”再根据失败样本决定加哪一层循环而不是一上来就堆反思链、多 Agent、复杂内存。这种“先直出再打补丁”的节奏能让我很快搞清楚当前场景到底是质量不足、结构不稳还是任务理解偏差三种问题的修法完全不同。希望这篇教程里的拆解思路也能成为你调试自己循环时的一个顺手的工具箱。