Skip to content

Agent 系统中如何设计优雅的终止条件?避免死循环有哪些策略? ​

  • 标签:AI、大模型、Agent

🏛 业务架构师 ​

Agent 的终止条件设计是"防失控"的核心工程,我分四类:

1. 目标达成终止(正常结束):模型判定任务完成、产出最终答案——通过让模型输出显式的完成信号(final answer 或结构化标记),框架据此退出循环。

2. 资源耗尽终止(硬熔断):

  • 最大步数上限(如 10 步);
  • token/费用预算上限(单任务封顶);
  • 总耗时超时;
  • 达到任一阈值强制终止,降级输出"部分结果+失败说明"或转人工。

3. 质量终止(智能收敛):连续 N 步无实质进展(输出相似度检测)、连续相同工具调用(重复指纹检测)、自评分数达标/停滞——识别"空转"提前止损。

4. 人工终止(治理兜底):高危节点暂停等人审批、用户主动取消、运维 kill 开关。

防死循环的组合策略:熔断保底(2 类)+ 空转检测(3 类)+ 反馈显性化(工具报错给可行动信息,减少模型原地打转)+ 幂等设计(即使循环了也不产生重复业务副作用)。

业务视角:终止条件本质是"风险预算"——每类阈值对应企业能承受的最坏情况(最多烧多少钱、最多错多久)。我的做法是把这些参数做成可配置项并按业务分级:内部工具 Agent 步数放宽到 15 步,对外服务收紧到 8 步+强制人审。上线后监控"终止原因分布"——正常完成率低、熔断率高说明任务定义或模型能力有问题,这是比任何指标都直接的改进信号。

🏗 系统架构师 ​

优雅终止条件我按**"正常终止 + 异常熔断 + 治理机制"**三层设计:

正常终止(任务完成信号):

  • 模型输出无工具调用的最终答案(默认信号);
  • 显式完成标记:System Prompt 约定输出 FINAL_ANSWER 结构,终止判断更可靠(不依赖隐式推断);
  • 目标达成校验:有可验证判据(测试通过、答案含必填字段)时由代码验证后终止——比模型自认"完成"可靠。

异常熔断(资源保险丝):最大步数(15~30 步)、token 预算、墙钟时长、循环检测(同 tool+args 连续重复 ≤2 次)、工具失败率阈值(连续 3 次失败停)——任何一个触发即"优雅终止":不是抛异常,而是输出中间结果 + 未完成说明 + 已完成步骤清单,让用户/上游可以续跑或人工接手。

治理机制:

  • Human-in-the-loop:模糊状态(模型反复犹豫、需要权限)转人工裁决;
  • 心跳与超时对齐:长任务定期 checkpoint,外部超时(网关 5 分钟)与内部熔断要协调,避免外部已判死内部还在烧钱;
  • 成本止损:单任务成本告警线 + 硬顶线(达到即停并通知)。

架构心得:终止设计的核心是**"可优雅地不完美"**——宁可带中间结果退出,不可死循环烧钱或粗暴 kill 丢状态。所有终止事件要分类打点(正常/熔断/超时/人工),熔断率高说明任务设计或工具质量有问题,是迭代信号而不是单纯的失败。

💻 全栈开发专家 ​

优雅终止 = 该停时停得住,停得有交代。我设计终止条件分四类:

  1. 目标达成(正常终止):

    • 显式完成信号:给模型一个 task_complete 工具/标记,让它主动宣告完成并交付结果——比「猜它说完了」可靠;
    • 验收判据(DoD):任务定义时写明可校验的完成条件(测试通过、输出符合 schema),运行时程序化检查,通过才准收工。
  2. 资源耗尽(预算终止):

    • 硬上限:max_steps、token 预算、金额预算、墙钟超时;
    • 到顶的动作:返回「部分结果 + 已完成步骤说明 + 未完成原因」,比空手而归或无限拖好得多。
  3. 无进展检测(防死循环):

    • 状态指纹:连续 N 步(工具+参数+结果摘要的 hash)重复即终止;
    • 进度评分器:每步让轻量模型判「是否朝目标推进」,连续低分熔断。
  4. 外部干预:人工中断、上游取消(级联取消子 Agent)、安全策略触发(高危确认被拒 N 次)。

「优雅」的实现要点:

  • 终止时强制产出结构化收尾:当前状态摘要、已完成/未完成清单、交付物指针、(若有)失败根因——让「半成品」也有价值;
  • 终止原因枚举并上报(DONE / BUDGET_EXCEEDED / STUCK / CANCELLED),监控里分类统计——BUDGET 高说明任务定义过大,STUCK 高说明工具或推理有问题;
  • prompt 里预先声明终止规则(「若发现无法完成,立即报告 NEED_HELP 而不是继续尝试」),模型配合度会明显提升。

反模式:只设递归上限当兜底、无任何中间状态保存——超时终止时一切归零,这是用户最差的体验。