Spring AI Advisors 核心原理与实战:从 AOP 思想到 AI 拦截链(2026.04.09)

小编 应用案例 2

一、开篇引入

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

Spring AI Advisors 核心原理与实战:从 AOP 思想到 AI 拦截链(2026.04.09)-第1张图片

二、痛点切入:为什么需要 Advisors

传统做法

Spring AI Advisors 核心原理与实战:从 AOP 思想到 AI 拦截链(2026.04.09)-第2张图片

假设一个简单的 AI 问答接口,不加入任何横切逻辑时,代码非常清爽:

java
复制
下载
@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();
    }
}

但一旦加入日志、敏感词过滤、对话记忆等功能,代码就会迅速膨胀:

java
复制
下载
@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;
}

传统方式的四大痛点

  1. 耦合度高:业务代码与日志、过滤、记忆逻辑混在一起

  2. 代码冗余:每个需要拦截的接口都要重复实现这些逻辑

  3. 扩展性差:增加新的横切需求(如加限流)需要修改所有相关方法

  4. 维护困难:改一处横切逻辑,要在多处同步修改

这正是 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 PointLLM 调用的执行(如 chatClient.call()
AdviceAdvisor 中实现的横切逻辑
Pointcut通过客户端配置决定哪些调用被拦截
Weaving运行时将 Advisors 附加到 ChatClient

一句话总结

Advisor ≈ AI 领域的 AOP Advice —— 用你熟悉的 Spring AOP 思维模型去理解 Advisor 就对了-4

五、内置 Advisors 速览

Spring AI 提供了多个开箱即用的内置 Advisor,覆盖常见场景-23

内置 Advisor功能
SimpleLoggerAdvisor日志拦截记录
SafeGuardAdvisor敏感词检测与过滤
ChatMemoryAdvisor对话记忆维护(无状态应用中保持上下文)
QuestionAnswerAdvisorRAG 检索增强生成
ToolCallAdvisor工具调用拦截与编排
SemanticCacheAdvisor基于 Redis 的语义缓存

这些内置 Advisor 可直接插拔使用,无需重复造轮子。

六、代码示例:自定义日志拦截 Advisor

核心接口与执行顺序

Advisor 通过 getOrder() 返回值控制执行顺序,值越小越先执行-23。框架将所有 Advisor 按顺序组成拦截链,最后一个 Advisor 真正调用 LLM。

完整实现

java
复制
下载
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

java
复制
下载
@Configuration
public class ChatClientConfig {
    
    @Autowired
    private LoggingAdvisor loggingAdvisor;
    
    @Bean
    public ChatClient chatClient(ChatClient.Builder builder) {
        return builder
            .build()
            .mutate()
            .withAdvisors(loggingAdvisor)  // 注册自定义 Advisor
            .build();
    }
}

执行流程说明

  1. 用户调用 chatClient.prompt("你好").call()

  2. 框架按 getOrder() 排序,依次执行各个 Advisor

  3. LoggingAdvisor 先执行前置代码,记录日志

  4. chain.nextCall(request) 触发下一个 Advisor(若无则直接调用 LLM)

  5. LLM 返回响应,逐层后置处理后回到客户端

七、进阶:递归 Advisors

Spring AI 从 1.1.0-M4 版本开始引入 Recursive Advisors,支持拦截链多次循环,实现迭代式工作流-23

应用场景说明
工具调用循环顺序执行多个工具,每个工具的输出作为下一步决策依据
输出校验与重试验证结构化响应,校验失败则附带反馈重试
自主 Agent 循环Agent 分析结果、决定下一步行动,循环执行直至任务完成
答案质量优化评估响应质量,不符合标准时重新生成

传统单次传递的 Advisor 无法处理这些需要迭代的场景,递归 Advisor 通过将下游拦截链复制为子链并多次循环来解决-23

八、底层原理与技术支撑

底层依赖技术

Spring AI Advisors 的底层依赖以下核心基础设施:

  1. AOP 设计理念:借鉴 Spring AOP 的 Advice、Pointcut、Join Point 概念,将横切逻辑模块化

  2. 职责链模式:Advisors 按顺序形成拦截链,每个 Advisor 决定是否调用链中下一个组件

  3. 动态代理(底层机制):ChatClient 实际是被动态代理包装的对象,调用时由代理分发到 Advisor 链

关键数据流转

拦截链中传递的核心数据结构是 AdvisedRequestChatClientResponse-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)

抱歉,评论功能暂时关闭!