Skip to content

12. 在 AI 智能体项目中,你如何解决 Agent Loop 可能出现的死循环问题? ​

难度 P1 高频 · 岗位 应用 · 频率 ★★★ · 预计阅读 17 min

本题阅读地图 ​

  1. 💡 简要回答
  2. 📝 详细解析
  3. 🎯 面试总结

👔面试官:Agent 执行过程中可能出现死循环,你怎么解决?

🙋‍♂️我:设置一个最大步数限制,超过就停止。

👔面试官:最大步数是最后的兜底手段。怎么在早期就检测到循环?怎么区分「正常多步执行」和「死循环」?

🙋‍♂️我:……可能看看是否一直在重复同样的动作?

死循环是 Agent 系统的经典问题,下面把完整的防护机制讲清楚。

💡 简要回答 ​

Agent Loop 死循环的防护分三层:

  1. 预防层:工具描述精确化,减少模型选错工具的概率
  2. 检测层:重复动作检测、状态哈希比对、无进展检测
  3. 兜底层:最大步数限制、超时控制

📝 详细解析 ​

死循环的典型场景 ​

场景1 - 工具选择错误:
模型想查天气,但调用了计算器工具 → 返回错误 → 模型再试 → 还是错 → 循环

场景2 - 参数错误:
模型调用搜索,query 参数为空 → 返回无结果 → 模型再搜 → 还是空 → 循环

场景3 - 循环依赖:
Step1: 搜索「A 公司的 CEO」→ 得到「张三"
Step2: 搜索「张三的公司」→ 得到「A 公司"
Step3: 再次搜索「A 公司的 CEO」→ 死循环

场景4 - 目标模糊:
用户说「帮我整理一下资料」→ 模型不知道具体要做什么 → 反复尝试不同工具

防护机制实现 ​

1. 最大步数限制(最后的兜底)

java
public class SafeAgentExecutor {
    private static final int MAX_STEPS = 15;

    public ExecutionResult execute(Task task) {
        for (int step = 0; step < MAX_STEPS; step++) {
            StepResult result = executeStep(task);
            if (result.isComplete()) {
                return ExecutionResult.success(result.getOutput());
            }
        }
        return ExecutionResult.failure("达到最大步数限制");
    }
}

2. 重复动作检测

java
public class LoopDetector {
    private final Set<String> executedActions = new HashSet<>();
    private final List<String> actionHistory = new ArrayList<>();

    public boolean isLooping(String action) {
        String actionHash = hashAction(action);

        // 检测完全重复的动作
        if (executedActions.contains(actionHash)) {
            return true;
        }

        // 检测循环模式(A→B→A→B)
        actionHistory.add(action);
        if (actionHistory.size() >= 4) {
            String last4 = String.join("->",
                actionHistory.subList(actionHistory.size() - 4, actionHistory.size()));
            if (last4.matches("(.+)->(.+)->\\1->\\2")) {
                return true;  // 检测到 A→B→A→B 模式
            }
        }

        executedActions.add(actionHash);
        return false;
    }
}

3. 无进展检测

java
public class ProgressTracker {
    private String lastObservation = "";
    private int noProgressCount = 0;

    public boolean hasProgress(String newObservation) {
        // 对比本次和上次观察结果,看是否有新信息
        double similarity = calculateSimilarity(lastObservation, newObservation);

        if (similarity > 0.9) {  // 相似度超过 90%,认为无进展
            noProgressCount++;
            if (noProgressCount >= 3) {
                return false;  // 连续 3 步无进展
            }
        } else {
            noProgressCount = 0;  // 有进展,重置计数
        }

        lastObservation = newObservation;
        return true;
    }
}

4. 目标偏离检测

java
public class GoalDriftDetector {
    private final String originalGoal;
    private final ChatClient chatClient;

    public boolean isOnTrack(String currentThought) {
        String prompt = """
            原始目标:%s
            当前思考:%s

            请判断当前思考是否偏离了原始目标。
            只回答"是"或"否":
            """.formatted(originalGoal, currentThought);

        String result = chatClient.prompt(prompt).call().content().trim();
        return result.contains("否");  // 返回 true 表示未偏离
    }
}

5. 工具描述的精确化(预防)

java
// ❌ 差的描述
@Tool(description = "查询数据")
public String query(String keyword) { ... }

// ✅ 好的描述
@Tool(description = """
    搜索互联网信息。
    使用场景:需要获取实时信息、新闻、百科知识时。
    参数 keyword: 搜索关键词,不能为空。
    注意:不要用于查询本地数据库内容。
    """)
public String searchWeb(@ToolParam(description = "搜索关键词,2-10个字") String keyword) { ... }

完整的 Safe Agent Loop ​

java
@Component
public class SafeAgentExecutor {
    private static final int MAX_STEPS = 15;
    private static final int MAX_TIME_SECONDS = 60;

    @Autowired private LoopDetector loopDetector;
    @Autowired private ProgressTracker progressTracker;
    @Autowired private GoalDriftDetector goalDriftDetector;

    public ExecutionResult safeExecute(Task task) {
        long startTime = System.currentTimeMillis();

        for (int step = 0; step < MAX_STEPS; step++) {
            // 1. 超时检查
            if (System.currentTimeMillis() - startTime > MAX_TIME_SECONDS * 1000) {
                return ExecutionResult.failure("执行超时");
            }

            // 2. 获取模型决策
            AgentDecision decision = getDecision(task);

            // 3. 重复动作检查
            if (loopDetector.isLooping(decision.getAction())) {
                return ExecutionResult.failure("检测到循环执行");
            }

            // 4. 目标偏离检查
            if (!goalDriftDetector.isOnTrack(decision.getThought())) {
                return ExecutionResult.failure("执行偏离目标");
            }

            // 5. 执行动作
            String observation = executeAction(decision.getAction());

            // 6. 进展检查
            if (!progressTracker.hasProgress(observation)) {
                return ExecutionResult.failure("执行无进展");
            }

            // 7. 完成检查
            if (isComplete(observation)) {
                return ExecutionResult.success(observation);
            }
        }

        return ExecutionResult.failure("达到最大步数限制");
    }
}

用户友好的退出策略 ​

当检测到死循环时,不应该直接报错,而是:

java
public ExecutionResult handleFailure(String reason, Task task) {
    // 1. 记录失败原因
    log.warn("Agent 执行异常: {}, 任务: {}", reason, task.getId());

    // 2. 尝试降级处理
    if (canFallback(task)) {
        return executeFallback(task);  // 切换到简单策略重试
    }

    // 3. 返回已收集的部分结果
    String partialResult = progressTracker.getCollectedInfo();

    return ExecutionResult.partialSuccess(partialResult,
        "执行过程中遇到" + reason + ",以下是已收集的信息:");
}

🎯 面试总结 ​

Agent 死循环防护的三层体系:

预防层:

  • 工具描述精确化,减少模型误选
  • Prompt 中明确禁止重复调用

检测层:

  • 重复动作检测(哈希比对)
  • 循环模式检测(A→B→A→B)
  • 无进展检测(Observation 相似度)
  • 目标偏离检测(LLM 判断)

兜底层:

  • 最大步数限制(15-20 步)
  • 超时控制(60 秒)

面试时要能说出 至少三种检测机制(重复、无进展、循环模式)和 优雅的退出策略(降级处理、返回部分结果)。



章节首页 · ← Q11 · Q13 →

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