告别大模型幻觉!RAG 原理 + Spring AI 代码实现一步到位

news2026/4/1 15:58:30
RAG 诞生背景大模型原生缺陷LLM 存在 3 个无法自愈的问题这是 RAG 技术的核心出发点LLM存在幻觉现象, 生成无事实依据、虚假编造的内容LLM知识更新缓慢, 预训练数据固定无法同步新数据 / 私有数据LLM对领域知识的理解有限, 对企业内部文档、专业手册等私有知识完全未知RAG的概念·RAGRetrieval Augmented Generation顾名思义先从外部私有知识库检索相关信息再将检索结果作为上下文输入大模型让模型基于真实事实生成回答。·类比:你可以把这个过程想象成开卷考试。让LLM先翻书再回答问题。·价值: 根治大模型私有知识未知、知识过时、内容幻觉三大痛点。·举例: 我想询问LLM有关于我公司内部的请假流程它肯定不知道,但是我把公司的员工手册先给它看,当我在询问的时候他就会知道RAG的检索流程这张图详细展示了检索增强生成Retrieval Augmented Generation, RAG的工作流程结合了向量数据库、嵌入模型和大语言模型LLM以实现基于外部知识的智能问答。整个流程分为7个步骤清晰地描绘了从文档预处理到最终响应生成的完整闭环。整体结构说明图表左侧标注“RAG”表明这是RAG架构的核心流程图。右侧按数字顺序1~7展示数据流与处理阶段·上半部分文档索引与向量化存储离线/批处理阶段·下半部分用户查询与实时响应生成在线/推理阶段中间核心组件包括·Embedding model嵌入模型·Vector database向量数据库·DeepSeek LLM大语言模型此处以 DeepSeek 为例分步详解① Encode —— 文档编码“Additional documents” → “Embedding model”系统将额外的非结构化文档如PDF、TXT、网页等输入嵌入模型将其转换为高维向量表示即“嵌入向量”。这些向量捕捉了文本的语义信息便于后续相似性匹配。✅ 关键点此步骤是ETL中的“Transform”环节通常批量执行。② Index —— 向量入库“Embedding model” → “Vector database”将上一步生成的向量存入向量数据库并建立索引以便高效检索。向量数据库支持近似最近邻搜索ANN能快速找到与查询最相似的文档片段。✅ 关键点向量数据库是RAG中“检索”能力的核心基础设施。③ Encode —— 查询编码“Query” → “Embedding model”当用户提出问题时Query同样通过同一个嵌入模型将其转化为向量。注意这里必须使用与文档编码相同的模型保证语义空间一致。✅ 关键点查询与文档需在相同向量空间中比较才能准确匹配相似度。④ Similarity search —— 相似性搜索“Vector database” ←→ “Similar documents”向量数据库接收查询向量后执行相似性搜索如余弦相似度或欧氏距离返回Top-K个最相关的文档片段Similar documents。✅ 关键点这一步实现了“检索”功能是RAG区别于纯生成式AI的关键。⑤ Retrieve —— 获取相关文档“Vector database” → “Similar documents” “Query”系统将检索到的相关文档片段与原始用户查询一起打包准备送入大语言模型。此时“Query Context”构成完整的提示词Prompt。✅ 关键点上下文增强——让LLM不仅依赖训练知识还能利用最新/专属数据作答。⑥ Prompt —— 构造提示词“Similar documents Query” → “DeepSeek LLM”将用户问题和检索到的相关文档片段组合成一个结构化的提示词Prompt发送给大语言模型如DeepSeek。例如请根据以下资料回答问题[相关资料片段1][相关资料片段2]…问题{用户提问}✅ 关键点Prompt工程决定LLM能否有效利用检索结果避免幻觉或无关输出。⑦ Final response —— 生成最终回答“DeepSeek LLM” → “Final response”大语言模型基于提供的上下文和问题生成自然流畅、准确有据的最终回答并返回给用户。✅ 关键点LLM负责“生成”而RAG框架确保其“有据可依”。流程总结RAG 文档向量化存储 用户查询实时检索 上下文增强的大模型生成它解决了传统LLM缺乏实时知识、易产生幻觉的问题特别适用于企业知识库、客服系统、法律医疗等专业领域。常见应用场景举例·企业内部知识库问答机器人·法律条文/合同条款智能解读·医疗文献辅助诊断建议·教育领域个性化学习助手详见RAG论文https://arxiv.org/pdf/2312.10997向量向量定义向量vector又称矢量在数学中也称为欧几里得向量、几何向量是数学中最基本的概念之一。其定义如下向量是指具有大小magnitude和方向的量。在RAG中用来做语义相似匹配的关键它解决了“电脑怎么理解文字意思”的问题。通常我们会用这些向量来做相似性搜索。比如通过一维向量可以显示出词语或短语之间在意义上的相近程度。举个例子“你好”、“hello”和“见到你很高兴”可以用一维向量来表示它们意思上的接近度。对于像小狗这样复杂的东西我们不能只靠一个特点来找到相似的。得考虑好几个方面才行比如毛色、体型、品种这些。然后把这些特点都变成向量的一部分组合成一个多维向量。举个例子吧一只棕色的小泰迪就可以用这样的多维向量表示[棕色, 小型, 泰迪]。要让搜索结果更准确我们就得用到更多种类的数据把这些数据放在一个更大的空间里。在这个多维度的空间中找相似的东西会变得更难一些。这时候我们需要用到一些方法比如余弦相似度或者欧式距离来衡量这些数据之间的相似程度。而向量数据库可以帮助我们完成这个任务。文本向量化通过向量模型可以把文本转换成向量。我们学到了一种新的模型叫做“向量模型”专门用来把文本变成向量。大语言模型不能直接把文本变成向量所以需要单独用一个向量模型来完成这个任务。现有向量模型厂商如下阿里百炼有大量向量模型spring.ai.dashscope.embedding.options.modeltext-embedding-v1ollama有大量向量模型spring.ai.ollama.embedding.modelqwen3-embedding那么我们用这种向量模型把一句话变成一个向量有什么用呢其实非常有用因为我们可以用这些向量来判断两句话有多相似。举个例子如果你想找和秋田犬类似的狗在向量数据库里每种狗的特点都会被表示成一个多维向量。你会发现秋田犬的向量和柴犬的向量最接近这样就能找到跟秋田犬相似的狗了。·向量模型的本质目标就是把语义相似的内容用“相近”的向量表示把“不相关”内容尽量拉远。·所以好的向量模型能够更好的识别语义 进行向量化.示例以阿里百炼平台向量模型spring.ai.model.embeddingdashscopespring.ai.dashscope.embedding.options.modeltext-embedding-v1com.alibaba.cloud.aispring-ai-alibaba-starter-dashscopeorg.springframework.aispring-ai-advisors-vector-storeAutowired EmbeddingModel embeddingModel; GetMapping(/embedding) public void embedding() { float[] embedded embeddingModel.embed(我叫柱子); System.out.println(embedded.length); System.out.println(Arrays.toString(embedded)); }向量数据库对于向量模型生成出来的向量我们可以持久化到向量数据库并且能利用向量数据库来计算两个向量之间的相似度或者根据一个向量查找跟这个向量最相似的向量。在SpringAi中VectorStore 表示向量数据库目前常见支持的向量数据库有·Chroma Vector Store - The Chroma vector store.·Elasticsearch Vector Store - The Elasticsearch vector store. 可以“以向量关键词”方式做混合检索。深度优化更多针对文本不是专门“向量搜索引擎”。向量存储和检索容量有限制查询延迟高于 Milvus。·Milvus Vector Store - The Milvus vector store.·MongoDB Atlas Vector Store - The MongoDB Atlas vector store.·Neo4j Vector Store - The Neo4j vector store.可以结合结构化图谱查询与向量检索 大规模嵌入检索如千万—亿级高维向量性能明显落后于 Milvus·Redis Vector Store - The Redis vector store. 低门槛实现小规模向量检索。对于高维大规模向量如几百万到上亿条性能和存储效率不如专用向量库。·SimpleVectorStore - A simple implementation of persistent vector storage, good for educational purposes.其中有我们熟悉的几个数据库都可以用来存储向量比如Elasticsearch、MongoDb、Redis。匹配检索在这个示例中我存储了某个PDF文件里面的内容到向量数据库中然后通过招标文件发售开始时间这几个关键字在向量数据库中进行查询以下为流程图此次示例代码讲解Milvus Vector StoreMilvus国产团队、文档友好、社区国内活跃、性能最佳、市场占用率大。 实战中使用的向量数据库2022 年Milvus 支持十亿级向量2023 年它以持续稳定的方式扩展到数百亿级为 300 多家大型企业的大规模场景提供支持包括 Salesforce、PayPal、Shopee、Airbnb、eBay、NVIDIA、IBM、ATT、LINE、ROBLOX、Inflection 等。详见 https://milvus.io/docs/zh 文档。在spring ai使用1、添加依赖org.springframework.aispring-ai-starter-vector-store-milvus2、配置milvusmilvus 配置spring.ai.vectorstore.milvus.client.host192.168.0.143spring.ai.vectorstore.milvus.client.port19530#spring.ai.vectorstore.milvus.client.usernameroot#spring.ai.vectorstore.milvus.client.passwordmilvusspring.ai.vectorstore.milvus.databaseNamedefaultspring.ai.vectorstore.milvus.collectionNameragtestspring.ai.vectorstore.milvus.initializeSchematruespring.ai.vectorstore.milvus.embeddingDimension1536SearchRequest组件可以利用SearchRequest设置检索请求·query 代表要检索的内容·topK 设置检索结果的前N条o通常我们查询所有结果查出来 因为查询结果最终要发给大模型 查询过多的结果会过多的token意味着更长延迟 更多的费用 并且过多上下文会超限研究表明过多的内容会降低 LLM 的召回性能·similarityThreshold 设置相似度阈值 可以通关设置分数限制召回内容相似度. 从而过滤掉废料。 中文语料要适当降低分数所以应遵循始终以“业务召回效果”为主而不是追求网上常说的高分阈值。public WriterController(EmbeddingModel embeddingModel, VectorStore vectorStore) {logger.info(“WriterController -- start read pdf file by page”);Resource resource new DefaultResourceLoader().getResource(Constant.PDF_FILE_PATH);PagePdfDocumentReader pagePdfDocumentReader new PagePdfDocumentReader(resource); // 只可以传pdf格式文件//pagePdfDocumentReader.read();this.documents pagePdfDocumentReader.get().subList(0, 5); // query 5 pagesthis.vectorStore vectorStore;this.embeddingModel embeddingModel;}GetMapping(/writeVector) public void writeVector() { logger.info(Writing vector...); vectorStore.add(documents); }GetMapping(“/search”)public Listsearch(RequestParam(“msg”) String msg) {msg “招标文件发售开始时间”;logger.info(“start search data: {}”, msg);float[] embed embeddingModel.embed(msg);logger.info(“embed: {}”, embed);return vectorStore.similaritySearch(SearchRequest.builder().query(msg).topK(2).similarityThreshold(0.5).build());}提取转换加载ETL在之前我们主要完成了数据检索阶段 但是完整的RAG流程还需要有emedding阶段 即提取读取、转换分隔和加载写入Document Loaders 文档读取器spring ai提供了以下文档阅读器·JSON·文本·HTMLJSoup·Markdown·PDF页面·PDF段落·TikaDOCX、PPTX、HTML……alibaba ai也提供了很多阅读器https://github.com/alibaba/spring-ai-alibaba/tree/main/community/document-parsers·document-parser-apache-pdfbox用于解析 PDF 格式文档。·document-parser-bshtml用于解析基于 BSHTML 格式的文档。·document-parser-pdf-tables专门用于从 PDF 文档中提取表格数据。·document-parser-bibtex用于解析 BibTeX 格式的参考文献数据。·document-parser-markdown用于解析 Markdown 格式的文档。·document-parser-tika一个多功能文档解析器支持多种文档格式。org.springframework.aispring-ai-jsoup-document-readerorg.springframework.aispring-ai-markdown-document-readerorg.springframework.aispring-ai-pdf-document-readerorg.springframework.aispring-ai-tika-document-reader读取TextGetMapping(“/text”)public ListreadText() {logger.info(“start read text file”);Resource resource new DefaultResourceLoader().getResource(Constant.TEXT_FILE_PATH);TextReader textReader new TextReader(resource); // 适用于文本数据return textReader.read();}读取markdownGetMapping(“/markdown”)public ListreadMarkdown() {logger.info(“start read markdown file”);MarkdownDocumentReader markdownDocumentReader new MarkdownDocumentReader(Constant.MARKDOWN_FILE_PATH); // 只可以传markdown格式文件return markdownDocumentReader.read();}读取pdf·PagePdfDocumentReader一页1个document·ParagraphPdfDocumentReader 按pdf目录分成一个个documentGetMapping(/pdf-page) public ListreadPdfPage() { logger.info(start read pdf file by page); Resource resource new DefaultResourceLoader().getResource(Constant.PDF_FILE_PATH); PagePdfDocumentReader pagePdfDocumentReader new PagePdfDocumentReader(resource); // 只可以传pdf格式文件 return pagePdfDocumentReader.read(); } GetMapping(/pdf-paragraph) public ListreadPdfParagraph() { logger.info(start read pdf file by paragraph); Resource resource new DefaultResourceLoader().getResource(Constant.PDF_FILE_PATH); ParagraphPdfDocumentReader paragraphPdfDocumentReader new ParagraphPdfDocumentReader(resource); // 有目录的pdf文件 return paragraphPdfDocumentReader.read(); }DocumentSplitter‌ 文档拆分器转换器由于文本读取过来后 还需要分成一段一段的片段(分块chunk) 分块是为了更好地拆分语义单元这样在后面可以更精确地进行语义相似性检索也可以避免LLM的Token限制。SpringAi就提供了一个文档拆分器·TextSplitter 抽象类·TokenTextSplitter 按token分隔TokenTextSplitterchunkSize (默认值: 800)o每个文本块的目标大小以token为单位minChunkSizeChars (默认值: 350) 建议小一点o如果块超过最小块字符数( 按照块的最后. ! ? /n 符号截取)o如果块没超过最小块字符数,不会按照符号截取(保留原块。minChunkLengthToEmbed (默认值: 5)o丢弃短于此长度的文本块(如果去掉/r/n 只剩5个有效文本 那就丢掉maxNumChunks (默认值: 10000)o最多能分多少个块 超过了就不管了keepSeparator (默认值: true)o是否在块中保留分隔符、换行符 /r/n分块经验过细分块的潜在问题‌语义割裂‌ 破坏上下文连贯性影响模型理解‌。‌计算成本增加‌分块过细会导致向量嵌入和检索次数增多增加时间和算力开销‌。‌信息冗余与干扰‌碎片化的文本块可能引入无关内容干扰检索结果的质量降低生成答案的准确性‌。分块过大的弊端‌信息丢失风险‌过大的文本块可能超出嵌入模型的输入限制导致关键信息未被有效编码‌。‌检索精度下降‌大块内容可能包含多主题混合与用户查询的相关性降低影响模型反馈效果‌。‌场景‌‌分块策略‌‌参数参考‌微博/短文本句子级分块保留完整语义每块100-200字符‌学术论文段落级分块叠加10%重叠每块300-500字符‌法律合同条款级分块严格按条款分隔每块200-400字符‌长篇小说章节级分块过长段落递归拆分为段落每块500-1000字符‌在实际应用中不应过度依赖基于文本主题的分割策略。由于实战数据体量庞大且缺乏规律难以确保每个切片Chunk都能完整覆盖单一主题即便引入人工干预也收效甚微。因此工程实践中通常需根据数据特性灵活选择分割器主流方案是采用按 Token 数量截断的策略。毕竟不存在完美的分割方法更优的解法往往是结合‘固定 Token 长度’为基础辅以人工规则或大模型智能分割的混合模式。分块五种策略以下是 RAG 的五种分块策略1固定大小分块生成块的最直观和直接的方法是根据预定义的字符、单词或标记数量将文本分成统一的段。由于直接分割会破坏语义流因此建议在两个连续的块之间保持一些重叠上图蓝色部分。这很容易实现。而且由于所有块的大小相同它简化了批处理。但有一个大问题。这通常会打断句子或想法。因此重要的信息很可能会分散到不同的块之间。2语义分块这个想法很简单。·根据句子、段落或主题部分等有意义的单位对文档进行细分。·接下来为每个片段创建嵌入。·假设我从第一个片段及其嵌入开始。o如果第一个段的嵌入与第二个段的嵌入具有较高的余弦相似度则这两个段形成一个块。o这种情况一直持续到余弦相似度显著下降。o一旦发生这种情况我们就开始新的部分并重复。输出可能如下所示与固定大小的块不同这保持了语言的自然流畅并保留了完整的想法。由于每个块都更加丰富它提高了检索准确性进而使 LLM 产生更加连贯和相关的响应。一个小问题是它依赖于一个阈值来确定余弦相似度是否显著下降而这个阈值在不同文档之间可能会有所不同。3递归分块首先根据固有分隔符如段落或章节进行分块。接下来如果每个块的大小超出了预定义的块大小限制则将其拆分成更小的块。但是如果块符合块大小限制则不再进行进一步拆分。输出可能如下所示如上图·首先我们定义两个块紫色的两个段落。·接下来第 1 段被进一步分成更小的块。与固定大小的块不同这种方法还保持了语言的自然流畅性并保留了完整的想法。然而在实施和计算复杂性方面存在一些额外的开销。4基于文档结构的分块这是另一种直观的方法。它利用文档的固有结构如标题、章节或段落来定义块边界。这样它就通过与文档的逻辑部分对齐来保持结构完整性。输出可能如下所示也就是说这种方法假设文档具有清晰的结构但事实可能并非如此。此外块的长度可能会有所不同可能会超出模型令牌的限制。您可以尝试使用递归拆分进行合并。5基于LLM的分块既然每种方法都有优点和缺点为什么不使用 LLM 来创建块呢可以提示 LLM 生成语义上孤立且有意义的块。显然这种方法将确保较高的语义准确性因为 LLM 可以理解超越简单启发式方法用于上述四种方法的上下文和含义。唯一的问题是它是这里讨论的所有五种技术中计算要求最高的分块技术。此外由于 LLM 通常具有有限的上下文窗口因此需要注意这一点。Document Writers文档写入文本向量化向量化存储之前在“文本向量化”介绍了 就是通过向量模型库进行向量化依然通过Qwen向量模型进行向量化 将第分割的chunk进行向量化Autowired EmbeddingModel embeddingModel; GetMapping(/embedding) public void embedding() { float[] embedded embeddingModel.embed(我叫柱子); System.out.println(embedded.length); System.out.println(Arrays.toString(embedded)); }存储向量我们通过向量数据库存储document 可以省略向量化这一步 向量数据库会在底层自动完成向量化GetMapping(“/writeVector”)public void writeVector() {logger.info(“Writing vector…”);vectorStore.add(documents);}向量数据库检索需要先将文本进行向量化 然后去向量数据库查询// 相似性查询Listdocuments vectorStore.similaritySearch(SearchRequest.builder().query(msg).topK(2).similarityThreshold(0.4).build());// 输出System.out.println(documents);完整代码public WriterController(EmbeddingModel embeddingModel, VectorStore vectorStore, EmbeddingModel embeddingModel1) {logger.info(“WriterController -- start read pdf file by page”);Resource resource new DefaultResourceLoader().getResource(Constant.PDF_FILE_PATH);PagePdfDocumentReader pagePdfDocumentReader new PagePdfDocumentReader(resource); // 只可以传pdf格式文件this.documents pagePdfDocumentReader.get().subList(0, 5); // query 5 pagesthis.vectorStore vectorStore;this.embeddingModel embeddingModel1;}GetMapping(/writeVector) public void writeVector() { logger.info(Writing vector...); vectorStore.add(documents); } GetMapping(/search) public Listsearch(RequestParam(msg) String msg) { msg 招标文件发售开始时间; logger.info(start search data: {}, msg); float[] embed embeddingModel.embed(msg); logger.info(embed: {}, embed); return vectorStore.similaritySearch(SearchRequest .builder() .query(msg) .topK(2).similarityThreshold(0.4) .build()); }与模型对话在Spring AI中结合 ChatClient 可以直接将检索和Advisor整合在一起,这边用QuestionAnswerAdvisor// 对话代理ChatClient chatClient;// 向量数据库 VectorStore vectorStore; public AiRagController(ChatModel chatModel, ChatMemory chatMemory, VectorStore vectorStore, MilvusClient milvusClient) { this.chatClient ChatClient.builder(chatModel) // 默认系统提示词 .defaultSystem( 你是太和知识库系统的对话助手请以乐于助人的方式进行对话 今天的日期{current_data} 我的用户ID是{user_id} ) .defaultAdvisors( PromptChatMemoryAdvisor.builder(chatMemory).build(), SimpleLoggerAdvisor.builder().build() // 日志拦截 ) .build(); this.vectorStore vectorStore; } GetMapping(/rag) public Fluxrag( RequestParam(value question, defaultValue 招标文件每套售价多少人民币) String question, HttpServletResponse response) { response.setCharacterEncoding(UTF-8); Long userId 100000000l; String currentDate LocalDate.now().toString(); Fluxcontent chatClient.prompt() .system(a - a.param(current_data, currentDate)) .system(a - a.param(user_id, userId)) .user(question) .advisors(a - a.param(ChatMemory.CONVERSATION_ID, userId)) // 简单快速 rag QuestionAnswerAdvisor实现思路 .advisors(QuestionAnswerAdvisor.builder(vectorStore) .searchRequest( SearchRequest.builder() .query(question) .similarityThreshold(0.4d).topK(2) .build() ) .build()) .stream() .content(); return content; }RAG高级阶段基于朴素RAG高级RAG主要通过预检索策略和后检索策略来提升检索质量。详见RAG论文https://arxiv.org/abs/2407.21059Pre-Retrieval预检索增强和转换用户输入使其更有效地执行检索任务解决格式不正确的查询、query 语义不清晰、或不受支持的语言等。QueryAugmenter 查询增强使用附加的上下文数据信息增强用户 query提供大模型回答问题时的必要上下文信息QueryTransformer查询改写因为用户的输入通常是片面的关键信息较少不便于大模型理解和回答问题。因此需要使用 prompt 调优手段或者大模型改写用户 queryQueryExpander查询扩展将用户 query 扩展为多个语义不同的变体以获得不同视角有助于检索额外的上下文信息并增加找到相关结果的机会。代码实现com.alibaba.cloud.aispring-ai-alibaba-ragco.elastic.clients elasticsearch-java org.elasticsearch.client elasticsearch-rest-client org.springframework.ai spring-ai-starter-vector-store-elasticsearch// 查询增强ContextualQueryAugmenter queryAugmenter ContextualQueryAugmenter.builder()// 用于增强输入查询的组件提供额外的数据用于为大型语言模型提供必要的上下文以回答用户查询。.allowEmptyContext(false) // 允许空上下文避免在没有上下文时生成空查询.emptyContextPromptTemplate(PromptTemplate.builder().template(“没有相关数据查询”).build()).build();var compressionQueryTransformer CompressionQueryTransformer.builder().chatClientBuilder(chatClient.mutate()).build(); // 查询压缩 --使用大型语言模型将对话历史和后续查询压缩为捕获对话本质的独立查询var rewriteQueryTransformer RewriteQueryTransformer.builder().chatClientBuilder(chatClient.mutate()).targetSearchSystem(“vector store”).build();// 重写用户查询var translationQueryTransformer TranslationQueryTransformer.builder().chatClientBuilder(chatClient.mutate()).targetLanguage(“english”).build();// 查询翻译 --使用大型语言模型翻译用户查询为目标语言// Query Transformation 查询改写ListqueryTransformers List.of(rewriteQueryTransformer,compressionQueryTransformer,translationQueryTransformer);// Query Expansion 查询扩展MultiQueryExpander multiQueryExpander MultiQueryExpander.builder().numberOfQueries(2).chatClientBuilder(chatClient.mutate()).build(); // 查询扩展 --使用大型语言模型扩展用户查询生成多个相关查询Post-Retrieval后检索对于由问题检索得到的一系列上下文后检索策略关注如何优化它们与查询问题的集成。这一过程主要包括重新排序。重新排列检索到的信息将最相关的内容予以定位标记。直接将所有相关文档输入到大型语言模型LLMs可能导致信息过载为了缓解这一点后检索工作集中选择必要的信息强调关键部分并限制了了相应的上下文长度。Document Post-Processing 后置处理器使用附加的上下文数据信息增强用户 query提供大模型回答问题时的必要上下文信息示例介绍下重排模型专业化模型重排序模型如 qwen3-vl-rerank专门针对文档相关性评估进行训练能够更准确地计算查询与文档的语义匹配度。分数阈值过滤通过设置最小分数阈值可以过滤掉低质量的文档确保只有高相关性的内容被保留。在实现中可以看到这个过滤逻辑动态参数调整支持根据实际效果动态调整 topN 等参数优化最终返回的文档数量和质量。示例组件用com.alibaba.cloud.ai.rag.postretrieval.DashScopeRerankPostProcessor重排模型rerank 配置spring.ai.dashscope.rerank.options.modelqwen3-vl-rerank// rerank 重排序DashScopeRerankPostProcessor dashScopeRerankPostProcessor DashScopeRerankPostProcessor.builder().rerankModel(rerankModel).rerankOptions(dashScopeRerankProperties.getOptions()).build();重排前后效果总结后高级RAG流程图如下整体示例代码GetMapping(“/advancedRag”)public FluxadvancedRag(HttpServletResponse response, RequestParam(value “question”, defaultValue “开标时间和地点分别是”) String question) {response.setCharacterEncoding(“UTF-8”);// 查询增强 ContextualQueryAugmenter queryAugmenter ContextualQueryAugmenter.builder() // 用于增强输入查询的组件提供额外的数据用于为大型语言模型提供必要的上下文以回答用户查询。 .allowEmptyContext(false) // 允许空上下文避免在没有上下文时生成空查询 .emptyContextPromptTemplate(PromptTemplate.builder().template(没有相关数据查询).build()) .build(); var compressionQueryTransformer CompressionQueryTransformer.builder() .chatClientBuilder(chatClient.mutate()) .build(); // 查询压缩 --使用大型语言模型将对话历史和后续查询压缩为捕获对话本质的独立查询 var rewriteQueryTransformer RewriteQueryTransformer.builder() .chatClientBuilder(chatClient.mutate()) .targetSearchSystem(vector store) .build(); // 重写用户查询 var translationQueryTransformer TranslationQueryTransformer.builder() .chatClientBuilder(chatClient.mutate()) .targetLanguage(english) .build(); // 查询翻译 --使用大型语言模型翻译用户查询为目标语言 // Query Transformation 查询改写 ListqueryTransformers List.of( rewriteQueryTransformer ,compressionQueryTransformer ,translationQueryTransformer ); // Query Expansion 查询扩展 MultiQueryExpander multiQueryExpander MultiQueryExpander.builder() .numberOfQueries(2) .chatClientBuilder(chatClient.mutate()) .build(); // 查询扩展 --使用大型语言模型扩展用户查询生成多个相关查询 // rerank 重排序 DashScopeRerankPostProcessor dashScopeRerankPostProcessor DashScopeRerankPostProcessor.builder() .rerankModel(rerankModel) .rerankOptions(dashScopeRerankProperties.getOptions()) .build(); // 创建RAG流程,基于模块化架构设计 Advisor retrievalAugmentationAdvisor RetrievalAugmentationAdvisor.builder() .queryTransformers(queryTransformers) .queryExpander(multiQueryExpander) .queryAugmenter(queryAugmenter) .documentRetriever(VectorStoreDocumentRetriever.builder() // Retrieval 检索器--从向量数据库中检索与查询最相关的文档 .similarityThreshold(0.40).topK(2) .vectorStore(vectorStore) .build()) .documentJoiner(new ConcatenationDocumentJoiner()) // 将从多个 query 和从多个数据源检索到的 Document 合并为一个 Document 集合 .documentPostProcessors(dashScopeRerankPostProcessor) // 文档后处理器用于对检索到的文档进行索引方便后续的检索和使用。 .build(); String answer chatClient.prompt().system(a - a.param(current_data, LocalDate.now().toString())).system(a - a.param(user_id, 100000000L)) .advisors(retrievalAugmentationAdvisor) .user(question) .call() .content(); Fluxcontent Flux.just(answer); return content;}这里给大家精心整理了一份全面的AI大模型学习资源包括AI大模型全套学习路线图从入门到实战、精品AI大模型学习书籍手册、视频教程、实战学习、面试题等资料免费分享扫码免费领取全部内容1. 成长路线图学习规划要学习一门新的技术作为新手一定要先学习成长路线图方向不对努力白费。这里我们为新手和想要进一步提升的专业人士准备了一份详细的学习成长路线图和规划。可以说是最科学最系统的学习成长路线。2. 大模型经典PDF书籍书籍和学习文档资料是学习大模型过程中必不可少的我们精选了一系列深入探讨大模型技术的书籍和学习文档它们由领域内的顶尖专家撰写内容全面、深入、详尽为你学习大模型提供坚实的理论基础。书籍含电子版PDF3. 大模型视频教程对于很多自学或者没有基础的同学来说书籍这些纯文字类的学习教材会觉得比较晦涩难以理解因此我们提供了丰富的大模型视频教程以动态、形象的方式展示技术概念帮助你更快、更轻松地掌握核心知识。4. 2026行业报告行业分析主要包括对不同行业的现状、趋势、问题、机会等进行系统地调研和评估以了解哪些行业更适合引入大模型的技术和应用以及在哪些方面可以发挥大模型的优势。5. 大模型项目实战学以致用当你的理论知识积累到一定程度就需要通过项目实战在实际操作中检验和巩固你所学到的知识同时为你找工作和职业发展打下坚实的基础。6. 大模型面试题面试不仅是技术的较量更需要充分的准备。在你已经掌握了大模型技术之后就需要开始准备面试我们将提供精心整理的大模型面试题库涵盖当前面试中可能遇到的各种技术问题让你在面试中游刃有余。7. 资料领取全套内容免费抱走学 AI 不用再找第二份不管你是 0 基础想入门 AI 大模型还是有基础想冲刺大厂、了解行业趋势这份资料都能满足你现在只需按照提示操作就能免费领取扫码免费领取全部内容

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2472460.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…