
我最早接触“循环”这个概念是在大学写排序算法的时候。后来工作里做数据处理管道循环变成了批处理任务。直到这两年做 AI Agent我才发现“循环”本身竟然能成为一门需要专门设计、专门调试、专门踩坑的工程学科社区里管它叫 Loop Engineering。如果你最近也在做 Agent 开发大概率已经感觉到了单次调用大模型已经解决不了实际问题真正的复杂度全在“让它反复尝试、自我纠错、直到完成”的这个过程里。这篇教程我想从一个实操者的角度把 Loop Engineering 从概念到落地完整拆一遍最后带一个可以直接改来用的项目实战希望给正在入门或卡在调优阶段的你一点参考。如果你是第一次听到这个词可以先这么理解Loop Engineering 不是某个框架也不是某种算法而是一套“把任务执行环路当成一等公民来设计、监控、优化”的工程方法论。它跟 Prompt Engineering 最大的区别在于Prompt 的输入是文本输出是文本过程是一次性的而 Loop 的输入是一个目标输出是一个结果中间是无数个“模型思考、工具执行、结果评估、记忆更新”的循环往返。这套东西真正火起来是因为 Agent 应用变多了大家发现只有把循环设计得够稳Agent 才不会跑着跑着就“鬼打墙”。1. Loop Engineering 到底是什么1.1 从“一次生成”到“反复尝试”两年前我们写 AI 应用最常用的模式就是把 Prompt 拼好调一次模型接口拿结果解析就完事。这种模式解决“给一段文字写个总结”这类任务绰绰有余但一旦遇到“帮我查竞品信息整理成对比表”这种需要多步操作、多个信息来源、甚至中途还要调整方案的任务单次调用就完全不够用了。原因很简单模型一次能接收的信息量有限工具调用的结果又是一轮新的信息你不可能在第一次 Prompt 里把所有路径都规划好。所以业界开始把任务拆成“感知 - 规划 - 行动 - 评估 - 反思”这样的循环每一轮都往状态池里补充新信息再根据新信息调整下一步行动。Loop Engineering 就是把这种循环过程工程化你不再只是写一句 Prompt而是设计一个完整的执行环路包括状态怎么存、每一步怎么决策、什么时候该停。1.2 核心定义与组成要素我用最简单的话给 Loop Engineering 下个定义它是一套以循环为主体架构的 AI 任务执行方案的设计与实现方法核心是让模型在闭合回路中通过“行动 - 反馈 - 再行动”逼近目标。一个标准的 Agent 循环工程至少包含七个要素目标定义把用户的需求转成机器可判定的任务描述比如“找出这几家竞品最近30天的定价变化并汇总”。状态跟踪记录已经做了什么、拿到了什么结果、还剩哪些待办。推理决策模型根据当前状态决定下一步动作比如“调用搜索工具”或“先读某篇文章”。动作执行调用外部工具、API 或代码模块获取真实数据。结果评估判断本轮动作是否有效信息是否足够目标是否达成。记忆更新将本轮有价值的结论写入状态或记忆库供后续轮次使用。终止判断满足条件则退出循环返回最终结果。把这七个要素串起来就是一个个闭环。为什么一定是闭环而不是线性流程因为真实世界充满不确定性工具可能失败、搜索可能无果、模型可能理解偏了只有闭环才能让系统自己发现问题并修正。1.3 和普通链式调用的区别很多人会混淆循环和链式调用。链式调用Pipeline是提前规定好的固定流水线A 步骤完成后必走 BB 完成后必走 C中间没有任何回退和分支。而循环是有条件跳转的每一步都可能回到之前的某一步甚至推翻之前的结论。我用一个表格来对比维度单次调用链式调用Pipeline循环工程Loop流程控制无线性预设动态条件跳转反馈机制无无或仅步骤间传递每轮评估反馈状态持久性无步骤间临时传递持续累积更新适用复杂度简单文本任务步骤明确的固定流程不确定、多路径的复杂任务调试难度低中高需要可观测性设计典型场景摘要、翻译数据清洗流水线Agent、自动化调研、复杂推理一句话总结Pipeline 适合“你提前知道了所有步骤”的任务Loop 适合“你知道目标但不知道最优路径”的任务。2. 核心原理与循环架构设计2.1 为什么循环比“一次到位”更可靠有个很经典的对比能说明问题微波炉热菜是设定好时间一次加热你没法根据菜的状态中途调整人炒菜是边炒边尝边调整火候最终出品更稳定。大模型单次调用就像微波炉面对简单任务没问题但复杂任务里一次输出往往有信息遗漏甚至幻觉。循环工程的核心优势在于引入了评估与纠正机制。假设每一轮模型输出有一个固定的错误率比如 10%单次调用成功率就是 90%但循环里每一轮都有评估器检查结果质量发现不对就重新来只要评估器本身准确率够高比如 95%多轮下来最终成功率会被推到 99% 以上。这不是玄学而是反馈控制的基本逻辑——你不需要模型一次做对只需要它能识别“自己还没做对”。当然前提是评估环节足够可靠否则错误的评估会把系统带偏这一点后文会专门讲。2.2 三种常见的循环拓扑做循环工程的第一步是搞清楚你的任务适合哪种循环形态。我实际用下来发现绝大多数场景都能归到下面三种。有限循环循环次数是固定的比如“执行三轮搜索后无论结果如何都总结”。这种最简单适合你有把握在固定轮数内能拿到足够信息的任务。优点是可控、可预测缺点是灵活性差可能第 2 轮就完成了但还在空转。条件循环每轮结束都做一次目标达成判断满足条件就退出。这是最常用的形态。条件可以是评估器打分超过阈值、收集到的关键信息覆盖率达到多少、或连续 N 轮没有新进展。缺点是条件设计需要经验条件太严容易死循环太松容易提前退出导致结果残缺。嵌套循环外层循环负责整体任务推进内层循环负责某个子任务的自我优化。比如外层循环在遍历“竞品A、竞品B、竞品C”三个对象每个对象内部有一个“抓取资料 - 提炼卖点 - 验证可靠性”的内层循环。这种结构功能最强但状态管理和日志追踪也最复杂新手建议从条件循环开始。2.3 状态管理的工程化实现状态设计是 Loop Engineering 和普通 Prompt 工程最大的分野。没有状态循环就只是无意义地重复调用有了状态循环才有“记忆”和“进步”。我建议用结构化的 JSON 来管理循环状态而不是简单地把历史聊天记录全部堆在一起。一个典型的 Agent 状态结构长这样{ task: 调研竞品的近期定价变化, goal_summary: 输出包含三家公司定价对比的报告, completed_steps: [], current_findings: [], pending_actions: [search:公司A定价, search:公司B定价], memory_summary: 已确认公司A在6月上调了企业版价格, iteration_count: 0, no_progress_count: 0 }每一轮循环结束必须更新这个状态对象。这里有一条我个人踩坑总结出的铁律写入状态的信息必须是“评估过的结论”而不是模型的原始输出。模型说“我觉得公司B可能降价了”这个不能直接写进记忆要等验证后变成“公司B的官网显示标准版价格下降10%”再写入。关于记忆的窗口设计我的建议是短期记忆保留最近 3 到 5 轮的工具结果原文长期记忆只保存每轮提炼出的一两句结论摘要。全量保留上下文既贵又容易让模型迷失在噪声里。2.4 终止条件设计的四种策略循环工程最怕两件事一是死循环二是“看似在跑但毫无进展”。所以终止条件必须至少包含以下四类之一最好组合使用。首先是最大轮数限制这是保底线任何循环都必须有。其次是目标达成判定用一个评估器去判断当前收集的信息是否足以生成最终输出。再次是无进展检测每一轮对比状态池如果连续两轮没有增加新信息、没有修正旧结论就强制触发终止或换策略。最后是资源预算上限比如总 token 消耗接近预算时自动降级输出。我实际写过一个经验公式终止条件里的“无进展连续轮数”设为目标总轮数的 20% 到 30% 比较合理比如最大 10 轮连续 3 轮无新信息就停。3. 保姆级实操搭建一个带反思的检索 Agent3.1 环境准备与依赖安装实操部分我基于 Python 3.10用最简单的依赖组合。你需要准备一个可调用的大模型接口本地有 Ollama 也行只要兼容 OpenAI 格式即可。核心依赖只有两个openai用于调用模型requests用于模拟联网检索工具。安装命令很简单pip install openai requests之所以不引入 LangChain 这类重型框架是因为我始终觉得理解循环本身的逻辑比学会某个框架的 API 更重要。框架帮你封装了细节但也遮住了问题。先徒手实现一遍你会对 Loop Engineering 的每一个齿轮都有体感。3.2 整体循环结构设计这个项目目标很直接给定一个主题让 Agent 通过多轮“自主规划 - 检索 - 评估 - 反思”最终产出一份高质量的中文调研报告。整体执行流程如下初始化任务状态把目标写进系统提示词。规划阶段模型根据当前状态列出需要检索的问题清单。执行阶段依次调用检索工具把结果归档到临时区域。评估阶段判断当前信息是否足够支撑最终报告给一个 0 到 1 的分数。反思阶段如果分数不足模型反思“还缺什么、下一步该做什么”。更新记忆回到第 2 步直到超过阈值或触发终止条件。生成最终报告。我把“评估”和“反思”拆成了两个环节。评估负责打分反思负责产生新的行动计划。不要试图在一个 Prompt 里同时完成两件事分开之后你会发现日志清晰得多哪一步出了问题一眼就能看到。3.3 核心代码实现下面是一份可以真跑的核心循环代码我刻意保持精简方便你在此基础上扩展import json from openai import OpenAI client OpenAI(base_urlhttp://localhost:11434/v1, api_keyollama) MODEL qwen2.5:14b # 模拟联网检索工具 def search_web(query: str) - str: # 真实项目中替换为搜索 API 调用 return f关于{query}的模拟检索结果找到3条相关链接部分内容有参考价值。 # 评估信息充分度 def evaluate_sufficiency(state: dict) - float: keywords state[pending_actions] if not keywords: return 0.0 # 用模型打分这里为了演示用规则替代 covered sum(1 for k in keywords if k in str(state[findings])) return covered / len(keywords) # 主循环 def agent_loop(task: str, max_iterations: int 8): state { task: task, findings: [], pending_actions: [task], iterations: 0, no_progress_count: 0, } while state[iterations] max_iterations: state[iterations] 1 print(f--- 第{state[iterations]}轮 ---) # 规划 planning_prompt f当前任务{state[task]}\n已有信息{state[findings]}\n请给出下一步检索关键词仅输出关键词列表。 plan client.chat.completions.create( modelMODEL, messages[{role: user, content: planning_prompt}], temperature0.3, ).choices[0].message.content print(规划结果, plan) # 执行 for kw in plan.strip().split(\n)[:3]: kw kw.strip().strip(-).strip() if kw: result search_web(kw) state[findings].append({query: kw, result: result}) # 评估 score evaluate_sufficiency(state) print(充分度评分, score) # 反思与终止 if score 0.8: print(信息足够准备生成报告) break else: state[no_progress_count] 1 if state[no_progress_count] 3: print(连续无进展强制终止) break # 最终报告生成 final_prompt f根据以下信息为任务{task}撰写结构化报告\n{state[findings]} report client.chat.completions.create( modelMODEL, messages[{role: user, content: final_prompt}], temperature0.3, ).choices[0].message.content return report if __name__ __main__: result agent_loop(调研2025年AI编程助手的主流定价模式) print(result)这段代码看起来很简单但它已经包含了一个最小闭环的所有关键节点规划时模型生成行动方案执行时调用外部工具评估时用规则判断进展反思时通过“无进展计数”兜底。你把它跑通之后再去替换更强的工具和评估模型就是一个生产级 Agent 的雏形。3.4 关键参数选择与调优心得实操里最影响循环质量的是四个参数我分别说下我的设置习惯。temperature我设在 0.2 到 0.4 之间。规划阶段需要稳定温度太高模型会频繁换方向导致状态池里全是零散信息。max_iterations我一般设最大轮数的两倍作为余量因为评估器偶尔会误判留余量能避免“明明快完成却被强制截断”的尴尬。evaluate_sufficiency的阈值建议动态调整。前期任务刚启动分数普遍低阈值固定太高会让循环跑满我更喜欢把阈值设为 0.7 到 0.8 之间配合“连续无进展就终止”的双保险。还有一个隐藏参数是系统提示词里对“输出格式”的约束规划阶段的输出格式越结构化你解析起来越省心。3.5 运行结果解读当你跑通这个脚本会看到类似下面的日志--- 第1轮 --- 规划结果 1. AI编程助手 定价模式 2. Copilot 订阅价格 3. 主流产品对比 充分度评分 0.33 --- 第2轮 --- 规划结果 1. 各产品免费版功能限制 2. 企业版定价 充分度评分 0.67 --- 第3轮 --- 规划结果 1. 按量付费产品 充分度评分 0.83 信息足够准备生成报告这个日志说明循环是健康的每轮都有新信息进账评分逐步上升最终在第三轮达标退出。如果日志里出现“连续两轮没有新发现”或者评分停滞在同一个值你就要回去检查是不是状态没有正确更新或者评估器的判定太宽松了。4. 项目实战多工具协作的竞品调研 Agent4.1 需求拆解与目标定义基础循环跑通之后我们来做一个更有工程味道的项目一个能调用多种工具完成竞品调研的 Agent。需求是这样的输入一个行业关键词输出一份涵盖“主要玩家、产品形态、定价策略、近期动态”的竞品调研报告。这个任务比单纯的检索难在两点。第一信息来源多样有的信息在官网定价页有的在社区讨论帖有的在新闻稿单一搜索工具不够。第二输出要求结构化需要合并多个来源、交叉验证。所以我在循环里加入了三种工具search_web负责关键词搜索fetch_page负责抓取指定页面文本query_db负责从本地知识库或历史数据中查记录。这都是通过函数注册表动态调度的。4.2 工具注册与动态调度机制工程化 Agent 和玩具脚本最大的区别就是工具调用不再是一句if query.startswith(搜索)能解决的。我用的模式是注册表加调度器TOOL_REGISTRY {} def register_tool(name, handler, description): TOOL_REGISTRY[name] {handler: handler, description: description} register_tool(search_web, search_web, 输入查询词返回相关网页标题和摘要列表) register_tool(fetch_page, fetch_page, 输入URL返回页面正文文本) register_tool(query_db, query_db, 输入SQL或关键词返回历史记录)模型规划阶段输出一个 JSON格式是{tool: search_web, args: {query: ...}}调度器解析后查注册表找到对应函数执行再把结果追加到状态池。这个设计的价值在于解耦新增一个工具只需要注册函数和描述循环主体完全不用改。description很重要因为模型是根据描述来决定调哪个工具的描述写得越精准调度成功率越高。我之前把某个工具描述写得太抽象模型十次里八次选错后来改成明确的行为描述准确率直接上来了。4.3 子任务调度与结果合并竞品调研的循环不能是单线到底的需要内层循环。我的做法是在主循环的“规划阶段”让模型先列出需要调研的实体清单然后对每个实体启动一个子循环检索官网信息、抓取定价页、查历史评价收集完毕再进入下一个实体。主循环负责全局协调子循环负责单个实体的深入挖掘两者共享同一个状态池但子循环有独立的暂停与恢复机制。实现上用“生成器”或者“子循环函数返回值回传”都可以。我用的是把子循环结果压缩成结构化摘要后回传主循环避免把原始长文全部堆进主状态里。合并结果的阶段我让模型按“公司名 / 产品名 / 定价模式 / 主要动态 / 来源可靠性”五段式输出。这五个字段是提前定义好的报告模板模型负责填内容保证最终输出的格式统一方便后续落库或者做对比报告。4.4 项目效果评估与优化迭代做完这个项目后我定了三个核心指标来评估系统健康状况指标定义优化前优化后任务完成率最终报告包含全部目标字段的比例72%94%平均轮次单个任务消耗的主循环轮数9.26.5有效信息率状态池中最终被报告引用的信息占比41%68%优化主要做了三件事。首先是精简规划提示词把“工具选择逻辑”明确的写在系统提示词里模型不再凭感觉选工具。其次是引入摘要压缩子循环返回前把原文压成两行结论主状态池不再被噪声撑爆。最后是加了一个“信息去重”环节模型在写入记忆前先检查是否已有等价结论减少重复检索这也是平均轮次下降的直接原因。5. 常见问题与排查技巧实录5.1 死循环与震荡问题这是 Loop Engineering 最经典的问题。现象是循环跑满最大轮数评分始终在某个区间震荡模型反复做类似的事信息却没有增量积累。排查思路先看日志确认“每一轮到底产出了什么新信息”如果新信息确实为零但评分还在涨那就是评估器坏了。如果新信息有但都是碎片的可能是规划阶段指令不够聚焦。我的止损方案是每次都给循环加一个“无进展检测轮数”比如两轮没有新增信息直接跳转到“总结当前已有内容”模式宁可结果残缺也不能空转烧钱。5.2 上下文污染与记忆固化循环次数一多状态池里的早期错误信息会像滚雪球一样影响后续决策。模型经常会把之前某轮的错误猜测当成既定事实。这里我推荐一个叫“来源标注”的习惯每条写入状态池的结论都带上来源字段标注“官网”“新闻稿”“模型推断”等。在评估阶段给不同来源设置不同的可信度权重模型推断的结论要经过后续检索确认才能升级为“已确认事实”。这样即使模型在某一轮产生了幻觉也不会污染长期的决策依据。5.3 成本失控多轮循环意味着多次模型调用如果没有成本意识一个复杂任务烧掉几块钱甚至几十块钱很正常。我的习惯是设置三层预算控制第一层是全局 token 预算用累加器实时统计达到上限就强制进入报告生成阶段。第二层是单轮预算如果某一轮规划出超过 5 个动作自动截断到最重要的 3 个。第三层是缓存检索相同关键词的结果直接复用避免重复调用。5.4 评估器不可信评估器是整个循环的“裁判”裁判瞎吹或瞎贬都会毁掉整个系统。规则评估器简单可靠但灵敏度低模型评估器灵活但会幻觉。我的方案是混合评估先用规则把硬性指标筛一遍比如覆盖关键词数量再让模型评估软性质量比如逻辑一致性、信息冲突两者都以分数形式汇总。如果发现评估器输出和真实质量明显不符优先怀疑 Prompt 里的“评估标准”描述太模糊。我踩过的坑是只写了“判断信息是否充分”模型根本不知道什么叫充分后来改成“是否覆盖目标中的所有子问题是否包含至少两个独立来源”准确率高了很多。5.5 调试困难与可观测性设计循环系统最讨厌的就是黑盒。模型不报错但你不知道它内部在想什么。所以我强烈建议从第一天就给循环加结构化日志每轮记录状态快照、规划输出、工具结果摘要、评估分数、终止原因全部落到 JSON Lines 文件里。调试时直接拉日志看轨迹哪一轮开始跑偏、哪个工具返回了空结果、哪个评估决策导致提前终止一目了然。我甚至会在状态里加一个reasoning_trace字段专门存模型每轮反思的文本这样回放时的信息量会大很多。5.6 问题速查表症状可能原因排查方法推荐方案循环跑满轮数评估阈值过高 / 规划不聚焦查看各轮评分曲线调低阈值增加无进展终止评分不升反降状态池引入噪声信息检查新写入结论的来源标注加强写入前评估控制来源工具频繁选错工具描述与实际行为不符打印模型选工具日志重写工具 description成本超过预期单轮规划动作过多 / 无缓存统计轮均 token 消耗增加动作数上限加缓存报告信息残缺提前终止触发过于激进检查终止条件命中轮次放宽无进展轮数阈值写在最后的个人体会把这套东西完整做下来我最深的感受是Loop Engineering 的难点不在“循环怎么写”而在“什么时候该停”。写一个死循环很容易写一个懂得“在合适的时候见好就收”的循环需要对任务本身有很清晰的理解也需要对模型的运行模式有足够的体感。我个人习惯的做法是先把终止条件和评估规则写出来再回头写规划逻辑因为退出条件决定了整个循环的边界和成本上限。最后分享一个小技巧所有循环调试的第一步永远是打开日志看轨迹不要凭感觉改 Prompt——数据永远比直觉更可靠。希望这篇教程能让你少踩几个我踩过的坑真的能把这个思路用到你自己的项目里去。