RAG 知识库调优:评估、切分、检索与重排

📅
2 分钟阅读
·

2022 年我整理过一篇 RAG:检索增强生成的收益与天花板,说明 RAG 解决的问题及其结构性限制。近年的工程实践增加了切分、检索和重排等环节的方法。本文讨论如何根据评估结果调整知识库配置,作为上一篇的补充。

知识库在 Agent 里的作用

在 Agent 场景中,知识库保存模型参数之外的信息,对应 RAG 原始论文中的非参数化记忆。RAG 的基本流程如下:

Query → Retriever → Top-K Documents → Context Augmentation → Generator → Response

知识库通常提供上传和召回两个接口。方案之间的差异主要在于召回的内容和排序方式。

是否使用知识库,取决于 LLM 的以下限制:

  • 训练结束后,模型参数中的知识不会随新内容更新。
  • 模型可能生成看似合理但实际错误的内容。
  • 企业内部文档和私有数据通常不在训练语料中。
  • 部分场景要求答案附带来源以便核对。

知识更新频繁、内容量较大或需要引用依据的场景可使用知识库。内容较少且基本不变时,引入知识库的维护成本可能超过收益。

Long Context 也会影响方案选择。不同模型的上下文窗口随版本和接口而变化。长上下文允许部分场景直接提供完整文档,但仍需评估输入长度、成本、延迟和模型处理长文本的实际效果。我的经验是:数据量较小、更新频率低且可接受一次性处理成本时,可直接使用 Long Context;数据量大、更新频繁或需要精确召回个别条目时,RAG 更适合;介于两者之间时,可先用 RAG 粗筛,再交给长上下文处理。50K tokens 只能作为某个项目的试验阈值,不能作为通用分界线。

评估体系

优化知识库前,需要定义衡量标准,否则无法判断改动的影响。

RAGAS(2023)是常见的 RAG 评估框架之一。它提供基于参考答案或 LLM 判断的指标。部分指标可在缺少人工标注时使用,但自动评分会受评估模型和数据集影响,不能替代人工标注与端到端测试。它将评估分为检索和生成两组指标。

检索侧:

  • Context Precision:相关文档是否排在不相关文档之前。同样召回 5 个 chunk,相关的 2 个位于第 1、2 位时,得分高于位于第 4、5 位的情况。
  • Context Recall:回答问题所需的信息被检索到的比例。做法是将参考答案拆成多个 claim,逐个判断是否可归因到检索上下文,再计算被支持的比例。该指标需要参考答案,不是完全的 reference-free。

生成侧:

  • Faithfulness:答案中的每个声明是否能从检索上下文中推断。用 LLM 从答案中抽取 claim,再逐条根据上下文验证。该指标用于检测幻觉。
  • Answer Relevance:答案是否直接回应问题。做法是从答案反向生成可能的提问,再计算其与原问题的相似度。答非所问时,反推问题与原问题的相似度较低。

传统 IR 指标(Precision、Recall、F1、NDCG)仍适用于检索评估。F1 是 Precision 和 Recall 的调和平均;两者差异较大时,结果偏向较小的一项。因此,较高的 F1 表示两个指标都处于相对较高的水平。

RAG 还需要评估检索内容对 LLM 生成的实际作用。文本与 query 语义相近,不代表模型可据此生成正确答案。ICLERB 提出端到端评估思路:将检索候选注入 LLM 生成答案,再用答案准确性评估检索器和重排器。仅依据 NDCG 选择检索组件,可能无法反映最终回答质量。

可将 RAG 幻觉分为三类:未召回相关内容;已召回但答案超出上下文支撑;上下文充足但答案与问题不相关。这些情况通常优先检查检索、忠实度和相关性;同一个 bad case 也可能同时涉及多个环节。不同场景对幻觉检测的要求不同;医疗和法律场景的要求更严格。这篇 2025 年的综述 汇总了相关检测方法。

构建流程

知识库构建包括离线索引和在线查询两个阶段:

离线:Load → Split → Embed → Store
在线:Query → Retrieve → Rerank → Generate

Load 从不同来源和格式中提取原始数据。Embed 使用 embedding 模型将文本块转换为稠密向量。Store 将向量和元数据写入向量库并建立索引。切分、查询、检索和重排会直接影响检索与回答结果。

切分的粒度与上下文

chunk 过小会导致语义不完整,检索结果缺少上下文;chunk 过大则会增加噪声,稀释 embedding 表示,并占用更多上下文窗口。切分参数需要同时满足粒度和语义完整性的要求。

常见策略可按切分边界和上下文保留方式区分:

  1. 固定长度切分

    • 说明:按固定的 token 或字符长度切块,可配置固定的 overlap。
    • 优点:实现和吞吐量稳定,chunk 大小可控,便于建立基线和估算索引成本。
    • 缺点:可能在句子、表格或语义单元中间截断;固定 overlap 无法只在需要的边界保留上下文。
    • 适用场景:文档结构较弱、来源格式杂乱,或需要先以较低成本建立原型的场景。chunk_size 和 overlap 应通过文档结构、模型窗口、召回效果和延迟验证。
  2. 递归切分

    • 说明:按分隔符优先级逐层尝试切分,例如先标题和段落,再句子,最后按字符或 token 截断。
    • 优点:在块大小受控时保留自然语言和 Markdown 的结构边界;不需要额外模型调用,通常可作为通用文档的默认选择。
    • 缺点:分隔符规则需要适配语料;超长段落、表格和代码块仍可能被拆散,也无法处理跨段依赖。
    • 适用场景:以说明文、Markdown、网页正文和普通 PDF 解析文本为主的知识库。
  3. 结构化切分(document-aware chunking)

    • 说明:利用标题层级、章节、列表、表格、代码块、页面或字段等文档结构确定边界,并将标题路径、页码等作为 chunk 元数据或正文前缀。
    • 优点:chunk 的业务语义更完整,来源定位更明确;章节标题会进入检索表示,可区分同名概念在不同模块中的含义。
    • 缺点:依赖可靠的文档解析;扫描件、格式混乱的 Office 文档和网页会降低结构提取质量,解析规则也需要维护。
    • 适用场景:产品文档、规范、手册、Markdown、带稳定标题层级的 Wiki,以及表格和代码块不能被任意拆开的语料。
  4. 段落窗口切分(windowed chunking,也可称滑动窗口或重叠切分)

    • 说明:先按自然段确定主内容,再为每个 chunk 拼入前一段的结尾和后一段的开头,或带上相邻的一到两个完整段落。
    • 优点:保留段落边界两侧的上下文,可减少定义、前提和结论跨段展开时的信息缺失。
    • 缺点:相邻 chunk 的内容会重复,索引体积、embedding 成本和送入模型的 token 数都会增加;窗口过大也会引入无关文本。
    • 适用场景:段落短、论述连续且跨段问答较多的文档。重叠范围应根据段落长度和 bad case 调整。
  5. 语义切分

    • 说明:计算相邻句子或候选片段的 embedding 相似度,在语义变化较大的位置设置边界。
    • 优点:边界可随内容主题变化,不完全受字符数或排版限制。
    • 缺点:需要额外的 embedding 计算和阈值选择。Is Semantic Chunking Worth the Computational Cost? 的实验显示,在文档检索、证据检索、答案生成三个任务上,它相对固定长度切分的提升有限,计算成本增加。
    • 适用场景:章节结构弱但主题转换明确的长文本;应先与固定长度或递归切分在自己的评估集上比较,不能假定收益覆盖成本。

还可考虑以下方法:

  • Late Chunking(Jina AI,2024)。传统流程先按边界将文档切成 chunk,再分别调用 embedding 模型。例如,产品文档将“权限配置”的前提写在第一段、具体操作写在第二段。第二段单独编码时,模型只能根据该段文字生成向量;即使检索命中操作步骤,也可能缺少其依赖的角色、版本或限制条件。

    Late Chunking 先将整篇文档作为序列输入长上下文 embedding 模型,获取模型为每个 token 输出的最后一层表示;随后按预先确定的字符或 token 边界,对同一 chunk 的 token 表示进行 mean pooling,得到该 chunk 的检索向量。Transformer 的自注意力使 token 在编码阶段可关注文档中的其他 token,因此第二段中每个 token 的表示可包含前文的相关信息。最终索引仍为 chunk 级向量,向量库和在线检索流程无需改为整篇文档检索。

    Late Chunking 用于处理局部块较短、理解依赖跨段上下文的表示问题。限制:它不会补充文档中没有的事实,也不保证每个查询都优于普通切分。工程实现还需满足三个约束:文档必须位于模型的有效上下文窗口内,超长文档仍需先分为较大的窗口;切分边界必须映射回 token 位置,避免在 token 中间截断;整篇文档一次编码的显存、延迟和批处理方式不同于逐 chunk 编码。采用前应在跨段问答样本上比较 Context Recall、端到端答案质量和索引成本。

  • Small-to-Big。检索使用小粒度 chunk 保证匹配精度;命中后提取其父段落或前后窗口并输入 LLM,以补充匹配 chunk 缺少的上下文。

  • 意图驱动切分。该方法根据“用户可能问什么问题”预测信息需求,再组织 chunk,而非仅依据文档结构确定边界。它可用于长文档和异构文档;工程成本仍需评估。

可先用递归切分建立 baseline,并将重叠比例作为待验证参数。结合 RAGAS 的 Context Precision、Context Recall 和人工抽样评估切分效果,重点检查答案和实体是否被切断。切分时保留来源、章节、页码等元数据,再按 bad case 迭代。

召回:稀疏、稠密与混合

召回阶段未返回的文档,后续 Rerank 和生成无法直接利用。

稀疏检索的代表是 BM25,基于词频统计打分:词在文档中出现越多、在全局语料中越稀有,得分越高,并使用文档长度归一化。它适用于精确匹配,专有名词、错误码、型号等查询通常适配较好;但无法识别语义等价关系,例如查询“怎么重置密码”可能匹配不到“找回账户口令”。

稠密检索使用 embedding 模型将文本映射到向量空间,按余弦或内积寻找近邻,可处理语义匹配;但对未见专有名词和长尾词的结果可能不如 BM25 稳定。

工程实现通常采用混合检索:分别从两路召回候选后再融合。常见融合方法包括:

  • Reciprocal Rank Fusion(RRF):score = Σ 1 / (k + rank_i),rank_i 是文档在第 i 路召回中的排名,k 通常取 60。不需要调权重,适用于排名融合。
  • 加权线性组合:对两路分数归一化后加权求和。权重需通过验证集或离线评估调节,不能预设跨数据集通用的范围。该方法提供更多参数空间,但依赖评估数据。

查询侧也可调整,因为用户的原始提问可能不适合直接检索:

  1. 查询改写。使用 LLM 将口语化提问改写为规范的检索语句;多轮对话还需要补全指代。
  2. HyDE(Precise Zero-Shot Dense Retrieval without Relevance Labels)。先使用 LLM 生成假设性答案,再用该文本的 embedding 检索。其前提是生成文本可能比原始问题更接近相关文档;生成内容也可能引入错误,需要用数据验证。
  3. Multi-Query。生成多个查询变体,分别检索后合并去重,以覆盖单一问法未覆盖的表述。
  4. EAR(Expand, Rerank, and Retrieve)。该方法先生成多个查询扩展,再对扩展排序并检索,以处理单个扩展质量不稳定的情况。论文中的提升来自特定数据集、任务和指标,不能直接外推到所有知识库。采用前应在自己的数据上复现或评估。

语料规模较大时可使用层次化检索(Dense Hierarchical Retrieval):先在文档或章节级别粗筛,再在命中范围内进行段落级精排。该方法可保留短段落的全局上下文,并利用标题和章节结构。

HNSW 是常用的近似最近邻索引。选择时需要结合数据规模、更新方式、召回率目标和资源约束,不能将其作为所有场景的默认方案。

重排中的 query-document 交互

双编码器在离线阶段将库中的每个 document 单独编码为固定长度向量并写入向量库。用户提问时,query 也单独编码为向量,再通过向量距离从大量 document 中寻找候选。document 向量可预先计算并建立索引,因此一次查询只需编码 query 并搜索向量库,适用于大规模语料。

限制:document 编码时不知道未来的 query,query 编码时也看不到具体候选文档。模型只能通过两个独立向量的距离表示整体相似度。例如,query 是“管理员如何重置密码”,候选可能分别说明“管理员重置密码的操作步骤”和“普通用户如何找回密码”。两者都可能接近 query,但独立向量的比较难以准确区分“管理员”和“普通用户”这一限定条件。

Reranker 通常采用交叉编码器。它为每个候选输入 [query, document] 文本对,直接输出相关性分数。编码阶段的自注意力可将 query 中的“管理员”与 document 中的角色描述关联,也可在当前上下文中判断“重置”和“找回”是否等价,因此可提供更细的排序。代价是每个 query-document 对都需要重新执行模型;document 不能预先计算可复用向量,也不能直接在向量库中完成搜索。

通常由双编码器从大量文档中召回候选,再由交叉编码器逐个打分并重排。

一种常见的起始配置是:向量检索召回 Top-100,经 Reranker 精排后取 Top-5 输入 LLM。

实践要点:

  • 召回数 K 和精排数 N 需根据语料规模、召回率、延迟预算和端到端效果调节。K 过小会遗漏相关文档;K 过大会增加延迟,因为交叉编码器需要处理更多候选。50 到 100 与 3 到 10 只能作为部分项目的起点。
  • Reranker 输出分数通常仅在同一模型、同一批候选和相近任务设置下可比较。是否按阈值截断需要用验证集校准,不能将固定分数作为通用标准。
  • 混合检索可先用 RRF 融合多路排名,再送入 Reranker;这一顺序应结合端到端结果验证。

开源的 bge-reranker 系列和 Qwen3-Reranker 可自部署,Cohere Rerank 和 Jina Reranker 通过 API 使用。中文语料为主时,可优先评估前两者。选型不能仅依据公开榜单,应使用自己的 query 和语料进行 ICLERB 式端到端评估。

配置搜索与检索方法

以下项目分别处理配置搜索和 query 与文档的匹配问题。

AutoRAGGitHub)处理 RAG 配置组合较多的问题。分块策略、embedding 模型、检索方式和 Reranker 都有多个选项,不同组合在不同数据集上的结果可能不同。AutoRAG 将 pipeline 的模块参数化,在指定数据集上自动执行评估并搜索配置组合。它适用于需要针对特定领域调整配置、但缺少调优经验的团队。

QuIM-RAG 将“query 对 document 的匹配”转换为“query 对 query 的匹配”:离线阶段为每个文档块预生成其可能回答的问题并建立倒排索引;在线阶段用用户问题匹配这些预生成问题,再取回对应文档。论文或项目报告中的部署案例和指标结果应在其数据集、配置和基线条件下理解。即使某个案例在 BERT-Score 和 RAGAS 指标上优于传统 RAG,也不能推断其他语料具有相同结果。该方法用于处理 query 与文档直接匹配时语义不准、信息被稀释的问题。

配置与知识治理限制

RAG 配置应由评估结果驱动。每次调整切分、检索或重排参数后,都应在同一评估集上比较结果,确认影响来自哪个环节。

递归切分、混合检索和轻量 Reranker 可作为初始配置,但是否满足需求仍需通过评估确认。bad case 可用于定位问题:需要区分相关内容未召回、答案超出上下文,或答案与问题不相关的情况;对应的修正方式不同。单个环节的 NDCG 无法代表最终答案质量,语义相似度也不能代表检索内容可支持 LLM 生成正确答案。

大多数 RAG 索引将文档视为静态快照,但企业知识会更新、失效或相互矛盾。索引需要保留生效时间、版本、来源和更新时间;查询时还应按问题的时间范围过滤或排序,避免将已失效规则与当前规则同时交给模型。

仅依赖 chunk 元数据,较难检查文档、实体、章节、版本和引用之间的关系。知识图谱可将节点和边展示出来,用于发现孤立文档、重复知识、冲突版本和错误关联。它可作为知识治理与检索调试界面;是否参与在线检索仍需通过端到端评估验证。

OpenViking(字节跳动火山引擎)使用文件系统范式管理上下文。它处理的问题与上一篇结尾的结构问题相关:记忆、资源和技能分散存储,扁平存储缺少全局视角,隐式检索链路难以调试,记忆仅作为记录存在。它将上下文组织为具有目录层级的虚拟文件系统,将检索实现为路径导航与语义匹配,并允许 Agent 在任务过程中整理和更新记忆。该方案可用于长时间运行的 Agent,以及对检索可解释性要求较高的场景。

具体配置取决于数据特点、业务场景和资源约束。文件系统范式、知识图谱和时序建模分别处理层级导航、实体关系和知识有效期。OpenViking 等文件系统范式尚未成为主流做法;时序建模和图谱进入实际检索链路的收益与成本仍需要通过端到端评估验证。


833 字 · 97 段落
ximing

Follow onGitHub

相关文章