2026年4月11日发布
开篇引入

在Spring AI框架体系中,Advisors(顾问)是与大语言模型(Large Language Model,LLM)交互的核心增强机制,属于掌握Spring AI框架后必须攻克的进阶知识点。
许多开发者在使用Spring AI时,常会陷入这样的困境:懂得如何调用ChatClient发送消息、接收回复,但面对“如何给AI对话加上记忆”“如何实现RAG检索增强”“如何统一处理日志与鉴权”等实际问题时,往往束手无策。概念易混淆(Advisors和AspectJ有何区别?)、底层原理模糊、面试答不出要点,是普遍存在的学习痛点。

本文将从痛点出发,系统讲解Spring AI Advisors的核心概念、内置顾问类型、底层原理与实战代码示例,并附高频面试题参考答案,帮助读者建立从概念到落地的完整知识链路。后续还将推出“手写自定义Advisor”等进阶内容,敬请关注。
一、痛点切入:为什么需要Advisors
先看一个典型的“无增强”AI调用示例:
@RestController public class ChatController { private final ChatClient chatClient; public ChatController(ChatClient.Builder chatClientBuilder) { this.chatClient = chatClientBuilder.build(); } @PostMapping("/chat") public String chat(@RequestBody String userInput) { // 每次对话都是孤立的,没有记忆 return chatClient.prompt().user(userInput).call().content(); } }
这段代码存在四个明显缺陷:
无状态隔离:大语言模型(LLM)本身是无状态的,每次调用都是独立的。多轮对话场景下,后续请求无法“记住”之前的对话内容。
缺乏上下文增强:无法在调用前向模型注入私有知识库信息,导致RAG(检索增强生成)等高级功能难以落地。
横切逻辑重复:日志记录、请求校验、鉴权、限流等通用能力,不得不侵入每个业务方法。
扩展性差:想要添加一个新功能(如对话压缩、输出校验),就需要修改核心调用代码,违反开闭原则。
痛点总结:开发者需要一个类似Spring AOP(面向切面编程)的机制,在不污染业务逻辑的前提下,拦截并增强每一次AI模型调用。
这正是Spring AI Advisors设计的初衷。
二、核心概念讲解:Advisors
标准定义
Advisors是Spring AI框架中用于拦截、修改和增强AI驱动交互的核心组件。它围绕ChatClient的请求与响应链路,提供了一套可插拔、可组合、可排序的增强处理机制-。
关键词拆解
拦截:Advisors可以“中途截获”即将发送给大语言模型(LLM)的请求,以及模型返回的响应。
修改:可以对请求进行“预处理”(如添加对话记忆、注入RAG检索结果),也可以对响应进行“后处理”(如格式化输出、校验内容合法性)。
增强:通过叠加多个Advisors,可以组合实现对话记忆、RAG检索、日志记录、护栏(Guardrails)等丰富功能-。
生活化类比
可以把Advisors理解为机场安检通道:
旅客手持的登机牌就是用户请求(Prompt);
安检员会核验身份、扫描行李,这个过程就是Advisor的拦截与预处理;
如果一切合规,旅客被放行登机,这是调用下一个Advisor或最终的大语言模型(LLM);
落地后行李被再次检查,这是后处理;
安检员还可以直接拒绝旅客登机(比如发现违禁品),对应阻止请求继续传递。
作用与价值
Spring AI Advisors的主要优势可以概括为三条-5:
封装通用模式:将对话记忆、RAG、日志记录等常见AI场景,打包成可重用的组件。
数据转换:增强发送给大语言模型(LLM)的数据,并优化返回给客户端的响应格式。
跨模型可移植:同一个Advisor可以用于OpenAI、Ollama、阿里云百炼等不同AI服务,无需修改代码。
三、关联概念讲解:Recursive Advisors(递归顾问)
标准定义
Recursive Advisors(递归顾问) 是Spring AI 1.1.0-M4版本引入的增强机制,它支持多次循环执行顾问链,每次迭代中可根据前一次响应条件决定是否重试或继续-6。
与普通Advisors的关系
普通Advisors是一次通过的线性处理——请求经过链中的每个Advisor一次,然后到达大语言模型(LLM),响应再原路返回。而Recursive Advisors允许重复循环下游顾问链,直至满足某个条件-2。
典型应用场景
| 场景 | 说明 |
|---|---|
| 工具调用循环 | 依次执行多个工具,每个工具的输出为下一个决策提供依据 |
| 输出校验与重试 | 校验结构化响应,验证失败时通过反馈重试 |
| 智能体循环 | 构建自主AI代理,通过分析结果并确定下一步动作,迭代直到目标达成 |
| 响应质量优化 | 根据响应质量或外部标准,优化请求后重新调用-6 |
快速示例
public class MyRecursiveAdvisor implements CallAdvisor { @Override public ChatClientResponse adviseCall(ChatClientRequest request, CallAdvisorChain chain) { // 首次调用 ChatClientResponse response = chain.nextCall(request); // 条件循环重试 while (!isConditionMet(response)) { request = refineRequest(request, response); response = chain.nextCall(request); } return response; } }
四、概念关系与区别总结
| 维度 | Advisors | Recursive Advisors |
|---|---|---|
| 执行次数 | 单次通过 | 可多次循环 |
| 适用场景 | 对话记忆、RAG、日志、护栏 | 工具调用、输出校验、智能体 |
| 调用模式 | 线性链式处理 | 迭代式循环处理 |
| 终止条件 | 链尾到达LLM | 满足自定义条件 |
一句话记忆:Advisors是增强AI交互的切面化组件,而Recursive Advisors是实现智能体自主迭代的循环引擎。
五、代码示例:给AI对话加上记忆功能
以下示例展示如何通过MessageChatMemoryAdvisor为无状态的AI调用注入对话记忆:
完整代码
import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor; import org.springframework.ai.chat.memory.InMemoryChatMemory; import org.springframework.stereotype.Service; @Service public class AIChatService { private final ChatClient chatClient; public AIChatService(ChatClient.Builder chatClientBuilder) { // 1. 构建内存级聊天记忆存储 var chatMemory = new InMemoryChatMemory(); // 2. 配置Advisor:将记忆能力注入ChatClient var memoryAdvisor = MessageChatMemoryAdvisor.builder(chatMemory) .build(); // 3. 构建带有记忆能力的ChatClient this.chatClient = chatClientBuilder .defaultAdvisors(memoryAdvisor) // ← 关键:注册Advisor .build(); } public String chat(String conversationId, String userMessage) { // 4. 调用时传入会话ID,框架自动关联历史记忆 return chatClient.prompt() .advisors(advisor -> advisor.param( ChatMemory.CONVERSATION_ID, conversationId)) .user(userMessage) .call() .content(); } }
执行流程解析
构建
InMemoryChatMemory:在内存中存储每个会话的历史消息。创建
MessageChatMemoryAdvisor:这是一个内置Advisor,负责在请求前自动将历史消息拼接到Prompt中,并在响应后将新消息存入记忆。注册
defaultAdvisors():将该Advisor注册到ChatClient.Builder中,成为每次调用的默认增强链-1。传入
CONVERSATION_ID:运行时通过.advisors()动态参数指定会话ID,框架根据ID自动区分不同用户的对话历史-1。
对比无记忆版本
| 版本 | 实现方式 | 多轮对话能力 |
|---|---|---|
| 无Advisor | 每次调用都是独立的 | 每次对话都是“失忆”的 |
使用MessageChatMemoryAdvisor | 一行代码配置Advisor | 自动记住上下文 |
效果差异:无记忆版本下,用户问“我叫小明”,再问“我叫什么名字”,AI会答非所问;加上记忆Advisor后,AI能准确回答“你叫小明”。
六、底层原理与技术支撑
Spring AI Advisors的底层实现依赖以下几个核心机制:
1. 责任链(Chain of Responsibility)模式
Advisors以链式结构串联执行,通过getOrder()方法控制执行顺序(值越低越优先)。当请求进入链时,链中的每个Advisor依次处理请求,可选择修改请求、调用下一个Advisor,或直接阻断并返回自定义响应-1。
2. 环绕通知模式(类似Spring AOP)
Advisors的设计与Spring AOP的@Around通知高度相似。核心接口CallAdvisor定义了adviseCall方法,该方法在调用前、调用后均可插入增强逻辑,与AOP切面的“环绕增强”理念一致-5。
3. Spring Boot自动配置
Spring AI通过@ConditionalOnClass、@AutoConfiguration等机制,实现了Advisors的零配置集成——引入对应Starter依赖后,内置Advisors自动生效。
4. 堆栈式执行顺序
Advisors链以堆栈方式运行:最先执行的Advisor(order值最小)在处理请求时最先被调用,但在处理响应时却是最后被调用的。这是因为请求沿链向下传递,响应则沿链向上返回,形成“先入后出”的栈式顺序-1。
原理示意图:
请求流向:A(低order) → B(中order) → C(高order) → LLM 响应流向:A ← B ← C ← LLM
七、高频面试题与参考答案
面试题一:什么是Spring AI Advisors?它的核心作用是什么?
参考答案:
Spring AI Advisors是框架中用于拦截、修改和增强AI交互的核心组件。它的核心作用有三:
封装通用AI模式:将对话记忆、RAG检索增强、日志记录等能力封装为可重用组件;
实现关注点分离:通过类似AOP的环绕通知模式,将横切逻辑从业务代码中解耦,符合开闭原则;
提供跨模型可移植性:同一套Advisor配置可适配OpenAI、Ollama、阿里云百炼等多种大语言模型(LLM),无需修改代码。
踩分点:提及“拦截修改增强”、“AOP式设计”、“内置Advisor类型”、“跨模型可移植”等关键词。
面试题二:Advisors的执行顺序是如何控制的?请简述其原理。
参考答案:
Advisors的执行顺序通过实现Ordered接口的getOrder()方法控制,order值越小,优先级越高,越先执行。
核心原理:Advisors链以堆栈方式运行。假设A.order=0、B.order=5、C.order=10,执行过程为:
请求流向下:A → B → C → LLM
响应流向上:A ← B ← C ← LLM
这意味着最先处理请求的Advisor,是最后处理响应的。若多个Advisors的order值相同,执行顺序不予保证。
踩分点:说出“order值越小越优先”、“堆栈式执行顺序”、“请求与响应的逆序处理”三个要点。
面试题三:普通Advisors和Recursive Advisors有什么区别?
参考答案:
普通Advisors采用单次通过的线性处理模式——请求依次经过链中每个Advisor一次,到达LLM后响应原路返回。适用于对话记忆、RAG检索、日志记录等一次性增强场景。
Recursive Advisors支持多次循环执行下游顾问链,可根据每次响应结果决定是否继续循环,直至满足特定条件。适用于工具调用循环、输出校验重试、自主智能体迭代等复杂场景。
一句话总结:普通Advisors处理“一次增强”,Recursive Advisors处理“迭代优化”。
踩分点:对比“单次通过vs多次循环”,举例说明各自适用场景。
八、结尾总结
本文核心知识点回顾
| 知识点 | 核心要点 |
|---|---|
| Advisors的定义 | 拦截、修改、增强AI交互的可插拔组件 |
| 解决的问题 | 无状态、横切逻辑侵入、扩展性差 |
| 设计思想 | 责任链 + AOP环绕通知 |
| 执行顺序 | getOrder()值越小越优先,堆栈式顺序 |
| 内置类型 | 对话记忆、RAG检索、日志记录、护栏 |
| Recursive Advisors | 支持循环迭代,用于工具调用和智能体 |
重点与易错提示
易错点1:混淆
defaultAdvisors()(构建时注册)与运行时.advisors()(动态传参)的用途——前者定义默认增强链,后者可在调用时动态覆盖参数。易错点2:误以为order值越大优先级越高——实际是值越小越优先。
重点记忆:Advisors链是堆栈式执行,请求与响应的处理顺序相反。
下篇预告
本文以对话记忆Advisor为例展示了基本用法。下一篇将深入手写自定义Advisor,从实现CallAdvisor接口到构建生产级的日志记录与鉴权增强组件,敬请期待。
参考资源:
Spring AI官方文档:Advisors API
Spring官方博客:Create Self-Improving AI Agents Using Spring AI Recursive Advisors
本文数据截至2026年4月,基于Spring AI 1.1.x版本编写。随着版本迭代,API可能有变化,请以官方最新文档为准。