Skip to content

高频面试题

Agent 死循环问题有遇到过吗?如何解决?

这题的高分点不是承认“加过 max_steps”,而是能像处理线上事故一样复盘:先看 trace,判断是哪类循环,再分别修工具、状态、终止条件、预算和降级。

适合阶段:Agent 工程 / 生产排障 / Runtime 设计面核心能力:Loop Detection · Trace Debugging · Stop Reason · Tool Error Recovery

面试官角度分析,想考什么

  • 怎么判断是死循环而不是合理多步?
    考进展:同一动作重复、错误不变、state 不推进,而不是 step 多就叫死循环。

  • 除了 max_steps 还有哪些止损手段?
    考 action 去重、no-progress、错误分类、预算和 stop reason。

  • 怎么排查和防止复发?
    考先看 trace 再改 prompt;badcase 进离线 eval 和线上指标。

可直接抄走的 30 秒参考答案

text
遇到 Agent 死循环我会先看 trace,而不是先改 prompt。判断它是不是连续调用同一工具同一参数、拿到同样错误、检索没有新增证据、state 没有变化,或者在计划和 handoff 之间空转。处理上先用 max_steps、timeout、token 和 tool call limit 止损;再加 action signature 去重、state progress 检测、错误分类和 stop reason;最后按原因恢复,比如参数错让模型改,权限错停止或授权,证据不足就说明不确定,缺信息就问用户。修完后把这个 case 放进离线 eval 和线上指标监控。

面试回答详解,知其所以然

这道题最好用“我会怎么排查和修复”来回答。即使没有真实公司案例,也可以讲一套可信的工程 SOP:先识别现象,再分层定位,再补 runtime 防线,最后把 case 进回归集。

1. 什么情况算 Agent 死循环

Agent 是多步系统,多跑几轮不一定是死循环。真正的死循环是:系统消耗了更多模型调用、工具调用或时间,但目标状态没有实质推进。

常见判断信号有:

  • 动作重复:同一个工具、同一组参数连续出现。
  • 错误重复:同一错误码或失败原因被反复触发。
  • 证据重复:搜索、检索、网页读取返回高度相同内容。
  • 状态不变:关键字段、任务 checklist、产物、计划状态没有变化。
  • 计划空转:一直“重新规划”,但没有执行动作或验证结果。
  • 结论摇摆:没有新增证据,却在两个方案之间来回切换。
  • handoff 空转:多个 Agent 互相转交,但没有新增信息。

可以用一句话区别合理多步和死循环:

text
合理多步 = 每轮都让任务状态更接近完成
死循环 = 每轮都消耗预算,但 state diff 基本为空

2. 第一反应:先止损,再定位

线上遇到死循环,第一步不是改 prompt,而是止损:

  • 暂停或取消当前 run。
  • 限制该用户、该工具或该任务类型的最大调用预算。
  • 对有副作用的工具立即切到人工确认。
  • 保留完整 trace,避免日志被后续重试覆盖。
  • 对用户返回可理解状态:已停止、已尝试路径、当前缺什么。

止损后再定位。否则 Agent 一边循环一边烧 token、打外部 API、甚至重复执行副作用操作。

3. 排查要按 trace 分层看

一次 Agent step 至少要能看到这些字段:

text
step_id
state_before
model_input_summary
model_output / tool_call
tool_name
tool_args
tool_result / error_type
state_after
state_diff
stop_reason
token / latency / cost

排查顺序可以这样走:

  • 看 action signaturetool_name + normalized_args + target_resource 是否重复。
  • 看 observation:工具是报错、空结果、重复结果,还是结果被模型误读。
  • 看 state diff:工具返回后 reducer 有没有把关键事实写入状态。
  • 看 prompt 和 memory:上下文里是否有冲突指令、旧错误、重复计划或污染内容。
  • 看 stop checker:是否缺少 need_userpermission_deniedno_progressinsufficient_evidence 等出口。
  • 看预算指标:是否过晚才触发 max_steps,是否应该更早触发成本阈值。

这套排查能避免一句“模型不行”盖过真正问题。

4. 常见死循环类型和修法

  • 工具重试循环:同一工具同一参数反复失败。
    修法:错误分类,确定性错误不重试;记录失败签名;连续命中后换工具、追问用户或停止。
  • 检索循环:不断改写相似 query,但证据没有新增。
    修法:记录 query embedding 或结果 ID;无新增证据后停止,返回已有证据和不确定性。
  • 规划循环:反复生成新计划,不执行也不验证。
    修法:要求计划步骤必须落到可执行 action;限制连续 replan 次数;每次 replan 必须说明新增信息。
  • 状态写回失败循环:工具明明返回成功,但 Agent 下一轮像没见过一样。
    修法:检查 reducer,把关键事实写入结构化 state,而不是只 append 到 messages。
  • 权限循环:403、401、审批未通过还一直尝试。
    修法:权限失败设为不可重试,直接进入 need_authpermission_deniedrequires_approval
  • 分页循环:反复拉同一页或 cursor 不变。
    修法:记录 cursor、page token、seen ids;cursor 不变或 has_more=false 立即停止分页。
  • 修复循环:代码 Agent 反复改同一类错误,测试失败类型没变化。
    修法:记录失败类别和 diff;连续同类失败后要求总结假设、缩小改动或请求人工。
  • 多 Agent handoff 循环:A 转给 B,B 又转回 A。
    修法:orchestrator 记录 handoff 路径,限制连续转交,并要求每次转交携带新增证据或明确阻塞原因。

5. 解决策略要分三层

第一层是硬保护,防止无限损失:

  • max_steps
  • timeout
  • token / cost budget
  • max total tool calls
  • max calls per tool
  • 高风险工具执行次数上限

第二层是进展检测,让系统更早识别空转:

  • action signature 去重
  • normalized args 比较
  • state diff 检查
  • evidence id / seen ids 去重
  • error_type 连续计数
  • replan 次数限制
  • handoff path 检测

第三层是恢复策略,让 Agent 知道停下来后该怎么办:

  • 可重试错误:指数退避、换参数、换工具。
  • 不可重试错误:明确停止并解释原因。
  • 缺少信息:向用户追问,不继续猜。
  • 无权限:走授权、审批或拒绝。
  • 证据不足:返回当前结论和不确定性。
  • 无进展:总结已尝试路径,转人工或交付部分结果。

6. 修复后要进评估和监控

死循环不是修一次 prompt 就结束。要把这次 badcase 变成可回归的测试:

  • 保存原始用户输入、工具 mock、关键 observation 和期望 stop reason。
  • 离线 eval 检查是否在 N 步内停止。
  • 指标监控 max_steps_reachedrepeated_action_blocked、平均 step、P95 step、重复工具率、无进展停止率。
  • 对高风险工具单独监控重复调用和失败后重试。
  • 每次修改工具描述、prompt、模型或路由策略后跑回归。

一个成熟回答要强调:死循环修复的目标不是“让它永远多跑几步”,而是让它在该继续时继续、该停时带着原因停。

面试官追问3个问题

追问一:怎么区分死循环和复杂任务本来就需要很多步?

  • 考察点:是否用“进展”而不是“轮数”判断。
  • 回答方向:看每轮是否产生新的目标相关状态:新增证据、新文件、新测试结果、新决策、待办减少、风险降低。如果 step 多但 state 一直推进,是合理多步;如果 step 少但重复同一动作且 state 不变,也是循环。

追问二:工具返回 200 但 Agent 还在循环,怎么排查?

  • 考察点:是否区分技术成功和业务成功。
  • 回答方向:检查返回内容是否为空、重复、业务失败或缺关键字段;检查 reducer 是否把结果写入 state;检查模型是否能看到关键 observation。HTTP 200 只是调用成功,不代表任务推进。

追问三:重复调用检测会不会误杀正常重试?

  • 考察点:是否理解重试和重复的差异。
  • 回答方向:会,所以要结合错误类型、参数变化、退避策略和状态变化。瞬时 5xx 可以有限重试;参数错误、权限错误和业务规则拒绝不应重试。重复检测触发后也可以先让模型换策略,而不是一律失败。

扩展知识

max_steps 为什么不是完整答案

max_steps 只回答“最多跑几轮”,不回答“为什么还在跑”。它像保险丝,能避免无限损失,但不能证明任务正常完成,也不能定位根因。

更完整的停止检查应该是:

text
每轮结束后检查:
  success checklist 是否满足
  是否缺少用户输入
  是否权限或审批阻断
  action signature 是否重复
  state diff 是否为空
  evidence 是否新增
  错误类型是否连续重复
  预算是否接近上限

action signature 怎么设计

不要直接比较原始 JSON 字符串,因为字段顺序、空格和同义参数可能不同。更稳的是做归一化:

text
signature = hash(
  tool_name
  + normalized_required_args
  + target_resource_id
  + operation_type
)

比如分页工具要把 cursor、page token 和 seen ids 放进签名;文件编辑工具要把文件路径和 patch 摘要放进签名;搜索工具可以把 query 归一化后再结合 top result ids。

stop reason 要能服务用户和工程

推荐不要只返回 failed。更好的 stop reason 包括:

  • success
  • need_user
  • permission_denied
  • requires_approval
  • insufficient_evidence
  • tool_unavailable
  • repeated_action_blocked
  • no_progress
  • max_steps_reached
  • timeout
  • budget_exhausted
  • handoff_loop_blocked

这些状态既能告诉用户发生了什么,也能进入监控和离线评估。

基于 MIT 协议开源