Skip to content

51. 如何设计 Agent 的完成判断与终止条件,避免过早结束? ​

难度 P0 必背 · 岗位 应用 · 频率 ★★★ · 预计阅读 5 min

👔面试官:如何设计 Agent 的完成判断与终止条件,避免过早结束?

🙋‍♂️我:设最大步数,到了就停。

👔面试官:太粗暴。要分四层:任务层(目标达成?)、工具层(关键调用成功?)、状态层(进入终态?)、保护层(最大步数/超时)。而且不能只看完成率,要看关键结果和状态字段。你能展开吗?

TL;DR 速记 ​

  • 是什么:Agent 终止条件要同时看任务产物、工具结果、状态机终态和保护阈值。
  • 关键点:不能只让模型说“完成了”,也不能只靠最大步数粗暴停止。
  • 怎么答:关键结果 + 关键工具成功 + 状态满足,才进入最终答复;否则继续、失败兜底或转人工。

图解 ​

💡 简要回答 ​

四层终止逻辑:

层级判断条件
任务层是否达成用户目标,是否拿到必须产物
工具层关键工具调用是否成功,结果是否满足预期
状态层是否进入 done/failed/need_human 终态
保护层最大步数、超时、重复无进展次数

关键:关键任务结果 + 工具返回 + 状态机条件 都满足,才允许进入最终答复。否则宁可继续或转人工。

常见踩坑与反例 ​

踩坑 1:只靠最大步数终止 ​

错误描述:「设置最多 5 步,到了就结束。」

正确做法:最大步数只是保护层,不是完成判断。真正终止要看用户目标、必要产物、关键工具结果和状态机终态。

踩坑 2:模型说完成就完成 ​

错误描述:模型输出“任务已完成”,系统就直接返回。

正确做法:把完成条件结构化,比如订单号、报告文件、检索证据、审批状态等字段必须存在并校验通过。

踩坑 3:工具失败后仍给最终答案 ​

错误描述:关键 API 调用失败,但 Agent 编一个答案结束。

正确做法:关键工具失败应进入重试、降级、失败终态或转人工,不能伪造结果。

踩坑 4:无法识别“无进展循环” ​

错误描述:Agent 每轮都在改写同一个查询,却没有新结果。

正确做法:记录重复动作、空结果次数、状态变化幅度;连续无进展时停止并转人工或返回可解释失败。

面试官可能继续追问 ​

  • 追问 1:完成条件怎么结构化? 答题要点:把目标拆成必需字段和校验函数,例如 status=done、artifact_url 存在、关键工具返回成功、结果通过质量检查。

  • 追问 2:最大步数应该怎么设? 答题要点:按任务类型和工具成本设置,不同路径不同阈值;同时设置超时、费用预算和连续失败次数。

  • 追问 3:过早结束怎么发现? 答题要点:回放 trace,看是否缺少关键工具调用、关键字段为空、状态没进终态;用验收用例覆盖边界场景。

  • 追问 4:失败时应该怎么回复用户? 答题要点:明确说明已完成哪些步骤、卡在哪个依赖、是否已重试,给出下一步选择,如补充信息、稍后重试或转人工。

📝 详细解析 ​

四层终止条件的实现细节 ​

任务层(Task Layer):把用户目标结构化为可校验的「完成条件」,而不是让模型主观判断:

python
# 错误方式:让模型说 "完成了" 就停止
# 正确方式:检查具体字段
def is_task_complete(state):
    return (
        state.get("report_url") is not None and  # 必须产物存在
        state.get("summary") and len(state["summary"]) > 50 and  # 摘要非空
        state.get("citations") and len(state["citations"]) >= 3  # 有引用来源
    )

工具层(Tool Layer):关键工具调用必须成功,失败时不能「绕过」:

  • 关键工具失败 → 重试(指数退避)→ 降级方案 → 失败终态,不伪造结果

状态层(State Layer):使用明确的状态机,定义终态集合:

  • in_progress:正在执行
  • done:成功完成
  • failed:失败,已记录原因
  • need_human:需要人工介入

保护层(Guard Layer):兜底约束,防止无限循环:

  • 最大步数(如 20 步)
  • 最大运行时间(如 5 分钟)
  • 连续无进展步数(如 3 步没有新的工具调用或状态变化,触发停止)
  • Token/Cost 预算

无进展循环的识别 ​

python
def detect_no_progress(history, window=3):
    recent = history[-window:]
    tool_calls = [step.get("tool") for step in recent]
    return len(set(tool_calls)) == 1  # 连续调用同一工具,可能陷入循环

🎯 面试总结 ​

四层判断,不能只看完成率。关键结果 + 工具成功 + 状态满足,才终止。


章节首页 · ← Q50 · Q52 →

最后更新2026-05-01
难度P0
频率medium
阅读5 min
主题agent
觉得有帮助?把这个链接转给正在求职的朋友 · 用 Ctrl + K 全站搜索其它题