微信扫码
添加专属顾问
我要投稿
探索RAG技术在上下文处理上的挑战与创新解决方案。 核心内容: 1. RAG技术基本原理及其面临的上下文挑战 2. Late Chunking与Contextual Retrieval两种策略对比 3. 上下文丢失问题对RAG性能的影响分析
RAG系统通过预先将知识库切分成许多小段并转换成向量,存入向量数据库;在用户提问时,系统检索与查询语义相似的文本片段,附加在提示中提供给生成式模型,以提高回答的准确性,这种方法让模型能够利用外部知识回答问题,避免了模型单靠训练记忆可能出现的遗漏。然而,RAG面临一个关键挑战:上下文的丢失与选择。传统RAG在对文档编码时往往丢失了重要的上下文信息,这导致检索到的片段并非真正相关的那部分内容换句话说,如果将文档割裂后各自编码,很多语义关联会被打断,系统可能检索不到正确的知识,降低了RAG整体性能。为了解决这一上下文缺失的问题,近期提出了两种先进策略——Late Chunking(延迟切分)和Contextual Retrieval(上下文检索),分别从不同角度改善向量嵌入对文档上下文的保留。
文档切分策略:Early Chunking vs. Late Chunking
RAG在预处理知识库时,需要将长文档切分成较小的片段(chunk)再嵌入,这是因为许多Transformer模型有输入长度限制(如512或1024个Token),无法一次编码完整长文档。传统方法是先切分,后嵌入,我们称之为“Early Chunking”(预先切分)。但这种朴素切分策略带来了严重的问题:
从数学上看,假设完整文档的理想嵌入为$E(D)$,而将其切分为若干片段$D_i$后各自嵌入得到$E(D_i)$。朴素切分相当于用这些局部向量集合来近似原文档的语义表示。但这种近似随着切分粒度变细而偏差增大,因为文档整体的连贯性无法由若干孤立片段简单相加重构。此外,每个片段的嵌入$E(D_i)$并不等同于该片段在全文上下文中应有的表示$E_(D_i|D)$。也就是说,在脱离全文的情况下得到的片段向量,往往并未捕捉该片段在原文中的真实语义。特别是当切分发生在句子中途或跨段落的概念链被切断时,这种失真更为严重。整体语义的割裂和片段语义的失真,就是传统切分(naive chunking)面临的主要挑战。
为了解决上述问题,业界提出了Late Chunking(延迟切分)策略。顾名思义,Late Chunking的理念是“先嵌入,后切分”:尽可能在嵌入阶段保留整篇文档的语境信息,然后再根据需要将嵌入结果划分成片段向量。具体而言,这一方法通常包含以下步骤:
通过Late Chunking,每个chunk的嵌入向量都带有全文的“烙印”,不再是彼此独立同分布(i.i.d.)的向量,而是条件化了全局上下文。这样大幅降低了语义丢失:原本跨片段的关联在嵌入阶段已被模型捕捉并传播到各个相关片段的向量中。
例如,在处理维基百科中关于柏林的文章时,包含短语“the city”的段落如果用传统方法嵌入,只会根据“the city”自身的词义生成向量,模型不可能知道“the city”指的是哪座城市。但采用Late Chunking时,由于模型一次处理了整篇文章,“the city”这个短语的向量表示将结合之前出现的“Berlin”信息。最终对这个短语池化得到的片段向量,自然地包含了“Berlin是那座城市”的语境关系,同时也保留了片段本身“the city”的局部含义。如此得到的嵌入比孤立片段嵌入更加语义准确,既抓住了局部意义又携带了宏观文档背景。
Late Chunking通过在嵌入阶段处理完整文档,使每个片段向量都带有全局上下文信息(右),对比传统方法每个片段各自嵌入导致语义割裂(左)。图示左侧展示了朴素切分先分后 embed 的流程,右侧为Late Chunking先 embed 后分的流程。
Late Chunking的优点首先在于语境保留。一次性编码全文只需经过模型一次前向传播,然后简单切分即可得到丰富的片段向量,这种流程相对直接高效。由于每个片段在生成向量时都“看过”全文,语义不再片面,大大降低了关键信息遗漏的风险。实验表明,在采用Late Chunking后,向量检索找到相关内容的准确率显著提升:例如对于查询“Berlin”,原本未直接提到“Berlin”的片段“the city is also one of the states…”在朴素切分下与查询的余弦相似度只有0.708,而Late Chunking下提高到0.825。这意味着经过Late Chunking处理,该片段向量与“Berlin”查询向量的角度明显更小,更容易被检索认为相关。Late Chunking几乎做到让每个片段向量都接近于理想的$E_(D_i|D)$,从而减轻了上下文缺失带来的负面影响。
以上是来自论文的完整算法,但重要的是要知道这是一个将整个文档的上下文插入每个分块的机制
需要注意的是,Late Chunking并非毫无代价。它受到嵌入模型上下文窗口大小的限制:模型能一次处理的Token数有上限,如果文档非常长(超过模型的窗口),仍然不得不拆分处理。换言之,Late Chunking依赖长上下文嵌入模型的能力,只有当文档长度在模型可承受范围内时才能充分发挥作用。目前大多数专用嵌入模型的上下文长度有限,而一些大型LLM(如GPT-4或Claude等)的上下文窗口更大,但直接用LLM做向量检索的嵌入既不经济也未必最优。因此,当面临超长文档时,我们需要寻求其他办法在片段中注入上下文——这正是Contextual Retrieval策略大显身手的场景。
Contextual Retrieval:让每个片段“自带上下文”
当文档长度远超出单一模型的处理能力,或我们无法更换长上下文模型时,另一种思路是:在每个片段里人为地加入它的上下文信息。这就是Contextual Retrieval(上下文检索)策略背后的核心思想。与Late Chunking从模型机制入手不同,Contextual Retrieval更像是在预处理阶段做文章:通过一个语言模型或其他手段,给每个文档片段配备一段额外的说明,使其更加“自含上下文”后再去嵌入和检索。
Anthropic在2024年提出了这一方法,并证明了它卓越的效果。具体而言,Contextual Retrieval包含两个关键步骤:上下文嵌入(Contextual Embeddings)和上下文BM25检索(Contextual BM25)。首先,对每个文档片段,利用一个强大的大语言模型(如Anthropic的Claude或OpenAI的GPT-4),根据整篇文档内容为该片段生成一段简洁的说明性上下文,将其前置拼接到片段文本前。然后,将这段“扩充了上下文信息”的新片段再进行向量嵌入;同时,对于生成的说明文本,我们也可以建立一个关键词检索索引(BM25),用于精确匹配查询中的关键术语。
举个例子:假设原始片段是“The company’s revenue grew by 3% over the previous quarter.(公司收入较上季度增长了3%。)”。单看这句话,我们并不知道“公司”指代哪家,也不清楚是哪一季度的业绩。针对这个片段,Contextual Retrieval会让模型阅读完整文件(比如一份财报),然后生成一句简要说明,例如:“本段摘自ACME公司的2023年第二季度财报,上季度营收为3.14亿美元。公司本季度收入较上季度增长了3%。”。新片段现在包括了公司名称和时间段等背景信息。我们将这段补充上下文后的文本再送入嵌入模型得到向量,同时在BM25索引中收录这段完整文本。这意味着,日后无论用户查询“ACME公司2023 Q2收入”这样的精确关键词,还是问“那家公司本季度业绩如何”这样模糊但需要上下文关联的问题,我们的检索库里都已有对应的向量和关键词可以匹配到相关片段。
Contextual Retrieval预处理流程示意:对于每个文档片段,都利用LLM阅读整份文档生成一段概括上下文,将其附加到片段前一起构造成“上下文化片段”,然后再送入嵌入模型编码并存入向量数据库。同时,这些上下文化文本也建立关键词索引(如BM25)用于精确匹配。该方法确保检索时即便查询使用不同措辞或只提及上下文信息,依然能找到相关片段。
这种方式相当于请大模型当一回“摘要标注员”:为知识库中每个孤立的段落写上一小段上下文说明,标明它出处为何、涵盖哪些关键信息。这样做的效果是惊人的:根据Anthropic的报告,引入Contextual Retrieval后,RAG系统检索失败率大幅下降了约49%,若再配合重排序(rerank)等手段,总体检索错误率可减少67%。换言之,以往因为片段缺乏背景而导致的检索miss,几乎降低了一半。这种提升直接带来了下游问答性能的提高——模型回答错误减少,内容准确性提高。
为什么给片段加一点“注释”就能有如此改善?从向量空间角度看,道理并不神秘:上下文说明为片段嵌入提供了更多辨别信息,使得原本远离查询的片段向量被拉近了查询向量。例如之前提到的代词指代问题,如果查询包含“柏林”而片段本身只有“the city”,朴素嵌入下二者向量可能距离很远(因为模型不知道“the city”就是柏林)。但通过上下文生成,我们在片段前附加了“此片段讲的是柏林这座城市…”,于是片段的新向量自然会靠近“柏林”关键词的语义位置。这就大幅提高了该片段与查询的余弦相似度,使其更有可能在检索中被选中。同理,BM25的加入确保了一些嵌入模型漏掉的精确匹配也能被找到,例如查询中包含的代码、姓名等专业术语,哪怕向量模型不擅长处理,关键词检索也能补上一把。因此,Contextual Retrieval本质上是将语义匹配与精确匹配结合,最大程度弥补了纯向量检索在上下文缺失下的弱点。
需要指出的是,Contextual Retrieval虽然有效,但相比Late Chunking开销更大。因为我们要为知识库中的每个片段调用一次LLM来生成上下文,这在文档很多时是一笔可观的费用和时间消耗。不过可以通过一些工程技巧降低成本,例如上下文缓存。Anthropic利用其Claude模型的一个特性:可以将整篇文档加载进模型的隐存(缓存)中,然后对每个片段重复使用该上下文,而不必每次都把全文重新输入模型。据称利用缓存后,批量生成上下文的成本可降低至原来的10%以内。此外也可以并行处理多个片段,或者一次让模型生成多个片段的上下文(虽然一次要求LLM写太多不同片段的摘要可能降低质量,Anthropic更推荐逐个生成)。总之,Contextual Retrieval在计算上要比普通RAG复杂一些,但在长文档(超出嵌入模型长度)或复杂语境下,它提供了一种切实可行的方案来保持上下文的一致性,被证明在实践中更有效地抓取到了正确的信息。
多轮检索的挑战:对话上下文的衔接
无论Late Chunking还是Contextual Retrieval,目前讨论的大多是针对单轮问答或独立查询的场景。然而,在实际应用中,用户往往会进行多轮对话式的提问。多轮对话下RAG面临新的挑战:如何在检索时利用对话上下文? 例如,用户第一问是:“柏林在哪一年首次被提及为德国首都?”,系统检索并回答了相关信息。接着用户追问:“它的人口有多少?”——这里的“它”显然仍指柏林。如果检索模块没有意识到这一点,直接用查询“它的人口”去向量数据库搜索,极可能什么也找不到,因为片段中不会写着“它的人口”这样的句子。这意味着RAG系统的检索必须具备对话记忆,能理解后续查询中的省略指代,主动将前文提到的主题(柏林)融入新的查询向量或检索关键字中。
目前应对多轮检索的一般做法,是在每次检索时将对话历史纳入考虑:例如,将之前用户的问题或系统的回答拼接到当前查询一起送入嵌入模型,生成带上下文的查询向量;或者对用户的追问进行共指消解,将“它”替换为具体对象(柏林)再检索。此外,还有一些多跳检索策略:系统在回答复杂问题时,可能先后检索多次,不断利用上一步的结果来完善下一步的查询。在这些多轮、多步互动中,Late Chunking和Contextual Retrieval的方法也需要相应调整。Late Chunking可以尝试在对话历史和新问题的组合上使用长上下文模型,使查询嵌入本身包含对话语境;而Contextual Retrieval则可以考虑为对话产生上下文,例如用LLM summarizer将前文重要信息归纳,再附加到当前查询的检索过程中。总的来说,多轮场景强化了“上下文就是王道”的原则:不仅文档需要上下文,查询本身也有上下文。如何让检索模块充分理解对话语境,仍然是在RAG应用中需要攻克的难点。
多模态文档的困境:文本与图像的语义融合
RAG系统最初主要用于文本,但真实世界的知识库往往是多模态的:包含文字、图片、表格、音频、视频等多种形式的数据。例如,一个企业的内部知识库里可能既有PDF文档(富含文字说明和数据表),又有产品图片、设计图纸,甚至视频教程。当我们希望构建一个多模态的RAG系统时,传统文本检索的方案必须扩展,以跨越模态地理解和检索信息。这带来了两个主要挑战:
首先,每种模态都有各自嵌入和理解的难点。文本可以用语言模型嵌入,那么图像怎么办?常见做法是使用预训练的图像嵌入模型(如CLIP等)将图像转成向量。但图像的语义往往和文字描述有所不同,如何确保图像嵌入空间和文本嵌入空间可以对齐比较,是一道难题。一种办法是训练一个多模态联合嵌入模型,能够同时接受文本和图像输入并映射到同一向量空间。但训练这样模型需要大量跨模态数据,而且可能出现信息损失——为了在一个向量中同时表示图像和文字内容,不可避免地要压缩掉一些细节。另一种办法是分别嵌入:文字用文本模型嵌入,图片用图像模型嵌入,分别建立向量索引。但这样检索时会产生一个新的问题:当用户提出问题可能涉及多模态信息时(比如“请给我这份报告里展示的销售趋势图”),系统如何比较文字片段和图片向量,决定提供哪一种结果?通常需要增加一个重排序或融合步骤,把不同模态的检索结果放在一起,由一个学习模型或启发式规则来判断哪个更相关。
其次,跨模态的上下文关联难以保持。想象一篇包含文字说明和插图的文档:文本里说“如下图所示,销量呈上升趋势”,对应的图像是一张折线图。如果我们把文字和图像分开嵌入,各自成为独立的检索单元,那么文字片段“销量呈上升趋势”本身并未提及是哪张图、什么产品的销量;而图像向量虽然编码了折线趋势,但不知道文字描述了它。朴素RAG检索时,可能既搜出了文字又搜出了图,但生成模型很难自动将二者关联起来(尤其当图和文不在同一个检索窗口返回时)。为了解决这种语义裂隙,我们需要多模态的上下文融合策略。一种实用方式是预先对带图的文档做分块处理:例如,把图像转为说明文字(通过图像描述算法获得Caption),将其与周围文本合并成一个混合片段,再一并嵌入。这有点类似Contextual Retrieval的思路:为图像添加文字上下文,使其意义明确化后参与检索。此外,像LangChain等工具也支持在回答阶段结合多模态:检索阶段分别找出相关的文字段落和图片,然后把图片转换成文字说明,再交由LLM生成最终答案。但不管怎样,多模态RAG的检索与上下文理解仍处于早期探索阶段,需要针对不同模态设计专门的上下文保留方法。例如,有研究者尝试对视频做分段字幕嵌入,同时生成每段的情景说明,以帮助检索跨镜头的内容。可以预见,多模态文档为Late Chunking和Contextual Retrieval提出了新的要求:我们不仅要在同一模态内保留上下文,还要在不同模态之间建立上下文关联。这方面的挑战和解决方案,正在逐步涌现并完善中。
写在最后:
RAG系统要真正做到“触类旁通、融会贯通”,还需要继续在多轮对话和多模态检索方面攻坚。这意味着不仅要让模型记住文档本身的上下文,也要记住人与AI交互过程中的上下文,还要能理解不同形式信息之间的关联。或许不久的将来,我们会看到扩充版的Late Chunking可以处理多模态输入,或是新颖的Contextual Retrieval能即时为对话上下文创建动态索引。可以肯定的是,随着上下文获取手段的不断创新,RAG系统将变得愈发智能,真正做到在海量信息中“抽丝剥茧”,找到针尖上的真知,为用户提供既精准又丰富的答案。
53AI,企业落地大模型首选服务商
产品:场景落地咨询+大模型应用平台+行业解决方案
承诺:免费场景POC验证,效果验证后签署服务协议。零风险落地应用大模型,已交付160+中大型企业
2025-05-31
RAG(检索增强生成):提升大语言模型性能的终极指南
2025-05-31
DO-RAG:一种使用知识图谱增强检索辅助生成的领域特定问答框架 - 清华大学等
2025-05-30
2025年GitHub上十大RAG框架深度解析:从技术原理到实战应用
2025-05-30
90%企业不知道的RAG优化秘籍:Dify原生集成RAGflow (2)
2025-05-30
基于Gemini与Qdrant构建生产级RAG管道:设计指南与代码实践
2025-05-30
RAG和向量数据库之间有什么关系?
2025-05-30
RAG相关术语快速了解
2025-05-29
超越基础:Agentic Chunking 如何彻底改变 RAG?
2024-10-27
2024-09-04
2024-05-05
2024-07-18
2024-06-20
2024-06-13
2024-07-09
2024-07-09
2024-05-19
2024-07-07
2025-05-30
2025-05-29
2025-05-29
2025-05-23
2025-05-16
2025-05-15
2025-05-14
2025-05-14