Spring AI + 阿里百炼:企业级RAG知识助手构建实战指南
目录
- 前言:攻克知识孤岛与模型幻觉
- 环境与前置准备
- ???? 核心依赖引入与版本锁定
- ???? 阿里百炼模型选型实战建议
- ⚙️ YAML 配置与 Nacos 动态管理
- ???? 为何选 Elasticsearch 8.x 作为向量存储?
- 实战:搭建高精度 RAG 核心流水线
- 一、 知识注入:Tika 文档解析与向量入库
- ???? 文件上传接口演示:
- ES 中验证向量数据
- 在这里插入图片描述
- 二、 检索架构:“二级漏斗”过滤机制
- 为什么 Rerank 模型是必不可少的环节?
- 三、 发起对话:流式 API 集成调用
- ???? RAG + Agent 联动对话演示:
- 总结:企业级 AI 应用的最终形态
前言:攻克知识孤岛与模型幻觉
在之前那篇《基于 Spring AI + DeepSeek:构建AI Agent 企业级服务与底层原理解析》中,我们重点拆解了如何让大模型拥有“记忆(Memory)”和“行动力(Tool Use)”。
但无论 Agent 能力多强,一个棘手的问题始终存在:大模型的知识储备截止于训练日期。它对公司的内部制度、技术规范或最新项目迭代一无所知——这正是“幻觉”问题的根源。
为了根治这个问题,ai-agent-rag 项目在 ai-agent-chat 的“记忆+工具”基础能力之上,嵌入了 RAG(检索增强生成)机制。本文的核心是:如何借助 Spring AI 的文档解析组件、Elasticsearch 向量数据库,以及阿里 DashScope 的 Rerank 重排模型,搭建一个高精度的“二级漏斗”知识检索智能体。
(注:关于 Memory 分布式缓存与 Tool Function 的底层原理,此处直接复用上篇架构,不再赘述。强烈建议搭配前文《基于 Spring AI + DeepSeek:构建AI Agent 企业级服务与底层原理解析》一起阅读,效果更佳。)
环境与前置准备
???? 核心依赖引入与版本锁定
本项目作为 spring-ai-lab 的子模块,除了继承父 POM 中的 Spring Boot (3.3.3) 和 Spring Cloud Alibaba 之外,为了支持复杂文档解析、向量存储与多模型打分,我们在 ai-agent-rag 的 pom.xml 中追加了以下关键依赖:
???? 阿里百炼模型选型实战建议
在本项目中,我们具体选用的模型搭配和注意事项如下:
1. 大语言对话模型 (LLM)
主要调用 DashScope API 的纯文本模型(如 qwen-plus)来完成最终的归纳与回复。
2. 文本向量化模型 (Embedding)
用于将上传的文档切片转化为数值向量。我们选用了最新的 text-embedding-v4。
- 选型要点:v4 版本性价比极高,更重要的是它支持丰富的输出维度选择(如2048、1536、1024、768等)。这让我们能够灵活指定维度(项目中统一为768维),从而更好地适配不同场景和 Elasticsearch 索引配置。
3. 文本排序模型 (Rerank)
在召回阶段之后,对初步匹配的文档切片进行二次精准排序,确保最相关的结果优先返回。
- 选型要点:根据官方公告,此前的
gte-rerank-v2模型将于2026年5月下线。因此我们遵循官方建议,直接启用全新的qwen3-rerank模型。该模型最大输入支持120,000 Token,非常适合在 RAG 应用中担任精排主力。
⚙️ YAML 配置与 Nacos 动态管理
以下是实际生产环境的配置示例。注释里已标注关键避坑点,配置时请务必注意维度的统一。
spring:ai:# 全局指定默认对话模型平台为 dashscopemodel:chat: dashscopedashscope:api-key: sk-xxxxxxxxxxxxxxxxxxxxxxxxxx # 你的阿里 DashScope API Key# 1. 向量化模型配置embedding:options:model: text-embedding-v4 # ???? 关键避坑:明确指定输出维度为 768dimensions: 768# 2. 重排序模型配置rerank:options:model: qwen3-rerank# 3. 大语言模型(对话)配置chat:enabled: true # 显式开启对话功能options:model: qwen-plus# 温度系数:0.1-0.2 适用于规章制度等严谨场景,能有效限制 AI 自由发挥,减少幻觉temperature: 0.2 # 单次回复的最大 Token 数max-tokens: 2000 # 核采样概率,通常保持默认 0.8 即可top-p: 0.8# 4. 向量数据库配置vectorstore:elasticsearch:# 告诉 Spring AI 把知识存入哪个索引index-name: company_knowledge_index# ???? 极关键:告诉 ES 要建多少维度的空间!# 该值【必须】与上面 embedding.options.dimensions 的值(768)完全一致,否则写入或检索时会直接报错!dimensions: 768# 距离计算方式:余弦相似度similarity: cosine# 尝试开启自动初始化(部分版本支持自动在 ES 中建立 Index 和 Mapping)initialize-schema: trueelasticsearch:uris: http://ip:9200 # 如果使用 http,请确保 ES 端关闭了强制 HTTPS 安全验证username: elasticpassword: ****** # 你的 ES 密码
???? 为何选 Elasticsearch 8.x 作为向量存储?
搭建 RAG 架构时,向量数据库的选择至关重要。本项目最终采用 Elasticsearch (ES) 8.x,主要基于以下几点:
1. ES 8.x 的原生向量检索能力升级
在 ES 7.x 版本中,实现向量检索往往需要依赖外部插件或基于 Script Score 的暴力数学计算,性能瓶颈明显。但从 ES 8.x 开始,其底层架构对向量搜索做了全面重塑:
- Lucene 底层重构:ES 核心搜索库 Lucene,在底层原生用 Java 实现了 HNSW(分层可导航小世界图)算法,显著提升了检索效率。
- 专属数据类型:引入了全新的
dense_vector(稠密向量)数据类型。 - 硬件级加速机制:当 Spring AI 将文档的特征向量(如768维浮点数)发送给 ES 时,ES 会将其存入
dense_vector字段,并在内存中构建 HNSW 索引树。查询时,ES 甚至能利用底层 SIMD 指令加速余弦距离计算,确保毫秒级的响应速度。
2. 为何不选用阿里的 DashVector?
既然模型全面拥抱阿里百炼,为什么不顺势接入阿里 DashVector 向量数据库?核心原因是生态集成便捷度。目前在 Java 环境中,DashVector 的 SDK 尚未提供好用的 Starter 依赖,需要开发者手写较多底层接入代码,集成体验相对繁琐。相比之下,ES 作为成熟检索引擎,配合 Spring AI 官方提供的 spring-ai-starter-vector-store-elasticsearch,能够实现顺滑的开箱即用。
3. 零成本架构复用与无缝接入
在大多数中大型企业架构中,Elasticsearch 几乎是提供日志分析(ELK)或复杂业务搜索的“标配”基础设施。这意味着在规划接入 AI 之前,一个稳定、高可用的 ES 集群通常已在生产环境中良好运转。此时为了落地 RAG 功能,完全不需要额外部署和运维一套全新的纯向量数据库(如 Milvus、Chroma 等)。只需复用现有的 ES 8.x 服务,即可无缝接入,极大地降低了新技术引入风险、服务器硬件成本以及运维团队的学习负担。
实战:搭建高精度 RAG 核心流水线
一、 知识注入:Tika 文档解析与向量入库
RAG 的第一步,是把人类的文档喂给数据库。普通文本解析器只能处理 .txt,这在实际企业中几乎没有价值。在 AgentRagFileController 中,我们实现了一个全自动的知识注入链路:
@PostMapping("/upload")public String uploadKnowledgeFile(@RequestParam("file") MultipartFile file) {long startTime = System.currentTimeMillis();String filename = file.getOriginalFilename();log.info("开始处理知识库文件上传任务, 文件名: {}", filename);try {// 1. 文件加载 (Load):巧妙利用 Spring 的 Resource 接口,避免在本地磁盘生成临时文件Resource resource = file.getResource();// ???? 细节亮点:使用 TikaDocumentReader// Tika 会自动嗅探文件类型(Word, PDF, Excel等),并智能剥离排版,提取出纯净文本!TikaDocumentReader documentReader = new TikaDocumentReader(resource);List
代码说明:使用 TikaDocumentReader 能够便捷地处理多种文档格式的解析,省去了针对不同后缀名编写特定解析器的繁琐工作。
???? 文件上传接口演示:
将一份内部技术操作手册(PDF或Word)通过接口传入:
上传接口日志输出:
ES 中验证向量数据
二、 检索架构:“二级漏斗”过滤机制
这是本项目中比较关键的一环。基础的 RAG 通常是去 ES 中获取 Top K 相似度的数据并直接交给大模型。
为了优化这一点,我们在 AgentRagChatController 中结合了阿里的 DashScopeRerankModel,设计了粗排+精排的二级漏斗检索机制。
@RestController@RequestMapping("/agentRag")public class AgentRagChatController {private final ChatClient chatClient;public AgentRagChatController(ChatClient.Builder chatClientBuilder,VectorStore vectorStore,ChatMemory chatMemory,DashScopeRerankModel rerankModel) {// ???? 核心细节:自研“二级漏斗”检索器 DocumentRetrieverDocumentRetriever dualRetriever = query -> {// 漏斗第一级:ES 粗排 (捞取 Top 20)// 粗排追求极致速度与高召回率(宁可错杀一千,不放过一个)List
为什么 Rerank 模型是必不可少的环节?
- ES 的向量搜索(粗排)是基于静态多维空间距离的。比如搜索“苹果公司”,它可能把“苹果又红又甜(水果)”也召回来,因为单个词向量的特征距离较近。
- Rerank 精排则是将“用户的问题”和“每一篇检索到的文档”合并,丢给大语言模型级别的神经网络去逐句阅读、交叉对比。它的算力消耗极大,因此只能对粗排出的 Top 20 逐个打分,筛选出最符合人类逻辑的 Top 3,从而彻底清洗掉噪音!
三、 发起对话:流式 API 集成调用
在完成了基础组件配置和检索逻辑后,最终的业务对话代码显得十分简洁,这也体现了 Spring AI 封装的便利性:
@GetMapping("/chat")public String chatWithKnowledge(@RequestParam("chatId") String chatId,@RequestParam("prompt") String prompt) {long startTime = System.currentTimeMillis();log.info("接收到会话 [{}] 的咨询: {}", chatId, prompt);try {// 这就是 Spring AI 极其惊艳的链式 APIString response = chatClient.prompt().user(prompt)// 绑定对话 ID,让 AI 知道本次对话属于哪个用户/窗口(触发 Memory 生效).advisors(a -> a.param("chat_memory_conversation_id", chatId)).call().content();log.info("会话 [{}] 思考完毕,耗时 {} ms", chatId, (System.currentTimeMillis() - startTime));return response;} catch (Exception e) {log.error("AI 思考时发生异常: {}", e.getMessage(), e);return "对不起,AI 助手暂时遇到了系统异常,请稍后再试。";}}
当请求到达时,底层主要经历了以下流转过程:
- 记忆加载:从 Redis 中取出
chatId对应的历史聊天记录。 - 知识检索:将用户的
prompt拿去 ES 检索出20条片段,并调用阿里大模型浓缩成3条核心片段。 - Prompt 拼装:将历史记录、3条私有文档、系统预设(System Prompt)糅合在一起,发给当前的主逻辑模型(如 DashScope 的对话模型)。
- 决策与 Tool 调用:如果大模型发现请求命中
orderFunction(例如问“根据手册规定,我的 D123456 订单退款怎么走?”),它会挂起响应,回调 Java 代码获取真实订单状态,再结合手册给出售后建议!
???? RAG + Agent 联动对话演示:
查询私有知识(RAG生效):询问刚才上传的技术手册中的公司报销流程规范。大模型准确根据文档作答,并在控制台输出精排日志。


跨界融合(RAG + Tool + Memory 生效):追问“那我的订单 D123456 满足刚刚说的报销规范吗?”。此时大模型会同时调用记忆(知道指的是报销规范)、调用 Tool(查询订单数据发现是100元已完成),然后进行推理回复!

总结:企业级 AI 应用的最终形态
通过 ai-agent-rag 这个模块,我们终于拼上了企业级 AI 应用拼图的最核心部分。
一个真正具备实战价值的 Agent 架构体系已经全面落地:
- 底座 (Memory):基于 Redis DTO 防腐层的持久化记忆。
- 左手 (RAG):基于 Elasticsearch + Tika + DashScope Rerank 搭建的“二级漏斗”私有知识大脑。
- 右手 (Tool):基于 Spring Bean
@Description实现的动态函数袋机制,链接现有业务服务。 - 大脑 (LLM):基于大语言模型的核心逻辑规划与决策。
在这一架构下,AI 不仅能进行基础对话问答,还具备了“理解意图、查阅私有文档、维持多轮上下文记忆、调用外部工具”的能力,真正成为了一个能够辅助处理实际业务流程的智能工具。
