Agent 架构中如何避免“无限循环”问题?
在 Agent(智能体)架构中,“无限循环”通常表现为 Agent 重复执行相同的动作、陷入思维死胡同、或者在两个步骤之间反复横跳。这不仅浪费 Token 成本,还会导致任务失败。
要解决这个问题,需要从系统工程(System Engineering)、提示词工程(Prompt Engineering)和模型策略(Model Strategy)三个层面构建多重防御机制。
以下是具体的解决方案:
1. 系统层面的硬限制(Hard Constraints)
这是最基础的“熔断机制”,用于防止失控。
- 最大迭代次数(Max Iterations/Steps):
- 设定一个 Agent 执行任务的最大步数(例如 10 步或 20 步)。一旦达到限制,强制停止并返回当前的最佳结果或错误信息。
- 代码逻辑示例:
if step_count > MAX_STEPS: return "Task failed due to iteration limit."
- 超时机制(Timeouts):
- 设定整个任务的执行时间上限。
- Token 消耗上限:
- 防止 Agent 在循环中消耗过多的 API 预算。
2. 状态监测与循环检测(State Monitoring)
让系统“意识到”自己正在重复。
- 历史动作去重(Action Deduplication):
- 维护一个
history_hash列表。在 Agent 决定采取行动前,检查该行动(工具名称 + 参数)是否在最近 N 步内完全一致。 - 如果发现重复,系统可以拦截该请求,并向 Agent 注入一条系统提示:“你刚才已经尝试过这个动作了,请尝试不同的方法。”
- 维护一个
- 观察结果检测:
- 如果 Agent 调用工具后的返回结果(Observation)与上一次完全相同,且 Agent 的思考(Thought)也相似,说明陷入了死循环。
- 策略: 强制修改 Prompt,提示 Agent “之前的操作无效,必须改变策略”。
3. 提示词工程与认知引导(Prompt Engineering)
通过优化指令,让 LLM 具备更好的规划能力和自我纠错能力。
- 明确的“完成”定义(Definition of Done):
- 在 System Prompt 中明确告知 Agent 何时应该停止。
- 示例: “当你获得最终答案时,必须调用
finish工具,而不是继续思考。”
- 思维链约束(Chain of Thought Constraints):
- 要求 Agent 在行动前进行反思。
- Prompt 示例: “在采取行动前,请回顾之前的步骤。如果你发现自己正在重复之前的尝试,请停止并换一种思路。”
- 负向约束(Negative Constraints):
- 明确列出禁止的行为。
- 示例: “如果搜索结果为空,不要使用相同的关键词再次搜索。”
4. 架构设计模式(Architectural Patterns)
通过引入外部监督者或改变架构来打破循环。
- Supervisor / Critic 模式(监督者/批评家):
- 引入第二个 Agent(或 LLM 调用)作为“监督者”。它不执行任务,只负责观察“执行者 Agent”的轨迹。
- 如果监督者发现执行者在兜圈子,它会介入并给出指令:“你陷入了循环,请跳过当前步骤,直接尝试方案 B。”
- 动态参数调整(Dynamic Temperature):
- 当检测到潜在的循环(例如连续输出相似内容的概率很高)时,动态提高 LLM 的
temperature(温度值)。 - 提高随机性可以帮助模型跳出当前的概率局部最优解,尝试新的路径。
- 当检测到潜在的循环(例如连续输出相似内容的概率很高)时,动态提高 LLM 的
- 人类介入(Human-in-the-loop):
- 在关键步骤或检测到疑似循环时,暂停执行并请求人类确认下一步操作。
5. 工具与环境反馈优化
有时候循环是因为工具报错或反馈信息不明确导致的。
- 丰富的错误信息:
- 如果工具调用失败,不要只返回
Error。返回具体的错误原因,帮助 Agent 理解为什么失败,从而避免盲目重试。
- 如果工具调用失败,不要只返回
- 环境状态变化强制性:
- 设计工具时,确保成功的操作会改变环境状态。Agent 通过读取状态变化来感知进度。如果状态未变,Agent 容易认为操作未执行而重复提交。
总结:一个健壮的防循环流程
在实际开发中(如使用 LangChain 或 AutoGen),通常采用组合策略:
- 设置
max_iterations=15(硬底线)。 - 记录
agent_scratchpad(思维暂存区)。 - 在每次 Loop 开始前运行一个轻量级检测函数:python
def check_loop(history, current_action): if current_action in history[-3:]: # 检查最近3步是否有相同动作 return True return False - 如果检测到循环:
- 方案 A: 向 Agent 发送观察结果:“系统警告:检测到重复动作。请立即改变策略或终止任务。”
- 方案 B: 临时提高 Temperature 重试。
- 方案 C: 强制结束。
通过这种多层防御,可以极大程度地减少 Agent 变“傻”的情况。