本文系统讲解RAG优化技术,涵盖文档切分、向量检索、混合检索
AIAI Summary (BLUF)
本文系统讲解RAG优化技术,涵盖文档切分、向量检索、混合检索、重排序及GraphRAG等进阶方案,并对比了常见向量数据库选型,适合技术开发者快速建立RAG优化知识框架。
核心洞察
这篇文章最有意思的点是,它把 RAGRetrieval-Augmented Generation - an AI framework that combines information retrieval with language generation to produce more accurate and contextually relevant responses. 从最原始的向量检索一路讲到了 GraphRAGRAG方法的高级变体,引入图结构数据,将信息表示为实体和关系的互联网络,以提高检索的完整性和准确性。,覆盖很全。不过我得泼点冷水:大部分项目能把文档切分和重排序做扎实,效果就够好了。知识图谱那套听着厉害,建图和维护成本都摆在那儿,先确认自己真有跨文档多跳推理的需求再上。
RAG(检索增强生成)现在是 LLM 落地最主流的架构之一。思路不复杂:模型开口前,先从外部知识库检索相关内容,再基于检索结果作答。这套做法治了 LLM 的两个老毛病。一个是知识截止日期,训练结束后发生的事,模型一概不知。另一个是幻觉,没把握的时候它会一本正经地编。
核心结论
文档切分中,典型固定大小切分配置为块大小512 tokens、重叠50–100 tokens;而父子文档检索通过小片段高精度召回、命中后返回所属大块,可兼顾召回精度与上下文完整性。
混合检索将向量召回与BM25关键词召回结果合并,能弥补纯向量检索在专有名词、产品型号、代码变量名等精确匹配场景下的不足,是这类场景的主要兜底方案。
重排序引入Cross-Encoder将问题和文档同时输入模型计算相关性分数的架构,通常用于重排序阶段。模型,对向量检索粗排返回的Top-50候选逐对打分,最终只取Top-5作为LLM上下文,比单纯依赖向量相似度粗排更能筛除噪声。
GraphRAG通过离线构建知识图谱(抽取三元组)、在线对实体关系路径与向量片段进行双路检索,可支持跨文档多跳推理问题,但建图与维护成本明显高于普通RAG,仅在确有此类需求时才值得采用。
RAGAS框架用四个自动化指标评估RAG系统:Context Recall(召回率)、Context Precision(精确率)、Faithfulness(答案是否忠于检索依据)、Answer Relevance(是否正面回答问题),分别量化检索与生成两个维度的质量。
RAG 基础原理
一套完整的 RAG 系统由两条流水线组成。一条离线,一条在线。
离线的叫索引流水线,负责把原始文档切成小块,用 Embedding 模型转成向量,再写进向量数据库A database system designed to store and perform high-dimensional semantic similarity searches on vector embeddings of data.。整个过程一次性完成,文档不更新就不重跑。
在线的叫查询流水线,每次请求都会完整走一遍:用户提问,Embedding 把问题转成查询向量,向量数据库做相似度检索,找出最接近的 Top-K 文档块,最后把问题和文档块拼成 Prompt 丢给 LLM。模型看到的信息,就是检索回来的这些片段。
数据预处理与文档切分
先解决复杂文档解析
切分之前有个坎要过:PDF、Word、扫描件,各种格式都有。尤其是表格、图片、多栏排版这三样,普通文本提取工具一碰就乱,抽出来的文本顺序错位,语义跟着支离破碎。
行业里目前主流的解法是上文档解析引擎,LlamaParse、Unstructured 都是这类的。也有团队直接用多模态大模型把图文转成结构化 Markdown。解析这步做不好,后面切分再讲究也白费。
切分策略怎么选
切分粒度直接决定检索质量。块太大,噪声多,模型容易看花眼;块太小,上下文断了,语义不完整。
常用的切分策略有四类,各有各的适用场景:
| 切分策略 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 固定大小切分 | 通用文本 | 实现简单,速度快 | 可能把一个完整句子从中间切断 |
| 递归字符切分 | Markdown、代码这类结构化文本 | 优先按段落、句子等语义边界切 | 实现稍复杂,需要调分隔符列表 |
| 语义切分 | 长文档、书籍 | 用 Embedding 算相邻句子的相似度,自动找语义转折点切 | 计算成本高,预处理慢 |
| 父子文档检索 | 覆盖面要求高的场景 | 小片段负责高精度检索,命中后返回大块给 LLM,两头都顾上 | 数据库设计多一层,维护成本翻倍 |
表里的父子文档检索值得多说一句。它的路子是用小片段去做精确命中,一旦命中,就把小片段所属的那个大块整块拿出来给 LLM。召回精度保住了,上下文完整性也没丢。
实际工程里还有个惯用技巧,加重叠。相邻两个块故意共享一部分字符,防止关键内容正好卡在切分边界上。比较典型的配置是块大小 512 tokens,重叠 50 到 100 tokens。
实例:用 LangChain 做递归切分
讲这么多,不如来一段实际代码。下面用 LangChain 的 RecursiveCharacterTextSplitter 演示:
from langchain.text_splitter import RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(
chunk_size=512, # 每块最大 token 数
chunk_overlap=50, # 相邻块重叠的 token 数,防止信息在边界被切断
separators=["\n\n", "\n", "。", ".", " "] # 按优先级找段落和句子边界
)
chunks = splitter.split_text(document_text)
print(f"切分为 {len(chunks)} 个文档块")
separators 这个参数决定了它优先在哪里下刀。双换行符排在最前,切出来的块语义最完整;找不到段落边界,才依次试换行、句号这些。
向量检索
Embedding 模型怎么挑
向量检索的第一步,是把文本变成向量。这个活由 Embedding 模型承担,输出通常是几百到几千维的稠密浮点数组,常见的有 768 维、1536 维。语义越相近的文本,向量在空间里离得越近。相似度检索的数学基础就建立在这上面。
挑模型主要看语言覆盖和成本。OpenAI 的 text-embedding-3-small 是 1536 维,性价比高,大规模索引基本都拿它打底。text-embedding-3-large 是 3072 维,精度最高,费用也高。中文场景可以看看开源的 BAAI/bge-m3,1024 维,中英双语都支持得不错。本地轻量部署用 sentence-transformers/all-MiniLM-L6-v2 就行,384 维,速度快,体积小。
相似度计算与 ANN
向量存进库之后,怎么判断两个向量像不像?最常用的是余弦相似度,看两个向量夹角的余弦值,范围在 -1 到 1,越接近 1 越相关。点积和欧氏距离也会用,但语义检索里余弦相似度是默认选项。
库里向量数量一上去,暴力遍历就不现实了。百万级数据要在毫秒级返回结果,靠的是 ANN,也就是近似最近邻算法。HNSWHierarchical Navigable Small World - a graph-based algorithm for approximate nearest neighbor search that provides efficient similarity search in high-dimensional spaces. 和 IVF 是两个典型代表。HNSW 把向量组织成多层图,上层稀疏,负责快速定位,下层稠密,负责精确查找,用一点精度损失换几十倍的提速。IVF 的路子则是先聚类分桶,只在候选的几个桶里搜索,也能省下大量计算。
进阶架构:给 RAG 加三道工序
基础版 RAG 最大的毛病是检索质量不稳。经常出现的情况是:该召回的相关内容没找到,无关内容倒是一大堆,真正有用的上下文被淹在噪声里。进阶版 RAG 的思路是检索前、检索中、检索后各加一道工序:预检索优化、混合检索、后检索优化。
预检索:先把问题调明白
用户丢过来的原话不见得适合直接拿去检索。口语化的问题,先让 LLM 改写一遍,整理成更规范的检索词,这一步叫查询改写。
HyDEA technique that generates hypothetical answers to improve query matching in retrieval systems. 是比改写更绕的一招。它先让 LLM 不依赖检索结果,凭空写一个假设性答案。这个答案虽然是猜的,但通常会带出不少行业术语和背景词汇。把这段假设答案的向量拿去检索,反而更容易命中质量高的文档。
混合检索:向量和关键词一起上
向量检索能听懂语义,同义替换不影响召回。可它也有短板,遇到专有名词、产品型号、代码变量名这种需要精确匹配的查询,经常翻车。混合检索把向量召回和 BM25 关键词召回的结果按权重合并,两边互补。专有名词密集的场景,基本就靠它兜底。
重排序:给候选文档精筛一遍
向量库的粗排结果直接当最终上下文,还是不够。它快,但打分粗糙。重排序这一步会引入 Cross-Encoder 模型,把问题和候选文档拼成一对,一起送进模型做联合推理,输出一个更精准的相关性分。开源方案里 bge-reranker 用得比较多。因为计算量不小,重排序只负责精筛:粗排拿回一批候选,它再从中挑出 Top-5 交给 LLM。
流程看代码更直观:
from sentence_transformers import CrossEncoder
reranker = CrossEncoder("BAAI/bge-reranker-v2-m3")
# 1. 粗排:向量检索快速召回 Top-50
candidates = vector_store.similarity_search(query, k=50)
# 2. 精排:构造 [问题, 文档] 对,逐个打分
pairs = [[query, doc.page_content] for doc in candidates]
scores = reranker.predict(pairs)
# 3. 挑出得分最高的 Top-5,作为最终上下文
ranked_docs = sorted(zip(scores, candidates), reverse=True)
final_docs = [doc for _, doc in ranked_docs[:5]]
Self-RAG 与 CRAG:让模型自己把关
这两类方案属于带自我反思的 RAG。Self-RAG 让模型生成时多一道判断,自己掂量检索到的内容能不能支撑回答,掂量完再决定怎么答。
CRAG 的机制更明确。检索结果回来后,先让 LLM 当评委,给这轮检索质量打分。如果知识库里根本没有相关内容,或者相关文档质量太差,系统就自动改走 Web Search,调 Google API 之类的外部接口补充检索。模型回答的素材源头多了一道质检,幻觉能少很多。
GraphRAG:知识图谱加进来
传统 RAG 把知识库看成一块块互相独立的文本,文档之间的关联关系,检索时根本看不见。碰到需要跨文档、多跳推理的问题就抓瞎。举个例子:找出所有同时由现任 CEO 创办、市值超过千亿的公司。这个问题涉及多个实体和好几层关系,纯向量检索很难答。
GraphRAG 的做法是把知识图谱接进来,把实体和关系显式建模。整条链路分三步:
- 建图谱。离线阶段用 LLM 从文档里抽三元组:主体、关系、客体,写进 Neo4j 这类图数据库。比如「某某公司 - 创始人 - 某某人」。
- 双路检索。用户问题进来后,除了常规向量检索,还针对问题里的实体在图谱上做遍历,把多跳关系链整条拉出来。
- 融合生成。向量检索拿回的文档片段,跟图检索拿回的关系路径,一起拼进 Prompt。LLM 既能看到具体描述,也能理解实体之间的全局关系,处理前面那种多跳问题就从容多了。
技术与数据库选型
到选型环节,没有绝对最优,主要看数据规模和运维意愿。按场景分几档:
不想自己运维基础设施,直接买全托管云服务。Pinecone 和 Zilliz Cloud 是典型代表,开箱即用。配上 Cohere Rerank 和 GPT-4o,是目前能最快跑通商用的组合。
企业私有化部署,Qdrant 很值得看。它用 Rust 写的,内存控制好,性能高,生产环境里相当能打。
知识库里的专有名词特别多,优先看 Weaviate 或 Elasticsearch。这两家自带的 BM25 加向量混合检索非常成熟,正好补上纯向量检索在精确匹配上的短板。
数据量到了十亿、百亿级别,那就绕不开 Milvus。分布式架构就是为这种超大规模检索设计的。
本地开发、个人知识库这种轻量场景,Chroma 或者 FAISS 就够用了。不用单独部署服务,验证想法特别快。
效果怎么评估:RAGAS 框架
RAG 系统上线前,得有个客观的衡量标准。现在主流用的是 RAGAS 框架,从检索和生成两个维度做自动化量化测试。
检索这边有两个指标。
Context Recall 看召回率。标准答案里的信息,系统有多大比例能捞回来。捞不回来,生成模型再强也白搭。
Context Precision 看精确率。捞回来的文档里,有多少是真正相关的。噪声太多,照样会把最终答案带偏。
生成这边也有两个。
Faithfulness 管幻觉。模型生成的每个陈述,是不是都能在检索文档里找到依据。找不到依据的,基本都是模型在自说自话。
Answer Relevance 管相关性。回答有没有正面回应用户的问题。有些模型能写一大段漂亮话,细看却发现答非所问,这个指标就是专门抓这种情况的。
常见问题(FAQ)
RAG优化中文档切分策略怎么选?
常用策略有固定大小、递归字符、语义和父子文档检索。固定大小简单但可能切断语义;递归切分适合结构文本;语义切分适合长文档但成本高;父子检索兼顾精度与上下文。实际可加重叠防止边界切断。
RAG检索精度不够怎么优化?
可从预处理、检索和后处理优化。预处理做查询改写或HyDE;检索用混合检索,合并向量与BM25的结果;后处理用CrossEncoder重排序,比如bge-reranker,精筛出Top-5。
GraphRAG和传统RAG有什么区别?
传统RAG将文本独立分块检索,难处理跨文档多跳推理。GraphRAG引入知识图谱显式建模实体与关系,能回答如“同时由现任CEO创办且市值超千亿的公司”这类复杂问题,但建图维护成本高。
版权与免责声明:本文仅用于信息分享与交流,不构成任何形式的法律、投资、医疗或其他专业建议,也不构成对任何结果的承诺或保证。
文中提及的商标、品牌、Logo、产品名称及相关图片/素材,其权利归各自合法权利人所有。本站内容可能基于公开资料整理,亦可能使用 AI 辅助生成或润色;我们尽力确保准确与合规,但不保证完整性、时效性与适用性,请读者自行甄别并以官方信息为准。
若本文内容或素材涉嫌侵权、隐私不当或存在错误,请相关权利人/当事人联系本站,我们将及时核实并采取删除、修正或下架等处理措施。也请勿在评论或联系信息中提交身份证号、手机号、住址等个人敏感信息。



