核心要点

  • 能讲清三者在 RAG 链路中的分工:Loader 负责「读进来」、Splitter 负责「切成块」、Retriever 负责「查得准」,前两者建索引、后者做检索

  • DocumentLoader 按数据源选:PDF、Word、网页、Markdown、数据库、Notion 等各有专用 Loader,关键是把异构来源统一成带 metadata 的 Document

  • TextSplitter 按结构与长度选:RecursiveCharacterTextSplitter 是通用首选,按 token 计数用 TokenTextSplitter,重语义完整用 SemanticChunker,代码/Markdown 有专用切分器

  • Retriever 按召回需求选:VectorStore 是基线,召回不全用 MultiQuery,块太碎丢上下文用 ParentDocument,要按元数据过滤用 SelfQuery,要融合多路用 Ensemble,要省 token 用 ContextualCompression

标准回答

这三个组件是 LangChain RAG 流水线的前半段,串起来就是「加载 → 切分 → 嵌入入库 → 检索」。

DocumentLoader:按数据源选

职责是把各种来源的原始数据读成统一的 Document(page_content + metadata)。选型完全由数据源决定:PDF 用 PyPDF / Unstructured,网页用 WebBaseLoader,Markdown、CSV、数据库、Notion、S3 等都有对应 Loader。要点是保留好 metadata(来源、页码、标题),后续过滤和溯源都靠它。扫描件 PDF 还要叠加 OCR

TextSplitter:按结构与长度选

文档太长无法整篇塞进上下文,也不利于检索精度,所以要切块。选型看内容结构:

  • RecursiveCharacterTextSplitter:通用首选,按段落→句子→词逐级递归切,尽量不破坏语义边界。
  • TokenTextSplitter:按 token 而非字符计数,能精确控制每块不超模型限制。
  • SemanticChunker:用 Embedding 在语义转折处切分,块内主题更聚合,代价是更慢更贵。
  • 专用切分器:代码、Markdown、HTML 有结构感知的切分器,按函数/标题切。

核心参数是 chunk_size 和 chunk_overlap,重叠用来避免把一句话从中间切断丢失上下文。

Retriever:按召回需求选

Retriever 决定「给定 query 取回哪些块」,是影响 RAG 质量的关键:

  • VectorStore Retriever:纯向量相似度召回,最常用的基线。
  • MultiQueryRetriever:让 LLM 把原始 query 改写成多个变体分别检索再合并,缓解「问法和文档措辞不一致」导致的漏召回。
  • ParentDocumentRetriever:用小块做精准匹配、但返回其所属的大块(父文档),兼顾检索精度与上下文完整。
  • SelfQueryRetriever:让 LLM 从自然语言里抽出元数据过滤条件(如时间、作者),做「语义 + 结构化过滤」混合检索
  • EnsembleRetriever:融合多个 Retriever(如向量 + BM25 关键词),用 RRF 重排,兼顾语义与精确匹配。
  • ContextualCompressionRetriever:召回后再用 LLM 或重排模型压缩/过滤无关内容,减少喂给生成模型的噪声和 token。

选型逻辑:先用 VectorStore 跑基线,再针对具体短板叠加——召回不全加 MultiQuery 或 Ensemble,上下文破碎用 ParentDocument,需要元数据过滤用 SelfQuery,上下文太长太杂用 ContextualCompression。

常见误区

⚠️ 常见踩坑

把切分当成无所谓的小事,随手设个固定 chunk_size 一刀切——块太大检索不精准、块太小丢上下文,且不同文档结构需要不同切法;同样别迷信「换更强的 Embedding 就行」,当召回不全或答非所问时,问题往往出在切分策略和 Retriever 选型,而不是嵌入模型本身。

追问

追问 1chunk_size 和 chunk_overlap 该怎么定?

没有万能值,要按内容和模型实验。常见起点是 chunk_size 在 300~800 token、overlap 取 chunk_size 的 10%~20%。块越大上下文越完整但检索越不精准、噪声越多;块越小匹配越准但易丢上下文、块数和成本上升。重叠是为了避免把关键句从边界切断。实务做法是准备一组验证问答,扫不同参数看召回命中率和答案质量,再定下来;结构化强的文档优先按其自然结构(标题、段落、函数)切,而不是死磕字符数。

追问 2什么时候该用 ParentDocumentRetriever?

当你既想要小块带来的检索精度、又不想丢失大块的上下文时用它。它把文档切成小子块去做向量匹配(命中更准),但召回时返回子块所属的父块(更大、上下文更完整)喂给 LLM。典型场景:技术文档、合同、论文这类「一个细节句子需要结合整段才能理解」的内容。相比把 chunk 调大,它避免了大块在检索阶段稀释相关性的问题,是「检索用小、生成用大」的折中。

追问 3向量检索和关键词检索(BM25)为什么常要一起用?

两者优势互补。向量检索懂语义、能匹配同义改写,但对精确的专有名词、产品型号、代码标识符、缩写等容易召回不准。BM25 关键词检索对这类精确字面匹配很强,却不理解语义。把二者用 EnsembleRetriever 融合(各自召回后用 RRF 倒数排名融合重排),既能召回语义相关又能锁定关键词精确命中,这就是常说的 Hybrid Search,在专业领域和含大量术语的语料上通常明显优于单一向量检索。

🔗 相似问题

同一考点的不同问法,面试官可能换着问,一起刷更稳

没找到想看的面试题?把你想看的告诉我们 →

延伸学习

按主题分类的相关资源,便于系统复习