提示:如果不能访问 OpenAI,请点击 AiCode API 注册账号,通过代理访问。
检索增强生成(RAG)作为一项核心技术,能够有效突破大语言模型在长文本处理、事实准确性及上下文感知三大维度的能力局限,为模型输出的可靠性与适配性提供关键支撑。
Spring AI 则以模块化架构为基础,为 RAG 技术的落地提供了灵活且高效的支持:一方面,开发者可基于该架构自由搭建符合特定业务需求的自定义 RAG 流程;另一方面,也能直接调用 Advisor API 所提供的开箱即用型 RAG 流程,快速实现功能部署,兼顾了技术落地的灵活性与效率。
检索增强生成(Retrieval-Augmented Generation,简称 RAG)是一种结合 “外部知识检索” 与 “大语言模型(LLM)生成” 的混合式 AI 技术,核心目标是解决纯 LLM 在事实准确性、知识时效性、领域适配性上的固有局限,让模型输出更可靠、更贴合特定场景需求。
纯 LLM(如 GPT-4、Llama 等)的训练依赖 “预训练阶段的海量通用数据”,但落地时会面临三大关键问题,而 RAG 正是针对这些痛点设计:
(1) 事实准确性差(幻觉问题)
模型可能生成 “看似合理但与事实不符” 的内容(如编造文献引用、错误数据),因为它本质是 “基于概率预测下一个词”,而非 “基于事实推理”。
使用 RAG 在生成前先从权威外部知识库中检索与问题相关的事实性信息,让模型基于“真实素材”输出,减少幻觉。
(2)知识时效性滞后
LLM 的预训练数据有“截止日期”(如 GPT-4 早期版本截止到 2023 年 4 月),无法获取训练后出现的新信息(如 2024 年的行业政策、新科研成果)。
使用 RAG 可将“最新数据”(如新闻、报告、政策文件)实时 / 定期纳入检索库,让模型随时调用“新鲜知识”。
(3)领域适配性弱
纯 LLM 的通用知识无法覆盖垂直领域的专业内容(如医疗行业的最新诊疗指南、企业内部的产品手册),输出的专业内容易流于表面。
使用 RAG 构建领域专属检索库(如医院的病例库、企业的知识库),让模型仅基于该领域的专业信息生成内容,提升专业性。
RAG 的工作逻辑可拆解为三个核心步骤,本质是“先找对素材,再精准生成”,具体流程如下:
(1)第一步:知识检索(Retrieval)—— 找到 “有用的素材”
这一步是 RAG 的“信息输入源”,核心是从外部知识库中快速定位与用户问题相关的信息,关键技术包括:
知识库构建:将原始数据(如文档、PDF、网页、数据库内容)转化为 “可检索的格式”:
文本分割:将长文档拆分为短片段(如 200-500 字的 “chunk”),避免长文本检索精度低;
向量编码:通过 “嵌入模型”(如 Sentence-BERT、OpenAI Embeddings)将文本片段转化为 “向量”(数值矩阵),捕捉文本的语义信息;
向量存储:将向量存入 “向量数据库”(如 Pinecone、Milvus、Chroma),支持高效的 “语义相似性检索”(而非传统的关键词匹配)。
检索触发:当用户提出问题时,先将问题也转化为向量,再在向量数据库中 “比对相似性”,筛选出 Top N(如 Top 5)与问题最相关的文本片段(即 “检索结果”)。
(2) 第二步:信息增强(Augmentation)—— 整合 “素材与问题”
这一步是 RAG 的“桥梁”,目的是让 LLM 清晰知道“基于哪些信息回答”:
将“用户问题” 与 “第一步检索到的相关文本片段” 整合为一个 “增强提示词(Prompt)”,格式通常为:“请基于以下参考信息回答用户问题:[检索到的文本片段 1]、[检索到的文本片段 2]... 用户的问题是:[用户原始问题]。要求:仅用参考信息回答,不编造内容。”
通过这种方式,强制 LLM “以检索到的事实为依据”,而非依赖自身可能过时或错误的预训练知识。
(3)第三步:内容生成(Generation)—— 输出 “可靠的答案”
这一步是 RAG 的 “结果输出端”,由 LLM 基于 “增强提示词” 生成最终回答:
LLM 会分析 “增强提示词” 中的问题与参考信息,结合自身的语言组织能力,生成逻辑连贯、事实准确的回答;
部分高级 RAG 还会加入“引用标注”(如“答案参考自文档 X 的第 Y 段”),进一步提升回答的可追溯性与可信度。
一个完整的 RAG 系统需要四大核心组件协同工作,各组件的选择直接影响 RAG 的效果:
数据源(Data Source): 提供 RAG 所需的外部知识,是“检索素材” 的源头。例如:企业文档(PDF/Word)、数据库、API 接口(如新闻 API)、网页、内部知识库等。
嵌入模型(Embedding Model): 将文本转化为语义向量,决定“检索的语义匹配精度”,常见嵌入模型有 Sentence-BERT、OpenAI Embeddings、LangChain Embeddings、阿里通义 Embeddings 等等。
向量数据库(Vector DB): 存储向量并支持高效相似性检索,决定“检索速度与规模”。常见向量数据库有 Pinecone(云服务)、Milvus(开源)、Chroma(轻量开源)、FAISS(Facebook 开源,适合小规模)等等。
大语言模型(LLM):基于增强提示词生成回答,决定“输出的语言质量与逻辑”。例如:GPT-4/3.5、Llama 3、Qwen(通义千问)、ChatGLM、Mistral 等等。
RAG 因 “可定制知识库” 的特性,广泛适用于需要“事实性、专业性、时效性” 的场景,典型案例包括:
(1)企业知识库问答
场景:员工查询企业制度、产品手册、客户案例;客户咨询产品功能 / 售后政策。
示例:某科技公司将 “产品 API 文档、故障排查手册” 存入 RAG 知识库,客服可通过 RAG 快速获取准确答案,无需记忆复杂技术细节。
(2)垂直领域研究辅助
场景:医生查询最新诊疗指南、科研人员检索领域论文、律师查阅法规案例。
示例:某医院构建 “肿瘤诊疗 RAG 系统”,整合《NCCN 肿瘤临床实践指南》及最新 SCI 论文,医生输入患者病情后,RAG 可输出基于权威文献的治疗建议。
(3)实时信息问答
场景:获取最新新闻解读、股票市场动态、行业政策分析。
示例:某财经平台将 “实时财经新闻、财报数据” 接入 RAG,用户提问 “某公司 2024 年 Q2 营收情况” 时,RAG 可检索最新财报数据并生成分析。
(4)文档理解与总结
场景:快速总结长文档(如合同、报告)、提取关键信息。
示例:律师上传一份 100 页的合同,RAG 可检索并提取 “违约责任、付款期限” 等核心条款,生成精简摘要。
很多人会混淆 RAG 与 LLM 微调,二者都是 “提升 LLM 适配性” 的技术,但核心逻辑完全不同,选择时需结合场景:
对比维度 | 检索增强生成(RAG) | 模型微调(Fine-Tuning) |
核心逻辑 | “外部调用知识”:不改变 LLM 本身,通过检索实时提供素材 | “内部植入知识”:用领域数据重新训练 LLM,改变模型参数 |
知识更新 | 灵活:新增知识只需更新检索库,无需重新处理 | 固定:更新知识需重新微调,成本高、周期长 |
数据需求 | 低:少量领域数据即可构建检索库(如几十篇文档) | 高:需大量高质量标注数据(通常数千 / 数万条) |
成本与难度 | 低:无需专业 AI 团队,开源工具(如 LangChain)可快速搭建 | 高:需算力(GPU)、数据标注、AI 算法团队支持 |
适用场景 | 知识频繁更新(如新闻、政策)、领域数据少、需可追溯性的场景 | 知识固定(如通用领域规则)、数据充足、对响应速度要求极高的场景 |
随着 AI 落地需求的增长,RAG 正朝着 “更高效、更智能、更易用” 的方向发展,主要趋势包括:
多模态 RAG:支持检索图片、音频、视频等非文本素材(如基于图片检索产品信息,生成图文结合的回答);
自适应检索:根据问题类型(如事实类、分析类)动态调整检索策略(如事实类选 Top 3 精准片段,分析类选 Top 10 全面片段);
轻量化部署:推出更轻量的向量数据库与嵌入模型,支持在企业私有服务器、边缘设备上部署(满足数据隐私需求);
与 Agent 结合:RAG 作为 AI Agent 的 “知识模块”,让 Agent 具备 “自主检索信息、解决复杂任务” 的能力(如 Agent 自主检索文献并撰写科研报告)。
Spring AI 通过 Advisor API 为常见 RAG 流程提供开箱即用的支持。例如 QuestionAnswerAdvisor(问答顾问组件)和 RetrievalAugmentationAdvisor(检索增强顾问组件)。
如果要使用 QuestionAnswerAdvisor 或 RetrievalAugmentationAdvisor,则需要添加 spring-ai-advisors-vector-store 依赖至项目,如下:
<dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-advisors-vector-store</artifactId> </dependency>
下面通过 QuestionAnswerAdvisor 演示如何在 Spring AI 中使用 RAG 功能。详细步骤如下:
第一步:添加依赖 spring-ai-advisors-vector-store 到 pom.xml。
第二步:配置 AI,这里使用 SimpleVectorStore(内存版本简单向量存储)替代向量数据库,预先存入 2025 年的几条新闻信息。然后配置 QuestionAnswerAdvisor,如下:
package com.hxstrive.springai.springai_openai.rag.rag1.config; import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor; import org.springframework.ai.chat.client.advisor.vectorstore.QuestionAnswerAdvisor; import org.springframework.ai.document.Document; import org.springframework.ai.embedding.EmbeddingModel; import org.springframework.ai.vectorstore.SimpleVectorStore; import org.springframework.ai.vectorstore.VectorStore; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.ArrayList; import java.util.List; /** * AI配置 * @author Administrator */ @Configuration public class AiConfig { @Bean public VectorStore vectorStore(EmbeddingModel embeddingModel) { // 使用内存实现的简单向量存储(生产环境需替换为 Pinecone 等) SimpleVectorStore vectorStore = SimpleVectorStore.builder(embeddingModel).build(); List<Document> documentList = new ArrayList<>(); documentList.add(new Document("2025 年 8 月 26 日,第三届反恐国际研讨会在新疆乌鲁木齐举行。" + "外交部安全司司长王立新出席并表示,国际反恐形势更趋复杂严峻," + "“东伊运” 等恐怖组织威胁中国及国际地区安全稳定,各国应践行相关倡议,维护世界和平安全。")); documentList.add(new Document("2025 年 8 月 27 日,国务院新闻办公室举行新闻发布会宣布," + "以 “数智领航,服贸焕新” 为年度主题的 2025 年中国国际服务贸易交易会将于 9 月 10 日至 14 日在北京举办。" + "届时将有 70 余个国家和国际组织设展办会,近 2000 家企业拟线下参展。")); documentList.add(new Document("2025 年 8 月 26 日,伊朗外交部发言人巴加埃宣布," + "伊朗总统佩泽希齐扬将赴华参加在天津举办的上海合作组织峰会,并期待进一步推动与中国的双边关系。")); documentList.add(new Document("2025 年 8 月 24 日,以色列国防军对也门首都萨那的多个军事目标发动空袭。" + "据胡塞武装控制的卫生部门统计,袭击已造成至少 4 人死亡、67 人受伤。" + "以总理内塔尼亚胡、防长卡茨以及以军总参谋长扎米尔当天在以色列空军指挥中心观摩了这次行动。")); vectorStore.add(documentList); return vectorStore; } @Bean public QuestionAnswerAdvisor questionAnswerAdvisor(VectorStore vectorStore) { return QuestionAnswerAdvisor.builder(vectorStore).build(); } @Bean public SimpleLoggerAdvisor simpleLoggerAdvisor() { return new SimpleLoggerAdvisor(); // 默认配置 } }
第三步:实现一个 controller,通过 /ai?message= 接口发起对话,如下:
package com.hxstrive.springai.springai_openai.rag.rag1.controller; import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor; import org.springframework.ai.chat.client.advisor.vectorstore.QuestionAnswerAdvisor; import org.springframework.ai.chat.memory.ChatMemory; import org.springframework.ai.chat.model.ChatModel; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class AIController { @Autowired private ChatModel chatModel; @Autowired private SimpleLoggerAdvisor simpleLoggerAdvisor; @Autowired private QuestionAnswerAdvisor questionAnswerAdvisor; @GetMapping("/ai") public String completion(@RequestParam("message") String message) { // 构建 RAG advisor 时需要完成 vectorStore 初始化 ChatClient chatClient = ChatClient.builder(chatModel) .defaultSystem("使用中文进行回复") .defaultAdvisors( simpleLoggerAdvisor, // 打印日志的 advisor questionAnswerAdvisor // 问答 advisor ) .build(); // conversationId 区分不同对话,定位对应的历史记录 String conversationId = "sessionId-202572020514"; return chatClient.prompt() // 运行时设置会话ID参数 .advisors(advisor -> { advisor.param(ChatMemory.CONVERSATION_ID, conversationId); }) .user(message) .call() .content(); } }
启动应用程,使用浏览器访问如下地址:
http://localhost:8080/ai?message=第三届反恐国际研讨会在哪里举行?
此时,浏览器将输出如下内容:
为了进一步了解 QuestionAnswerAdvisor 是如何工作的,去看看后端打印的日志,如下:
提示:如果不能访问 OpenAI,请点击 AiCode API 注册账号,通过代理访问。