Agent工具调用中无限重试死循环的根因与修复

Agent 工具调用中"无限重试死循环"的根因与修复------技术复盘

问题现象

Agent 在执行任务时,调用某个工具后进入死循环------不断以相同或微调参数重试同一个工具调用,每次返回相似结果但仍继续重试,Token 快速消耗,任务卡死无法推进。

典型日志:

[Turn 3] tool_call: search_database(query="用户订单") [Turn 4] tool_call: search_database(query="用户订单 2026") [Turn 5] tool_call: search_database(query="用户订单 2026年") [Turn 6] tool_call: search_database(query="用户 订单 2026 年") ...直到 context window 耗尽

排查过程

  1. 检查工具返回内容:工具返回了 {"error": "no results found", "hint": "try different keywords"},这个 hint 本身就是诱因------它在引导 Agent 换关键词重试。
  2. 检查 Agent 的 System Prompt:Prompt 中写了"如果工具返回错误,请分析原因并重试",但没有给重试次数上限。
  3. 检查工具实现:工具在无结果时返回 HTTP 200 + 错误描述,而不是返回空数组 \[\]。Agent 无法区分"真的没数据"和"查询方式有问题"。
  4. 统计同类问题:发现 24% 的失败任务都有类似的重试模式,平均浪费 8-12 轮对话。

根因分析

三重原因叠加:

层面 问题
工具层 错误返回格式不标准,hint 字段诱导 LLM 继续尝试
Prompt 层 没有最大重试次数约束,没有"空结果即停止"的规则
编排层 缺少工具级 circuit breaker,没有重试计数和熔断机制

核心矛盾:LLM 天然倾向于"再试一次可能就行了",而工具的错误信息恰好给了它这个理由。

解决方案

Layer 1:工具返回规范化

`python

错误时返回明确的 STOP 信号,不包含诱导性 hint

def tool_response(status, data=None, error=None):

return {

"status": "empty" if not data else "ok",

"data": data or \[\],

"total": len(data) if data else 0

}

❌ 不再返回 {"error": "no results", "hint": "try different keywords"}

`

Layer 2:Prompt 硬约束

在 System Prompt 中加入:

`

工具调用规则:

  1. 同一工具同一参数最多重试 2 次,超过则报告用户而非继续尝试
  2. 收到空结果(data=\[\]且total=0)立即停止,换策略而非换参数
  3. 单个任务工具调用总次数不超过 20 轮
    `

Layer 3:编排层熔断器

`python

class ToolCircuitBreaker:

def init (self, max_retries=3, window_turns=5):

self.max_retries = max_retries

self.window_turns = window_turns

self.call_history = \[\]

复制代码
def check(self, tool_name, params_hash):
    recent = [c for c in self.call_history[-self.window_turns:]
              if c['tool'] == tool_name and c['params_hash'] == params_hash]
    if len(recent) >= self.max_retries:
        return False, "检测到重复调用,已自动跳过,请报告用户或更换策略"
    return True, None

`

复盘总结

维度 教训
设计原则 工具的错误信息要"终结歧义"而非"产生歧义"。模糊的 hint 是毒药
防御性编程 永远不要信任 LLM 会自己停下来。重试上限必须写在 Prompt + 代码两层
监控意识 应该对工具调用轮次设置告警(单任务 > 20 轮 → 人工介入)
可迁移性 这个模式同样适用于 API 调用、数据库查询、文件操作等所有工具

一句话总结:让工具说清楚"为什么停"比告诉 Agent "怎么继续"更重要。Prompt 是柔性约束,代码是刚性约束,两层都要做。


#Agent #技术复盘 #AI工程 #工具调用 #死循环调试

相关推荐
像风一样自由20203 小时前
23.OCR在知识库中的作用扫描件和图片文字如何进入RAG
postgresql·大模型·ocr·rag
武子康3 小时前
商业比较词进入 AI Overview:Semrush 60 万关键词研究能说明什么
人工智能·ai·架构·agent·claude·codex·semrush
ToTensor3 小时前
DataGen——合成数据生成器:把一句任务描述变成可校验的训练数据
langchain·agent
冬奇Lab3 小时前
Code Agent 解剖(23):从零扩展——接入 MCP 外部工具生态
人工智能·agent
不是株4 小时前
AI Agent 记忆系统全解:从 Markdown、SQLite、向量检索到 GraphRAG
sqlite·知识图谱·agent·memory·graphrag·harness
用户8082598666876 小时前
从零手写 ReAct Agent:不用任何框架,200 行代码跑通 Agent 核心循环
agent
明月_清风6 小时前
AI 时代,为什么架构师又开始谈"本体论"?
人工智能·后端·agent
lifallen7 小时前
短暂 Agent 与持久化工程:让理解脱离对话
人工智能·学习·ai·重构·ai编程
阿里云大数据AI技术7 小时前
闲鱼「鱼卖卖」的长期记忆实践:用阿里云 Milvus 记住卖家的经营偏好
人工智能·agent
ch8568 小时前
别再让 RAG 翻车在「入库」这一步!1200 行保姆级离线入库全流程(PDF → 可检索)
agent