检索增强生成(Retrieval-Augmented Generation, RAG)已成为大语言模型(LLM)应用落地最经典和有效的范式。然而,一个基础的RAG系统在面对真实世界的复杂问题时,效果往往不尽人意。许多人认为大模型的成本主要在训练阶段,但要构建一个高性能的RAG应用,在推理使用阶段的开销同样不容忽视。
本文将深入探讨一个核心优化思想:让大模型更深度地参与到RAG流程的每一个关键环节中 ,而不仅仅是作为最后一步的"总结工具人"。我们将分三个阶段------知识构建 、查询理解 和检索排序,详细拆解如何利用LLM自身的能力,显著提升R.A.G系统的准确性和相关性。
阶段一:知识构建 ------ 从"固定切分"到"语义切分"
RAG的第一步是构建知识库,核心任务是对原始文档进行切分(Chunking)。
传统切分的痛点
最简单的方法是基于规则的固定切分,例如:
-
按固定长度(如512个字符)切分。
-
按标点符号(如句号、换行符)切分。
-
按文档结构(如段落、章节)切分。
这种"一刀切"的方式虽然简单高效,但存在一个致命缺陷:破坏了知识的语义完整性。一个完整的知识点、一个复杂的逻辑推理链,很可能被硬生生地从中间切断,分散到两个或多个文本块(Chunks)中。当后续检索命中其中一个不完整的文本块时,模型无法获取完整的上下文,自然难以生成准确的答案。
用大模型进行语义切分
要解决这个问题,我们需要让一个能"理解"文档内容的角色来指导切分,而大模型本身就是最佳人选。因为LLM具备强大的自然语言理解(NLU)能力,可以识别出文档中独立的、完整的语义单元。
具体实现思路:
- 摘要即知识 (Summary as Context)
对于一篇长文档,可以先让LLM为其生成一个高度凝练的摘要。这个摘要本身就是一个包含了核心信息的、完整的"知识点",可以直接作为一个高质量的Chunk存入向量数据库。它适合用于回答关于文档主旨的宏观问题。
- 多知识点提炼 (Multi-Point Extraction)
可以设计一个Prompt,要求LLM通读全文或一个较长的段落,然后以Q&A对、要点列表或"实体-关系-实体"三元组的形式,提炼出其中包含的多个核心知识点。每一个提炼出的知识点都可以作为一个独立的Chunk。
- 分层切分与提炼 (Hierarchical Chunking)
这是一种兼顾效率与效果的实用方法。
-
第一步: 先使用宽松的规则(例如按段落或更大的固定长度)对文档进行初步的、粗粒度的切分,得到一些"大块"(Large Chunks)。
-
第二步: 遍历这些"大块",让LLM对每一个"大块"进行独立的知识点提取或总结。这样既保证了LLM处理的上下文不会过长(控制成本和处理时间),又利用了其理解能力在更小的范围内进行精细化的语义切分。
通过这种方式,我们得到的每个Chunk都是一个逻辑自洽、信息完整的知识单元,为后续的精准检索奠定了坚实的基础。
阶段二:查询理解 ------ 从"直接向量化"到"查询重构"
当用户提出问题时,传统的RAG流程是直接将用户输入(Query)转换为向量,然后进行相似度搜索。但用户的提问方式是多变的,这给检索带来了挑战。
用户问题的挑战
-
问题模糊宽泛:用户可能问一个非常笼统的问题,如"介绍一下这家公司"。如果直接用这个Query去检索,可能只会匹配到公司简介的片段。但用户内心可能还想了解公司的产品、发展历,程和创始人故事。
-
口语化与非正式表达:用户的提问往往是口语化的,比如"A产品咋样?"、"B方案咋办啊?"。而知识库中的文档通常是正式、书面的语言。这种语言风格上的不匹配(Mismatch)会导致向量空间上的距离变远,从而检索不到相关的正式文档。
大模型驱动的查询优化
我们可以利用LLM在用户查询进入检索系统前,对其进行一次"预处理"或"重构",以提升查询的质量和泛化能力。
具体实现思路:
- 查询扩展 (Query Expansion)
当探测到用户问题比较宽泛时,可以调用LLM,让它根据原始问题生成3-5个不同角度、更具体、更深入的子问题。
-
原始问题: "介绍一下周瑜老师。"
-
LLM扩展后的问题:
-
"周瑜老师的个人履历和专业背景是什么?"
-
"周瑜老师目前开设了哪些课程?课程特色是什么?"
-
"周瑜老师的创业经历是怎样的?"
然后,将原始问题和扩展后的多个问题一起或分别送入检索系统,召回更全面、更丰富的知识片段。
-
- 查询改写 (Query Rewriting/Transformation)
针对口语化或有歧义的表达,可以让LLM将其改写为更正式、更清晰、更适合在书面文档中检索的标准化查询。
-
原始问题: "你们那个AI大模型课咋报啊?"
-
LLM改写后的问题: "请问如何报名贵机构的AI大模型课程?报名流程和所需条件是什么?"
这一步相当于在用户和知识库之间增加了一个"智能翻译",弥合了口语与书面语之间的鸿沟,显著提升了检索的召回率。
阶段三:检索排序 ------ 从"单一相似度"到"智能重排"
通过向量相似度从海量Chunks中召回了K个候选文档(例如Top 20),就万事大吉了吗?并非如此。向量相似度高,并不完全等同于内容最相关。我们还需要最后一道精加工工序。
向量检索的局限
向量检索主要衡量的是"语义相似性",但有时用户的问题需要的是一个非常精确的答案,而不仅仅是语义上沾边的内容。此外,如果结合了传统的关键词搜索(如BM25)进行混合搜索(Hybrid Search),不同来源的结果如何融合排序也是一个难题。
引入重排与混合搜索
在将最终的上下文(Context)交给LLM进行答案生成之前,增加一个**重排序(Re-ranking)**步骤,可以让LLM亲自对召回的候选Chunks进行"质检",确保喂给它的都是"好料"。
具体实现思路:
- 混合搜索 (Hybrid Search)
首先,在召回阶段,不要只依赖向量搜索。结合传统的词法搜索(如BM25算法)和语义搜索(向量检索)。词法搜索能精准匹配关键词,而语义搜索能理解同义词和上下文。两者结合,可以取长补短,得到一个更鲁棒的初始候选集(例如,向量检索返回Top 10,BM25返回Top 10,合并去重)。
- 大模型重排序 (LLM as a Re-ranker)
这是提升最终答案质量最关键的一步。
-
第一步: 将混合搜索召回的候选Chunks(例如15个)和用户的原始问题打包。
-
第二步: 设计一个Prompt,要求LLM扮演一个"相关性评估专家"的角色。让它逐一评估每个Chunk与用户问题的相关性,并输出一个相关性分数(例如1-10分)。
-
第三步: 根据LLM返回的分数,对这15个Chunks进行重新排序。
-
第四步: 只选择重排后得分最高的Top N个Chunks(例如Top 3或Top 5),将它们拼接成最终的Context,再连同原始问题一起交给LLM进行最后的答案生成。
这一步虽然增加了额外的LLM调用成本和一定的延迟,但它能极大地过滤掉初始召回中的噪音,将最关键、最相关的信息喂给生成模型,从而在根本上提升了最终答案的准确性和忠实度。
结论:成本与效果的权衡
回到最初的观点:一个高性能的RAG系统,必然是一个在推理阶段"更费钱"的系统。
-
朴素RAG流程 :
Query -> Embedding -> Retrieve -> Generate
-
优化后RAG流程:
-
知识构建 :
Document -> LLM Chunking -> Embedding
-
查询与检索 :
Query -> LLM Rewriting/Expansion -> Hybrid Search -> LLM Re-ranking
-
生成 :
Top-K Chunks + Query -> LLM Generate
-
可以看到,LLM的调用从一次增加到了多次。每一次额外的调用,都是为了在RAG的数据流中注入更多的"智能",从而解决特定环节的痛点。这种"用魔法打败魔法"的思路,是当前提升RAG应用效果最直接、最有效的路径。
作为开发者,我们需要在成本、延迟和效果之间做出明智的权衡。对于追求极致用户体验和高准确率的场景,上述三阶段的深度优化策略,无疑是值得投入的。
期待大家关注我的【公众号:AI周瑜】,专注分享AI Agent应用、大模型底层等AI知识,一定能帮助你成为未来稀缺的AI人才。