在 AI 超级智能体项目中,你如何解决 Agent Loop 可能出现的死循环问题?
超级智能体往往步数多、工具广、链路长——ReAct / Plan-Execute 一旦缺少终止与检测,就会出现 反复同一工具调用、空转推理、错误重试不退出。本篇讲分层治理的面试答法;循环模型见 Agent 核心概念与架构;LangGraph 硬上限见 [LangGraph 编排实践](/docs/ai/Agent/LangGraph 编排实践);OpenManus 软检测见 [OpenManus 概览与实现原理](/docs/ai/Agent/面试/OpenManus 概览与实现原理)。
死循环长什么样
| 类型 | 表现 | 常见原因 |
|---|---|---|
| 同调用重复 | 连续 N 次 search(x) 或 read_file(a) 参数不变 | 工具报错未理解、检索结果空 |
| 同错重试 | 422/404 仍用相同 args 再调 | 无错误分类,Prompt 未要求改参 |
| 空转推理 | assistant 反复输出相似「我再想想」无 tool | 目标含糊、无 Terminate、无步数上限 |
| 工具↔工具 ping-pong | A→B→A→B,任务无进展 | 多 Agent 互委派无全局状态 |
| 规划层死循环 | Plan 某步永远 in_progress | Flow 未 mark 完成、无 step 超时 |
面试先一句话:硬终止保底 + 重复检测 + 错误分类 + 降级出口,四层叠加,不能只靠 Prompt 写「别重复」。
治理总图(纵深防御)
第 1 层:硬终止(必须有)
max_steps / 墙钟 timeout / recursion_limit / token&成本预算
第 2 层:重复与无效检测
相同 tool+args、相同 assistant 文本、连续失败次数
第 3 层:恢复策略
反思 prompt、换工具/改参、缩 scope、跳步
第 4 层:人工与产品出口
人审 interrupt、AskHuman、转人工、返回部分结果 + 说明
第 1 层:硬终止(保底)
| 手段 | 作用 | 落地 |
|---|---|---|
| max_steps | 限制 ReAct 轮数 | 手写 for step in range(max_steps);见 Agent 最小可运行项目 |
| 墙钟 timeout | 防单步工具卡死拖垮整链 | 每 tool call + 整任务 deadline |
| recursion_limit | 防图编排边写错无限跳 | LangGraph invoke(..., {"recursion_limit": N}) |
| token / 成本上限 | 超级 Agent 空转烧钱 | 超预算强制 FINISHED;见 Token 计算与成本 |
| Terminate 工具 | 模型显式结束 | OpenManus Terminate → AgentState.FINISHED |
原则: 硬终止优先于「模型自觉停」——PoC 也要设,生产更要设。
# 最小 loop 硬终止(示意)
for step in range(max_steps):
if time.monotonic() - t0 > wall_clock_sec:
return degrade("超时,已保存部分进度")
decision = await agent.step()
if agent.state == FINISHED:
return decision
return degrade("达到最大步数")
LangGraph 中 业务 max_steps(state 计数)与 recursion_limit(运行时图跳转上限)并用——见 [LangGraph 编排实践](/docs/ai/Agent/LangGraph 编排实践)。
第 2 层:重复与无效检测
同 tool + 同 args
对轨迹维护 (tool_name, canonical_args) 指纹,滑动窗口内重复 ≥ k 次 → 触发 stuck 处理。
def fingerprint(tool: str, args: dict) -> tuple:
return (tool, json.dumps(args, sort_keys=True))
def is_repeat_loop(history: list, k: int = 3) -> bool:
if len(history) < k:
return False
tail = [fingerprint(h["tool"], h["args"]) for h in history[-k:]]
return len(set(tail)) == 1
同 assistant 文本(OpenManus 思路)
is_stuck():最近 assistant 消息与更早 assistant 内容完全相同 ≥ 阈值 → 往 next_step_prompt 注入「换策略,勿重复无效路径」。见 [OpenManus 概览与实现原理](/docs/ai/Agent/面试/OpenManus 概览与实现原理)。
连续失败计数
同一工具连续失败 m 次(尤其 4xx 参数错)→ 停止重试,进入反思或降级,而非无限 loop。
无进展检测(超级 Agent 常用)
| 信号 | 判定 |
|---|---|
| 步数增但任务 checklist 无新完成项 | 规划层 stuck |
| 检索/搜索 query 哈希不变 | 检索 loop |
| 工作区文件 hash 不变却反复 edit | 编辑 loop |
第 3 层:恢复策略
检测到 stuck 后,不要只加一句「请停止」——要给可执行出路:
| 策略 | 做法 |
|---|---|
| Reflection | 把最近失败摘要写入 Prompt:「已失败 3 次,原因 X,请换 Y」 |
| 改参 / 换工具 | 422 → 改 schema 字段;search 空 → 换关键词或换数据源 |
| 缩 scope | 「先完成子目标 A,其余标注 blocked」 |
| 跳步 | PlanningFlow 中 mark step blocked,执行下一步或 finalize |
| 重置子上下文 | 清空无关 tool 观察,减噪声(注意别丢关键 state) |
错误分类重试(与 Agent 系统高频题 一致):
- Timeout / 5xx:有限重试 + 退避
- 4xx 参数错:不重试同 args,要求 LLM 改参
- 权限 / 404 真不存在:终止该路径,换方案或拒答
第 4 层:人工与产品出口
超级智能体必须设计「出不去时怎么办」:
| 出口 | 场景 |
|---|---|
| AskHuman | 缺信息、歧义、需确认 |
| interrupt_before 人审 | LangGraph 在危险 tool 前暂停 |
| 转人工 | 超步数 / 超时的 graceful degrade |
| 部分结果 + 说明 | 交付已完成的子任务与 blocked 原因 |
比静默失败或无限 spin 更符合 FDE 交付预期——见 FDE 交付闭环实践。
超级智能体项目的额外注意
| 点 | 说明 |
|---|---|
| 多 Agent | 全局 orchestrator 也要 max_steps;子 Agent 不能各自无限 loop |
| 长时任务 | 用 checkpointer 分段续跑,每段独立步数/超时 |
| 工具面大 | 重复调错工具 = 另一种 loop;轨迹日志 + 离线评「无效调用率」 |
| MCP / 浏览器 | 外部工具 RT 长,墙钟 timeout 比步数更重要 |
| 可观测 | trace 标 stuck_detected、forced_terminate_reason |
怎么验证「治住了」
离线评测集加 loop 用例:
{"id": "loop-search", "input": "查不存在的 SKU-XXX", "max_steps": 8, "expect_no_repeat_tool": 3}
{"id": "loop-timeout", "mock_tool": "always_timeout", "expect": "degrade_not_hang"}
指标:触顶 max_steps 比例、同 tool 重复率、平均步数 P95、强杀率——纳入 [AI 应用测试与效果评估](/docs/ai/Agent/面试/AI 应用测试与效果评估)。
常见坑
| 坑 | 说明 |
|---|---|
| 只写 Prompt「不要死循环」 | 无硬上限仍可能空转几十步 |
| 只有 max_steps 无重复检测 | 8 步内反复 8 次同样坏调用 |
| 检测到了不恢复 | 需 reflection / 换策略 / 降级 |
| 子 Agent 无全局预算 | 总成本与步数失控 |
| 强杀无用户反馈 | 用户以为「还在跑」 |
面试参考答法(60~90 秒)
超级 Agent 的 loop 我会做四层防御。
第一层硬终止:max_steps、整任务墙钟 timeout、LangGraph recursion_limit,再加 token/成本预算,Terminate 工具让模型能主动停。
第二层检测:轨迹里看相同 tool+args 是否连调、assistant 是否复读、同一错误是否连犯——OpenManus 的 is_stuck 就是 assistant 重复检测的典型。
第三层恢复:触发 stuck 后注入反思 Prompt,4xx 改参、5xx 有限重试,Planning 场景可 mark blocked 换步,而不是继续原路径。
第四层出口:AskHuman、人审 interrupt、超步转人工或返回部分结果。上线用 trace 和评测集专门测 loop case,看重复调用率和触顶步数比例。
延伸阅读
| 篇 | 关系 |
|---|---|
| Agent 系统高频题 | 规划失败与重试速答 |
| 工具调用与评测实践 | 轨迹 JSONL、失败重试 |
| [LangGraph 编排实践](/docs/ai/Agent/LangGraph 编排实践) | recursion_limit、interrupt |
| [OpenManus 概览与实现原理](/docs/ai/Agent/面试/OpenManus 概览与实现原理) | is_stuck 软检测 |
面试速记
- 四类 loop: 同调用重复、同错重试、空转推理、多 Agent ping-pong。
- 四层防御: 硬终止 → 重复检测 → 恢复策略 → 人工/降级出口。
- 硬终止必备: max_steps + 墙钟 timeout +(LangGraph)recursion_limit + 成本预算。
- 软检测: 同 tool+args、assistant 复读、连续失败、任务 checklist 无进展。
- 恢复: 反思、改参换工具、缩 scope、blocked 跳步;评测集要有 loop case。