Spring AI 2.0 开发Java Agent智能体 - Advisors —— 拦截器模式增强AI能力
2026/5/4 20:13:53 网站建设 项目流程

大家好,我是Java1234_小锋老师,最近更新《2027版本 Spring AI 2.0 开发Java Agent智能体 视频教程》专辑,感谢大家支持。

本课程主要介绍和讲解Spring AI 2.0简介,Spring AI 2.0 HelloWorld搭建,Advisors — 拦截器模式增强AI能力,对话与提示词工程(Prompt),工具调用(Function Calling / Tools) ,RAG(检索增强生成),MCP(模型 上下文协议)和多模态支持。
等这个Spring AI2.0基础课程录制完成,接下来要发布2个 企业级Java AI实战课程,RAG企业知识库系统和AI智能客服系统。大家可以点点关注,后面更精彩。


视频教程+课件+源码打包下载:

链接:https://pan.baidu.com/s/1o-zRfndo1HHrS_uFroOiCw?pwd=1234
提取码:0000

Spring AI 2.0 开发Java Agent智能体 - Advisors —— 拦截器模式增强AI能力

Advisors 简介

Spring AI Advisors API 提供了一种灵活而强大的方式,用于拦截、修改和增强 Spring 应用程序中的 AI 驱动交互。通过利用 Advisors API,开发人员可以创建更复杂、可重用且易于维护的 AI 组件。

Spring AI 2.0 的Advisors(顾问)本质是AI 交互的中间件 / 拦截器,像给 AI 聊天加了一层 "智能过滤网",能在请求发送前、响应返回后自动处理通用逻辑,让你专注于业务核心。

这个想法来自AOP(面向切面编程)。如果你学过Spring中的AOPFilter(过滤器),那理解Advisors会觉得非常亲切。

工作原理:Advisors 如何运作?

Advisors 基于责任链模式AOP 面向切面编程思想,工作流程如下:

  1. 请求阶段:用户→ChatClient→Advisor1→Advisor2→...→LLM

    • 每个 Advisor 可以修改请求(如添加历史对话、优化提示词)

    • 也可以拦截请求(如发现敏感词直接返回错误)

  2. 响应阶段:LLM→AdvisorN→...→Advisor2→Advisor1→ChatClient→用户

    • 每个 Advisor 可以修改响应(如格式化输出、提取关键信息)

    • 也可以拦截响应(如发现不符合要求时触发重试)

Spring AI 2.0 提供两种核心接口:

  • CallAdvisor:处理非流式请求(一问一答)

  • StreamAdvisor:处理流式请求(边生成边返回)Spring

核心方法是nextCall()(非流式)和nextStream()(流式),通过调用这些方法将请求传递给下一个 Advisor,形成完整的处理链。

常用内置 Advisors:开箱即用的能力

Spring AI 2.0提供了一批内置的、可以直接使用的强大顾问,覆盖了最常见的AI增强需求:

顾问名称主要作用通俗解释
MessageChatMemoryAdvisor对话记忆“记对话”:记住用户最近说了啥,让聊天感觉是连续的
PromptChatMemoryAdvisor提示记忆“提炼对话”:把整个聊天记忆压缩成一个精炼的提示摘要
VectorStoreChatMemoryAdvisor向量存储记忆“搜相关知识”:根据用户问题,从向量数据库中找最相关的历史对话来增强记忆
QuestionAnswerAdvisor检索增强生成 (RAG)“查资料”:先在知识库里查相关信息,再把信息“喂”给AI来回答问题]
SimpleLoggerAdvisor日志记录“记流水账”:忠实记录下每次请求和响应的内容,方便调试和监控
Semantic Cache Advisor语义缓存“聪明缓存”:如果遇到意思相同的问题(而不是只字不差),可以直接返回之前缓存的答案,省时省力
ToolCallAdvisor工具调用“调用外部工具”:实现AI调用外部API、数据库等能力,通过递归(Recursive)模式可以多次循环执行
GuardrailsAdvisor安全护栏“安全检查”:在请求到达AI前或AI响应返回前拦截不当内容

自定义实现Advisors

我们来实现一个自定义简单的请求和响应日志记录Advisor

第一步:新建MySimpleLoggerAdvisor类,实现CallAdvisor和StreamAdvisor接口,同时支持两种模式。

package com.java1234.advisor; import org.springframework.ai.chat.client.ChatClientRequest; import org.springframework.ai.chat.client.ChatClientResponse; import org.springframework.ai.chat.client.advisor.api.CallAdvisor; import org.springframework.ai.chat.client.advisor.api.CallAdvisorChain; import org.springframework.ai.chat.client.advisor.api.StreamAdvisor; import org.springframework.ai.chat.client.advisor.api.StreamAdvisorChain; import reactor.core.publisher.Flux; /** * 实现CallAdvisor和StreamAdvisor接口,同时支持两种模式 */ public class MySimpleLoggerAdvisor implements CallAdvisor, StreamAdvisor { @Override public ChatClientResponse adviseCall(ChatClientRequest request, CallAdvisorChain chain) { System.out.println("发送请求:" + request); // 调用下一个Advisor,继续处理链 ChatClientResponse response = chain.nextCall(request); System.out.println("收到响应:" + response); return response; } @Override public Flux<ChatClientResponse> adviseStream(ChatClientRequest request, StreamAdvisorChain chain) { System.out.println("发送流式请求:" + request); return chain.nextStream(request) .doOnNext(response -> System.out.println("收到流式响应片段:"+response)); } @Override public String getName() { return "简单日志Advisor"; } /** * 这个 getOrder() 方法用于指定 Advisor(通知器)的执行顺序。 * 作用说明: * 返回值越小,优先级越高,越早执行 * 返回 0 表示高优先级 * 如果有多个 Advisor,Spring AI 会按照此值从小到大依次执行 * @return */ @Override public int getOrder() { return 0; } }

第二步:AiConfiguration的ChatClient聊天客户端里,构建ChatClient的时候,添加Advisor。

@Bean public ChatClient chatClient(OpenAiChatModel model){ return ChatClient .builder(model) // 创建 ChatClient 对象,并设置模型为 model .defaultAdvisors(new MySimpleLoggerAdvisor()) // 添加一个 MySimpleLoggerAdvisor,记录请求日志 .build(); // 构建 ChatClient 对象 }

最后我们来测试下:

先测试 阻塞式

http://localhost:8080/ai?question=你是谁?

控制台输出:

发送请求:ChatClientRequest[prompt=Prompt{messages=[UserMessage{content='你是谁?', metadata={messageType=USER}, messageType=USER}], modelOptions=OpenAiChatOptions: {"model":"qwen3.6-plus","streamUsage":false}}, context={}] 收到响应:ChatClientResponse[chatResponse=ChatResponse [metadata={ id: chatcmpl-005ad77a-27b5-9816-80ad-b2b269dbba56, usage: DefaultUsage{promptTokens=12, completionTokens=658, totalTokens=670}, rateLimit: { @type: org.springframework.ai.openai.metadata.OpenAiRateLimit, requestsLimit: null, requestsRemaining: null, requestsReset: null, tokensLimit: null; tokensRemaining: null; tokensReset: null } }, generations=[Generation[assistantMessage=AssistantMessage [messageType=ASSISTANT, toolCalls=[], textContent=你好!我是 Qwen(通义千问),是由阿里巴巴集团旗下通义实验室研发的大语言模型。你可以把我当作一个真诚、乐于助人的 AI 伙伴。 无论是探讨问题、寻找灵感,还是协助处理文字和逻辑任务,我都在这里。今天有什么我可以帮你的吗?, metadata={role=ASSISTANT, messageType=ASSISTANT, refusal=, finishReason=STOP, index=0, annotations=[{}], id=chatcmpl-005ad77a-27b5-9816-80ad-b2b269dbba56}], chatGenerationMetadata=DefaultChatGenerationMetadata[finishReason='STOP', filters=0, metadata=0]]]], context={}]

再测试流式的

http://localhost:8080/ai2?question=你是谁?

控制台输出:

项目里配置日志记录SimpleLoggerAdvisor

我们给项目配置下内置的SimpleLoggerAdvisor日志记录Advisor

package com.java1234.config; ​ import com.java1234.advisor.MySimpleLoggerAdvisor; import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor; import org.springframework.ai.ollama.OllamaChatModel; import org.springframework.ai.openai.OpenAiChatModel; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; ​ @Configuration public class AiConfiguration { ​ /** * 创建一个 ChatClient 对象,用于处理聊天请求。 * * @param model OpenAiChatModel 对象,用于处理聊天请求。 * @return ChatClient 对象,用于处理聊天请求。 */ @Bean public ChatClient chatClient(OpenAiChatModel model){ return ChatClient .builder(model) // 创建 ChatClient 对象,并设置模型为 model // .defaultAdvisors(new MySimpleLoggerAdvisor()) // 添加一个 MySimpleLoggerAdvisor,记录请求日志 .defaultAdvisors(new SimpleLoggerAdvisor()) // 添加一个 SimpleLoggerAdvisor,记录请求日志 .build(); // 构建 ChatClient 对象 } ​ /** * 创建一个 ChatClient 对象,用于处理聊天请求。 * * @param model OllamaChatModel 模型,用于处理聊天请求。 * @return ChatClient 模型,用于处理聊天请求。 */ @Bean public ChatClient chatClient2(OllamaChatModel model){ return ChatClient .builder(model) // 创建 ChatClient 对象,并设置模型为 model .defaultAdvisors(new SimpleLoggerAdvisor()) // 添加一个 SimpleLoggerAdvisor,记录请求日志 .build(); // 构建 ChatClient 对象 } }

以及application.yml里面要配置下日志级别:

logging: level: org.springframework.ai: debug

我们来测试下:

http://localhost:8080/ai?question=你是谁?

控制台日志输出,请求和响应都有完整的数据显示

2026-04-25T14:33:37.198+08:00 DEBUG 49764 --- [helloWorld] [nio-8080-exec-3] o.s.a.c.c.advisor.SimpleLoggerAdvisor : request: ChatClientRequest[prompt=Prompt{messages=[UserMessage{content='你是谁?', metadata={messageType=USER}, messageType=USER}], modelOptions=OpenAiChatOptions: {"model":"qwen3.6-plus","streamUsage":false}}, context={}] 2026-04-25T14:33:43.232+08:00 DEBUG 49764 --- [helloWorld] [nio-8080-exec-3] o.s.a.c.c.advisor.SimpleLoggerAdvisor : response: { "metadata" : { "empty" : false, "id" : "chatcmpl-795a2d7a-ee98-9612-bb6f-0a1f741b5416", "model" : "qwen3.6-plus", "promptMetadata" : [ ], "rateLimit" : { "requestsLimit" : null, "requestsRemaining" : null, "requestsReset" : null, "tokensLimit" : null, "tokensRemaining" : null, "tokensReset" : null }, "usage" : { "promptTokens" : 12, "completionTokens" : 267, "totalTokens" : 279, "nativeUsage" : { "completion_tokens" : 267, "prompt_tokens" : 12, "total_tokens" : 279, "prompt_tokens_details" : { }, "completion_tokens_details" : { "reasoning_tokens" : 236 } } } }, "result" : { "metadata" : { "contentFilters" : [ ], "empty" : true, "finishReason" : "STOP" }, "output" : { "media" : [ ], "messageType" : "ASSISTANT", "metadata" : { "role" : "ASSISTANT", "messageType" : "ASSISTANT", "finishReason" : "STOP", "refusal" : "", "index" : 0, "annotations" : [ { } ], "id" : "chatcmpl-795a2d7a-ee98-9612-bb6f-0a1f741b5416" }, "text" : "我是 Qwen(通义千问),由阿里巴巴集团旗下通义实验室自主研发的大语言模型。有什么我可以帮你的吗?", "toolCalls" : [ ] } }, "results" : [ { "metadata" : { "contentFilters" : [ ], "empty" : true, "finishReason" : "STOP" }, "output" : { "media" : [ ], "messageType" : "ASSISTANT", "metadata" : { "role" : "ASSISTANT", "messageType" : "ASSISTANT", "finishReason" : "STOP", "refusal" : "", "index" : 0, "annotations" : [ { } ], "id" : "chatcmpl-795a2d7a-ee98-9612-bb6f-0a1f741b5416" }, "text" : "我是 Qwen(通义千问),由阿里巴巴集团旗下通义实验室自主研发的大语言模型。有什么我可以帮你的吗?", "toolCalls" : [ ] } } ] }

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询