Spring AI 常用 Advisor

文章目录

  • [Spring AI 常用 Advisor:ChatClient 增强链路与 RAG 挂载](#Spring AI 常用 Advisor:ChatClient 增强链路与 RAG 挂载)
    • [一、Advisor 是什么?](#一、Advisor 是什么?)
      • [1 三种挂载方式](#1 三种挂载方式)
    • [二、常用 Advisor 总览](#二、常用 Advisor 总览)
      • [1 Maven 依赖](#1 Maven 依赖)
    • [三、RAG 类 Advisor](#三、RAG 类 Advisor)
      • [1 QuestionAnswerAdvisor:最简 Naive RAG](#1 QuestionAnswerAdvisor:最简 Naive RAG)
      • [2 RetrievalAugmentationAdvisor:模块化 RAG](#2 RetrievalAugmentationAdvisor:模块化 RAG)
      • [3 RetrievalRerankAdvisor:检索 + 百炼 Rerank](#3 RetrievalRerankAdvisor:检索 + 百炼 Rerank)
      • [4 RAG 三者怎么选?](#4 RAG 三者怎么选?)
    • [四、记忆类 Advisor](#四、记忆类 Advisor)
      • [1 MessageChatMemoryAdvisor](#1 MessageChatMemoryAdvisor)
      • [2 VectorStoreChatMemoryAdvisor](#2 VectorStoreChatMemoryAdvisor)
    • [五、工具与调试类 Advisor](#五、工具与调试类 Advisor)
      • [1 ToolCallingAdvisor](#1 ToolCallingAdvisor)
      • [2 SimpleLoggerAdvisor](#2 SimpleLoggerAdvisor)
    • [六、推理与安全类 Advisor](#六、推理与安全类 Advisor)
      • [1 ReReadingAdvisor(Re2)](#1 ReReadingAdvisor(Re2))
      • [2 SafeGuardAdvisor](#2 SafeGuardAdvisor)
    • [七、组合示例:记忆 + RAG](#七、组合示例:记忆 + RAG)
    • 八、小结

Spring AI 常用 Advisor:ChatClient 增强链路与 RAG 挂载

技术栈:Java 21 / Spring Boot 4.1 / Spring AI 2.0.0-M1 / spring-ai-alibaba 2.0.0-M1.1。

官方参考:Advisors API · Retrieval Augmented Generation · ChatClient


一、Advisor 是什么?

Advisor 是挂在 ChatClient 上的拦截增强器 :在请求发往 LLM 之前(before)和收到回复之后(after)修改 Prompt / Response。

概念 说明
Advisor 链 多个 Advisor 按 getOrder() 排序,值越小越先执行 before
ChatClientRequest 未密封的 Prompt + context Map,Advisor 间可共享状态
before / after 改 Prompt / 改 Response;RAG 类 Advisor 主要在 before 里检索并增强用户消息

1 三种挂载方式

方式 API 适用
单次 .prompt().advisors(...) 某次调用才需要增强
默认 ChatClient.builder(...).defaultAdvisors(...) 整个 Client 统一行为
运行时参数 .advisors(a -> a.param(key, value)) 动态 filter、conversationId 等
java 复制代码
// 默认挂载 + 运行时传参
ChatClient chatClient = ChatClient.builder(chatModel)
        .defaultAdvisors(qaAdvisor)
        .build();

String answer = chatClient.prompt()
        .advisors(a -> a.param(ChatMemory.CONVERSATION_ID, "session-001"))
        .user("你好")
        .call()
        .content();

二、常用 Advisor 总览

Advisor 来源 分类 作用
QuestionAnswerAdvisor Spring AI RAG Naive RAG:VectorStore 检索 → 拼 Prompt
RetrievalAugmentationAdvisor Spring AI RAG 模块化 RAG:Query 改写 / 多路检索 / 后处理可拼装
RetrievalRerankAdvisor spring-ai-alibaba RAG 检索 → 百炼 Rerank → 生成
MessageChatMemoryAdvisor Spring AI 记忆 把历史消息注入 Prompt
VectorStoreChatMemoryAdvisor Spring AI 记忆 从 VectorStore 检索相关历史
ToolCallingAdvisor Spring AI 工具 自动执行 Function Calling 循环
SimpleLoggerAdvisor Spring AI 调试 打印 request / response
ReReadingAdvisor Spring AI 推理 Re2 重读策略,增强推理
SafeGuardAdvisor Spring AI 安全 拦截有害内容
text 复制代码
QuestionAnswerAdvisor          →  检索 → 拼 Prompt → 生成
RetrievalAugmentationAdvisor   →  预处理 → 检索 → 后处理 → 增强 → 生成
RetrievalRerankAdvisor         →  检索 → 百炼重排 → 拼 Prompt → 生成

1 Maven 依赖

xml 复制代码
<!-- RAG:QuestionAnswerAdvisor、VectorStoreChatMemoryAdvisor -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-advisors-vector-store</artifactId>
</dependency>

<!-- RAG:RetrievalAugmentationAdvisor -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-rag</artifactId>
</dependency>

<!-- RAG:RetrievalRerankAdvisor -->
<dependency>
    <groupId>com.alibaba.cloud.ai</groupId>
    <artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
    <version>2.0.0-M1.1</version>
</dependency>
包名
QuestionAnswerAdvisor org.springframework.ai.chat.client.advisor.vectorstore
RetrievalAugmentationAdvisor org.springframework.ai.rag.advisor
RetrievalRerankAdvisor com.alibaba.cloud.ai.advisor
MessageChatMemoryAdvisor org.springframework.ai.chat.client.advisor
ToolCallingAdvisor org.springframework.ai.chat.client.advisor
SimpleLoggerAdvisor org.springframework.ai.chat.client.advisor
ReReadingAdvisor 需自行实现或引用示例(见官方文档)

三、RAG 类 Advisor

1 QuestionAnswerAdvisor:最简 Naive RAG

向量检索 → 把文档拼进 Prompt → 调用 LLM。无 Rerank、无 Query 改写

java 复制代码
SearchRequest request = SearchRequest.builder()
        .topK(5)                        // 最多返回 5 条文档
        .similarityThreshold(0.45)      // 相似度下限
        .build();

// 单次挂载
String answer = ChatClient.builder(chatModel)
        .build()
        .prompt()
        .user("请基于资料详细解释机器学习")   // 用户问题
        .advisors(QuestionAnswerAdvisor.builder(vectorStore)  // 本次调用才挂载 QA Advisor
                .searchRequest(request)
                .build())
        .call()
        .content();
java 复制代码
// 默认挂载
QuestionAnswerAdvisor qaAdvisor = QuestionAnswerAdvisor.builder(vectorStore)  // 向量库作为检索源
        .searchRequest(SearchRequest.builder().topK(5).similarityThreshold(0.45).build())  // 检索参数
        .build();

ChatClient chatClient = ChatClient.builder(chatModel)
        .defaultAdvisors(qaAdvisor)   // 整个 Client 默认走 RAG
        .build();
java 复制代码
// 运行时 metadata 过滤
String answer = chatClient.prompt()
        .user("请介绍 Spring AI")       // 用户问题
        .advisors(a -> a.param(QuestionAnswerAdvisor.FILTER_EXPRESSION, "source == 'doc.md'"))  // 只检索 source=doc.md 的文档
        .call()
        .content();
Builder 方法 说明
searchRequest(SearchRequest) topK、similarityThreshold、filter
promptTemplate(PromptTemplate) 自定义模板,需含 {query}{question_answer_context}

2 RetrievalAugmentationAdvisor:模块化 RAG

基于 Modular RAG 架构,Builder 拼装:Query 变换 → DocumentRetriever → DocumentPostProcessor → QueryAugmenter。

Naive RAG

java 复制代码
Advisor ragAdvisor = RetrievalAugmentationAdvisor.builder()
        .documentRetriever(VectorStoreDocumentRetriever.builder()
                .vectorStore(vectorStore)       // 检索来源
                .similarityThreshold(0.45)      // 相似度下限
                .topK(5)                        // 最多 5 条
                .build())
        .build();

String answer = ChatClient.builder(chatModel)
        .build()
        .prompt()
        .advisors(ragAdvisor)                   // 挂载模块化 RAG Advisor
        .user("什么是机器学习?")
        .call()
        .content();

允许空检索结果时也回答

java 复制代码
Advisor ragAdvisor = RetrievalAugmentationAdvisor.builder()
        .documentRetriever(VectorStoreDocumentRetriever.builder()
                .vectorStore(vectorStore)
                .similarityThreshold(0.45)
                .topK(5)
                .build())
        .queryAugmenter(ContextualQueryAugmenter.builder()
                .allowEmptyContext(true)          // 检索为空时仍允许 LLM 回答
                .build())
        .build();

Advanced RAG:检索前改写 Query

java 复制代码
Advisor ragAdvisor = RetrievalAugmentationAdvisor.builder()
        .queryTransformers(RewriteQueryTransformer.builder()
                .chatClientBuilder(ChatClient.builder(chatModel).build().mutate())  // 用 LLM 改写 Query
                .build())
        .documentRetriever(VectorStoreDocumentRetriever.builder()
                .vectorStore(vectorStore)
                .similarityThreshold(0.45)
                .topK(5)
                .build())
        .build();
Builder 方法 说明
documentRetriever(...) 检索来源,常用 VectorStoreDocumentRetriever
queryTransformers(...) 检索前改写 Query
queryExpander(...) 一扩多 Query
queryAugmenter(...) 如何把检索文档拼进 Prompt
documentPostProcessors(...) 检索后处理,可在此做 Rerank

3 RetrievalRerankAdvisor:检索 + 百炼 Rerank

Alibaba 扩展:VectorStore 初检 → DashScope RerankModel 精排 → Prompt → LLM 。详见 RAG检索与Rerank重排序.md

java 复制代码
RetrievalRerankAdvisor rerankAdvisor = new RetrievalRerankAdvisor(
        vectorStore,    // 初检来源
        rerankModel,    // 百炼 Rerank 模型
        SearchRequest.builder().topK(5).similarityThreshold(0.45).build()  // 初检参数
);

ChatClient chatClient = ChatClient.builder(chatModel)
        .defaultAdvisors(rerankAdvisor)       // 默认走 检索→重排→生成
        .build();

String answer = chatClient.prompt()
        .user("什么是机器学习?")               // 实际 query 以 user 消息为准
        .call()
        .content();
构造参数 说明 默认值
vectorStore 初检来源 ---
rerankModel DashScopeRerankModel ---
searchRequest topK、similarityThreshold 空 SearchRequest
promptTemplate RAG Prompt 模板 内置英文模板
minScore Rerank 得分下限 0.1

SearchRequest.query 为占位,实际以 .user("...") 为准

4 RAG 三者怎么选?

场景 推荐
快速验证、代码最少 QuestionAnswerAdvisor
Query 改写 / 多路检索 / 空上下文策略 RetrievalAugmentationAdvisor
初检噪声多,需要百炼 Rerank RetrievalRerankAdvisor

四、记忆类 Advisor

多轮对话需要把历史消息注入 Prompt,常用两个 Advisor。

1 MessageChatMemoryAdvisor

ChatMemory 读取历史,以 Message 列表 形式追加到 Prompt(保留 user/assistant 结构)。

java 复制代码
ChatMemory chatMemory = MessageWindowChatMemory.builder()
        .maxMessages(20)                        // 滑动窗口最多保留 20 条消息
        .build();

ChatClient chatClient = ChatClient.builder(chatModel)
        .defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build())  // 注入对话记忆
        .build();

String answer = chatClient.prompt()
        .advisors(a -> a.param(ChatMemory.CONVERSATION_ID, "user-123"))  // 区分不同用户/会话
        .user("我叫小明")
        .call()
        .content();
运行时参数 说明
ChatMemory.CONVERSATION_ID 会话 ID,区分不同用户 / 会话

2 VectorStoreChatMemoryAdvisor

把对话历史存入 VectorStore,检索时按语义找相关历史注入 system 文本(适合长对话、历史很多)。

spring-ai-advisors-vector-store 依赖,与 QuestionAnswerAdvisor 共用 VectorStore 基础设施。


五、工具与调试类 Advisor

1 ToolCallingAdvisor

ChatClient 默认自动注册,负责 Function Calling 循环:模型请求工具 → 执行 → 结果回传 → 直到不再调用工具。

java 复制代码
// 显式注册工具,ToolCallingAdvisor 自动生效
String answer = ChatClient.builder(chatModel)
        .build()
        .prompt()
        .tools(new DateTimeTools())             // 注册可调用工具
        .user("现在几点?")                     // 模型可能触发工具调用
        .call()
        .content();
配置项 说明 默认
spring.ai.chat.client.tool-calling.enabled 是否自动注册 true
spring.ai.chat.client.tool-calling.advisor-order 链中执行顺序 HIGHEST_PRECEDENCE + 300

禁用自动注册(自行控制工具循环):

java 复制代码
chatClient.prompt()
        .advisors(AdvisorParams.toolCallingAdvisorAutoRegister(false))  // 禁用自动工具循环
        .user("...")
        .call();

2 SimpleLoggerAdvisor

打印 request / response,调试 Advisor 链和 Prompt 拼装结果。建议放在链末尾

java 复制代码
String answer = ChatClient.builder(chatModel)
        .build()
        .prompt()
        .advisors(new SimpleLoggerAdvisor())    // 打印 request/response,便于调试
        .user("你好")
        .call()
        .content();

六、推理与安全类 Advisor

1 ReReadingAdvisor(Re2)

把用户问题重复一遍拼进 Prompt,提升 LLM 推理准确率(论文:Re-Reading Improves Reasoning in LLMs)。

java 复制代码
// 官方示例为自定义类,核心 before 逻辑:
// augmentedUserText = "{query}\nRead the question again: {query}"
ChatClient chatClient = ChatClient.builder(chatModel)
        .defaultAdvisors(new ReReadingAdvisor())  // Re2 重读策略,增强推理
        .build();

2 SafeGuardAdvisor

简单内容安全拦截,防止模型生成有害内容(具体规则由实现配置)。


七、组合示例:记忆 + RAG

Advisor 按注册顺序执行;常见生产组合:先记忆,再检索

java 复制代码
ChatMemory chatMemory = MessageWindowChatMemory.builder().maxMessages(20).build();  // 对话记忆

QuestionAnswerAdvisor qaAdvisor = QuestionAnswerAdvisor.builder(vectorStore)
        .searchRequest(SearchRequest.builder().topK(5).similarityThreshold(0.45).build())
        .build();

ChatClient chatClient = ChatClient.builder(chatModel)
        .defaultAdvisors(
                MessageChatMemoryAdvisor.builder(chatMemory).build(),  // ① 先注入历史
                qaAdvisor,                                              // ② 再检索资料拼 Prompt
                new SimpleLoggerAdvisor()                               // ③ 最后打日志(可选)
        )
        .build();

String answer = chatClient.prompt()
        .advisors(a -> a.param(ChatMemory.CONVERSATION_ID, "session-001"))  // 指定会话
        .user("继续上一题,再详细说说迁移学习")   // 可引用上文 + 新知识库检索
        .call()
        .content();

#mermaid-svg-dPAkGLzFONBPV6iw{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-dPAkGLzFONBPV6iw .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-dPAkGLzFONBPV6iw .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-dPAkGLzFONBPV6iw .error-icon{fill:#552222;}#mermaid-svg-dPAkGLzFONBPV6iw .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-dPAkGLzFONBPV6iw .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-dPAkGLzFONBPV6iw .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-dPAkGLzFONBPV6iw .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-dPAkGLzFONBPV6iw .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-dPAkGLzFONBPV6iw .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-dPAkGLzFONBPV6iw .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-dPAkGLzFONBPV6iw .marker{fill:#333333;stroke:#333333;}#mermaid-svg-dPAkGLzFONBPV6iw .marker.cross{stroke:#333333;}#mermaid-svg-dPAkGLzFONBPV6iw svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-dPAkGLzFONBPV6iw p{margin:0;}#mermaid-svg-dPAkGLzFONBPV6iw .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-dPAkGLzFONBPV6iw .cluster-label text{fill:#333;}#mermaid-svg-dPAkGLzFONBPV6iw .cluster-label span{color:#333;}#mermaid-svg-dPAkGLzFONBPV6iw .cluster-label span p{background-color:transparent;}#mermaid-svg-dPAkGLzFONBPV6iw .label text,#mermaid-svg-dPAkGLzFONBPV6iw span{fill:#333;color:#333;}#mermaid-svg-dPAkGLzFONBPV6iw .node rect,#mermaid-svg-dPAkGLzFONBPV6iw .node circle,#mermaid-svg-dPAkGLzFONBPV6iw .node ellipse,#mermaid-svg-dPAkGLzFONBPV6iw .node polygon,#mermaid-svg-dPAkGLzFONBPV6iw .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-dPAkGLzFONBPV6iw .rough-node .label text,#mermaid-svg-dPAkGLzFONBPV6iw .node .label text,#mermaid-svg-dPAkGLzFONBPV6iw .image-shape .label,#mermaid-svg-dPAkGLzFONBPV6iw .icon-shape .label{text-anchor:middle;}#mermaid-svg-dPAkGLzFONBPV6iw .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-dPAkGLzFONBPV6iw .rough-node .label,#mermaid-svg-dPAkGLzFONBPV6iw .node .label,#mermaid-svg-dPAkGLzFONBPV6iw .image-shape .label,#mermaid-svg-dPAkGLzFONBPV6iw .icon-shape .label{text-align:center;}#mermaid-svg-dPAkGLzFONBPV6iw .node.clickable{cursor:pointer;}#mermaid-svg-dPAkGLzFONBPV6iw .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-dPAkGLzFONBPV6iw .arrowheadPath{fill:#333333;}#mermaid-svg-dPAkGLzFONBPV6iw .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-dPAkGLzFONBPV6iw .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-dPAkGLzFONBPV6iw .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-dPAkGLzFONBPV6iw .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-dPAkGLzFONBPV6iw .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-dPAkGLzFONBPV6iw .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-dPAkGLzFONBPV6iw .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-dPAkGLzFONBPV6iw .cluster text{fill:#333;}#mermaid-svg-dPAkGLzFONBPV6iw .cluster span{color:#333;}#mermaid-svg-dPAkGLzFONBPV6iw div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-dPAkGLzFONBPV6iw .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-dPAkGLzFONBPV6iw rect.text{fill:none;stroke-width:0;}#mermaid-svg-dPAkGLzFONBPV6iw .icon-shape,#mermaid-svg-dPAkGLzFONBPV6iw .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-dPAkGLzFONBPV6iw .icon-shape p,#mermaid-svg-dPAkGLzFONBPV6iw .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-dPAkGLzFONBPV6iw .icon-shape .label rect,#mermaid-svg-dPAkGLzFONBPV6iw .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-dPAkGLzFONBPV6iw .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-dPAkGLzFONBPV6iw .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-dPAkGLzFONBPV6iw :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 用户消息
MessageChatMemoryAdvisor
QuestionAnswerAdvisor / RetrievalRerankAdvisor
SimpleLoggerAdvisor
ChatModel
回答


八、小结

需求 推荐 Advisor
最简 RAG QuestionAnswerAdvisor
可拼装 RAG 流水线 RetrievalAugmentationAdvisor
RAG + 百炼 Rerank RetrievalRerankAdvisor
多轮对话 MessageChatMemoryAdvisor
Function Calling ToolCallingAdvisor(默认已有)
调试 Prompt SimpleLoggerAdvisor
相关推荐
cxr8281 小时前
HyperMind Lab M1 架构地基 Implementation Plan <二>
开发语言·人工智能·架构
长三角活动观察1 小时前
苏州独石传媒项目SOP拆解:从苏州智博会到出海大会,千人级活动的流程管控方法论
大数据·人工智能·传媒
小玮看世界1 小时前
[Python] str() 和 join() 的区别与实战避坑指南
前端·javascript·python
卷无止境1 小时前
FastAPI 的 WebSocket 装了些什么
后端·python·fastapi
sali-tec1 小时前
C# 基于OpenCv的视觉工作流-章103-空车位识别
人工智能·opencv·计算机视觉
码云骑士1 小时前
108-vLLM推理引擎-PagedAttention-连续批处理-吞吐提升10倍
python·vllm
DeepVisionary1 小时前
从微软砍掉Copilot的AI播客、Deep Research看AI产品“做减法“:个人版与企业版合并,超级应用呼之欲出
python·自动化
IT·侯老师1 小时前
qq-auto-reply
python
迷迭香yy1 小时前
大宗交易折溢价因子怎么挖掘本地化Python全流程实战
开发语言·人工智能·python