【AI Agent 全栈开发】RAG(检索增强生成)

发布时间:2026/5/19 4:08:50

【AI Agent 全栈开发】RAG(检索增强生成) 欢迎来到我的CSDN博客Optimistic _ chen✨一名热爱技术与分享的全栈开发者在这里记录成长专注分享编程技术与实战经验助力你的技术成长之路与你共同进步我的专栏推荐专栏内容特色适合人群C语言从入门到精通系统讲解基础语法、指针、内存管理、项目实战零基础新手、考研党、复习Java基础语法系统解释了基础语法、类与对象、继承Java初学者Java核心技术面向对象、集合框架、多线程、网络编程、新特性解析有一定语法基础的开发者Java EE 进阶实战Servlet、JSP、SpringBoot、MyBatis、项目案例拆解想快速入门Java Web开发的同学Java数据结构与算法图解数据结构、LeetCode刷题解析、大厂面试算法题面试备战、算法爱好者、计算机专业学生Redis系列从数据类型到核心特性解析项目必备我的承诺✅ 文章配套代码每篇技术文章都提供完整的可运行代码示例✅ 持续更新专栏内容定期更新紧跟技术趋势✅ 答疑交流欢迎在文章评论区留言讨论我会及时回复支持互粉 关注我解锁更多技术干货⏳ 每天进步一点点未来惊艳所有人✍️ 持续更新中记得⭐收藏关注⭐不迷路 ✨ 标签:#技术博客 #编程学习 #Java #C语言 #算法 #程序员文章目录什么是RAGRAG增强LLM构建向量数据库什么是向量向量数据库RAG的工作流程简单上手文本向量化向量存储相似性检索Advisor让LLM“看到”向量数据库ETL(提取转化加载)Document数据模型DocumentReader(⽂档阅读器)DocumentTransformer(⽂档转换器DocumentWriter(⽂档编写器)重排序完结撒花什么是RAG官方给出的解释是Retrieval Augmented Generation,检索增强⽣成。是一种结合信息检索retrieval和文本生成generation的混合架构。解释一下传统⼤型语⾔模型(LLM)依赖训练数据中的知识,但⽆法获取最新信息以及⼀些⾮公开信息所以当你询问一些私有信息时就会出现“幻觉”答非所问。RAG技术如同为LLM配备了实时更新的知识库。它不仅依靠预训练数据还能通过检索特定知识片段来获取最新信息。这些检索到的内容作为上下文输入模型使回答既准确又与时俱进有效减少了信息误差并实现了知识的动态更新。RAG增强LLMRAG技术有一套严谨的工作流程为LLM的回答提供真实有效的依据。RAG第一个优势就是通过从外部知识库获取相关信息来增强⼤语⾔模型(LLM)的输出,从⽽⽣成更准确,上下⽂更丰富的回答,有效解决模型幻觉,知识过时等问题。但是RAG知识库可能包含多种格式和语言的文档导致这些数据难以被有效检索。因此我们需要将这些数据进行进一步处理构建出可以被高效检索的知识库。构建向量数据库什么是向量向量是数学中的基本概念表示高维空间中的一个坐标点。在机器学习领域向量常被用来将文本、图像、音频等非结构化数据映射为高维空间中的点。每个维度代表潜在的语义特征这些特征虽然不一定对应人类直观理解的具体概念如颜色或大小但共同编码了对象的语义信息。核心特性在于向量位置反映语义关系语义相近的对象在向量空间中的位置也会更接近。关于向量的计算方法我们主要通过Embedding模型将自然语言转换为机器可理解的语义编码。具体计算过程不在本文讨论范围内感兴趣的读者可以自行探索。向量数据库向量数据库(Vector Database)是⼀种专⻔⽤于存储、管理和⾼效检索⾼维向量数据的数据库系统。它以向量作为基本存储单元⽀持对⾮结构化数据(如⽂本、图像、⾳频、视频)进⾏语义级相似性搜索。对比传统关系型数据库的精准匹配向量数据库的核心是向量化处理可以将原始数据转化为高维向量相似性度量使用余弦相似度、欧式距离等方法衡量向量间的语义接近程度高效检索采⽤⾼效的索引算法,大幅度提高查询速度RAG的工作流程文档加载Document Loading加载不同来源的文档不同的文档加载器可以加载不同格式的非结构化数据文本分割(Splitting)文本分割把Document切分为指定大小的块数据向量化将切分好的Document块进行嵌入模型转化即将⽂档块转换成向量的形式存储(Storage)将Embedding后的向量数据,存储到向量数据库中检索(Retrieval)数据存入向量数据库后当我们需要进行数据检索时通过检索算法找到与输入问题相似的文档块增强上下文构建系统将检索到的文本块与原始用户问题按照一定模板组合成一个新的、内容丰富的提示词输出将上述增强后的Prompt发送给大模型大模型生成的答案返回给用户简单上手文本向量化添加pom.xml依赖dependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactId/dependency/dependencies文本向量化这里需要引入嵌入模型来实现向量化我使用的是阿里百炼平台提供的向量模型。dependencygroupIdorg.springframework/groupIdartifactIdspring-webflux/artifactId/dependencydependencygroupIdcom.alibaba.cloud.ai/groupIdartifactIdspring-ai-alibaba-starter-dashscope/artifactId/dependencyapplication.yml配置文件中添加配置:spring:ai:dashscope:api-key:${DASHSCOPE_API_KEY}相关代码可以观看官方文档向量化模型向量存储目前支持的向量数据库有Vector Database也可以使用Redis、Oracle等数据库学习阶段我们使用SimpleVectorStore来存储向量SimpleVectorStore是SpringAI内置的⼀个内存版向量数据库⽆需外部依赖开箱即⽤。定义VectorStore//作⽤类似于 Configuration ,但专⻔⽤于测试环境TestConfigurationstaticclassTestConfig{BeanpublicVectorStorevectorStore(DashScopeEmbeddingModelembeddingModel){returnSimpleVectorStore.builder(embeddingModel).build();}}存储⽂档到VectorStoreTestpublicvoidinit(AutowiredVectorStorevectorStore){DocumentdocDocment.builder().text(2026年美加墨世界杯预计吸引全球目光)build();Documentdoc2Docment.builder().text(枯藤老树昏鸦小桥流水人家)build();Documentdoc3Docment.builder().text(基于机器学习的大语言模型)build();Documentdoc4Docment.builder().text(今天天气不错适合出游)build();//文本向量化vectorStore.add(Arrays.asList(doc,doc2,doc3,doc4));}相似性检索向量存⼊到向量数据库之后,就可以来查找了TestvoidsimilaritySearchTest(AutowiredVectorStorevectorStore){// 3. 相似性查询SearchRequestsearchRequestSearchRequest.builder().query(机器学习).topK(5).similarityThreshold(0.3).build();ListDocumentresultsvectorStore.similaritySearch(searchRequest);// 4.输出System.out.println(results);}调用similaritySearch方法时会执行相似性搜索将“搜索词”转为向量计算它与1向量库中文档的相似度根据请求过滤出相似度≥0.3的文档并去top 5,最后返回这些匹配的原始文档列表。Advisor让LLM“看到”向量数据库Advisor机制是Spring AI提供的开箱即用支持用于实现RAG技术。QuestionAnswerAdvisor和RetrievalAugmentationAdvisor是SpringAI中实现RAG的两个核⼼组件。QuestionAnswerAdvisor⾯向问答场景的语义检索增强RetrievalAugmentationAdvisor灵活可控的通⽤RAG增强层它不局限于问答场景,⽽是作为⼀个通⽤的增强层,适⽤于任何需要引⼊外部知识的⽣成任务.程序员通过自定义的Retriever接口来控制检索逻辑BeanpublicRetrievalAugmentationAdvisorretrievalAugmentationAdvisor(ChatModelchatModel,VectorStorevectorStore){// 1. 创建检索器指定返回3个文档varretrieverVectorStoreRetriever.builder(vectorStore).similarityThreshold(0.75)// 可选相似度阈值.topK(3)// 检索 top-3 结果.build();// 2. 自定义 Prompt 模板StringpromptTemplateStr 你是一个企业智能助手请根据以下【参考资料】回答问题。 如果资料中没有相关信息请回答抱歉我无法找到相关信息。 【参考资料】: {documents} 【问题】: {question} 【回答】: ;PromptTemplatetemplatenewPromptTemplate(promptTemplateStr);// 3. 构建 AdvisorreturnRetrievalAugmentationAdvisor.builder().documentRetriever(retriever)// 使用自定义检索器.queryAugmenter(newContextualQueryAugmenter(template))// 注入模板.build();假设开发⼈员已经将数据加载到中 VectorStore,就可以通过QuestionAnswerAdvisor实例来执⾏RAGTestvoidchatRagTest(AutowiredVectorStorevectorStore,AutowiredDashScopeChatModelchatModel){ChatClientchatClientChatClient.builder(chatModel).build();Stringmessage世界杯什么时候举⾏;StringcontentchatClient.prompt().advisors(newQuestionAnswerAdvisor(vectorStore)).user(message).call().content();System.out.println(content);}ETL(提取转化加载)RAG的核⼼理念是通过从⼤量数据中检索相关信息来增强⽣成式AI模型的能⼒从⽽提⾼⽣成内容的质量和相关性。⽽ETL过程正是实现这⼀⽬标的关键环节——它将原始文档转化为可以被高效检索和使用的结构化数据为后续检索和生成过程奠定基础。Extract从原始数据源读取并捕获数据,输出为初步解析的中间格式Transform转化原始数据为向量化数据Load存入向量数据库供检索使用Document数据模型Document是ETLAPI的核⼼数据模型,它构成了整个数据处理流程的基本单元。用来处理数据的提取、转化和加载。DocumentReader(⽂档阅读器)publicinterfaceDocumentReaderextendsSupplierListDocument{defaultListDocumentread(){returnget();}}例如JsonReader是一个用于将JSON数据转化为Document对象的工具类主要用于从JSON文件中提取结构化数据并生成文档对象。DocumentReader 是一个统一的顶层接口或称抽象概念代表所有文档读取器的总称。而 JsonReader 则是DocumentReader接口的一个具体实现。简单来说JsonReader 是一种对特定文档类型即 JSON 格式文件的读取器。DocumentTransformer(⽂档转换器知识库中原始⽂档通常太⻓、格式混乱或缺乏结构化元数据,⽆法直接输⼊给LLM使⽤对文本进行必要的转化和处理。publicinterfaceDocumentTransformerextendsFunctionListDocument,ListDocument{defaultListDocumenttransform(ListDocumenttransform){returnapply(transform);}}主要有四个组件TextSplitter(文本切分器)把⻓⽂切成⼩块ContentFormatTransformer(内容格式转换器): 统⼀清洗⽂本KeywordMetadataEnricher(关键词提取器):借助AI模型⾃动提取关键词,类似给⽂档贴标签SummaryMetadataEnricher(摘要⽣成器):借助AI模型⽣成⽂档摘要具体代码可以到官方文档处查看DocumentWriter(⽂档编写器)publicinterfaceDocumentWriterextendsConsumerListDocument{defaultvoidwrite(ListDocumentdocuments){accept(documents);}}FileDocumentWriter 是⼀个实现了 DocumentWriter 接⼝的类,⽤于将⼀组 Document 对象的内容写⼊到指定的⽂本⽂件中.适⽤于调试、⽇志记录或⽣成⼈类可读的⽂档输出。FileDocumentWriterwriternewFileDocumentWriter(output.txt,true,MetadataMode.ALL,false);向量化的存储上面提到的SimpleVectorStore就是其中一种。重排序RAG已经实现了快速从海量⽂档中找到看起来相关的⽚段,但是,在实际应⽤中,我们发现其排序结果并不总是最优最相似的向量 ≠ 最相关的答案Re-Ranking(重排序) 是指在初步检索出⼀批候选⽂档后,使⽤⼀个更加精细、专精于相关性判断的模型,重新评估每个⽂档与查询之间的匹配程度,并按新得分重新排序。粗排阶段使⽤向量数据库进⾏快速ANN搜索,召回⼀批候选⽂档精排阶段调⽤更精细的排序模型(如Cross-Encoder类重排序模型)计算每个⽂档与原始查询之间的细粒度语义匹配分数根据重排序后的得分重新排列⽂档顺序,选取top-k⾼质量上下⽂将优化后的上下⽂注⼊Prompt,交由LLM⽣成最终回答Spring AI中提供了开箱即用的支持组件RetrievalRerankAdvisorSpringBootTestpublicclassRerankTest{privateSimpleVectorStoresimpleVectorStore;AutowiredpublicRerankTest(EmbeddingModelembeddingModel){this.simpleVectorStoreSimpleVectorStore.builder(embeddingModel).build();}BeforeEachvoidtestSimpleVectorStore(Value(classpath:/file/rule.txt)Resourceresource){//读取TextReaderreadernewTextReader(resource);ListDocumentdocumentsreader.get();TokenTextSplittersplitternewTokenTextSplitter(200,50,5,1000,true);ListDocumentapplysplitter.apply(documents);simpleVectorStore.add(apply);System.out.println(向量存储写入完成);}TestvoidtestRerank(AutowiredDashScopeRerankModelrerankModel,AutowiredDashScopeChatModelchatModel){ChatClientclientChatClient.builder(chatModel).build();//1. 定义一个advisor, 提供rerank模型RetrievalRerankAdvisorrerankAdvisornewRetrievalRerankAdvisor(simpleVectorStore,rerankModel,SearchRequest.builder().topK(10).build());//2. 把这个advisor 绑定给chatclientStringcontentclient.prompt().user(金卡会员打几折).advisors(rerankAdvisor).call().content();System.out.println(content);}}完结撒花如果这篇博客对你有帮助不妨点个赞支持一下吧你的鼓励是我创作的最大动力✨想获取更多干货欢迎关注我的专栏 →optimistic_chen收藏本文下次需要时不迷路我们下期再见 持续更新中……悄悄说点击主页有更多精彩内容哦

相关新闻