当前位置: 首页 > news >正文

RAG篇(RAG的流程)

RAG的流程

  • 简略版

RAG一般分为三步:首先将文本分割成块;然后使用embedding编码模型将这些块嵌入到向量中,将所有这些向量放入索引中;最后为LLM创建一个提示,告诉模型根据我们在搜索步骤中找到的上下文来回答用户的查询。

在运行时,使用相同的embedding编码器模型将用户查询向量化,然后针对索引执行该查询向量的搜索,找到前k个结果,从向量数据库中检索相应的文本块,并将他们作为上下文输入到LLM提示中,最后总结输出答案。

  • 复杂版

      Indexing:建库

    • 数据收集与处理:系统从各种数据源(如文本文件、PDF、网站、数据库或API)中收集数据,并转换成统一的纯文本格式。

    • 数据分割:将处理后的文本分割成适当大小的块,以便于后续的检索和管理,常用分割方法有固定长度分块、重叠分块等

    • 向量化表示:使用预训练的模型(如BERT、BGE等)将文本块转换为向量表示,这些向量捕获了文本的语义信息。

    • 索引构建:将这些向量存储在专门的数据库中,构建索引结构(如倒排索引或向量索引),以便快速检索。

  Retrieval:检索

  • 查询编码:当用户提交查询时,使用相同的编码器将查询转换为向量表示。

  • 相似性计算:计算查询向量与索引中的文档向量之间的相似度,常用的相似性度量方法包括余弦相似度和欧氏距离。

  • 排序与选择:根据相似度得分对文档进行排序,并选取排名最高的前K个文档或文档片段作为与查询最相关的文档。

  • 查询优化(可选):进行重新排序或过滤,以提高检索结果的质量。

  Generation

  • 上下文整合:将检索到的文档片段与用户的原始查询结合,形成一个连贯的提示(prompt),为生成模型提供丰富的上下文信息。

  • 生成响应:生成llm模型基于这些上下文信息和原始查询生成最终的回答。生成的文本不仅利用了检索到的信息,还结合了模型的语言生成能力,以确保回答的准确性和流畅性。

  • 输出优化:在生成阶段,可能会加入后处理步骤,如答案的置信度评估、多候选答案筛选、格式解析等,以确保生成的答案是相关且准确的。

追问:实际项目中可以有哪些优化

召回源可以考虑多路召回,例如稀疏召回,语义召回,字面召回等。对于多路召回阶段和召回分数对齐的问题,还会采用在召回后面加一个重排序的阶段,精简召回数并提升召回的质量。另外,其中的embedding模型、rerank模型、以及生成模型,都可以根据系统回答的指标情况,进行针对性的微调。

追问:RAG一般怎么做效果评估

RAG做效果评估主要针对检索和生成两个环节。

对于检索环节,可以采用MRR即平均倒排率,前k项的Hits Rate命中率,NDCG排序指标等。

对于生成环节,首先是量化指标,例如Rouge-L,文本相似度,关键词重合度等指标;第二个是多样性,除了准确度,还可以评估生成答案的多样性,看看模型是否能够生成多种合理且相关的答案;除此之外,还需要引入人类评估,进行人工评估,一般是负责该项目的产品经理和测试人员,以及内测的普通用户对模型的回答进行质量、准确性、连贯性的评分;另外,还应该考虑资源效率,尤其是在资源受限的环境中,看看RAG是否能够以合理硬件资源效果提供更好的性能。

使用RAG解决了哪些问题

  • 提升生成内容的准确性:通过引入外部知识库的信息,能够在生成文本时补充模型自身的知识缺陷,提高生成内容的准确性和可靠性。尤其是在特定领域中,RAG可能检索到相比模型训练时更丰富的知识。

  • 即时更新知识:RAG模型具备检索库的更新机制,可以实现知识的即时更新,无需重新训练模型,从而提供与最新信息相关的回答。

  • 增强可解释性:由于RAG模型的答案直接来自检索库,其回复具有很强的可解释性,用户可以核实答案的准确性,从信息来源中获取支持。

  • 缓解幻觉问题:让大模型避免对不了解的内容进行胡说八道。

GraphRAG

基于RAG的大模型应用面临的问题

  • 平面检索: RAG 将每个文档作为一个独立的信息。想象一下,阅读单独的书页,却不知道它们之间是如何连接的。这种方法错过了不同信息片段之间更深层次的关系。

  • 语境缺陷: 如果不理解关系和语境,人工智能可能会提供不连贯的反应。这就像有一个图书管理员,他知道在哪里可以找到书,但是却不知道书中的故事之间的联系。

  • 可伸缩性问题: 随着信息量的增长,寻找正确的文档变得越来越慢,也越来越复杂,就像试图在不断扩展的库中找到一本特定的书一样。

介绍GraphRAG

GraphRAG 不使用非结构化的文本,而是利用知识图谱,利用图结构捕捉数据中的实体、关系及复杂依赖,从而更高效地检索相关信息并生成准确答案。GraphRAG 的一大特色是利用图机器学习算法针对数据集进行语义聚合和层次化分析,因而可以回答一些相对高层级的抽象或总结性问题, 这一点恰好是常规 RAG 系统的短板(例如:用户提问一个问题,需要全局搜索整个数据集,而不是搜索相似性片段,在这种场景下rag性能比较差)。

知识图谱的构建流程

  1. 输入文档:GraphRAG 将一组文本文档的chunking作为输入,这些输入一般存储在图形数据库中。

  2. 实体和语义关系提取: LLM 用于从输入文档中自动提取实体(人、地点、概念)以及它们之间的关系。这是使用命名实体识别关系提取等自然语言技术完成的。

  3. 知识图谱生成: 利用提取的实体和关系构造知识图谱数据结构,通过知识融合对数据进行逻辑归属和冗杂/错误过滤。

  4. 分层社区检测: 使用图算法(例如Leiden),找出紧密相关的实体群体形成的社区。这些社区代表了跨越多个文档的主题或主题。社区按等级组织,高层次社区包含低层次的子社区。

  5. 生成信息摘要:利用LLM为每个社区生成摘要,包括社区中的实体、关系。此外再将社区的分层结构保留在分层摘要中。

GraphRAG中的检索样式

  • 局部检索: 局部搜索旨在理解和回答关于特定实体及其相关概念的详细问题。将用户查询与社区摘要进行匹配,以查找最相关的高社区,在社区中检索相关信息。

  • 全局检索: 全局搜索是为了理解和回答关于整个文档集的综合性问题,如“数据中的前N个主题是什么?”这类需要跨文档聚合信息的查询。利用知识图的分层结构对整个数据集进行搜索,以查找回答查询所需的特定实体、关系和信息。这包括了遍历知识图谱和组合来自多个社区的信息,可以提供全面的响应。

社区检测算法Leiden:

Leiden算法是一种用于复杂网络社区检测的高效算法,它是对Louvain算法的改进,解决了Louvain在社区划分中存在的两大问题:

  • 分辨率限制(Resolution Limit):无法检测小规模社区。

  • 不连通社区(Disconnected Communities):算法可能生成内部不连通的社区。

Leiden算法通过引入迭代细化和严格保证社区连通性,显著提升了社区检测的准确性和稳定性。Leiden算法的核心步骤为:

  1. 局部节点移动(Local Moving)

  • 每个节点尝试移动到相邻社区,选择使模块度增益最大的社区。

  • 与Louvain不同,Leiden采用快速启发式策略,避免陷入局部最优。

  1. 社区细化(Refinement)

  • 将当前社区进一步划分为子社区,通过递归划分提升模块度。

  • 保证每个子社区内部高度连通,避免不完整划分。

  1. 社区聚合(Aggregation)

  • 将每个社区视为超级节点,构建新的网络层次结构。

  • 重复上述步骤,直到模块度不再提升。

RAG的一些技巧

  • 用户查询改写

    • 将用户查询改写成多个查询,分别做检索;

    • 将用户查询拆分成小问题,逐个小问题进行检索和生成,类似于思维链COT;

    • 将用户查询改写成更宏观的问题,检索更多可能相关的文档;

    • 根据用户查询生成一些文档,基于这些生成文档进行检索。

  • Routing:首先计算用户查询于文档库之间的相关性,再在最相关的文档库中查询。

  • 结构化用户查询:从用户查询中拆分出关键词,例如时间、地点、任务等,根据关键词进行检索。

文档解析

文档解析的作用是什么,解析不好会造成什么影响?

在RAG体系里,文档解析是将原始文档转换为可检索的内容的第一步,对后续的向量检索和生成式模型至关重要。它的核心价值在于:

  1. 提取关键信息:准确地从文档中获取可用文本、结构化数据以及上下文关系。

  2. 保留文档结构:对章节层次、表格、列表等结构的保留能帮助检索阶段更精准地定位答案。

  3. 保证文本质量:减少OCR或编码格式导致的噪音与错误,从而提高检索召回的精准度。

如果解析不当,容易导致:

  • 召回错误或缺失:信息被遗漏或文本打乱后,检索阶段就很难拿到正确答案。

  • 上下文扭曲:段落或跨页内容被拆分错位,模型生成时会出现无关或错误的回答。

  • 系统不稳定:一些质量很差的解析结果可能在下游产生连锁反应,导致用户体验大幅下降。

给你一些不同格式的文档,文档解析的大致思路?

  1. 格式识别与路由:首先根据文件类型(PDF、DOCX、图片、HTML等)将文档路由给不同的解析子模块。

  2. 文本抽取

    1. PDF/Word:使用现成的解析库或自研工具来获取文本内容和粗略的排版信息。

    2. 扫描版PDF/图片:通过OCR引擎识别文本,并尽量恢复段落、表格或公式等结构。

  3. 布局和结构化处理:利用布局分析或者自然语言处理手段恢复文档的层级和排版,对表格、标题、列表等进行拆分或标注。

  4. 切分与清洗:在提取到的内容基础上进行去噪(比如去除页眉页脚、重复水印等),并按照自然段或逻辑单元做分块。

  5. 元数据标注:给每个切分后的片段添加文档名、章节标题、页码等元数据,方便后续检索和溯源。

怎么提升OCR的准确率?

  1. 图像预处理:在OCR之前进行去噪、增强对比度、纠偏等操作,减少因扫描质量造成的识别错误。

  2. 分块识别:针对文档中表格、公式、文本区域,采用分块方式单独识别并保留其结构,而不是一次性把整页识别完。

  3. OCR引擎选择:结合场景特点(如语种、字体)选择适配性高的OCR模型,有些模型对手写体或模糊文字有更好的鲁棒性。

  4. 字典和语言模型约束:基于领域词库(例如医学术语、财会术语)对OCR输出做二次校正,修正常见拼写和字符混淆。

  5. 多通道对比:对重要文档,可能用不同OCR引擎并对结果进行对比或融合,尽量降低漏识别或误识别的概率。

多级文档怎么保证在检索阶段保留层级信息?

  1. 结构化存储:将文档各个章节、子章节的标题层级以及表格、图例的位置都转换成可索引的元数据,例如使用JSON、XML或者数据库的方式存储。

  2. Chunk附带上下文:在每个Chunk的属性里记录其在文档中的位置(页码、章节索引)以及父子关系(上级标题、下级标题),必要时也可以记录所有祖先节点的名称。

  3. 检索策略:对查询做匹配时,可以先通过Chunk的文本向量相似度检索出候选结果,再根据层级信息来做二次过滤或排序。例如,如果用户想查“第二章里的某个概念”,那么就可以优先考虑第二章内的Chunks。

  4. 可视化回溯:当将答案呈现给用户时,可以用层级信息告诉用户“本段内容位于第3节第2小节”,让用户更好地理解上下文并找到原文位置

怎么评价文档解析效果?

  1. OCR准确率:统计从图片或扫描PDF中提取的文本与人工校对文本的差异(字符级或词级错误率)。

  2. 段落完整度:对自然段、列表或表格进行完整性对比,看是否有切分过度或拼接错误。

  3. 结构保真度:如果文档包含表格、分栏、多级标题等结构,评估解析后是否能够正确地保留和表示。

  4. 检索测试:在上线阶段,用一组真实查询对解析结果做向量检索,查看召回率和准确率是否符合预期;如果解析质量高,相关查询自然能得到更准确的Chunks。

  5. 可溯源性:是否能通过解析后的结果快速定位到文档原始位置(页码、段落),这也可以作为衡量解析质量的一个指标。

设计一套企业级别RAG检索方案

  • 查询扩展:结合语义理解、用户历史数据和行业术语优化搜索词。

  • 检索优化:结合实体识别、知识图谱、向量检索等技术,提升相关性。

  • 网页筛选:基于权威度、PageRank、时间相关性等筛选Top 50,并优化至Top 32。

  • 回答生成:融合LLM知识与搜索信息,使用Markdown格式,确保结构清晰。

  • 后处理:整理信息提纲,并提供个性化推荐。

查询扩展

在接收到用户输入后,首先对查询进行智能扩展或改写,以准确捕捉用户意图并提高检索覆盖范围。主要包括:

  • 语义同义词扩展:利用自然语言处理理解查询含义,识别其中的同义词、相关词以及行业术语,将这些词加入或替换原查询词。这样可以更准确地描述用户的信息需求,减少查询歧义并提高检索准确度。同义词扩展通常结合用户搜索日志和点击日志,从中挖掘与原查询类似的高频词汇作为扩展候选。模型可通过词向量(如 Word2Vec)计算查询词的语义相似度,自动选择语义相关度最高的词来扩充查询。

  • 拆解长查询:对于过长或复杂的查询,将其拆分为多个有意义的子句或关键词组合,以分别进行检索。查询分段技术会把长查询划分为一系列语义单元,每个单元包含一个或多个关键词。例如,一个冗长的问题可以按子主题拆解成若干短语分别搜索,扩大覆盖面的同时确保每个子查询都有较明确的焦点。然后,再综合各子查询的结果,以完整回答原始长查询。

  • 本地知识库 + Web 搜索结合:同时利用本地知识库和外部搜索引擎对查询进行检索,拓宽信息来源,提高结果多样性。对于特定领域的问题,内部知识库往往包含权威的专业数据,而Web搜索能提供最新、全面的补充信息。通过并行查询本地知识库和互联网,融合两边的结果,可以获取更丰富且最新的资讯。这种结合方式确保在利用领域语义丰富性的同时,兼顾通用搜索的广度和实时性。

检索优化

查询扩展生成多个增强版的查询后,进入检索阶段。该阶段重点在于提高搜索的精准率去除噪音,具体措施如下:

  • 搜索引擎与多渠道检索:执行 Web 检索,获取初步的候选结果列表。同时结合内部索引或数据库(如企业文档、FAQ 等)进行检索,将内部结果与Web检索结果合并。这样既利用了强大的网页搜索能力,又不会遗漏企业内部的有用信息,实现外部信息与内部知识的同步检索。

  • 实体识别与知识图谱加强:对用户查询应用命名实体识别 (NER),提取其中的人名、地名、专业名词等关键实体。根据识别的实体借助知识图谱扩展查询含义,了解实体间的语义关系并加入相关概念词汇,从而使检索更加精确。例如,查询中出现某专业术语时,知识图谱可提供该术语的上下位概念或关联词,一并用于检索以提高召回率。通过实体理解和知识关联,搜索引擎可以更好地“理解”用户想找的对象或主题。

  • 语义向量检索融合:引入embedding 嵌入向量检索技术,将查询和候选文档映射到向量空间中,通过计算语义相似度来匹配相关内容。这补充了传统关键词检索的不足,能够找到那些与查询语义相符但未必包含相同关键词的结果。例如,对于描述性的自然语言问题,向量检索可以根据语义相关性找到潜在答案出处,提高搜索覆盖面。实践中通常采用混合检索(Hybrid Search)方式,将关键词匹配与向量语义检索相结合,以兼顾精确度和召回率。

  • 结果去重与初步过滤:针对检索得到的大量网页结果,设置规则清理噪音和重复项。首先对Top 50左右的初始结果进行去重,移除URL重复或内容高度相似的页面,避免冗余。随后应用过滤规则剔除与查询无关或低质量的结果,例如排除标题或摘要不含查询要点的条目,以及明显广告或泛内容页。可以考虑根据发布时间过滤(确保信息新鲜度)以及根据摘要相关度打分,淘汰关联度差的结果。经过这一轮处理,剩余结果按照相关性重新排序,只保留最相关的候选集用于深度分析。最终大约筛选出Top 32条高质量结果进入下一阶段,用于生成回答 。

信息筛选

在获取候选网页列表后,需要对其内容进行深入的筛选评估,提炼出可供回答的问题相关知识点。主要从以下方面入手:

  • 地区与语言匹配:识别网页内容的语言和地域属性,优先选择与用户偏好相符的结果。例如,针对中文提问者应优先提供中文网页的信息,英文页面则作为次选。类似地,若用户关注本地资讯,则本地来源的网站更具参考价值。通过过滤语言不匹配或地域不相关的内容,可以提高最终答案对用户的适用性和亲切感。

  • 权威度与可信度评估:参考搜索引擎的排名算法(如PageRank)和站点权威性指标,对候选网页的可靠性进行评估。PageRank通过分析网页链接关系来衡量网页的重要性和权威性,更受其他页面引用的网页往往更重要 。因此优先保留权威网站的信息,例如知名新闻媒体、政府或机构官网、学术期刊等来源,因为它们提供的数据通常更准确可信。通过剔除来源可疑、内容陈旧或缺乏引用支持的页面,确保传递给模型的是高质量的信息。

  • 内容要点提取与问答对构建:对筛选后的网页内容进行解析,提炼出能够直接回答用户问题的关键信息点,并将其组织为问答形式的数据。例如,从网页中抽取与查询相关的段落,总结其要旨,形成“问题-回答”对:问题可以是用户查询本身或细分出的子问题,回答则来自网页的事实陈述。这样构造出的问答对不仅浓缩了网页中的有用信息,也方便后续的大语言模型快速查找和引用答案要点。通过将非结构化的网页文本转换为结构化的问答知识,保证提供给模型的是干净且与查询高度相关的资料。这一过程最终产出高质量的知识片段集,为生成回答奠定坚实基础。

回答生成

经过上述检索和信息整理,系统进入由LLM生成自然语言回答的阶段。本环节注重将检索知识与模型自身的语言生成能力相结合,以生成准确、流畅且结构清晰的答案:

  • 融合检索信息与模型知识:利用检索增强生成 (RAG) 的思路,将筛选后的相关信息片段作为提示上下文提供给大型语言模型。在生成答案时,LLM会参考这些外部知识进行回答,从而补充模型参数中未包含或最新的内容 。同时,模型自身的常识和语言理解能力有助于将检索片段串联成连贯的说明。通过将检索得到的事实与模型已有的知识综合,回答既包含了精确的查证信息,又能根据需要进行推理和组织,使内容更加完善。

  • Markdown 格式结构化输出:为了提高答案的可读性和条理性,生成内容采用 Markdown 语法进行排版。答案根据内容自然分段,使用适当的标题、列表、表格等格式来呈现信息。例如,对于步骤流程类的问题,用有序列表逐步列出解决方案;对于要点汇总类的问题,可用无序列表整理关键点;涉及数据对比时则以表格形式展示。清晰的层次结构便于用户快速浏览定位所需信息。与此同时,在答案中嵌入原始来源的引用链接,以支持关键论述并增强答案的可信度(如引用事实数据时附上来源)。整个回答保证语言简洁明了,专业术语配以通俗解释,避免冗长生涩,确保用户易于理解。

后处理与个性化推荐

答案生成后,可以进行结果的后续处理和个性化优化,以提升用户体验:

  • 提纲式总结:在完整答案的基础上,提炼核心结论或步骤要点,形成简短的摘要供用户参考。这个摘要可以作为答案开头的概览,帮助用户快速了解主要结论。提纲列举了本次回答涉及的关键点,让用户一目了然内容结构。如果用户需要深入细节,可以继续阅读后面的详细解答;如果只是寻找概括性的答案,摘要部分即可满足需求。这样的层次化呈现满足不同深度需求的用户,提高了信息获取效率。

  • 个性化推荐:系统结合用户的历史查询记录和行为偏好,对答案进行个性化调整和扩展。通过构建用户画像模型,分析用户以往的搜索主题、点击习惯以及感兴趣的领域,推断其关注点 。基于这些偏好,在提供通用答案的基础上增加个性化内容推荐。例如,如果检测到用户长期关注某一领域的进展,则在回答末尾附上该领域的最新动态或深入阅读链接;如果用户多次询问相关话题,则提供“您可能还想了解…”的扩展问答或相关工具资源。这种个性化策略确保答案对每个用户都具有更高的相关性和实用价值,提升用户满意度和参与度。同时,系统也利用用户反馈不断迭代推荐策略——根据用户对推荐内容的点击和评价,调整后续推荐以更加贴合用户需求。

怎么评估RAG系统的效果

可以从以下角度进行评估:

  • 召回率/准确率: 使用BLEU、ROUGE、MRR等指标评估问答匹配情况(这些指标都是nlp领域常用的指标)。

  • 可信度: 计算答案与支持文档的匹配度,例如检索文档的覆盖率。

  • 响应速度: 记录系统的查询时间并进行统计。

  • 可扩展性: 通过不同规模的数据集测试RAG系统的稳定性。

  • 用户体验: 进行人工评估和反馈收集。

Chunking

为什么要做Chunking

  • RAG需要先将长文档拆分成可检索的文本块(chunks)供向量检索或索引,以保证检索效率和模型处理的上下文长度限制。

  • 不经过合理切分,会导致检索和生成时出现重要信息丢失或上下文拼接不完整等问题。

  • 适当切分可以减轻检索负担,提高检索准确度和后续模型生成效果。

RAG 建库时怎么做chunking

基于Langchain的分块方案:

  • Character:按固定字符数分割。 可以设置重叠字符来保持上下文

  • Recursive:Langchain的默认文本分割器,它按不同的字符递归地分割文档(默认使用[“\n\n” ,"\n" ," ",""]),按照顺序逐个遍历列表中的分隔符直到块足够小为止。 可以设置重叠字符来保持上下文。

  • Token:按照token数量进行分块。常用的分词器有BPE、tiktoken等

  • Document:使用特定的分隔符或规则进行分割,如markdown中的标题符号、Python代码中的类和函数等。

  • Semantic:通过计算句子间embedding距离,把具有相似主题或内容的句子分为一块。

  • Agentic:最高级别的chunking方法,通过LLM做决策,将文本分块为独立的命题。

追问:chunking时应该考虑的因素
  1. 被索引内容的性质是什么? 是处理较长的文档(如文章或书籍),还是处理较短的内容(如微博或即时消息)?

  2. 使用的是哪种Embedding模型?例如,sentence-transformer模型在单个句子上工作得很好,但像text- embedt-ada -002这样的模型在包含256或512个tokens的块上表现得更好。

  3. 对用户查询的长度和复杂性有什么期望?用户输入的问题文本是简短而具体的还是冗长而复杂的?这也直接影响到我们选择分组内容的方式,以便在嵌入查询和嵌入文本块之间有更紧密的相关性。

  4. 如何使用检索结果? 例如,它们是否用于语义搜索、问答、摘要或其他目的?

一个比较好的Chunk切分方案(规则 + 语义融合)

  • 基于规则的切分:利用文档格式特征,如章节标题、段落换行、列表项、表格边界等作为切分点。一旦检测到新的章节点或列表起始,就结束当前Chunk开启新Chunk。对于表格、代码块和图片,整段内容视为一个Chunk,避免中途截断。

  • 语义连贯的调整:在规则初切分后,检查相邻Chunks的内容连贯性。如果发现某Chunk过短且与前后段落语义上紧密相关(例如上一个Chunk以冒号结尾或内容未完结),则可以和相邻Chunk合并,确保信息完整。例如跨页的段落,如果下页开头并非新章标题,则应与前页末尾合并为同一Chunk。再如表格跨越多页时,将各页片段合成为一个整体表格Chunk。通过简单的NLP或embedding相似度检测,也可判断段落主题是否延续,辅助决定是否合并或继续切分。

  • 长度和平衡:在保证语义完整的前提下控制Chunk长度,使其适合向量检索和后续模型处理(例如不超过512字或一定token数)。过长则适当按语义次级节点再拆分,过短则与相邻补充。最终每个Chunk都应是自含意义明确的一段内容。

怎么保证跨页图片和表格不被拆分到不同的chunk中?

  • 在解析阶段标记表格/图片的起始和结束位置,将它们视为不可拆分单元;

  • 引入版面检测或分页信息(如PDF解析时的page number、坐标等)来判定表格或图片是否被跨页切断,然后在合并逻辑中优先“整块”保留。

  • 当其Token大小超过预设阈值时,需将其单独放进一个Chunk,而不是与其他文本混合。

如何避免将一个完整段落或语义单元拆分到多个Chunk中?

  • 通过句子边界检测、段落级ID或layout信息(如行距、换行检测)标识完整段落,确保同一段落内的语义单元尽可能保留在同一个Chunk。

  • 引入Token计数逻辑时,先检查合并后的长度是否超过阈值。若不会超,则整段放在一个Chunk,否则在自然的语义边界(如句号、分号等)进行拆分。

如何根据chunk定位到原文位置?

  • 在每个Chunk中记录其对应的页码、段落ID、或者其他排版信息(如“(p1)”、“paragraph_id=xxx”);

  • 通过结构化的元数据(JSON或数据库字段)与检索系统集成,能让RAG在检索结果中快速定位到原文位置;

  • 这样不仅能在检索环节准确找到对应Chunk,也方便前端应用在输出时展示文档来源。

如何评价Chunk切分效果?

  • 信息完整度:表格/图片/标题等是否完整保留,量化为“完整保留率”或“信息缺失率”;

  • 语义连贯度:检查原文被过度割裂的比例,如“句子被打断”的次数占比;

  • 段落/标题结构准确率:切分后标题与对应正文保持正确层级的比例;

  • 搜索检准率:在RAG场景下,经切分后的文档块能否有效提升检索与回答准确率;

 

混合检索方案

  1. 意图识别与路由:通过简单的规则或训练分类模型对查询进行分类。如果检测到查询是流程/制度类问题(通常包含“制度”、“流程”等关键词),则可以对BM25检索给予更高权重;如果是开放性思考类问题(包含“如何”、“怎么办”等),则侧重向量检索结果。此前置步骤保证不同查询走最合适的检索路径。

  2. BM25检索:构建文档的关键词倒排索引(可使用Elasticsearch或其他搜索库),检索出Top N候选文档片段。BM25根据查询词在文档中的频率、文档长度等打分。对于短查询,可直接采用BM25结果;对于长查询,BM25结果可作为补充。

  3. 向量检索:利用Embedding模型将查询编码成向量,在Milvus向量数据库中进行近邻搜索,获取Top N候选片段。向量检索能找出语义相关的内容,即使字面不匹配。

  4. 结果合并与去重:将两种检索的候选列表合并。由于BM25分数和向量相似度分值不在同一量纲,需进行归一化处理。例如,可将BM25分数归一到0-1区间,向量相似度天然在0-1(如余弦相似度)。然后按一定策略融合,如线性加权组合或者直接取两者结果集的并集。在组合过程中处理重复文档(相同chunk多次出现)以避免干扰。

  5. 提高召回率:混合检索确保潜在相关结果进入候选集。尤其在只用向量或只用BM25无法检索到某些答案时,另一种方式可以补充,使真正相关的片段不被漏掉。

生成面临的问题

  1. 多轮对话的语义连贯性不足:在用户多轮提问时,如果新问题是对上一轮回答的跟进(例如用户问:“这个怎么申请?”),系统需要理解“这个”指代什么。缺少对话上下文的关联可能导致LLM误解提问,给出不相关或幻觉的答案。

  2. 多模态知识的利用困难:金融保险领域的知识库包含PDF手册、PPT演示、文本说明、视频讲解等多种形式。如果不对这些不同格式的数据进行预处理和结构化,检索时可能遗漏关键信息,导致答案不全面。

  3. 缺少来源引用降低可解释性:用户希望了解答案出处以建立信任。如果生成的答案没有标注来源,用户无法追溯信息真实性。特别是从长文档提取内容时,不注明具体出处会降低答案的可信度和可检查性。

索引

RAG怎么做索引

RAG将embedding后的向量存储在专门的数据库中,构建索引结构(如倒排索引或向量索引),以便快速检索。这就需要用到向量数据库了。向量数据库是一种专门用于存储、索引、查询和检索高维向量数据的数据库系统。它特别适合处理非结构化数据,如图像、音频和文本,能够实现传统数据库难以完成的高级分析和相似性搜索,具备高效存储和处理高维向量数据的能力。

追问:如何选择向量数据库

常见的向量数据库包含milvus、Elasticsearch、Faiss、Chroma等,选择时可以考虑的因素有:

  1. 数据规模和速度需求:考虑你的数据量大小以及查询速度的要求。一些向量数据库在处理大规模数据时更加出色,而另一些在低延迟查询中表现更好。

  2. 持久性和可靠性:根据你的应用场景,确定你是否需要数据的高可用性、备份和故障转移功能。

  3. 易用性和社区支持:考虑向量数据库的学习曲线、文档的完整性以及社区的活跃度。

  4. 成本:考虑总体拥有成本,包括许可、硬件、运营和维护成本。

  5. 特性:考虑你是否需要特定的功能,例如多模态搜索等。

  6. 安全性:确保向量数据库符合你的安全和合规要求。

追问:常见向量索引算法
  • IndexFlatL2:直接对所有向量进行精确搜索,计算每个查询向量与数据集中所有向量的L2距离。

  • IVF:使用如K-means聚类等技术将整个数据分成多个簇,每个向量被分配到一个特定的簇。查询时识别最近或最相似的簇,并在这些簇内搜索特定的文档。

  • HNSW:创建了类似概率跳表的层,节点之间建立图形化的连接。每一层的节点不仅连接到当前层的节点,还连接到下层的节点。查询时从最顶层的预定义节点开始,逐步向下移动到较低的层,直到达到最后一层或到达与所有其他连接节点距离最小的节点。

  • DiskANN:DiskANN是一种基于磁盘的高性能向量近邻搜索算法,旨在解决大规模向量数据检索中的内存消耗问题。通过将轻量级的索引结构置于内存中,而将海量的原始数据和构建好的图结构存放在磁盘上,DiskANN能够在保持高召回率和低时延的同时,大幅减少对内存资源的依赖。

文档嵌入做索引的时候,很多文档特别相似怎么区别

  1. 语义去重:用LSH算法检测近重复文档(>90%相似),保留唯一副本,过滤掉重复的内容。

  2. 文档分块:将长文档分割成更小的片段(如段落或句子级别),然后分别进行嵌入。这样可以更细致地捕捉文档的语义信息,提高相似文档的区分度

  3. 元数据注入:为文档添加时间戳、来源、作者等字段到文档头部等关键实体作为标签

  4. 嵌入模型优化:使用性能更优的嵌入模型,在下游领域微调嵌入模型,

  5. 索引优化:采用密集向量检索+稀疏检索+多向量检索的方式,构建多级索引结构,如树状索引(如RAPTOR),通过分层的方式提升信息检索的效率和精度,同时适应不同粒度的查询需求

  6. 检索优化:采用粗排+精排。

RAG中为什么会出现幻觉?

幻觉问题是大模型的一个通病,出现幻觉问题的原因主要分为两大类,一类是生成结果与数据源不一致,自相矛盾。另一类是用户问题超出了大模型的认知。

针对前者可能是训练数据和源数据不一致、数据没有对齐或者编码器理解能力的缺陷和解码器策略错误可能导致幻觉,后者则是因为用户的问题不在语言模型认知范围内。

Embedding

怎么选择合适的embedding模型

可以参考huggingface上的排行榜:mteb,它提供了一个公开的embedding模型排行榜,用于展示各个模型在不同任务上的表现。覆盖了 8 类任务和 58 个数据集,涉及 112 种语言,是目前最全面的文本嵌入评估基准之一。虽然可以通过 MTEB 排行榜对比不同向量模型的差异,但也只能作为一个参考,这些模型在公开数据集上的benchmark 在垂直领域、企业自身的业务领域不一定成立,具体选择哪个向量模型还需结合业务特点进行综合比较、权衡。可以从以下几个角度考虑:

  1. 语言支持和性能:大部分开源向量模型只支持单一或者有限的文本语言,所以需要确保 Embedding 模型支持的语言种类。多语言模型如 OpenAI Embedding 和 bge-m3 等模型能够处理多种语言。bge-m3 支持 100 多种语言,适合多语言需求的场景。另外,某些模型在主要语言(如中文)中的表现较好,但在处理较少使用的语言时可能会表现不佳。因此,需要评估模型在所有必需语言中的准确性,以确保一致的性能。

  2. 处理长文本的能力:切分的文本片段后续需要通过 Embedding 模型进行向量化,所以必须考虑向量模型对输入文本块的 tokens 长度限制,超出这个限制则会导致模型对文本进行截断,从而丢失信息,影响下游任务的性能。不同的 Embedding 模型对文本块长度的支持能力不同。比如,BERT 及其变体通常支持最多 512 个tokens,处理长文本时则需要将文本分成更小的块,意味着需要更加精细化的分块策略。而 Jina AI 的 Embedding 模型和 bge-m3 模型则支持 8K 的 tokens 输入,适合处理长文本块。

  3. 模型在特定领域的表现:通用 Embedding 模型在特定垂直领域(如医学、法律和金融等)可能不如专用模型有效。这些领域通常需要专门训练 Embedding 模型来捕捉特定的专业术语和语境。为特定业务需求优化的 Embedding 模型能够显著提升检索和生成的质量。例如,通过结合向量检索和重排序(reranking)技术,可以进一步优化结果。

  4. 存储和内存等资源需求:高维向量需要更多的存储空间,这可能会带来长期成本。例如,较高维度的模型如 text-embedding-ada-002 需要更多的存储资源。另外,较大的模型可能会占用更多内存,因此不适合内存有限的设备。

  5. 模型响应时间:Embedding 模型的处理速度在实时应用中尤为关键。例如,intfloat/e5-base-v2 模型在处理速度上表现优异,但需要在 GPU上 运行以达到最佳性能。在选择模型时,需要评估其在嵌入和检索过程中的延迟。例如,OpenAI 的 Embedding 模型在许多基准测试中显示出较高的性能和较低的延迟。

通用的 Embedding 模型通常是在大规模、多样化的数据集上训练的,可能不完全适合特定领域的任务,比如医学、法律等专业领域,它们无法很好的理解一些专有词汇。如果模型在业务数据集上表现不能满足预期,可以通过微调,让模型学习到特定领域的词汇和概念,使其在特定应用场景中表现更佳。

因此,在特定领域,对向量模型进行 Finetune 的主要目标是提高 Recall@N (前 N 个检索结果中包含相关文档的比例)的准确率和优化正例与负例的 similarity 值域分布。通过微调,模型可以更好地适应特定领域,提高 Embedding 表示的质量,减少检索结果中的噪声,提高相关文档的检索准确性。同时,微调可以更好地分辨正例和负例,使它们在向量空间中的分布更加明显,形成清晰的边界。这样,当检索结果的相似度值低于某个阈值时,可以舍弃对它们的召回,减少误判风险,从而减少生成模型的负担和幻觉风险,提升整体系统性能和用户体验

你了解哪些embedding模型?

bge模型,全称BAAI General Embedding,是智源研究院提出的,有多个版本,比如v1、v1.5、m3等,还有对应的中文和英文版,bge v1版本的训练分为3个阶段:

(1)预训练:用Wudao数据集纯文本语料训练,利用了RetroMAE,重建污染的编码向量;

(2)弱监督学习:用C-MTP无标签数据集训练,对比学习从负样本学习中如何区分出成对的文本,在这一步中使用in-batch负采样+大的batch size的方法避免了挖掘难负样本。

in-batch负采样是:假设你有一个batch内的m条文本,然后你对每条文本p都配对加入其对应的一条正样本文本q(即相关文本),这样,在该btach内,除了跟你相关的正文本,其他文本都是跟你不相干的负文本,可以组成负样本集合。

(3)有监督微调:用C-MTP有监督数据集训练,由于标签数据是多任务的,所以加入了指令微调实现多任务下的微调。在这一步中使用了ANN-style采样策略来挖掘难负样本。

conan-embedding,腾讯提出的最近在C_MTEB霸榜的embedding模型。主要通过挖掘更多质量更高的负样本的方法提升了embedding模型的能力。训练过程可以分为两个阶段:弱监督预训练和有监督微调。

其中弱监督预训练阶段主要收集了大量高质量的负样本,使用了一些过滤方法,比如使用bge-large-zh-v1.5模型对数据进行评分,过滤掉得分低于0.4的低质量数据。然后就是常规的in-batch对比学习训练。

在有监督微调阶段,将训练数据分为retrieve和STS两种任务类型,使用了两种优化技巧:

  • 动态硬负样本挖掘:每经过一段时间,重新计算在最新模型下hard negative的得分,如果得分太低,就重新挖掘。

  • 跨GPU批次平衡损失:提出了联合损失函数,平衡retrieve任务和STS任务的训练损失,避免模型优化方向不一致。

追问:对比学习是怎么做的

对比学习是一种自监督学习方法,目的是要通过将相似的样本(positive pair)拉近距离,将不相似的样本推远,从而学习到数据的有效表示。在对比学习中,我们通过设计合适的loss函数来度量样本对之间的相似性,并优化模型。

追问:loss是怎么算的

常用的loss函数包括对比损失、InfoNCE损失和Triplet Loss等。InfoNCE损失通过类似softmax的公式,计算目标样本与正负样本之间的相似度,并用温度参数τ来调节区分度;Triplet Loss则通过三元组的方式确保锚点和正样本的距离小于锚点和负样本的距离。

1. 对比损失(Contrastive Loss)

对比损失是基于样本对来工作的,目标是使得相似的样本在嵌入空间中距离更近,不相似的样本距离更远。具体来说,损失函数会计算样本对之间的欧几里得距离。如果样本对是正样本(相似的),它会鼓励这两个样本的距离变小;如果是负样本(不相似的),它会惩罚这两个样本的距离过大。具体来说,对于每一对样本,损失是正样本对距离的平方加上一个负样本对的距离。为了防止负样本过度影响,负样本对距离的平方通常会加上一个阈值,这个阈值通常叫做 margin。这样做的目的是要控制负样本的影响,不让负样本距离过小。

2. InfoNCE损失(Information Noise Contrastive Estimation)

InfoNCE损失的公式有点类似softmax的形式。它的目的是通过计算样本之间的相似度来区分正样本和负样本。具体来说,它的分子是目标样本和正样本的相似度(通常用余弦相似度或点积来表示),而分母是所有样本与目标样本的相似度的总和。为了让模型能够更好地区分正负样本,分母中会包括多个负样本的相似度。因此,分母不仅仅是负样本,而是整个候选样本集。这个损失函数的一个关键点是它有一个温度参数τ,用来控制相似度值的缩放,τ越小,正负样本的区分越明显。

3. Triplet Loss

Triplet Loss的设计使用了三元组结构,由一个锚点(anchor),一个正样本和一个负样本组成。锚点和正样本之间应该更相似,而锚点和负样本之间应该更不相似。具体来说,损失函数计算锚点与正样本之间的距离,并与锚点与负样本之间的距离做对比。目标是确保锚点与正样本的距离小于锚点与负样本的距离,且两者的距离差应该大于一个指定的margin。损失函数通过确保锚点和负样本之间的距离至少比锚点和正样本之间的距离大一个margin来推动模型进行优化。

追问:InfoNCE loss中参数$$\ta$$的作用

τ的作用类似于softmax中的“温度”,它决定了这些分数的“平坦度”。较小的τ值会使得分数差异变大,梯度更新变得更加尖锐,这样训练过程中,模型会更加强调正样本与负样本之间的区别,可能会导致模型对负样本的区分更加敏感,从而加速收敛,但也可能导致训练过程中的不稳定,容易过拟合或者训练不充分。

而较大的τ值则会使得分数差异变小,更新变得更加平滑,这样训练过程中,模型对于正负样本的区别会变得不那么明显,训练会变得更加稳定,但可能会导致收敛速度变慢,模型学习到的区分能力较弱,进而需要更多的训练迭代来达到较好的性能。

怎么提升Embedding模型效果

  • 有监督微调:使用领域问答对或相关性标注的数据,通过度量学习损失函数(如Triplet LossMultipleNegativesRankingLoss等)训练模型,使得相似问句-文档对的向量距离更近,不相关对更远。

  • 继续预训练:将Embedding模型(如BGE)在大量无监督文本上继续训练(如通过Masked Language Model任务或者对比学习),让模型嵌入空间更贴合领域分布。

  • Cross-Encoder蒸馏:用一个强大的交叉编码器(如一个微调后的BERT问答模型)生成query-doc相关性得分,然后微调bi-encoder的Embedding模型去拟合这些得分,实现知识蒸馏。

Embedding模型再下游任务表现不佳有什么体现

预训练的Embedding模型可能在下游任务上表现不佳,体现在以下方面:

  • 语义理解偏差:模型可能将一般语境下相似的词判为相关,但在下游领域可能意义不同(例如“保费” vs “费用”)。

  • 同义词识别:领域内常见的不同表述(如“推广”与“推销”)需要模型识别为相似。

  • 重点概念强化:通过训练让模型强调领域高频概念,从而在嵌入空间上将相关主题的文档聚类更紧密,提升召回准确率召回率

http://www.lryc.cn/news/587096.html

相关文章:

  • STM32-第六节-TIM定时器-2(输出比较)
  • Linux驱动开发2:字符设备驱动
  • iOS UI视图面试相关
  • 哪些行业的“反内卷”前景更好?
  • ADB 调试日志全攻略:如何开启与关闭 `ADB_TRACE` 日志
  • 【Datawhale夏令营】用AI做带货视频评论分析
  • [附源码+数据库+毕业论文+答辩PPT+部署教程+配套软件]基于SpringBoot+MyBatis+MySQL+Maven+Vue实现的交流互动管理系统
  • 每天学一个八股(二)——详解HashMap
  • 26-计组-指令执行过程
  • HTML5 离线存储
  • MyBatis04-MyBatis小技巧
  • Typecho后台编辑器自定义按钮开发实战指南
  • Spring Boot 集成 Spring Security 完整示例
  • Sping AI Alibaba
  • 《区间dp》
  • Linux锁的概念及线程同步
  • Python异步编程
  • 【版本控制】Perforce Helix Core (P4V) 完全入门指南(含虚幻引擎实战)
  • CAU数据挖掘第四章 分类问题
  • 从儿童涂鸦到想象力视频:AI如何重塑“亲子创作”市场?
  • LAN-401 linux操作系统的移植
  • 在线事务处理OLTP(Online Transaction Processing)负载是什么?
  • vector各种接口的模拟实现
  • python 虚拟环境 Anaconda Miniconda
  • 音视频学习(三十八):像素与位深
  • Linux | 数据库操作基础
  • 【ROS2】自定义消息接口的创建和使用
  • # 通过wifi共享打印机只有手动翻页正反打印没有自动翻页正反打印,而通过网线连接的主机电脑可以自动翻页正反打印
  • 信息收集(外围打点)
  • 在上海开发小程序,怎么做出“高级感”?