芥末
发布于 2026-06-16 / 1 阅读
0
0

Agent Loop 工程化:让 AI Agent 自主执行又能及时停下

AI Agent 和普通聊天机器人的关键区别,不是模型参数更大,也不是提示词写得更长,而是它背后有一个能持续运行的循环。

普通聊天机器人通常是“一问一答”:用户给一段输入,大语言模型(Large Language Model,LLM)生成一段输出,然后流程结束。AI Agent 则不同,它会在多轮迭代中观察环境、分析当前状态、选择工具、执行动作、读取结果,再决定下一步怎么做。

这个循环就是 Agent Loop。

一个可靠的 Agent Loop 不能只是:

while True:
    call_llm()

这只是无限调用模型,既不会判断目标是否完成,也不会控制成本,更无法处理工具失败、重复尝试、上下文膨胀等问题。生产级 Agent Loop 至少要具备四个能力:

能力 作用
状态管理 把任务进展、工具结果、重要事实传到下一轮
行动选择 让 LLM 根据上下文决定下一步动作,而不是硬编码固定流程
观察反馈 工具执行结果会改变后续推理路径
终止条件 在目标完成、预算耗尽、陷入重复或达到上限时停止

可以把 LLM 看成“大脑”,把 Agent Loop 看成“心跳”。心跳让系统持续感知和行动,但它必须有节律控制、异常处理和停止机制,否则 Agent 会在错误路径上越跑越远。

Agent Loop 解决什么问题

复杂任务很难靠一次模型调用完成。比如“调研三个竞品并生成对比报告”,里面至少包含搜索资料、筛选信息、提取特征、比较差异、组织结构、生成文档等步骤。单次推理只能给出一个静态答案,无法根据中间结果继续决策。

Agent Loop 让任务从“一次性生成”变成“分步推进”。

flowchart LR
    U[用户目标] --> L[Agent Loop]
    L --> T1[拆解任务]
    T1 --> T2[调用工具]
    T2 --> T3[读取结果]
    T3 --> T4[调整策略]
    T4 --> L
    L --> R[最终结果]

它主要解决三类问题。

问题 没有 Loop 的表现 有 Loop 的处理方式
任务太复杂 一次生成容易遗漏步骤 拆成多轮执行,每轮根据结果推进
环境会变化 工具超时或返回空结果后直接失败 观察错误,换关键词、换工具或降级策略
成本会失控 不知道用了多少 token,也不知道何时停 设置迭代上限、预算上限和收敛检测

但 Loop 不是越长越好。没有约束的 Agent Loop 是一台持续消耗 token 的机器,尤其在多智能体场景中,多个 Agent 互相传递上下文,成本可能迅速放大。工程上真正要做的不是“让 Agent 一直跑”,而是“让 Agent 在必要时自主推进,在该停时可靠停止”。

Agent Loop 的五阶段模型

一个典型 Agent Loop 可以拆成五个阶段:感知、推理、规划、行动、观察。

flowchart TD
    A[Perceive 感知<br/>接收用户输入、工具结果、错误信息] --> B[Reason 推理<br/>理解当前状态并评估选项]
    B --> C[Plan 规划<br/>把推理结果转成可执行步骤]
    C --> D[Act 行动<br/>调用工具、写文件、发请求或执行命令]
    D --> E[Observe 观察<br/>收集执行结果并更新状态]
    E --> A

每个阶段都承担不同职责:

阶段 输入 输出 常见问题
感知 用户目标、工具返回、错误信息 当前状态 输入太杂,关键信息被淹没
推理 当前状态、任务目标、历史记忆 下一步判断 模型只关注局部,忽略全局目标
规划 推理结论 操作计划 计划过细导致僵硬,计划过粗无法执行
行动 工具调用参数、命令、API 请求 执行动作 工具设计差,错误信息不可用
观察 工具结果、日志、异常 新事实和反馈 结果原样塞回上下文,导致窗口膨胀

并不是所有 Agent 都显式包含 Plan 阶段。ReAct 模式会把推理和行动交替进行,适合探索式任务;Plan-Execute 模式会先生成完整计划,再按顺序执行,适合流程明确的任务。

四种常见 Agent Loop 模式

Agent Loop 没有一个固定形态。不同任务的不确定性、延迟要求、成本预算和可审计要求不同,对应的循环模式也不同。

模式 核心思路 延迟 灵活性 适合场景
ReAct 边推理边行动 搜索、诊断、客服、调试
Plan-Execute 先规划再执行 中低 报告生成、审批流程、批处理
Reflection 生成后自我评估并修正 质量敏感的文档、代码、分析任务
Multi-Agent 多个 Agent 分工协作 中高 复杂调研、并行分析、多角色协作

ReAct:边想边做

ReAct 是 Reasoning and Acting 的缩写,意思是推理和行动交替发生。Agent 每一轮都会根据最新观察决定下一步,不提前写死完整路径。

sequenceDiagram
    participant User as 用户
    participant Agent as Agent
    participant Tool as 工具

    User->>Agent: 给出目标
    Agent->>Agent: Thought:判断下一步
    Agent->>Tool: Action:调用工具
    Tool-->>Agent: Observation:返回结果
    Agent->>Agent: Thought:基于结果重新判断
    Agent->>Tool: Action:继续调用工具
    Tool-->>Agent: Observation:返回结果
    Agent-->>User: 输出答案

ReAct 的优势是响应快、适应性强。比如排查接口异常时,Agent 可以先查日志;如果日志为空,就改查监控;如果监控发现错误率升高,再继续查最近发布记录。

它的风险也很明显:缺乏全局规划。长链路任务中,Agent 可能被最近一次观察牵着走,逐渐偏离目标。上下文窗口也会承受压力,因为每一步的思考、动作和结果都可能被追加进去。

适合 ReAct 的任务通常有三个特征:

特征 示例
路径不确定 “查一下为什么这个接口变慢”
需要实时反馈 “根据搜索结果继续追踪线索”
每一步可以小步验证 “运行测试,修一个错误,再运行测试”

Plan-Execute:先规划再执行

Plan-Execute 会先把目标拆成步骤,再交给执行器按计划完成。它更像一个项目管理流程:先定路线,再逐项推进。

flowchart TD
    A[用户目标] --> B[Planner 生成计划]
    B --> C[Step 1 执行]
    C --> D[Step 2 执行]
    D --> E[Step 3 执行]
    E --> F[汇总结果]

这种模式适合步骤清晰、目标稳定的任务,比如生成竞品分析报告、执行合规检查、批量处理数据。它的可审计性更好,因为每一步为什么存在、执行到哪里、失败在哪里都比较清楚。

代价是灵活性较低。如果环境中途变化,早期计划可能失效。比如计划里写着“调用接口 A 获取数据”,但接口 A 返回权限错误,Agent 不能只是反复执行原计划,而要触发重新规划。

一个更稳妥的 Plan-Execute 结构会在每个阶段加入检查点:

flowchart TD
    A[生成计划] --> B[执行当前步骤]
    B --> C{步骤成功?}
    C -->|是| D{计划完成?}
    C -->|否| E[局部修正或重新规划]
    E --> B
    D -->|否| B
    D -->|是| F[输出结果]

Reflection:做完再检查

Reflection Loop 会在生成结果后加入评估和修正环节。它的重点不是“多做几步”,而是让 Agent 对自己的输出进行质量判断。

flowchart LR
    A[生成初稿] --> B[评估质量]
    B --> C{达到标准?}
    C -->|否| D[指出问题并修正]
    D --> B
    C -->|是| E[输出最终结果]

它适合质量敏感任务,比如写技术设计文档、生成代码补丁、整理研究报告。评估器可以检查结构是否完整、事实是否一致、代码是否满足测试、输出是否符合格式约束。

Reflection 的主要风险是“验证循环”。如果没有明确标准,Agent 可能不断觉得“还能再改一点”,于是陷入生成、检查、微调、再检查的循环。解决办法是把“足够好”的标准写成可判断条件:

不好的停止标准 更好的停止标准
结果看起来不错 所有必填章节存在,表格字段完整
代码质量可以 单元测试通过,lint 无新增错误
报告足够完整 覆盖指定竞品、指标和结论
再检查一下 最多执行 2 轮评估修正

Multi-Agent:分工协作

Multi-Agent Loop 会把任务分配给多个 Agent,让它们分别承担研究、编码、审查、汇总等角色。常见结构是 Lead Agent 负责拆解和协调,Sub-Agent 负责具体执行。

flowchart TD
    A[Lead Agent<br/>理解目标并拆解任务] --> B[Research Agent<br/>检索和整理资料]
    A --> C[Code Agent<br/>实现或修改代码]
    A --> D[Review Agent<br/>检查质量和风险]
    B --> E[Lead Agent 汇总]
    C --> E
    D --> E
    E --> F[最终输出]

它适合任务复杂、可以并行、角色边界清楚的场景。比如一个深度调研任务可以让多个 Agent 分别查不同信息源,再由 Lead Agent 合并结论。

Multi-Agent 的成本和复杂度都更高。每个 Agent 都有自己的上下文、工具调用和循环逻辑,彼此通信还会产生额外 token。如果任务本来单 Agent 就能完成,引入多智能体只会增加编排负担。

场景 是否适合 Multi-Agent 原因
简单问答 不适合 编排成本高于收益
单文件代码修改 通常不适合 一个 Agent 足够完成理解、修改、验证
多来源研究报告 适合 可并行检索和交叉验证
大型代码迁移 可能适合 可拆成分析、修改、测试、审查角色
强实时对话 谨慎使用 多角色通信会增加延迟

终止条件是 Agent Loop 的刹车系统

让模型自己决定何时停止,并不是可靠策略。模型可以表达“任务完成”,但生产系统不能只依赖这句话。终止条件应该由多层机制共同控制。

flowchart TD
    A[每轮 Loop 结束] --> B{目标已完成?}
    B -->|是| Z[正常结束]
    B -->|否| C{达到迭代上限?}
    C -->|是| Y[返回部分结果并说明限制]
    C -->|否| D{超过 token 或成本预算?}
    D -->|是| Y
    D -->|否| E{检测到重复或收敛?}
    E -->|是| F[触发反思或换策略]
    F --> G{仍然无进展?}
    G -->|是| Y
    G -->|否| H[继续下一轮]
    E -->|否| H

常见终止条件可以分成四类。

类型 示例 作用
硬上限 max_iterations=15max_retries_per_step=3 防止无限循环
预算上限 token_budget=50000cost_limit=5.0 防止账单失控
目标达成 测试通过、文件生成、字段齐全 正常结束任务
收敛检测 多轮动作相似、结果无新增信息 识别卡住状态

收敛检测比精确匹配更重要。Agent 可能不是重复同一句话,而是换着说法做同一件事。比如连续几轮都在用相似关键词搜索同一个无结果主题,工具参数略有变化,但本质没有推进。此时可以用语义相似度、工具调用哈希、结果差异度来判断是否陷入循环。

一个实用的 stuck 处理策略可以分成四层:

层级 动作 目的
轻度干预 注入反思提示,要求说明重复原因 让 Agent 意识到卡住
策略切换 建议换工具、换关键词或换数据源 避免重复失败动作
上下文重置 压缩历史,只保留关键事实 降低上下文噪声
优雅退出 返回已完成部分和未解决原因 避免继续消耗成本

一个可落地的 ReAct Loop 骨架

下面的代码强调结构,不绑定具体框架。核心点是:每轮都要构建上下文、选择动作、执行工具、更新记忆,同时检查重复、预算和停止条件。

def run_agent_loop(goal, tools, llm, max_steps=15, token_budget=50_000):
    memory = AgentMemory()
    recent_calls = []
    total_tokens = 0

    for step in range(max_steps):
        context = memory.build_context(goal=goal)

        action = llm.decide_next_action(context=context, tools=tools)
        total_tokens += action.token_usage

        if action.type == "finish":
            return action.final_answer

        if total_tokens >= token_budget:
            return memory.partial_result(reason="token budget exceeded")

        if memory.is_converging(action):
            reflection = llm.reflect(
                goal=goal,
                recent_steps=memory.recent_steps(),
                problem="The loop appears to be repeating without progress."
            )
            memory.add_reflection(reflection)
            continue

        call_key = hash_tool_call(action.tool_name, action.arguments)
        if call_key in recent_calls:
            memory.add_observation({
                "status": "duplicate_call",
                "suggestion": "Use a different tool or change the arguments."
            })
            continue

        recent_calls.append(call_key)

        observation = tools.execute(
            name=action.tool_name,
            arguments=action.arguments
        )

        memory.add_observation(compress_observation(observation))

        if memory.goal_satisfied(goal):
            return memory.final_result()

    return memory.partial_result(reason="max steps reached")

这段骨架里有几个生产系统必须重视的细节:

设计点 为什么重要
hash_tool_call 避免同一个工具用同一组参数反复调用
compress_observation 工具结果不原样塞入上下文,降低 token 消耗
is_converging 识别语义重复和无进展循环
partial_result 失败时返回已有成果,而不是只返回错误
token_budget 用程序强制控制成本,不能依赖模型自觉

三层记忆:让上下文既够用又不爆炸

Agent Loop 跑到 5 到 10 轮后,上下文管理会变成核心问题。所有历史消息、工具返回、推理过程都塞进 prompt,看似信息完整,实际会带来两个后果:token 成本持续升高,模型更难定位真正重要的信息。

更稳定的做法是把记忆分成三层。

flowchart TD
    A[工作记忆<br/>当前最相关事实] --> D[本轮上下文]
    B[短期记忆<br/>最近几轮完整步骤] --> D
    C[长期记忆<br/>压缩摘要和向量检索] --> D
    D --> E[LLM 推理]
记忆层 保存内容 更新方式 用途
工作记忆 当前步骤最相关的少量事实 每轮重建 让模型专注眼前决策
短期记忆 最近几轮动作和观察 滑动窗口保留 保持推理连贯
长期记忆 压缩摘要、关键结论、检索索引 按需写入和读取 保存跨阶段知识

上下文窗口应该被当成受限资源,而不是无限日志。静态内容和动态内容要分开管理:系统规则、工具说明属于静态内容;工具结果、错误信息、阶段性结论属于动态内容。工具返回尤其要做摘要,只把对下一步决策有用的信息放进上下文。

一种常见省成本策略是:用便宜模型压缩工具输出,用更强模型做关键推理。比如搜索工具返回 20 条结果,不必把全部网页片段塞给主模型,可以先压成结构化摘要:

{
  "status": "ok",
  "facts": [
    "Competitor A supports SSO and audit logs.",
    "Competitor B offers lower pricing for small teams."
  ],
  "uncertainties": [
    "Enterprise pricing is not publicly available."
  ],
  "suggested_next_step": "Search for customer case studies or pricing pages."
}

这样的结果比一大段网页文本更适合进入下一轮 Loop。

错误恢复的重点不是重试,而是换策略

很多 Agent 失败不是因为没有重试,而是因为一直重试同一个错误动作。工具超时后再次调用同一个接口、搜索无结果后继续用同一个关键词、权限不足后重复请求同一个资源,都会让 Loop 原地打转。

更合理的错误恢复应该是“少量重试 + 策略转向”。

flowchart TD
    A[工具调用失败] --> B{是否临时错误?}
    B -->|是| C[快速重试一次]
    C --> D{成功?}
    D -->|是| E[继续任务]
    D -->|否| F[延迟后再试一次]
    F --> G{成功?}
    G -->|是| E
    G -->|否| H[反思失败原因并换策略]
    B -->|否| H
    H --> I[换工具、换参数、降级或请求人工介入]

工具输出也要为 Agent 提供可行动线索。返回空数组或一句“请求失败”,模型很难判断下一步该做什么。结构化错误信封更有效:

{
  "status": "no_results",
  "reason": "No documents matched the exact keyword.",
  "suggestion": "Try a broader keyword or search by product category."
}

再比如权限错误可以返回:

{
  "status": "permission_denied",
  "reason": "The current token cannot access billing data.",
  "suggestion": "Ask the user to provide billing permission or continue with public pricing data."
}

好的工具输出会告诉 Agent 三件事:发生了什么、为什么失败、下一步可以尝试什么。Loop 的智能程度,很大一部分取决于工具反馈是否清晰。

如何选择合适的 Loop 模式

选择 Agent Loop 模式时,不要从框架或热门架构出发,而要从任务特征出发。

任务特征 推荐模式 原因
路径不确定,需要边查边判断 ReAct 每轮可以根据观察调整方向
步骤固定,结果需要可追踪 Plan-Execute 计划清晰,便于审计和回放
输出质量要求高 Reflection 能加入评估和修正
子任务可以并行,角色边界清楚 Multi-Agent 可以分工处理并汇总结果
成本预算很紧 简化 ReAct 或固定 Workflow 减少多轮推理和角色通信
风险较高,需要人工确认 Human-in-the-Loop 在关键动作前加入人工审批

实际系统经常使用混合策略。例如,整体任务用 Plan-Execute 管理阶段,单个步骤内部用 ReAct 探索信息,最终输出前再跑一轮 Reflection 检查质量。

flowchart TD
    A[用户目标] --> B[Plan-Execute<br/>拆成阶段]
    B --> C[ReAct<br/>阶段内探索和工具调用]
    C --> D[Reflection<br/>质量评估和修正]
    D --> E{达到标准?}
    E -->|否| C
    E -->|是| F[输出结果]

这种混合结构比单一模式更贴近真实任务:全局需要计划,局部需要灵活,交付前需要验证。

生产级 Agent Loop 检查清单

一个 Agent Loop 能跑起来不难,难的是稳定、可控、可观测。上线前至少要检查这些点。

检查项 必要设计
目标表达 目标必须可判断完成,不能只写“尽量做好”
工具协议 工具返回 statusreasonsuggestion 等结构化字段
上下文管理 区分工作记忆、短期记忆、长期记忆
去重机制 对工具名和参数做哈希,避免重复调用
收敛检测 检查动作相似度、结果新增信息和多轮进展
成本控制 设置 token、金额、迭代次数和单步骤重试上限
错误恢复 重试有限次数,失败后换策略
优雅退出 到达限制时返回部分结果和未完成原因
可观测性 记录每轮输入、动作、工具结果、token 消耗
人工介入 高风险动作前暂停,等待确认

尤其要注意两个常见陷阱。

第一个陷阱是把框架默认值当成策略。很多 Agent 框架会提供 max_iterations 之类的参数,但这只是兜底,不等于完整终止逻辑。真正的停止条件还要覆盖目标达成、重复检测、预算熔断和质量标准。

第二个陷阱是用 Multi-Agent 掩盖工具设计问题。如果工具返回的信息含糊,多个 Agent 只会一起在含糊信息里打转。Agent 架构越复杂,对工具协议、状态管理和编排逻辑的要求越高。

小结

Agent Loop 的核心不是“多调用几次模型”,而是把 LLM 放进一个可观察、可控制、可恢复的执行循环里。感知、推理、规划、行动、观察构成了 Agent 自主工作的基础;ReAct、Plan-Execute、Reflection、Multi-Agent 则对应不同任务形态。

工程上最重要的部分往往不在模型本身,而在 Loop 的边界条件:什么时候继续,什么时候换策略,什么时候压缩上下文,什么时候停止。一个可靠的 Agent,不仅要能自己往前走,还要知道在无进展、超预算或达到目标时及时停下。

参考来源: Agent Loop 深度拆解

评论