一、开篇引入
在 AI 应用开发中,调用大模型远不止“发一个 Prompt、收一个 Response”这么简单——日志记录、敏感词过滤、对话记忆维护、RAG 检索增强、合规检查、重试与限流等横切关注点,如果散落在各处代码中,会让项目变得耦合且难以维护。Spring AI Advisors 正是为解决这些问题而生的声明式拦截机制。本文从设计理念、核心概念到底层原理全面拆解,搭配代码示例与高频面试题,助你快速掌握这一必学知识点。

二、痛点切入:为什么需要 Advisors
传统做法

假设一个简单的 AI 问答接口,不加入任何横切逻辑时,代码非常清爽:
@RestController public class ChatController { private final ChatClient chatClient; public ChatController(ChatClient.Builder builder) { this.chatClient = builder.build(); } @GetMapping("/chat") public String chat(@RequestParam String message) { return chatClient.prompt(message).call().content(); } }
但一旦加入日志、敏感词过滤、对话记忆等功能,代码就会迅速膨胀:
@GetMapping("/chat") public String chat(@RequestParam String message) { // 日志记录 log.info("用户输入: {}", message); // 敏感词检测 if (containsSensitiveWords(message)) { return "输入包含敏感词,请修改后重试"; } // 加载历史对话 List<Message> history = conversationService.getHistory(sessionId); // 构建完整 Prompt String fullPrompt = buildPrompt(history, message); // 调用大模型 String response = chatClient.prompt(fullPrompt).call().content(); // 保存对话历史 conversationService.save(sessionId, message, response); // 日志记录响应 log.info("AI 响应: {}", response); return response; }
传统方式的四大痛点
耦合度高:业务代码与日志、过滤、记忆逻辑混在一起
代码冗余:每个需要拦截的接口都要重复实现这些逻辑
扩展性差:增加新的横切需求(如加限流)需要修改所有相关方法
维护困难:改一处横切逻辑,要在多处同步修改
这正是 AOP(Aspect-Oriented Programming,面向切面编程) 所解决的问题。Spring AI Advisors 借鉴了 Spring AOP 的设计理念,将横切关注点从核心业务逻辑中剥离出来-4。
三、核心概念讲解:什么是 Advisor
标准定义
Advisor(顾问/拦截器) 是 Spring AI 中拦截并增强 AI 模型调用的模块化组件,它在请求发送到模型之前和模型返回响应之后介入,可修改输入、输出或执行流程-3-4。
生活化类比
把 AI 调用想象成一次“发快递”:
核心业务:发快递这件事本身
横切关注点:快递员上门前打电话确认、包装检查、称重计费、物流单打印、签收确认——这些环节不改变“寄快递”这个核心业务,但必不可少
Advisor:每一个环节的标准化处理节点,可以灵活组合、调整顺序、插拔替换
Advisor 的核心能力
| 能力 | 说明 |
|---|---|
| 增强 Prompt | 自动注入系统提示词、对话历史、检索文档 |
| 转换输入 | 敏感词过滤、提示词重写、格式化 |
| 处理响应 | 结果校验、格式化输出、后处理 |
| 维护状态 | 对话记忆持久化、会话管理 |
| 实现模式 | RAG、Few-shot、Prompt Engineering 等可复用模式 |
四、关联概念讲解:Advisor 与 AOP 的映射
AOP 概念回顾
AOP 通过以下核心元素实现横切逻辑的模块化:
| AOP 概念 | 说明 |
|---|---|
| Join Point(连接点) | 可以插入横切逻辑的位置(如方法调用) |
| Advice(通知) | 在 Join Point 执行的横切逻辑(Before / After / Around) |
| Pointcut(切点) | 定义哪些 Join Point 需要被增强 |
| Weaving(织入) | 将 Advice 应用到目标对象的过程 |
Advisor 到 AOP 的映射
Spring AI Advisors 与 AOP 概念形成清晰的一一对应关系-4:
| AOP 概念 | Spring AI Advisor 对应 |
|---|---|
| Join Point | LLM 调用的执行(如 chatClient.call()) |
| Advice | Advisor 中实现的横切逻辑 |
| Pointcut | 通过客户端配置决定哪些调用被拦截 |
| Weaving | 运行时将 Advisors 附加到 ChatClient |
一句话总结
Advisor ≈ AI 领域的 AOP Advice —— 用你熟悉的 Spring AOP 思维模型去理解 Advisor 就对了-4。
五、内置 Advisors 速览
Spring AI 提供了多个开箱即用的内置 Advisor,覆盖常见场景-23:
| 内置 Advisor | 功能 |
|---|---|
| SimpleLoggerAdvisor | 日志拦截记录 |
| SafeGuardAdvisor | 敏感词检测与过滤 |
| ChatMemoryAdvisor | 对话记忆维护(无状态应用中保持上下文) |
| QuestionAnswerAdvisor | RAG 检索增强生成 |
| ToolCallAdvisor | 工具调用拦截与编排 |
| SemanticCacheAdvisor | 基于 Redis 的语义缓存 |
这些内置 Advisor 可直接插拔使用,无需重复造轮子。
六、代码示例:自定义日志拦截 Advisor
核心接口与执行顺序
Advisor 通过 getOrder() 返回值控制执行顺序,值越小越先执行-23。框架将所有 Advisor 按顺序组成拦截链,最后一个 Advisor 真正调用 LLM。
完整实现
import org.springframework.ai.chat.client.advisor.CallAdvisor; import org.springframework.ai.chat.client.ChatClientRequest; import org.springframework.ai.chat.client.ChatClientResponse; import org.springframework.ai.chat.client.advisor.CallAdvisorChain; @Component public class LoggingAdvisor implements CallAdvisor { private static final int ORDER = 100; @Override public int getOrder() { return ORDER; // 值越小越先执行 } @Override public String getName() { return "loggingAdvisor"; } @Override public ChatClientResponse adviseCall(ChatClientRequest request, CallAdvisorChain chain) { // 1. 前置处理:记录用户输入 log.info("【请求拦截】用户输入: {}", request.userText()); // 2. 调用链中下一个 Advisor(或最终调用 LLM) ChatClientResponse response = chain.nextCall(request); // 3. 后置处理:记录 AI 响应 log.info("【响应拦截】AI 输出: {}", response.response().getResult().getOutput()); return response; } }
注册到 ChatClient
@Configuration public class ChatClientConfig { @Autowired private LoggingAdvisor loggingAdvisor; @Bean public ChatClient chatClient(ChatClient.Builder builder) { return builder .build() .mutate() .withAdvisors(loggingAdvisor) // 注册自定义 Advisor .build(); } }
执行流程说明
用户调用
chatClient.prompt("你好").call()框架按
getOrder()排序,依次执行各个 AdvisorLoggingAdvisor先执行前置代码,记录日志chain.nextCall(request)触发下一个 Advisor(若无则直接调用 LLM)LLM 返回响应,逐层后置处理后回到客户端
七、进阶:递归 Advisors
Spring AI 从 1.1.0-M4 版本开始引入 Recursive Advisors,支持拦截链多次循环,实现迭代式工作流-23:
| 应用场景 | 说明 |
|---|---|
| 工具调用循环 | 顺序执行多个工具,每个工具的输出作为下一步决策依据 |
| 输出校验与重试 | 验证结构化响应,校验失败则附带反馈重试 |
| 自主 Agent 循环 | Agent 分析结果、决定下一步行动,循环执行直至任务完成 |
| 答案质量优化 | 评估响应质量,不符合标准时重新生成 |
传统单次传递的 Advisor 无法处理这些需要迭代的场景,递归 Advisor 通过将下游拦截链复制为子链并多次循环来解决-23。
八、底层原理与技术支撑
底层依赖技术
Spring AI Advisors 的底层依赖以下核心基础设施:
AOP 设计理念:借鉴 Spring AOP 的 Advice、Pointcut、Join Point 概念,将横切逻辑模块化
职责链模式:Advisors 按顺序形成拦截链,每个 Advisor 决定是否调用链中下一个组件
动态代理(底层机制):ChatClient 实际是被动态代理包装的对象,调用时由代理分发到 Advisor 链
关键数据流转
拦截链中传递的核心数据结构是 AdvisedRequest 和 ChatClientResponse-3:
| 组件 | 说明 |
|---|---|
userText | 用户输入的文本 |
systemText | 系统指令 |
messages | 完整对话历史 |
chatOptions | 模型配置(temperature、max_tokens 等) |
toolCallbacks | 工具/函数定义 |
Advisor 通过 AdvisedRequest.from(request).withXxx(...).build() 模式创建修改后的请求副本,既支持不可变安全修改,又保持了其他字段不变-3。
九、高频面试题与参考答案
Q1:什么是 Spring AI Advisors?解决了什么问题?
标准答案:Advisor 是 Spring AI 中拦截和增强 AI 模型调用的模块化组件,在请求发送前和响应返回后介入执行横切逻辑。它解决了传统 AI 调用中将日志、过滤、记忆、RAG 等横切关注点与业务代码耦合的问题,实现了关注点分离、代码复用和非侵入式增强。-1
踩分点:拦截机制 + 横切关注点 + 关注点分离 + 非侵入式增强
Q2:Advisors 和 Spring AOP 有什么关系?
标准答案:Advisors 借鉴了 Spring AOP 的设计理念,形成清晰的映射关系:Join Point 对应 LLM 调用执行点,Advice 对应 Advisor 中的横切逻辑,Pointcut 通过客户端配置实现,Weaving 对应运行时将 Advisors 附加到 ChatClient。Spring AI 刻意沿用 AOP 思维模型,让 Spring 开发者零成本上手。-4
踩分点:AOP 映射关系 + 四个概念一一对应 + 刻意设计
Q3:多个 Advisor 的执行顺序如何控制?
标准答案:通过实现 getOrder() 方法返回 int 值控制,数值越小越先执行。框架将所有 Advisor 按 order 值排序后组成拦截链,最后一个 Advisor 调用 LLM。推荐为不同功能定义清晰的 Order 常量,如日志 100、安全检查 200、RAG 300。-23
踩分点:getOrder() + 值越小越先执行 + 拦截链
Q4:如何自定义一个 Advisor?请简述步骤。
标准答案:实现 CallAdvisor 接口(或 StreamAroundAdvisor 支持流式),需重写三个方法:getOrder() 定义执行顺序、getName() 返回标识符、adviseCall() 实现横切逻辑。在 adviseCall() 中通过 chain.nextCall(request) 调用链中下一个 Advisor,前置处理写在调用前,后置处理写在调用后。-23-10
踩分点:接口实现 + 三个核心方法 + 前后置处理 + 注册到 ChatClient
Q5:Recursive Advisor 是什么?与传统 Advisor 有何区别?
标准答案:Recursive Advisor 是从 1.1.0-M4 引入的增强特性,支持拦截链多次循环执行,而传统 Advisor 只做单次传递。它通过复制下游拦截链为子链实现迭代控制,适用于工具调用循环、输出校验重试、Agent 自主决策等需要多轮迭代的场景。-23
踩分点:迭代执行 + 子链复制 + 适用场景
十、结尾总结
核心知识点回顾
| 知识点 | 核心要点 |
|---|---|
| Advisor 本质 | 拦截 AI 调用的模块化组件,处理横切关注点 |
| AOP 映射 | Join Point → LLM 调用;Advice → Advisor 逻辑 |
| 执行顺序 | getOrder() 值越小越先执行 |
| 内置 Advisor | 日志、记忆、RAG、缓存、工具调用等开箱即用 |
| 递归 Advisor | 支持迭代循环,用于 Agent、重试等场景 |
| 底层支撑 | AOP 思想 + 职责链模式 + 动态代理 |
重点与易错点
⚠️ 易错提醒:不要混淆 Advisor 和 Tool Calling——前者是横切拦截器,后者是模型调用外部函数的能力,二者可以配合使用但职责不同。
💡 一句话记忆:Advisor = 放在 AI 调用流程中的 AOP 拦截器,解耦横切关注点,按 order 值有序执行。
下篇预告
下一篇将深入讲解 Spring AI 中的 Tool Calling(函数调用),从原理到实战,结合 Advisor 构建自主决策的 AI Agent,敬请关注!
📌 参考来源:
[0] Spring AI 官方博客 (2026-01-23~2026-03-26)
[1] DeepWiki Advisors Framework (2026-01-13)
[2] DZone: Aspects to Advisors (2026-01-15)
[3] Volito Digital: How Spring AI Advisors Work (2026-01-19)
[4] 面试题来源:GitCode、面试鸭等 (2026-01~03)