资讯动态

Spring AI RAG 检索增强生成:概念、实战与完整代码

发布时间:2026/8/23 2:54:14 来源:尧图企业网站定制
场景Spring AI ChatMemory 对话记忆配置JDBC方式到Mysql数据库实战示例与原理讲解https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/161040572基于上述基础学习RAG的使用。大语言模型LLM存在知识滞后、易产生幻觉、领域知识不足等局限性。检索增强生成Retrieval Augmented GenerationRAG技术通过“外部知识检索 LLM生成”的模式在回答问题前先从外部知识源中查找相关信息再结合自身能力组织语言输出有效弥补了这些缺陷。本文将基于之前的 Spring AI 1.1.2 Ollama 技术栈系统性地介绍 RAG 的核心概念、Spring AI 中的实现方式并提供可直接运行的完整实例代码。一、RAG 核心概念与工作流程1.1 什么是 RAGRAG 技术的核心在于将检索与生成相结合。传统的生成模型依赖训练数据来生成回答当面对新问题或新兴领域知识时可能产生不准确或不合逻辑的回答。RAG 引入检索机制在接收到用户问题后首先从外部知识库中检索相关信息然后将其与原始问题一同输入给生成模型从而产生更准确、上下文相关的答案。1.2 RAG 四步流程步骤说明关键技术① 文档加载与分块Ingestion将原始文档PDF、TXT 等加载进来切割成适合嵌入的小片段chunksDocumentReader、TokenTextSplitter② 向量化与存储Embedding Store用 Embedding 模型将文本片段转换为高维向量存入向量数据库EmbeddingModel、VectorStore③ 语义检索Retrieval用户提问时将问题同样向量化在数据库中执行相似度搜索检索最相关片段SearchRequest、相似度计算④ 增强生成Generation将检索到的相关文档片段作为上下文与用户问题一起提交给 LLM生成精准回答ChatClient PromptTemplate1.3 向量数据库向量数据库专门用于存储、管理和高效检索高维向量数据。其核心优势是支持语义级搜索——例如“苹果手机”和“iPhone”虽关键词不同但语义相近其向量距离很小可被精准匹配到。Spring AI 通过 VectorStore 接口抽象了向量数据库的访问支持多种实现SimpleVectorStore内存向量库适合原型开发ElasticsearchPgVectorMilvus / Weaviate / Chroma 等1.4 关键组件依赖关系组件角色Spring AI 接口Document表示原始文档及其元数据org.springframework.ai.document.DocumentDocumentReader从文件系统加载文档JsonReader、TextReader、PagePdfDocumentReaderTextSplitter将长文本切割成小块TokenTextSplitterEmbeddingModel将文本转换为向量EmbeddingModelOllama 提供VectorStore存储和检索向量SimpleVectorStore、ElasticsearchVectorStore等QuestionAnswerAdvisor拦截用户请求自动检索并注入上下文QuestionAnswerAdvisor.builder(vectorStore)二、Spring AI RAG 实现方式Spring AI 通过 Advisor API 为 RAG 提供了开箱即用的支持核心组件是 QuestionAnswerAdvisor。使用时需要添加 spring-ai-advisors-vector-store 依赖2.1 QuestionAnswerAdvisor 工作原理当用户问题发送到 AI 模型时QuestionAnswerAdvisor 会查询向量数据库以获取与用户问题相关的文档将这些文档附加到用户文本中作为上下文然后再提交给 AI 模型生成回答。其可配置项为配置项说明示例similarityThreshold相似度阈值低于此值的文档将被过滤0.8topK返回最相关的前 K 个文档6FILTER_EXPRESSION动态过滤表达式类似 SQL WHEREtype SpringpromptTemplate自定义提示词模板控制上下文与用户问题的拼接方式包含{query}和{question_answer_context}占位符2.2 检索与生成分离的 ETL 模型Spring AI RAG 遵循 ETLExtract-Transform-Load模型Extract提取从知识库中读取文档。Transform转换将文档分割为小块并通过 Embedding 模型转换为向量。Load加载将向量数据写入向量数据库。这三个步骤通常在应用启动时完成。运行时基于 ETL 模型实现真正的 RAG——用户的查询被嵌入向量数据库被查询检索到的文档被注入到 LLM 的提示词中。2.3 RAG Advisor 与其他 Advisor 的组合RAG 的 QuestionAnswerAdvisor 可以与之前介绍的 Advisor 自由组合组合方式效果QuestionAnswerAdvisorMessageChatMemoryAdvisor带记忆的 RAG 问答QuestionAnswerAdvisorSensitiveWordGuardAdvisor安全过滤 RAGQuestionAnswerAdvisorSimpleLoggerAdvisor调试日志全部组合安全过滤 → 日志记录 → 对话记忆 → 文档检索 → LLM 生成注博客https://blog.csdn.net/badao_liumang_qizhi实现以下示例基于 Spring AI 1.1.2 Ollama SimpleVectorStore演示如何从零构建一个本地 RAG 知识库问答系统。pom.xmlproperties java.version17/java.version spring-ai.version1.1.2/spring-ai.version /properties !-- 新增使用 Spring AI BOM 统一管理所有模块版本 -- dependencyManagement dependencies dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-bom/artifactId version${spring-ai.version}/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency !-- Spring AI Ollama 核心 -- dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-model-ollama/artifactId /dependency !-- RAG Advisor核心提供 QuestionAnswerAdvisor -- dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-advisors-vector-store/artifactId /dependency !-- Tika 文档读取器支持 PDF、Word、TXT 等多种格式 -- dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-tika-document-reader/artifactId /dependency /dependencies示例知识库文件在src/main/resources/knowledge-base/badao-internal.txt 中创建Badao科技内部知识库 ## 公司政策 - 员工年假入职满1年享受10天带薪年假满3年增加到15天。 - 远程办公每周三、周五为固定远程办公日。 - 报销流程所有报销需在“易报销”系统提交金额超过500元需部门经理审批。 ## 内部项目 - 项目代号“天枢”基于Spring AI与Ollama构建的企业智能助手负责人为张三。 - 项目代号“瑶光”下一代实时数据湖方案采用Apache Iceberg Flink负责人为李四。 - 内部编码规范所有Java项目必须使用Lombok禁止使用var关键字SQL必须使用参数化查询。 ## 技术选型 - 消息中间件统一使用RocketMQ禁止引入RabbitMQ。 - 向量数据库生产环境采用PgVector开发环境可使用SimpleVectorStore。 - 前端框架统一使用React 18 Ant Design 5.x。 ## 团队联系人 - 基础架构组赵六zhaoliubadao.com - AI组王五wangwubadao.com - 数据组钱七qianqibadao.comapplication.yml​ server: port: 886 spring: # 替换为实际密码 ai: ollama: base-url: http://localhost:11434 chat: model: qwen2.5:7b-instruct options: temperature: 0.3 # RAG 场景建议使用较低温度减少幻觉 embedding: model: nomic-embed-text # Embedding 模型用于文档向量化 options: num-batch: 4 # 一次处理的文本数量 logging: level: org.springframework.ai.rag: DEBUG org.springframework.ai.vectorstore: DEBUG ​Embedding 模型下载项目启动前执行ollama pull nomic-embed-text模型选型说明Chat 模型qwen2.5:7b-instruct 支持工具调用且中文能力强适合生成自然语言回答。也可选择 deepseek-r1:8b、llama3.1:8b 等。Embedding 模型nomic-embed-text 生成 768 维向量免费且质量好。也可选择 bge-m31024 维、mxbai-embed-large1024 维等但需修改配置文件中 dimensions 参数。核心要求Chat 模型和 Embedding 模型都必须是 Ollama 本地已下载的模型且 Embedding 模型的向量维度必须与向量数据库的 dimensions 配置一致。VectorStoreConfig — 文档加载与向量存储初始化Spring AI 在 RAG 流程中默认不负责文档分词文档的加载与分词需要开发者显式调用 DocumentReader 和 TextSplitter 来完成。package com.badao.ai.config; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.ai.document.Document; import org.springframework.ai.document.DocumentReader; import org.springframework.ai.reader.tika.TikaDocumentReader; import org.springframework.ai.transformer.splitter.TokenTextSplitter; import org.springframework.ai.vectorstore.SimpleVectorStore; import org.springframework.ai.vectorstore.VectorStore; import org.springframework.ai.embedding.EmbeddingModel; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.CommandLineRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.Resource; import java.util.List; Configuration public class VectorStoreConfig { private static final Logger logger LoggerFactory.getLogger(VectorStoreConfig.class); Value(classpath:knowledge-base/badao-internal.txt) private Resource knowledgeResource; Bean public VectorStore vectorStore(EmbeddingModel embeddingModel) { // 创建内存向量库开发演示用 return SimpleVectorStore.builder(embeddingModel).build(); } Bean public CommandLineRunner loadDocuments(VectorStore vectorStore) { return args - { // 1. 使用 Tika 读取文档自动检测文件类型 DocumentReader reader new TikaDocumentReader(knowledgeResource); ListDocument documents reader.get(); logger.info(共读取到 {} 个文档, documents.size()); // 2. 文本分块TokenTextSplitter 按语义切分更适合中文 TokenTextSplitter splitter TokenTextSplitter.builder() .withChunkSize(300) // 每个块最多 300 token .withMinChunkSizeChars(50) // 最小块字符数避免出现极短碎片替代原来 minChunkSize 的功能 .withMinChunkLengthToEmbed(5) // 保留默认过滤极短内容 .withKeepSeparator(true) // 保留原文换行等分隔符 .build(); ListDocument chunks splitter.apply(documents); logger.info(文本切分为 {} 个片段, chunks.size()); // 3. 写入向量数据库自动调用 EmbeddingModel 向量化 vectorStore.add(chunks); logger.info(向量化完成向量库初始化成功); }; } }要点说明SimpleVectorStore 是 Spring AI 内置的内存向量库实现适合原型开发和小规模知识库文档量不超过几千条。数据存在内存中服务重启后需要重新加载生产环境请替换为 PgVectorStore、ElasticsearchVectorStore 等持久化方案。TokenTextSplitter 按 Token 数量切分文本避免切断句子。chunkOverlap 设置重叠区域保证语义连贯性防止关键信息被切断。TikaDocumentReader 基于 Apache Tika可自动识别 PDF、Word、TXT、HTML 等多种文档格式无需手动判断文件类型。RagConfig — 注册 RAG Advisorpackage com.badao.ai.config; import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.client.advisor.vectorstore.QuestionAnswerAdvisor; import org.springframework.ai.chat.model.ChatModel; import org.springframework.ai.vectorstore.SearchRequest; import org.springframework.ai.vectorstore.VectorStore; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; Configuration public class RagConfig { Bean public ChatClient chatClient(ChatModel chatModel, VectorStore vectorStore) { return ChatClient.builder(chatModel) .defaultAdvisors( QuestionAnswerAdvisor.builder(vectorStore) .searchRequest(SearchRequest.builder() .similarityThreshold(0.7) // 相似度阈值 .topK(3) // 返回前 3 个最相关文档 .build()) .build() ) .build(); } }RagServicepackage com.badao.ai.service; import org.springframework.ai.chat.client.ChatClient; import org.springframework.stereotype.Service; Service public class RagService { private final ChatClient chatClient; public RagService(ChatClient chatClient) { this.chatClient chatClient; } /** * 基于知识库的 RAG 问答 */ public String ask(String question) { return chatClient.prompt() .user(question) .call() .content(); } }控制器package com.badao.ai.controller; import com.badao.ai.service.RagService; import org.springframework.web.bind.annotation.*; RestController RequestMapping(/api) public class RagController { private final RagService ragService; public RagController(RagService ragService) { this.ragService ragService; } PostMapping(/rag) public ChatResponse rag(RequestBody ChatRequest request) { String result ragService.ask(request.message()); return new ChatResponse(200, success, result); } public record ChatRequest(String message) {} public record ChatResponse(int code, String msg, String data) {} }测试验证常用优化策略策略说明配置示例提高相似度阈值相同topK下减少候选文档量剔除不相关文档similarityThreshold(0.8)降低相似度阈值相同topK下增加候选文档量适合文档量大的场景similarityThreshold(0.5)控制返回数量topK不宜过大否则会超出模型上下文窗口topK(3)文档分块优化调整chunkSize和chunkOverlap平衡精度和召回率chunkSize(300),chunkOverlap(50)动态过滤按文档类型、日期等元数据过滤.param(QuestionAnswerAdvisor.FILTER_EXPRESSION, type manual)自定义提示词模板控制上下文与用户问题的拼接格式提升回答质量见 上文总结环节核心组件关键操作文档加载TikaDocumentReader自动识别多种文档格式文本分块TokenTextSplitterchunkSize(300),chunkOverlap(30)向量化EmbeddingModelOllama 提供nomic-embed-text模型向量存储VectorStore开发用SimpleVectorStore生产用 PgVector / Elasticsearch检索 生成QuestionAnswerAdvisorsimilarityThresholdtopK控制检索质量增强生成ChatClient检索结果自动注入上下文RAG 技术让通用大模型能够“读懂”你的私有文档在面对特定领域问题时给出精准答案。结合 Spring AI 的模块化设计和 Ollama 的本地模型能力Java 开发者可以轻松构建安全、高效、低成本的本地知识库问答系统。本文系统地介绍了 Spring AI RAG 的核心概念与完整实现方式。关键要点回顾

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价