核心要点

  • Spring AI 定位偏「框架原语」:ChatClient、Tool Calling、Advisors、ChatMemory,而非现成的 Agent 黑盒

  • ReAct = 在这些原语上手写控制流:思考(Reason)→ 选工具(Act)→ 执行 → 观察(Observation)→ 回灌上下文 → 循环,直到模型判断完成

  • 把工具用 @Tool/ToolCallback 注册给 ChatClient,每轮让模型决定下一步动作或给出最终答案,用 ChatMemory 维护推理与观察过程

  • 防死循环是关键:设最大迭代次数、成本/时间预算,并明确终止判断(模型声明完成或无新动作),超限即终止或转人工

标准回答

Spring AI 的定位

Spring AI 没有把「自主 Agent」封成一键黑盒,而是提供一组 框架原语ChatClient(统一对话入口)、Tool Calling(把方法暴露给模型调用)、Advisors(在请求/响应链上做拦截增强,如 RAG、日志)、ChatMemory(多轮记忆)。构建 ReAct Agent,本质是用这些原语自己拼出控制流,而不是期待框架替你做规划

ReAct 循环的骨架

ReAct(Reason + Act)的核心是让模型显式「边想边做」:每一轮先 推理(Thought) 当前该干什么,再决定 动作(Action)——调用某个工具或直接给出最终答案;工具执行后把 观察(Observation) 结果回灌进上下文,进入下一轮。用 Spring AI 实现时,外层是一个由你掌控的 while 循环:调用 ChatClient → 若模型发起工具调用则执行并把结果加入记忆 → 否则视为产出最终答案、跳出循环。

用框架原语拼装

把可用工具通过 @Tool 注解或 ToolCallback 注册到 ChatClient;模型在每轮可自主选择调用哪个工具,框架负责 Function Calling 的参数解析与回填。用 ChatMemory 把每轮的 Thought、工具入参出参、Observation 累积为过程上下文,让模型基于完整历史决定下一步。可用 Advisor 注入系统提示(约束输出 ReAct 格式或要求每步声明是否完成)、做 RAG 增强或统一记录 trace。系统提示是关键:明确告诉模型「需要更多信息就调用工具,信息足够就直接回答」。

终止与防死循环

自主循环最大的风险是失控。必须设 最大迭代次数成本/时间预算,达到上限即强制终止并降级(返回已有信息或转人工)。终止判断有两类信号:模型显式声明「已完成」并给出最终答案,或某轮不再产生新的工具调用。对重复或低收益的动作(反复调同一工具拿同样结果)做去重并提前结束。每步可校验工具结果是否有效,避免模型在错误观察上空转。

可观测与可靠性

把每轮的推理、动作、观察、耗时与成本落 trace,便于复盘 Agent 为何绕路或失控。工具失败做有限重试加退避,不可恢复则降级。评估上关注端到端任务完成率与平均迭代步数,而非单步工具成功率,才能真实反映这套手写 ReAct 控制流的可靠性。

常见误区

⚠️ 常见踩坑

把 Spring AI 当成自带「自主 Agent」的框架,期待一行配置就能规划——它给的是原语,控制流要自己写。另一个常见错误是只管让模型循环调用工具,却不设最大迭代、预算与明确终止判断,导致死循环、成本爆炸或在错误观察上空转。还有人忽视 ChatMemory,每轮丢失之前的 Thought/Observation,模型无法基于完整过程推进。最后,只看单步工具调用是否成功、不看端到端任务完成率,会高估 Agent 可靠性。

追问

追问 1ChatMemory 在 ReAct 循环里具体维护什么,为什么不可省?

ReAct 的每一步依赖前面所有 Thought、Action 与 Observation:模型要看到「我已经查过什么、得到什么结果」才能决定下一步,否则会重复调用或丢失线索。ChatMemory 负责把这些过程性消息按轮累积进对话上下文,使每次 ChatClient 调用都带着完整推理轨迹。若省略,模型每轮近乎无状态,既无法收敛也容易循环。需要注意控制记忆长度,过长会撑爆上下文窗口、抬高成本,可用窗口截断或对早期步骤做摘要。

追问 2如何在循环中可靠地判断「任务已完成」该退出?

主要有两类信号。其一是模型主动声明完成:在系统提示里约定输出格式,要求模型在信息足够时直接给出最终答案而非再发工具调用,框架检测到本轮无工具调用即视为结束。其二是结构化终止条件:要求模型每轮显式输出「是否完成」字段或特定结束标记,由外层循环解析判断。两者都应叠加硬性兜底——最大迭代次数与成本/时间预算,达到即强制终止,避免模型永远不声明完成而无限绕圈。

追问 3相比直接用 LangGraph 这类编排框架,手写 Spring AI ReAct 循环有什么取舍?

手写控制流的优点是轻量、透明、完全可控,逻辑都在自己的 Java 代码里,便于调试、嵌入既有 Spring 服务并复用其事务、安全、监控体系,适合流程相对线性、工具数量可控的场景。代价是规划、状态机、分支回退、并行子任务等复杂编排都得自己实现,循环、终止与防失控逻辑容易写得不健壮。LangGraph 这类图编排框架把这些能力固化成原语,复杂多步流程更省心,但引入额外抽象与依赖。选型看 Agent 复杂度:简单循环用框架原语自拼即可,复杂多分支编排可考虑专门的编排层。

🔗 相似问题

同一考点的不同问法,面试官可能换着问,一起刷更稳

没找到想看的面试题?把你想看的告诉我们 →

延伸学习

按主题分类的相关资源,便于系统复习