核心内容摘要
《泡我家的黑田辣妹》第二集免费观:心动与心碎的成人童话
在 AI 应用开发中大模型常面临 “知识过期”“不懂私有数据” 的痛点而检索增强生成RAG技术正是解决这一问题的核心方案。
RAG 能够将大模型与私有知识库结合让生成的回答更准确、更具针对性。
本文将深入拆解 RAG 的技术原理、核心流程重点讲解其与 Embedding 技术的协同逻辑并结合智普 AI 实现本地知识库检索的完整实操帮助大家掌握 Spring AI 中 RAG 模块的开发精髓。
什么是 RAG核心原理与
核心价值一RAG 定义Retrieval-Augmented GenerationRAG即检索增强生成是一种结合 “检索” 与 “生成” 的 AI 技术。
它通过在大模型生成回答前从外部知识库中检索与用户问题相关的信息并将这些信息作为上下文传递给大模型从而让大模型基于外部知识生成更准确、更可靠的回答。
二RAG 的
核心价值RAG 的
核心价值是为大模型 “外接动态知识库”在不重训 / 微调的前提下低成本解决知识过期、私有数据不可用、幻觉与高成本四大核心痛点让回答更准、更新、更合规、更易维护。
解决知识局限无需重新训练大模型即可让其掌握私有数据如企业文档、专业知识库或最新信息避免 “知识过期” 问题。
提升回答准确性基于具体的外部知识生成回答减少大模型 “一本正经地胡说八道”幻觉现象。
降低开发成本无需投入海量算力进行模型微调通过简单的知识库配置即可扩展大模型能力。
支持灵活更新外部知识库可独立更新无需改动大模型或应用代码适配快速变化的业务需求。
三RAG 与 Embedding 的协同逻辑语义检索的核心支撑RAG 技术的核心是 “精准检索”而 Embedding 技术是实现这一目标的关键前提二者是 “基础支撑” 与 “上层应用” 的紧密协同关系。
简单来说Embedding 是 RAG 技术的 “语义翻译官”它将非结构化的文本知识库片段、用户问题翻译成机器可理解、可计算的向量语言没有 Embedding 提供的语义量化能力RAG 就无法实现高效的 “检索增强”只能依赖大模型的原生知识库。
RAG 的核心流程RAG 技术的完整流程可分为三个核心阶段每个阶段都与 Embedding 技术深度协同一索引阶段知识库向量化存储将本地知识库文档、数据库等解析为文本片段Chunks再通过 Embedding 模型将这些片段转换为语义向量保存到向量数据库。
二检索阶段相似文本精准匹配将用户提出的问题通过相同的 Embedding 模型将问题转换为语义向量然后在向量数据库中通过相似度算法如余弦相似度计算问题向量与所有文本片段向量的相似度筛选出 TopK如 Top
Top3个最相似的文本片段。
三生成阶段结合上下文生成回答将检索到的相关文本片段与用户问题作为上下文传递给大模型辅助生成准确回答。
而这些片段之所以能精准匹配用户问题本质是 Embedding 技术保证了 “问题语义” 与 “片段语义” 的一致性映射。
下图是 AI 如何处理文档并回答用户问题的完整流程图
实操准备环境配置基于 Spring AI 智普 AI一准备工作需提前完成智普 AI 账号注册与 API Key 获取参考上一篇 Embedding 文章的配置步骤Spring AI 进阶Embedding 技术原理、相似度算法与实操并创建 Spring Boot 项目。
创建 Spring Boot 项目项目名称Weiz-SpringAI-RAG核心配置JDK
Spring Boot
3.
5.
Maven依赖选择Spring Web后续通过 pom.xml 补充 Embedding 相关依赖项目结构如下Weiz-SpringAI-RAG/├── src/│ ├── main/│ │ ├── java/│ │ │ └── com/│ │ │ └── example/│ │ │ └── weizspringai/│ │ │ ├──WeizSpringAiRAGApplication.java │ │ │ ├── controller/│ │ │ └── service/│ │ └── resources/│ │ ├── application.properties │ └── test/└── pom.xml
配置 pom.xml 依赖?xml version
0encodingUTF-8?project xmlnshttp://maven.apache.org/POM/
4.
0xmlns:xsihttp://www.w
org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/
4.
0 https://maven.apache.org/xsd/maven-
4.
0.
xsdmodelVersion
4.
0/modelVersionparentgroupIdcom.example/groupIdartifactIdWeiz-SpringAI/artifactIdversion
0.
1-SNAPSHOT/version/parentartifactIdWeiz-SpringAI-RAG/artifactIdnameWeiz-SpringAI-RAG/namedescriptionWeiz-SpringAI-RAG/descriptiondependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.ai/groupIdartifactIdspring-ai-starter-model-zhipuai/artifactId/dependency!--spring-ai-client-chat 中包括TokenTextSplitter、TextReader、Document等工具--dependencygroupIdorg.springframework.ai/groupIdartifactIdspring-ai-client-chat/artifactIdversion${spring-ai.version}/version/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependency/dependencies/project
application.properties 配置# 应用名称 spring.application.nameWeiz-SpringAI-RAG # 服务端口 server.port8080# 智普 AI 基础配置 spring.ai.zhipuai.api-key你的智普 AI APIKeyspring.ai.zhipuai.base-urlhttps://open.bigmodel.cn/api/paas #Embedding模型配置用于文本向量化 spring.ai.zhipuai.embedding.options.modelembedding-2#Chat模型配置用于生成回答 spring.ai.zhipuai.chat.options.modelGLM-4-Flash注意需将 “你的智普 AI APIKey” 替换为实际获取的密钥。
二准备本地知识库文件在 src/main/resources 目录下创建 户外旅行安全指南.txt作为本地知识库内容如下户外旅行安全指南----1露营安全-选址避开低洼积水区、陡坡和可能落石的区域优先选择平坦硬质地面。
-防火远离干草、枯枝等易燃物使用炉具时保持通风睡前彻底熄灭明火。
-防虫携带驱蚊液、防虫网避免在草丛密集处搭建帐篷睡前检查帐篷内是否有虫类。
-应急随身携带手电筒、急救包和足够的饮用水提前下载离线地图。
----2徒步安全-路线规划提前查询路线难度、天气情况选择与自身体能匹配的路线告知亲友行程。
-装备要求必须穿防滑登山鞋、戴防晒帽携带充足食物和水配备登山杖和护膝。
-环境应对遇到暴雨立即寻找高地躲避避免涉险过河遭遇野生动物保持冷静切勿投喂或驱赶。
-体能管理保持匀速前进每小时休息
分钟避免过度疲劳。
----3城市漫游安全-交通骑行遵守交通规则不逆行、不闯红灯佩戴安全头盔乘坐公共交通保管好个人财物。
-选址避开偏僻小巷和治安较差区域优先选择人流密集的商业街区和景点。
-应急保存当地派出所、医院的联系方式携带少量现金备用手机保持电量充足。
实操案例RAG 本地知识库检索完整实现本案例将实现 RAG 的全流程加载本地知识库并向量化、接收用户问题并检索相似文本、结合上下文生成回答。
核心工具类复用相似度计算逻辑可以复用上一篇文章中的SimilarityCalculator.java类Spring AI 进阶Embedding 技术原理、相似度算法与实操该类封装了余弦相似度、欧氏距离等多种主流算法支持 RAG 检索阶段的相似度计算。
编写 RagService创建 com.example.weizspringai.service.RagService 类整合索引、检索、生成三个RAG 核心逻辑importorg.springframework.ai.chat.client.ChatClient;importorg.springframework.ai.embedding.EmbeddingModel;importorg.springframework.core.io.ClassPathResource;importorg.springframework.core.io.Resource;importorg.springframework.stereotype.Service;importjava.io.IOException;importjava.nio.charset.StandardCharsets;importjava.util.ArrayList;importjava.util.List;ServicepublicclassRagService{// Embedding 模型文本向量化privatefinalEmbeddingModelembeddingModel;// Chat 模型生成回答privatefinalChatClientchatClient;// 本地知识库文本片段privatefinalListStringdocChunksnewArrayList();// 文本片段对应的向量privatefinalListfloat[]docVectorsnewArrayList();// 相似度算法默认余弦相似度可根据需求修改privatefinalEmbeddingService.SimilarityAlgorithmsimilarityAlgorithmEmbeddingService.SimilarityAlgorithm.COSINE;// 构造方法注入依赖初始化知识库索引阶段publicRagService(EmbeddingModelembeddingModel,ChatClient.BuilderchatClientBuilder)throwsIOException{this.embeddingModelembeddingModel;this.chatClientchatClientBuilder.build();// 加载本地知识库文件并切分片段loadAndSplitDocument();}/** * 加载本地知识库文件切分为文本片段索引阶段第一步 */privatevoidloadAndSplitDocument()throwsIOException{// 读取 resources 目录下的知识库文件ResourceresourcenewClassPathResource(户外旅行安全指南.txt);StringcontentnewString(resource.getInputStream().readAllBytes(),StandardCharsets.UTF_
;// 按 ---- 切分文本根据文件格式自定义切分规则String[]chunkscontent.split(----);for(Stringchunk:chunks){StringcleanChunkchunk.strip();if(!cleanChunk.isBlank()){docChunks.add(cleanChunk);// 文本片段向量化并缓存索引阶段第二步、第三步docVectors.add(embeddingModel.embed(cleanChunk));}}}/** * 处理用户提问返回 RAG 增强后的回答检索生成阶段 * param question 用户问题 * return 大模型生成的回答 */publicStringanswer(Stringquestion){//
用户问题向量化检索阶段第一步float[]questionVectorembeddingModel.embed(question);//
检索 Top2 最相似的文本片段检索阶段第二步、第三步ListStringtopRelevantChunksretrieveTopRelevantChunks(questionVector,
;//
构建上下文生成阶段第一步StringcontextString.join(\n---\n,topRelevantChunks);//
构建提示词生成阶段第二步StringpromptString.format(以下是户外旅行安全指南的知识\n%s\n请基于上述知识简洁明了地回答问题%s,context,question);//
调用 Chat 模型生成回答生成阶段第三步returnchatClient.prompt().system(你是户外旅行安全助手仅基于提供的上下文回答问题不添加额外信息。
).user(prompt).call().content();}/** * 检索 TopK 最相似的文本片段检索阶段核心逻辑 * param questionVector 用户问题向量 * param topK 返回前 K 个相似片段 * return TopK 相似文本片段 */privateListStringretrieveTopRelevantChunks(float[]questionVector,inttopK){ListChunkSimilaritysimilarityListnewArrayList();// 计算问题向量与所有文本片段向量的相似度使用指定算法for(inti0;idocVectors.size();i){doublesimcalculateSimilarity(questionVector,docVectors.get(i));similarityList.add(newChunkSimilarity(i,sim));}// 按相似度降序排序取前 topK 个similarityList.sort((a,b)-Double.compare(b.similarity,a.similarity));returnsimilarityList.stream().limit(topK).map(item-docChunks.get(item.index)).toList();}/** * 相似度计算调用工具类支持算法切换 */privatedoublecalculateSimilarity(float[]a,float[]b){returnswitch(similarityAlgorithm){caseCOSINE-SimilarityCalculator.cosineSimilarity(a,b);caseEUCLIDEAN-SimilarityCalculator.euclideanSimilarity(a,b);casePEARSON-SimilarityCalculator.pearsonCorrelation(a,b);caseMANHATTAN-SimilarityCalculator.manhattanSimilarity(a,b);default-SimilarityCalculator.cosineSimilarity(a,b);// 默认 fallback 到余弦相似度};}/** * 辅助类存储文本片段索引与相似度 */privatestaticclassChunkSimilarity{intindex;doublesimilarity;ChunkSimilarity(intindex,doublesimilarity){this.indexindex;this.similaritysimilarity;}}}
编写 RagController创建 com.example.weizspringai.controller.RagController 类提供 RAG 检索接口importcom.example.springaiembedding.service.RagService;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RequestParam;importorg.springframework.web.bind.annotation.RestController;importjava.util.Map;RestControllerRequestMapping(/rag)publicclassRagController{AutowiredprivateRagServiceragService;/** * RAG 本地知识库检索接口 * param question 用户问题 * return 包含问题与回答的响应 */GetMapping(/ask)publicMapString,Stringask(RequestParam(question)Stringquestion){StringanswerragService.answer(question);returnMap.of(question,question,answer,answer);}}
测试 RAG 本地知识库检索启动 Weiz-SpringAI-Rag 项目浏览器访问http://localhost:8080/rag/ask?question露营选址有什么安全要求。
响应结果如下{question:露营选址有什么安全要求,answer:露营选址需避开低洼积水区、陡坡和可能落石的区域优先选择平坦硬质地面同时要远离干草、枯枝等易燃物避免在草丛密集处搭建帐篷。
}再测试其他问题如http://localhost:8080/rag/ask?question徒步时遇到暴雨该怎么办响应{question:徒步时遇到暴雨该怎么办,answer:徒步遇到暴雨时应立即寻找高地躲避避免涉险过河同时注意远离陡坡和可能落石的区域确保自身安全。
}测试结果表明大模型能够基于本地知识库文件的内容生成准确回答验证了 RAG 技术的
核心价值。
RAG 优化思路为后续进阶铺垫当前 RAG 实现存在一些可优化点后续文章将深入讲解
文本切分策略当前按固定符号切分可优化为按 Token 数量切分如每段
字符避免语义断裂。
向量数据库集成当前使用内存缓存向量生产环境需替换为 Milvus、Redis 等向量数据库支持海量数据存储与高效检索。
相似度阈值过滤仅保留相似度高于阈值如
05的文本片段避免引入无关噪声。
上下文扩展检索到相关片段后同时获取其前后相邻片段提升语义连贯性。
引入 Spring AI 开箱即用 RAG 组件Spring AI 提供了 QuestionAnswerAdvisor、RetrievalAugmentationAdvisor 等开箱即用的 RAG 组件可简化开发流程支持自动索引、检索优化、提示词工程等功能适配生产级场景。
算法动态选择根据知识库类型如短文本、专业文档、稀疏向量自动匹配最优相似度算法例如专 业文档优先使用皮尔逊相关系数稀疏向量优先使用杰卡德相似度。
总结本文深入解析了 RAG 技术的核心原理、核心流程重点厘清了其与 Embedding 技术的协同逻辑并通过 Spring AI 智普 AI 实现了 RAG 本地知识库检索的完整案例。
RAG 技术通过 “检索外部知识 增强生成能力” 的模式完美解决了大模型的知识局限问题而 Embedding 技术提供的语义向量能力是 RAG 实现精准检索的核心支撑。
核心结论如下RAG 的
核心价值在于 “无需微调快速扩展大模型能力”适配私有数据、最新知识等场景。
Embedding 是 RAG 的 “语义基础”其生成的语义向量决定了检索阶段的精准度进而影响最终回答质量。
基础版 RAG 实现简单但生产环境需关注文本切分、向量数据库集成、算法选择等优化点提升系统的稳定性、高效性和准确性。