GEOZ

本文系统讲解RAG优化技术,涵盖文档切分、向量检索、混合检索

2026/9/10
本文系统讲解RAG优化技术,涵盖文档切分、向量检索、混合检索

AIAI Summary (BLUF)

本文系统讲解RAG优化技术,涵盖文档切分、向量检索、混合检索、重排序及GraphRAG等进阶方案,并对比了常见向量数据库选型,适合技术开发者快速建立RAG优化知识框架。

核心洞察

这篇文章最有意思的点是,它把 RAG 从最原始的向量检索一路讲到了 GraphRAG,覆盖很全。不过我得泼点冷水:大部分项目能把文档切分和重排序做扎实,效果就够好了。知识图谱那套听着厉害,建图和维护成本都摆在那儿,先确认自己真有跨文档多跳推理的需求再上。

RAG(检索增强生成)现在是 LLM 落地最主流的架构之一。思路不复杂:模型开口前,先从外部知识库检索相关内容,再基于检索结果作答。这套做法治了 LLM 的两个老毛病。一个是知识截止日期,训练结束后发生的事,模型一概不知。另一个是幻觉,没把握的时候它会一本正经地编。

核心结论

  1. 文档切分中,典型固定大小切分配置为块大小512 tokens、重叠50–100 tokens;而父子文档检索通过小片段高精度召回、命中后返回所属大块,可兼顾召回精度与上下文完整性。

  2. 混合检索将向量召回与BM25关键词召回结果合并,能弥补纯向量检索在专有名词、产品型号、代码变量名等精确匹配场景下的不足,是这类场景的主要兜底方案。

  3. 重排序引入Cross-Encoder模型,对向量检索粗排返回的Top-50候选逐对打分,最终只取Top-5作为LLM上下文,比单纯依赖向量相似度粗排更能筛除噪声。

  4. GraphRAG通过离线构建知识图谱(抽取三元组)、在线对实体关系路径与向量片段进行双路检索,可支持跨文档多跳推理问题,但建图与维护成本明显高于普通RAG,仅在确有此类需求时才值得采用。

  5. RAGAS框架用四个自动化指标评估RAG系统:Context Recall(召回率)、Context Precision(精确率)、Faithfulness(答案是否忠于检索依据)、Answer Relevance(是否正面回答问题),分别量化检索与生成两个维度的质量。

RAG 基础原理

一套完整的 RAG 系统由两条流水线组成。一条离线,一条在线。

离线的叫索引流水线,负责把原始文档切成小块,用 Embedding 模型转成向量,再写进向量数据库。整个过程一次性完成,文档不更新就不重跑。

在线的叫查询流水线,每次请求都会完整走一遍:用户提问,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,也就是近似最近邻算法。HNSW 和 IVF 是两个典型代表。HNSW 把向量组织成多层图,上层稀疏,负责快速定位,下层稠密,负责精确查找,用一点精度损失换几十倍的提速。IVF 的路子则是先聚类分桶,只在候选的几个桶里搜索,也能省下大量计算。

进阶架构:给 RAG 加三道工序

基础版 RAG 最大的毛病是检索质量不稳。经常出现的情况是:该召回的相关内容没找到,无关内容倒是一大堆,真正有用的上下文被淹在噪声里。进阶版 RAG 的思路是检索前、检索中、检索后各加一道工序:预检索优化、混合检索、后检索优化。

预检索:先把问题调明白

用户丢过来的原话不见得适合直接拿去检索。口语化的问题,先让 LLM 改写一遍,整理成更规范的检索词,这一步叫查询改写。

HyDE 是比改写更绕的一招。它先让 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 的做法是把知识图谱接进来,把实体和关系显式建模。整条链路分三步:

  1. 建图谱。离线阶段用 LLM 从文档里抽三元组:主体、关系、客体,写进 Neo4j 这类图数据库。比如「某某公司 - 创始人 - 某某人」。
  2. 双路检索。用户问题进来后,除了常规向量检索,还针对问题里的实体在图谱上做遍历,把多跳关系链整条拉出来。
  3. 融合生成。向量检索拿回的文档片段,跟图检索拿回的关系路径,一起拼进 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创办且市值超千亿的公司”这类复杂问题,但建图维护成本高。

晓婷深圳
本文由 晓婷 审核,最后更新于 2026年9月11日
联系编辑 →
← 返回文章列表
分享到:微博

版权与免责声明:本文仅用于信息分享与交流,不构成任何形式的法律、投资、医疗或其他专业建议,也不构成对任何结果的承诺或保证。

文中提及的商标、品牌、Logo、产品名称及相关图片/素材,其权利归各自合法权利人所有。本站内容可能基于公开资料整理,亦可能使用 AI 辅助生成或润色;我们尽力确保准确与合规,但不保证完整性、时效性与适用性,请读者自行甄别并以官方信息为准。

若本文内容或素材涉嫌侵权、隐私不当或存在错误,请相关权利人/当事人联系本站,我们将及时核实并采取删除、修正或下架等处理措施。也请勿在评论或联系信息中提交身份证号、手机号、住址等个人敏感信息。