Spring AI 的 Advisors

16 阅读5分钟

声明:大学牲学习记录,笔记来自官方和ai,非干货,佬可滑走。

Adivosrs前言

Spring AI Adviosrs 提供了一种灵活而强大的方式来拦截、修改和增强 Spring 应用中的AI 驱动交互。通过利用 Advisors API, 开发者可以创建更复杂、可重用和可维护的 AI 组件。 其主要优势包括封装重复的生成式 AI 模式、转换发送到大型语言模型(LLM)和从其接收的数据,以及在各种模型和用例之间提供可移植性。

ChatMemory chatMemory = ... // Initialize your chat memory store
VectorStore vectorStore = ... // Initialize your vector store

var chatClient = ChatClient.builder(chatModel)
    .defaultAdvisors(
        MessageChatMemoryAdvisor.builder(chatMemory).build(), // chat-memory advisor
        QuestionAnswerAdvisor.builder(vectorStore).build()    // RAG advisor
    )
    .build();

var conversationId = "678";

String response = this.chatClient.prompt()
    // Set advisor parameters at runtime
    .advisors(advisor -> advisor.param(ChatMemory.CONVERSATION_ID, conversationId))
    .user(userText)
    .call()
	.content();

建议在构建时使用构建器的 defaultAdvisors() 方法注册 Advisor。

Advisors 也参与可观察性堆栈,因此您可以查看与其执行相关的指标和追踪。

Client 的增强插件,纯能力层:RAG、记忆持久化、提示词加固、内容过滤都靠各种 Advisor。

用户提问
    ↓
ChatClient 入口
    ↓
【所有注册的 Advisor 前置拦截】
    ↓
QuestionAnswerAdvisor 触发:
   1. 拿用户问题 → 调检索器查向量库
   2. 把检索到的文档上下文 拼接到 Prompt
    ↓
加工后的完整Prompt
    ↓
发送给 大模型 Model
    ↓
模型生成答案返回
    ↓
【Advisor 后置拦截(可选)】
    ↓
最终结果返回

PromptChatMemoeryAdvisor 实现上下文记忆

String analysisResult = chatClient
        .prompt(analysisPrompt)
        .advisors(a -> a
                .param(CHAT_MEMORY_CONVERSATION_ID_KEY, requestParameter.getSessionId()) // 绑定会话ID,实现上下文记忆
                .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 1024))
        .call().content(); // 限制最多拉1024字符历史

底层实现原理

// 全局注册:内存型记忆管理器 + 记忆增强器
PromptChatMemoryAdvisor.builder(
    MessageWindowChatMemory.builder()
    .maxMessages(100) // 默认最多存100条对话 
    .build()
).build()

MessageWindowChatMemory:JVM 内存存储(底层是 ConcurrentHashMap) Key:sessionId Value:该会话的所有历史对话(用户提问 + AI 回答)

PromptChatMemoryAdvisor 是 Spring AI 实现上下文记忆的核心增强器,工作流程如下

  1. 存储层:默认使用 MessageWindowChatMemory 基于 JVM 内存的ConcurrentHashMap存储对话,以 sessionId 为 Key;
  2. 调用前:拦截 AI 请求,根据传入的 sessionId 读取历史对话,按 retrieveSize 限制长度后,拼接到当前 Prompt 上下文;
  3. 调用后:自动将本次对话追加到内存中,超过最大条数则淘汰旧消息;
  4. 参数传递:代码中传入的会话 ID 和拉取长度,是专门供给该增强器使用的固定参数,实现精准的上下文管理。整个记忆过程全自动,无需手动操作存取逻辑。

Advisor跟RAG什么关系?

Advisor与RAG知识库的关系可以概括为:Advisor是RAG功能的实现载体,具体体现在以下几个方面: Spring AI 使用Advisor API 为常见的 RAG 流提供开箱即用的支持。 要使用 QuestionAnswerAdvisorVectorStoreChatMemoryAdvisor,需要在项目中添加 spring-ai-advisors-vector-store 依赖。

<dependency>
   <groupId>org.springframework.ai</groupId>
   <artifactId>spring-ai-advisors-vector-store</artifactId>
</dependency>

1. QuestionAnswerAdvisor:RAG的核心实现组件

向量数据库存储 AI 模型不知道的数据。当用户问题发送到 AI 模型时,QuestionAnswerAdvisor 会查询向量数据库以获取与用户问题相关的文档。 向量数据库的响应会附加到用户文本中,为AI 模型生成响应提供上下文。 假设您已经将数据加载到 VectorStore 中,您可以通过向 ChatClient 提供 QuestionAnswerAdvisor 实例来执行检索增强生成(RAG) 代码示例:展示QuestionAnswerAdvisor的配置和使用

// 1. 初始化向量存储
VectorStore vectorStore = new PgVectorStore(jdbcTemplate, embeddingModel);

// 2. 配置QuestionAnswerAdvisor
QuestionAnswerAdvisor ragAdvisor = QuestionAnswerAdvisor.builder(vectorStore)
       .withSearchRequest(SearchRequest.builder()
               .topK(5)  // 返回前5个结果
               .similarityThreshold(0.7)  // 相似度阈值
               .filterExpression("knowledge_type == 'technical'")  // 过滤条件
               .build())
       .build();

// 3. 集成到ChatClient
ChatClient chatClient = ChatClient.builder(chatModel)
       .defaultAdvisors(ragAdvisor)
       .build();

// 4. 使用带RAG的ChatClient
String response = chatClient.prompt()
       .user("Spring AI框架的核心组件有哪些?")
       .call()
       .content();

在此示例中,QuestionAnswerAdvisor 将对向量数据库中的所有文档执行相似性搜索。为了限制搜索的文档类型,SearchRequest 接受一个类似 SQL 的过滤表达式,该表达式在所有 VectorStore 中都是可移植的。

此过滤表达式可以在创建 QuestionAnswerAdvisor 时配置,因此它将始终适用于所有 ChatClient 请求,或者可以在运行时根据每个请求提供。

以下是如何创建 QuestionAnswerAdvisor 实例,其中阈值为 0.7 并返回前 5 个结果。

工作原理:

  1. 拦截用户问题
  2. 将问题转换为向量
  3. 在向量数据库中执行相似性搜索
  4. 将检索到的相关文档附加到用户问题中
  5. 将增强后的上下文发送给AI模型
  6. 处理模型响应并返回给用户

2. 架构层面的关系

  • RAG流程 :RAG = 检索(Retrieval) + 增强(Augmentation) + 生成(Generation)
  • Advisor角色 :QuestionAnswerAdvisor负责"检索"和"增强"两个步骤,是RAG流程的关键环节
  • 集成方式 :通过ChatClient的advisors()方法集成到AI交互流程中

3. 技术实现细节

  • 向量存储依赖:QuestionAnswerAdvisor需要依赖VectorStore(如PgVectorStore)来存储和检索向量
  • 过滤能力:支持通过SearchRequest设置过滤表达式,限制搜索范围
  • 参数配置:可配置相似度阈值、返回结果数量等参数
  • 运行时参数:支持在运行时动态设置参数,如conversationId

4. 优势与价值

  • 封装复杂性:将RAG的复杂逻辑封装为简单的Advisor接口
  • 可重用性:同一QuestionAnswerAdvisor实例可在多个ChatClient中重用
  • 可移植性:基于Spring AI的标准接口,可在不同模型和用例间移植
  • 可观察性:参与可观察性堆栈,支持指标和追踪