LLM 面试备考
首页/Agent 架构

Agent 与 ReAct 循环 Agent & ReAct Loop

所属:01-fundamentals / 04-agent-architecture
面试权重:★★★
来源:通用领域知识(B站「AI Agent 八股」合集高频);未做一手考证
相关项目:Race Bot (HKJC) —— Agentic Workflow 编排;Writing Copilot —— LangGraph 多智能体 → 见 02-interview/projects/race-bot-hkjc.md、02-interview/projects/writing-copilot.md

一句话#

Agent 是由模型自己决定控制流的系统:它在「思考 → 调用工具 → 观察结果」的循环里,用上一步的观测决定下一步做什么,直到任务完成或触发终止条件;ReAct(Reasoning + Acting)是这一循环最早、也最通用的形态。

为什么重要(面试角度)#

这是 agent 方向的第一道题,也是最容易被答成背书的一道题。面试官想知道的不是「ReAct 就是 Thought/Action/Observation」,而是:

  • 你能不能给出**「什么算 agent、什么不算」的判据**(而不是把任何 LLM 应用都叫 agent)
  • 你知不知道什么时候根本不该用 agent(这题答得出来,比会背 ReAct 更值钱)
  • 你理解 agent 的失败模式:错误复合、上下文退化、工具选错、无限循环
  • 你说得清错误恢复的设计:重试、反思、降级、兜底

你在 Race Bot 里做的就是编排式 agent(Agentic Workflow),在 Writing Copilot 里做的是 LangGraph 多智能体 —— 这题必然被问,而且会顺着往项目里挖。

核心内容#

判据:什么算 agent#

关键不是「有没有用 LLM」,也不是「工具数多少」,而是控制流由谁决定:

形态 控制流由谁决定 例子
固定工作流(workflow) 代码决定步骤顺序,模型只在某几步内做单次调用 翻译流水线、分类 → 检索 → 生成
路由(routing) 代码决定候选分支,模型只做一次选择 意图识别后分流到不同处理链
编排式 agent(agentic workflow) 代码定骨架,模型在骨架内做有限决策(选哪个工具、要不要重试) Race Bot:安全检测 → 话题分类 → 分流到 KB / 搜索 / Text2SQL
自主 agent(autonomous agent) 模型决定下一步做什么、做几步,循环直到自认为完成 编码 agent、深度研究 agent

行业里一个被广泛引用的划分(Anthropic 的 agent 设计指南)就是这个意思:workflow 是「用代码编排模型」,agent 是「让模型自己编排」。这个区分之所以重要,是因为大多数生产系统其实是 workflow,而很多人把它叫成 agent。

一句话判据:如果你能画出确定的流程图,且流程图与用户输入无关 —— 那是 workflow;如果下一步依赖上一步的返回内容、且步数不确定 —— 那才是 agent。

ReAct 循环#

ReAct 出自 2022 年的同名论文,核心是让推理与行动交替进行:

Thought(推理:现在知道了什么、下一步该做什么)
   ↓
Action(调用一个工具,带参数)
   ↓
Observation(工具返回的结果)
   ↓
(回到 Thought,直到给出 Final Answer 或触发终止条件)

关键点:必须在循环里。 把工具结果直接拼进 prompt 再问一次不叫 ReAct —— ReAct 的本质是用观测修正下一步决策。这也是 ReAct 与「一次调用换一次工具」的区别。

现代实现已经换了皮。 论文里 ReAct 是让模型输出 Thought: ... Action: ... 这种文本、由外部用正则解析。今天主流做法是原生 function calling / tool use:模型直接输出结构化的调用请求(工具名 + JSON 参数),由运行时执行并回灌结果。格式从「文本约定」变成了「模型被训练过的输出结构」,稳定性显著提升。所以面试时正确说法是:

ReAct 是范式,function calling 是今天实现它的主流机制。两者不是替代关系。

循环控制(生产上必须显式设计)#

没有终止条件的 agent 是一个会烧钱和烧时间的死循环。至少要控制:

  • 最大步数 / 最大迭代:防死循环,是硬性兜底
  • 预算上限:token 或金额上限,比步数更贴近真实成本
  • 成功判据:什么算完成(有明确判据的任务才适合做 agent)
  • 无进展检测:连续 N 步观测内容无实质变化 → 中断(模型陷入重复调用同一个工具的「打转」状态很常见)
  • 超时:单步超时 + 整体超时
  • 终止后的兜底:耗尽预算时返回什么 —— 部分结果?澄清追问?报错?这个决策就是产品设计

错误恢复#

agent 的价值一半在「能多步做事」,另一半在「出错能自己回来」。分层设计:

层次 做法 注意
工具层重试 超时 / 限流 / 瞬时故障重试 前提是幂等;写操作重试可能造成重复副作用
错误回灌 把错误信息作为 Observation 返回给模型,让它改参数重试 错误信息要结构化且可读(字段名 + 原因),别只抛异常栈
反思(Reflection) 让模型自检输出并修正 有效但会增加步数与成本;注意「越修越错」,要设重试上限
降级 换更小的模型 / 换备用工具 / 返回部分结果 降级后的质量损失要和用户沟通
兜底 都不行时转人工(见 human-in-the-loop.md)或澄清追问 这比硬给一个错答案好

Race Bot 的 Text2SQL 用的就是这套:retry-and-fix 循环 + 次数上限 + 失败后降级到澄清追问。要点是:错误重试必须有上限和兜底,否则一次失败会变成一次超时。

什么时候确定性的 workflow 更好#

这是最容易被忽略、也最能体现工程判断力的一问。能用 workflow 就用 workflow,理由:

  • 可靠性:每多一次模型决策,就多一个失败点。n 步每步 95% 正确的链路,端到端只有 0.95^n —— 10 步就掉到 60%。
  • 成本与延迟:agent 循环意味着多轮长上下文调用,成本比单次调用高一个量级(量级关系取决于实现,但方向明确)。
  • 可评测:固定流程的每一步可以单独评测、单独优化(Race Bot 的核心决策理由);agent 的轨迹空间爆炸,评测难得多。
  • 可审计:合规场景要求「为什么得出这个结论」可复现,agent 的非确定性天然不友好。
  • 可预测:SLA 能承诺,因为步数有界。

判据:任务步骤事先已知且稳定 → workflow;步骤依赖中间结果、事先无法枚举 → agent。真实系统里通常是混合:外层编排固定(安全检测、分流),内层某一环才用 agent 循环。

为什么 agent 会失败#

按面试里最常见的五个原因排序:

  1. 错误复合(error compounding):多步串联,每步的小错误率被幂放大。这是 agent 的头号杀手。
  2. 上下文退化:步数一多,工具返回的大段内容挤进窗口,早期的重要约束被稀释甚至被遗忘(见 context-engineering.md)。表现为「它明明一开始答应了要输出 JSON」。
  3. 工具选择错误:工具多了描述互相重叠,模型选错(见 tool-use.md、mcp.md)。
  4. 没有清晰的成功判据:模型不知道「做完了」是什么样,于是要么过早结束、要么无限打转。成功判据模糊的任务本来就不该交给 agent。
  5. 循环病态:重复调用同一个工具、参数来回震荡、被自身错误观测带偏。

次要但真实的原因还有:工具返回值格式不稳定(同一个工具有时返回数组有时返回对象)、错误信息不可读导致模型改不对、以及延迟过长导致用户中途放弃。

如果要把「agent 为什么失败」变成训练问题(而不是靠 prompt 与工程兜底),那就是 Agentic RL:多轮轨迹的信用分配、组内 advantage 归零、环境噪声、rollout 与 policy lag → 见 02-post-training/08-agentic-rl.md。这是目前两块内容之间的缝,面试里常被合起来问。

常见面试问法#

Q:怎么区分 agent 和 workflow? A:看控制流由谁决定。代码决定步骤顺序的是 workflow(模型只在步内做单次调用);模型根据上一步观测决定下一步做什么、做几步的是 agent。能画出与输入无关的固定流程图,就是 workflow。生产系统多数是「外层 workflow + 内层局部 agent」的混合体。

Q:ReAct 的流程说一下。 A:Thought → Action → Observation 循环。推理产出下一步动作,执行工具拿到观测,观测修正下一步推理,直到产出最终答案或触发终止条件。关键是在循环里用观测修正决策。今天主流用原生 function calling 实现,而不是解析文本格式。

Q:为什么不直接做一个全自主 agent,什么都能干? A:可靠性、成本、可评测性三条都吃亏。步骤越多错误复合越严重,成本随轮数放大,而且自主 agent 的轨迹不可枚举、难以评测和审计。工程上的正确答案是把能固定的部分固定下来,只在真正需要的地方给模型决策权。

Q:agent 出错了怎么恢复? A:分层:工具层的幂等重试 → 把结构化错误信息回灌给模型让它改参数 → 反思自修正(设上限)→ 降级到备用工具/小模型/部分结果 → 兜底转人工或澄清追问。核心是每一次重试都要有上限和兜底。

Q:你的 Race Bot 为什么用编排式工作流,而不是一个大 agent? A:用户请求类型差异太大(闲聊 / 事实查询 / 结构化聚合),走的是完全不同的工具链。塞进一个大 agent 会导致工具描述冗长、选择错误率上升,且无法对单步做评测和优化。拆成编排后每一步可独立替换和评测 —— 意图识别错了只修意图识别,不动整个模型。

易错点#

  • ❌ 把任何用了 LLM 的应用都叫 agent —— 没有自主控制流的就是 workflow。
  • ❌ 认为「更自主 = 更好」。默认应该是「能固定就固定」。
  • ❌ 忘记终止条件 / 预算上限,把死循环留到线上。
  • ❌ 只讲 ReAct 的格式,讲不出「用观测修正决策」这个本质。
  • ❌ 说 ReAct 和 function calling 是竞争关系 —— 它们是范式和实现机制的关系。
  • ❌ 忽略错误复合:把多步链路的可靠性说成「每步都不错所以整体不错」。
  • ❌ 重试不带幂等考虑,导致副作用工具被执行多次。
  • ❌ 不给「终止后返回什么」设计兜底,等于把失败直接抛给用户。

自测#

1. 给出一个能区分「agent」和「workflow」的可操作判据,并用 Race Bot 举例。

答案

判据是控制流由谁决定:如果步骤顺序由代码写死、与输入内容无关,则是 workflow;如果下一步动作依赖上一步工具返回的内容、且步数事先不确定,则是 agent。Race Bot 的外层骨架(安全检测 → 话题分类 → 查询改写 → 意图识别 → 分流)是 workflow,因为流程固定;但在 Text2SQL 内部有一个按执行结果决定是否重试的 retry-and-fix 循环,那一段具备 agent 性质。所以它是编排式 agent / agentic workflow:外层固定、内层局部自主。

2. 为什么说「步骤越多的 agent 越不可靠」?请用数字说明。

答案

因为错误复合:若每一步的独立成功率为 p,n 步串联的端到端成功率约为 p^n。例如每步 95% 正确时,5 步约 77%,10 步约 60%。而且真实链路里各步并不独立 —— 上一步的错误观测会污染下一步的决策,使实际退化比这个上界更严重。工程含义是:减少步数、把能合并的步骤合并、给每一环加校验,比「让 agent 更聪明」更有效。

3. ReAct 和 function calling 是什么关系?为什么今天的实现和原始论文不一样?

答案

ReAct 是一种范式:推理与行动交替,用工具观测修正下一步决策。原始论文的实现在文本层面约定 Thought / Action / Observation 格式,靠外部解析。今天主流做法是模型原生支持 function calling,直接输出结构化的工具名与参数,不再需要正则解析。差别在于输出结构的可靠性:文本约定会被模型的措辞变化打破,而结构化输出是模型被训练过的能力,解析失败率低得多。所以 function calling 是 ReAct 的现代实现机制,不是替代品。

4. 你的 agent 在第 4 步开始反复调用同一个工具、每次参数几乎一样。可能的原因和三个对策是什么?

答案

可能原因:① 工具返回的信息不足或不可读,模型无法判断「已经够了」;② 成功判据不明确,模型不知道该停;③ 上下文里早期约束被长观测稀释,模型忘了目标;④ 工具本身有问题(返回空、返回格式不稳定),模型在徒劳地换参数试探。对策:加无进展检测(连续 N 步观测无实质变化即中断);让工具返回值结构化且带状态信息(例如明确返回「无更多结果」而不是空数组);显式写出完成判据和步数上限;必要时把这一环降级为确定性步骤。

5. 什么情况下你会拒绝用 agent,改用固定 workflow?

答案

当步骤已知且稳定(能画出固定流程图)、当延迟和成本有硬约束、当每步需要单独评测和优化、当合规要求过程可审计可复现、或者当失败代价高而正确性必须由外部约束保证时 —— 这些场景都应优先用 workflow。一个实用的判断顺序是:先用 workflow 实现,只在「确实需要根据中间结果做决策」的环节引入 agent 循环。反过来先上全自主 agent、再想办法加约束,通常是以更高的成本和更差的可靠性换到同样的效果。