← AI Agent

Agent 如何避免无限循环?

高频 中等 循环控制、失败恢复与预算 · 第 1 / 3 问 更新于 2026/10/05
AI Agent循环控制状态机故障恢复
本题落地项目AI Agent智能教务排课与教学质量分析系统

简化版

不能让 Agent 仅凭模型输出的“完成”决定循环终止。生产系统要同时设置最大步数、时间、Token、费用和工具调用预算,并用确定性完成条件、重复动作检测、无进展检测控制退出;达到边界后返回可恢复状态,转人工或降级,而不是继续重试。

详细版

Agent 循环一般是“规划—行动—观察—再规划”。无限循环常由目标含糊、工具持续失败、观察没有新信息、模型反复改计划或完成条件不可验证引起。

控制器至少维护这些状态:

step_count, deadline, token_used, cost_used
last_actions, state_fingerprint, progress_score
task_status, side_effect_log

每轮先检查硬预算,再校验动作是否合法;执行后比较新旧状态。如果连续多轮状态指纹相同、同一工具参数重复出现,或进度分数没有改善,就触发澄清、换策略或停止。成功必须由业务条件验证,例如目标文件存在且测试通过,不能只接受模型说 done。

完整版教学

一、循环为什么会失控

LLM 不持有可靠的程序计数器,也不能天然证明目标已经完成。工具报错后,它可能换一种措辞重复同一调用;搜索没有答案时,它可能不断改写查询;目标模糊时,它还可能持续“优化”已经可用的结果。

plan -> act -> observe -> plan
          ^                 |
          +--- 无新信息 ----+

记忆钩子:模型负责提出下一步,控制器负责决定这一步还能不能走;终止权必须在确定性代码手里。

二、硬预算是最后一道保险

无论推理多合理,都要设置不可突破的上限:最大步骤、墙钟时间、累计 token、费用、工具调用次数和单工具重试次数。多个限制要同时存在,因为 20 步可能每步只花 0.1 秒,也可能每步等待 30 秒。

假设限制为 12 步、60 秒和 0.5 元。Agent 第 7 步累计 0.46 元,即使时间只过 15 秒,也只能执行预计成本不超过 0.04 元的动作。预算检查应发生在调用前,而不是账单产生后。循环交给框架托管时,轮数上限和调用计数放在哪里,见「框架托管的工具循环是黑盒,怎么记录每一步、怎么限制轮数?」。

三、完成条件必须可以验证

“我认为任务完成了”只是模型声明,不是证据。不同任务要有对应验证器:代码任务运行测试,数据任务核对行数与约束,预订任务检查确认号,研究任务检查必需问题是否都有来源。

目标弱完成条件可验证条件
修复代码模型输出 done测试通过且 diff 在允许范围
发邮件已生成正文收件人确认后 API 返回 message_id
收集资料找到了很多网页必需字段齐全且每项有证据

验证失败应产生结构化原因,让下一轮能针对缺口行动;只返回 false 容易让模型盲目重试。

四、用状态指纹识别重复

动作文本稍有不同,不代表取得进展。可以把规范化后的工具名、关键参数、结果摘要和任务状态做哈希,形成状态指纹。最近窗口中同一指纹出现三次,通常说明进入环路。

fingerprint = hash(normalize({
    "tool": tool_name,
    "args": semantic_args,
    "result": result_code,
    "state": task_state,
}))

敏感参数不能直接写日志;哈希前也要规范化时间戳、请求 ID 等随机字段,否则每次都会得到不同指纹,检测不到实质重复。

五、无进展检测比重复检测更广

有些循环每一步都不同,却没有靠近目标。例如搜索词一直变化,但必需字段覆盖率始终是 60%。因此控制器要定义进度指标,如已完成子目标数、测试失败数、缺失字段数或验证器分数。

若覆盖率依次为 40%、60%、60%、60%,连续两轮增量为零,就应触发策略切换;若新策略后仍不改善,则停止。进度不是让模型自评“80%”,而应尽量来自外部状态或验证器。

六、重试要有分类和退避

超时、限流等瞬态错误可以指数退避重试;参数非法需要修正参数;权限拒绝不能靠重试解决;资源不存在则要换数据源或询问用户。把所有异常统一重试,是工具循环最常见的根源。

第 1 次等待 1s -> 第 2 次 2s -> 第 3 次 4s -> 停止

写操作还必须携带幂等键。否则 Agent 因响应超时再次调用付款接口,可能实际付款两次。停止循环不仅是省成本,也是在保护现实世界状态。

七、退出时要保留可恢复状态

达到预算不应只抛出“失败”。控制器应保存已完成步骤、最后可靠状态、未满足条件、工具副作用和建议下一步。这样人工可以接管,稍后也能从检查点继续,而不是重新执行全部动作。

退出策略可分为成功、需要澄清、可重试失败、预算耗尽、高风险拦截和人工接管。每种状态对用户的提示和后续恢复方式不同,不能都映射成 HTTP 500。

八、用故障场景验证循环控制

测试不能只跑顺利路径。应注入工具连续超时、返回相同结果、交替返回矛盾结果、完成验证器永久失败、模型反复选同一动作等故障。

一个 200 条任务的测试集中,可统计任务完成率、平均步骤、P95 步数、无进展停止率、错误副作用数和人工接管率。若完成率提高 1%,但 P95 从 8 步涨到 40 步,系统可能只是用暴力重试掩盖问题。

九、常见误区与追问

  • 误区:设置最大步数就解决了循环。 它只能止损,不能识别无进展原因或提供恢复路径。
  • 误区:模型输出 done 就代表完成。 必须由业务验证器检查真实状态。
  • 误区:每次工具参数不同就不算重复。 应比较规范化语义和任务状态,而不是原始字符串。
  • 误区:工具失败多重试几次总会成功。 权限和参数错误重试无效,还可能扩大副作用。
  • 误区:超时以后直接从头运行最简单。 已发生的写操作可能被重复执行,需要检查点和幂等。
  • 追问:最大步骤设多少合适? 根据成功任务的步骤分布和业务成本确定,并按任务类型分档。
  • 追问:如何检测模型只是换说法? 对工具、语义参数、结果和状态规范化后生成指纹。
  • 追问:停止后怎样让用户继续? 返回缺失信息和检查点,补齐参数后从安全状态恢复。

十、加强记忆

Agent 循环控制记住“四道闸”:硬预算限制最多走多远,完成验证器证明是否到达,状态指纹与进度指标发现原地打转,分类重试和检查点保证安全退出。模型可以建议行动,但控制器掌握终止权;涉及副作用时,再加幂等键和操作日志,才能既防烧钱又防重复执行。

项目实战落地

项目里怎么做的

《AI Agent智能教务排课与教学质量分析系统》的排课 Agent 一次任务背后是七八十次工具调用,循环控制分两层:

  • 指令里先约束:Agent 指令写明单点检测工具「每节课最多调用一次」,四项最终确认不通过就换下一条候选,候选用完就在最终回复里说明资源不足,「不要用单点检测工具穷举搜索」;
  • 代码里硬拦截:8 个工具的方法入口都先调 beforeToolCall,先算出加上这一次之后的调用次数,总调用超过 MAX_TOOL_CALL_COUNT = 180 次,或连续调用同一个工具超过 MAX_SAME_TOOL_CALL_COUNT = 45 次,就抛业务异常终止本次排课;
  • 拦下之后说人话:提示语直接给出下一步,比如「工具调用超过 180 次仍未完成……请缩小课程/班级范围,或检查模型是否一直在重复调用工具」;任务的 catch 分支把状态改成「执行失败」,原因写进 ai_plan,前端轮询到失败就弹出这段原因。

《AI Agent 智慧医院智能导诊就诊系统》的分诊 Agent 有三道:推理轮数最多 12 轮,工具总调用最多 20 次,同一工具携带完全相同的入参连续 4 次判为空转;判空转时比对入参,症状检索换个词再查不算重复。

《AI 多 Agent 长租公寓智能合租匹配平台》的三个子角色共用一个执行器,循环里两道闸,外面还有一道调度轮次上限,三个上限都在系统参数页可改:

  • 工具调用总数:角色自己配了上限就用角色的(画像师 10、筛选官 20、审核官 30),没配才用系统参数 AGENT_MAX_TOOL_CALL(默认 30);
  • 同一工具连续调用:AGENT_MAX_SAME_TOOL(默认 10),按工具名算,不比入参;
  • 调度轮次:SUPERVISOR_MAX_ROUND(默认 12),主管每一轮先把轮次加一,超了直接收尾。

角色被闸拦下不等于整个任务失败:执行器把「触发了哪道闸」写成一条失败状态的角色结论,顺着回边交回主管,由主管决定换个角色、换个要求,还是收尾。

《AI Agent电商平台导购与运营增长系统》的导购循环只有一道轮数上限:MAX_AGENT_ITERATIONS = 10,一轮是一次模型请求,模型在一轮里并排返回的多个工具调用都会逐个执行。循环在三种情况下结束:模型调用 submit_recommendations 提交推荐、模型不再返回工具调用、跑满 10 轮;工具调用总次数和同一工具的重复调用没有单独限制。

为什么这样取舍

  • 只靠提示词不够:模型可能一直调用 checkClassroomAvailableTool 之类的检测工具停不下来,入口处的计数保证后台不会无限跑下去。
  • 分诊比对入参:症状检索换个词再查是有意义的,换了参数不算空转;连参数都一模一样,才是真的在原地打转。

面试官还会追问

  • 资源查询工具的入参里没有任务 ID,beforeToolCall 怎么知道这次调用属于哪个排课任务?
  • 排课执行中管理员切到别的菜单再切回来,进度卡片是怎么恢复的?为什么不能只看表格里的「执行中」状态?
  • 进度条的百分比是怎么算的?为什么工具调用次数只贡献一小段?

学完《AI Agent智能教务排课与教学质量分析系统》,上面这些追问你都会迎刃而解。

本题落地项目地狱锤炼AI Agent智能教务排课与教学质量分析系统基于 SpringAI Agent、Function Calling 和教务知识库检索,实现教师、班级、课程、教室等资源管理,支持排课规则维护、智能排课、冲突检测、课表发布、教学评价和质量分析,覆盖教务排课与质量管理核心闭环。SpringbootSpringAIAgentFunction CallingRAG源码+SQL喂饭学习教程配套面试文档环境安装文档项目运行文档 学习这个项目 也可以学AI Agent 智慧医院智能导诊就诊系统地狱锤炼 查看项目 也可以学AI 多 Agent 长租公寓智能合租匹配平台地狱锤炼 查看项目 也可以学AI Agent电商平台导购与运营增长系统地狱锤炼 查看项目