RAG(Retrieval-Augmented Generation)系统的质量,往往在上游数据加载阶段就已经决定了。本文系统梳理了从文本、JSON、网页到 PDF、表格、图片等全部数据源的加载方案,重点拆解 PDF 解析的五层递进策略,并附上 15 道高频面试 Q&A,帮你一次搞懂 RAG DataLoader。
一、为什么 DataLoader 是 RAG 的第一道坎
RAG 的完整管道可以概括为五个阶段:
DataLoading → Chunking → Embedding → Retrieval → Generation
DataLoader 处于管道最上游,负责一件事:把异构数据源统一为结构化的 Document 对象。这一步做得好不好,直接决定了下游分块、检索、生成的质量。
现实世界的数据源极其多样:TXT、JSON、Markdown、HTML、PDF、Word、PPT、CSV、SQL 数据库、图片......每种数据源都有不同的解析策略和工具链。选错 Loader,轻则丢失关键信息(比如表格变成乱码),重则整个 RAG 系统的检索准确率大幅下降。
面试官为什么爱问这一环? 因为 DataLoader 是 RAG 质量的上游决定因素。一个工程师如果能清楚地讲出「PDF 有哪几种解析方案,各适合什么场景」,说明他不只是调 API,而是真正理解了工程细节。
本文导读:
| 章节 | 内容 | 篇幅 |
|---|---|---|
| 核心概念 | Document 对象、元素类型、父子关系 | ★★ |
| 文本与结构化文档 | TextLoader、JSON、网页、Markdown | ★★ |
| PDF 五层方案 | PyPDF → PyMuPDF → OCR → Unstructured → LlamaParse | ★★★★★ |
| 表格与图片 | 四种表格方案 + 多模态读图 | ★★★ |
| 端到端实战 | 从 DataLoader 到 RAG 的完整链路 | ★★★ |
| 面试 Q&A | 15 道高频面试题,含回答模板 | ★★★★ |
二、核心概念 --- 一切皆为 Document
无论数据源是什么,最终都要转化为统一的 Document 对象,才能进入后续的分块和检索流程。这是整个 DataLoader 层的核心抽象。
Document 对象模型
LangChain 的 Document:
python
from langchain_core.documents import Document
doc = Document(
page_content="这是一段文本内容",
metadata={"source": "report.pdf", "page": 1}
)
LangChain 的设计非常简洁:page_content 存文本,metadata 存元数据字典。元数据可以携带来源、页码、章节等任意信息,在检索时可以用来过滤或加权。
LlamaIndex 的 Document:
python
from llama_index.core import Document
doc = Document(
text="这是一段文本内容",
metadata={"source": "report.pdf", "page": 1},
excluded_llm_metadata_keys=["source"], # 不送入 LLM 的元数据
metadata_template="{key}: {value}",
)
LlamaIndex 在 LangChain 的基础上增加了精细控制:excluded_llm_metadata_keys 可以指定哪些元数据不参与 LLM 提示词拼接,metadata_template 控制元数据的格式化方式。这在生产环境中非常实用------避免把不相关的元数据塞进上下文窗口。
选型建议: 快速原型用 LangChain,需要精细控制元数据流向时用 LlamaIndex。
元素类型体系
Unstructured 库在解析文档时,会将内容拆分为不同类型的元素(Element),这是比 Document 更细粒度的抽象:
| 元素类型 | 说明 | 典型场景 |
|---|---|---|
Title |
标题 | 章节标题、图表标题 |
NarrativeText |
叙述文本 | 正文段落 |
Table |
表格 | 数据表、对比表 |
Image |
图片 | 插图、图表截图 |
ListItem |
列表项 | 要点列表、步骤说明 |
这种分类的价值在于:检索时可以按类型过滤(比如只搜表格),分块时可以按类型采用不同策略(表格不适合按字数切分)。
父子元素关系(Parent-Child)
Unstructured 解析时会为每个元素分配一个唯一 ID,并通过 parent_id 建立层级关系:
[Title: 第一章 公司概况] ← parent
├── [NarrativeText: 本公司成立于...] ← child
├── [Table: 营收数据表] ← child
└── [NarrativeText: 如上表所示...] ← child(可引用父元素获取上下文)
这个机制在检索时非常有用: 当检索命中了一个子元素(比如表格),可以通过 parent_id 回溯到父元素(章节标题),获取完整的上下文信息。这就是 RAG 中常见的「Small Chunk 检索 + Big Chunk 送入 LLM」策略的基础。
三、文本与结构化文档加载
简单文本加载
最基本的场景:加载一个或一批文本文件。
单个文件:
python
from langchain_community.document_loaders import TextLoader
loader = TextLoader("notes.txt", encoding="utf-8")
docs = loader.load()
批量加载目录:
python
from langchain_community.document_loaders import DirectoryLoader
loader = DirectoryLoader(
"./docs",
glob="**/*.txt", # glob 模式过滤
show_progress=True,
silent_errors=True, # 跳过无法读取的文件
)
docs = loader.load()
LlamaIndex 的等价写法是 SimpleDirectoryReader,API 更简洁但定制性略低。
踩坑提示:
DirectoryLoader默认使用TextLoader,遇到非文本文件会报错。务必设置silent_errors=True或通过glob限定文件类型。
JSON 结构化提取
JSON 文件有两种加载思路:
python
# 思路一:当纯文本加载(丢失结构)
loader = TextLoader("data.json")
# 思路二:用 jq schema 提取特定字段(推荐)
from langchain_community.document_loaders import JSONLoader
loader = JSONLoader(
file_path="data.json",
jq_schema=".messages[].content", # 提取每条消息的内容
text_content=False,
)
jq_schema 是关键参数------它用 jq 语法从 JSON 中提取指定路径的数据。比如 .messages[].content 表示提取 messages 数组中每个元素的 content 字段,每个字段生成一个独立的 Document。
网页内容抓取
python
from langchain_community.document_loaders import WebBaseLoader
loader = WebBaseLoader(
web_paths=["https://example.com/article"],
bs_kwargs=dict(parse_only=bs4.SoupStrainer("article")), # 只提取 article 标签
)
docs = loader.load()
如果需要更精细的结构化解析(识别标题、段落、表格),可以用 Unstructured 的 UnstructuredLoader,它会自动识别元素类型并建立父子关系。
Markdown 加载
python
from langchain_community.document_loaders import UnstructuredMarkdownLoader
loader = UnstructuredMarkdownLoader("readme.md", mode="elements")
docs = loader.load() # 每个 Heading、Paragraph、Table 成为独立元素
mode="elements" 将 Markdown 按结构拆分为独立元素,比 "single" 模式(整个文档作为一个 Document)更适合 RAG 场景。
四、PDF 解析五层方案 --- 本文重点
PDF 是 RAG 数据加载中最复杂、也最常见的数据源。文字可选中型、扫描件、混合型各有不同解法,表格和多栏排版更是增加了难度。
以下方案按能力递进排列,从简单到专业:
第 1 层:PyPDF --- 基础逐页提取
python
from langchain_community.document_loaders import PyPDFLoader
loader = PyPDFLoader("report.pdf")
pages = loader.load() # 每页一个 Document
# metadata 包含: source, page(页码)
优点: 安装简单,无系统依赖,速度快。
缺点: 只能提取可选中文字;无法识别表格结构;多栏排版可能打乱阅读顺序。
适用场景: 简单的文字型 PDF,排版规整,无复杂表格和图片。
第 2 层:PyMuPDF --- 元数据/图片/链接/坐标
python
import fitz # PyMuPDF
doc = fitz.open("report.pdf")
for page in doc:
text = page.get_text()
images = page.get_images() # 提取图片
links = page.get_links() # 提取链接
blocks = page.get_text("dict") # 带坐标的文本块
优点: 信息提取全面(文字、图片、链接、坐标);速度依然很快;可定位元素在页面中的物理位置。
缺点: 同样无法识别表格结构;对扫描件无能为力。
适用场景: 需要精细控制的中等复杂度 PDF,比如提取特定区域的文本或下载嵌入图片。
踩坑提示: PyMuPDF 的包名是
pymupdf,但 import 时用fitz。安装时pip install pymupdf。
第 3 层:pytesseract + pdf2image --- 扫描件 OCR
python
from pdf2image import convert_from_path
import pytesseract
images = convert_from_path("scanned.pdf")
for img in images:
text = pytesseract.image_to_string(img, lang="chi_sim+eng")
优点: 可以处理扫描件和图片型 PDF;支持多语言 OCR。
缺点: 准确率依赖图片质量;无法保留文档结构(标题、表格全部变成平文本);处理速度较慢。
适用场景: 扫描件 PDF、图片型 PDF,对结构保留要求不高的场景。
踩坑提示: pytesseract 需要系统安装 Tesseract OCR 引擎。Mac 上用
brew install tesseract,还需额外安装中文语言包。
第 4 层:Unstructured partition_pdf --- 结构化解析
python
from unstructured.partition.pdf import partition_pdf
elements = partition_pdf(
"report.pdf",
strategy="hi_res", # fast / hi_res / ocr_only
infer_table_structure=True, # 推断表格结构
)
for el in elements:
print(f"{el.type}: {el.text[:50]}...") # Title, NarrativeText, Table...
三种策略对比:
| 策略 | 原理 | 速度 | 质量 | 适用场景 |
|---|---|---|---|---|
fast |
直接提取文本 | ★★★★★ | ★★ | 文字型 PDF 快速处理 |
hi_res |
版面分析模型 + OCR | ★★ | ★★★★★ | 复杂排版、含表格/多栏 |
ocr_only |
纯 OCR | ★★★ | ★★★ | 扫描件 PDF |
hi_res 模式是 Unstructured 的核心竞争力------它使用版面分析模型识别文档的物理布局(标题、段落、表格、图片),并保留坐标信息。配合 infer_table_structure=True,可以将表格转为 HTML 结构。
优点: 能识别文档结构和元素类型;保留坐标和父子关系;表格可转为结构化格式。
缺点: hi_res 模式需要下载模型,首次运行较慢;对 GPU 有一定需求。
适用场景: 需要保留文档结构的复杂 PDF,尤其是含表格、多栏排版的场景。
第 5 层:LlamaParse --- 云端高质量解析
python
from llama_parse import LlamaParse
parser = LlamaParse(
result_type="markdown", # markdown / text
language="zh",
)
documents = parser.load_data("complex_report.pdf")
优点: 解析质量最高,输出高质量的 Markdown 或 HTML;表格、公式、多栏都能准确处理。
缺点: 云端付费服务;数据需要上传(有隐私顾虑);网络延迟。
适用场景: 对解析质量要求极高的场景,比如法律文书、学术论文、财务报告。
五层方案选型对比
| 方案 | 速度 | 质量 | 成本 | 适用场景 |
|---|---|---|---|---|
| PyPDF | ★★★★★ | ★★ | 免费 | 简单文字型 PDF |
| PyMuPDF | ★★★★ | ★★★ | 免费 | 需要精细控制的中等 PDF |
| OCR (pytesseract) | ★★ | ★★★ | 免费 | 扫描件/图片型 PDF |
| Unstructured hi_res | ★★ | ★★★★ | 免费(需 GPU) | 含表格/多栏的复杂 PDF |
| LlamaParse | ★★★ | ★★★★★ | 付费 | 追求最高解析质量 |
选型一句话:简单场景用 PyPDF/PyMuPDF,复杂 PDF 用 Unstructured 或 MinerU,追求极致质量用 LlamaParse,扫描件用 OCR 或多模态大模型。
补充方案:MinerU --- 开源高质量解析
除了上述五层方案外,MinerU 是近年崛起的开源文档解析工具,由 OpenDataLab 团队开发,在学术论文和技术文档场景表现尤为突出。
python
# MinerU 命令行使用
pip install mineru
magic-pdf -p input.pdf -o output_dir
# 也支持 API 调用(需申请 key)
核心能力:
- 支持 PDF、图片、DOCX、PPTX、XLSX 五种输入格式
- 输出 Markdown 和 JSON
- 自动去除页眉页脚脚注页码,保证语义连续性
- 学术公式识别是其强项
- MinerU 2.5/2.5-Pro 在 CVPR 2025 OmniDocBench 基准测试中,文本/公式/表格识别表现优异,超过通用 VLM(Gemini-2.5 Pro、Qwen2)
优点: 完全免费开源(Apache 2.0),可本地部署数据不出本机,学术文档解析质量极高。
缺点: CPU 模式每页约2分钟,必须配 GPU 才有实用速度;部署门槛较高,需自行搭建环境和配置 GPU;RAG 生态整合不如 LlamaParse 开箱即用。
适用场景: 学术论文、技术文档解析;有 GPU 资源、重视数据隐私的团队。
MinerU vs LlamaParse 对比
两者定位不同,直接对比如下:
| 维度 | MinerU | LlamaParse |
|---|---|---|
| 类型 | 开源免费(Apache 2.0) | 商业 SaaS(有免费额度) |
| 可自部署 | 完全本地运行 | 核心不可自部署(开源了精简版 LiteParse) |
| 输入格式 | PDF、图片、DOCX、PPTX、XLSX | PDF、PPT、其他文档 |
| 输出格式 | Markdown、JSON | Markdown、纯文本、JSON |
| 定价 | 免费 | 每周 7000 页免费,之后约 $0.003/页,复杂模式更贵 |
| 速度 | 依赖 GPU(CPU 约 2min/页) | 云端 API 调用,较快 |
| 部署门槛 | 高(需 GPU + 环境配置) | 低(几行代码接入) |
| RAG 生态 | 需自行对接 | 与 LlamaIndex 深度集成 |
| 学术/公式 | 极强 | 强 |
| 表格准确率 | 简单表格优秀,复杂表格偶有瑕疵 | 简单表格接近 100%,复杂表格可能错位 |
| 数据隐私 | 数据不出本地 | 文档需上传到云端 |
| 布局保真 | 优秀 | 优秀 |
选型建议:
- 学术论文/技术文档、有 GPU、重视隐私 → MinerU
- 快速构建 RAG 应用、不想折腾部署、文档量不大 → LlamaParse
- 两者可以组合:敏感文档用 MinerU 本地解析,一般文档用 LlamaParse 云端处理
PDF 布局分析与可视化
Unstructured 的 hi_res 模式会返回每个元素的坐标信息(metadata.coordinates),可以精确定位元素在页面中的位置。配合 PyMuPDF + matplotlib,可以可视化渲染 PDF 页面,直观验证解析质量:
python
import fitz
import matplotlib.pyplot as plt
doc = fitz.open("report.pdf")
page = doc[0]
pix = page.get_pixmap()
plt.imshow(pix.samples_numpy.reshape(pix.h, pix.w, pix.n))
这个步骤在生产环境中很重要------自动化解析后抽样可视化检查,确保表格没有被拆乱、多栏没有被交叉读取。
五、表格数据与图片处理
表格数据加载
CSV 文件:
python
from langchain_community.document_loaders import CSVLoader
loader = CSVLoader("sales.csv", csv_args={"delimiter": ","})
docs = loader.load() # 每行一个 Document
SQL 数据库:
python
from llama_index.core import VectorStoreIndex
from llama_index.readers.database import DatabaseReader
reader = DatabaseReader(uri="mysql+pymysql://user:pass@host/db")
docs = reader.load_data(query="SELECT title, content FROM articles")
PDF 表格提取四方案对比
| 方案 | 原理 | 优势 | 局限 |
|---|---|---|---|
| camelot | 基于线条检测 | 提取精度高 | 仅适合有明确边框线的表格 |
| pdfplumber | 基于文本坐标聚合 | 轻量,API 友好 | 对无框线表格效果一般 |
| Unstructured | 版面分析模型 | 自动识别表格位置 | 速度较慢 |
| LlamaParse | 云端 AI 解析 | 质量最高 | 付费,有延迟 |
python
# pdfplumber 示例
import pdfplumber
with pdfplumber.open("report.pdf") as pdf:
for page in pdf.pages:
tables = page.extract_tables()
for table in tables:
for row in table:
print(row)
选型建议: 免费方案首选 pdfplumber(简单快速);有框线表格用 camelot(精度最高);复杂场景用 Unstructured 或 LlamaParse。
表格 + 上下文关联 是一个容易被忽略但很重要的点。Unstructured 在提取表格时可以保留周围的文本(比如表格上方的说明文字),这些上下文信息对 RAG 检索至关重要------用户可能问「第三章的营收数据是多少」,如果没有上下文关联,检索时可能找不到对应的表格。
图片与 OCR
python
# Unstructured 图片 OCR
from unstructured.partition.image import partition_image
elements = partition_image("chart.png", strategy="hi_res")
# 多模态大模型读图(GPT-4o)
from pdf2image import convert_from_path
import base64, openai
images = convert_from_path("diagram.pdf")
# 将图片编码后送给 GPT-4o 分析
多模态大模型(如 GPT-4o)带来了一个范式变化:不再需要传统的 OCR 管道,直接让 VLM(Vision Language Model)理解图片内容。对于图表、流程图等非文字图片,VLM 的效果远超 OCR。
工具选型速查表
| 需求 | 推荐方案 |
|---|---|
| 简单 txt/md 文件 | LangChain DirectoryLoader |
| JSON 结构化提取 | JSONLoader + jq |
| 网页抓取 | WebBaseLoader 或 Unstructured |
| 普通 PDF(文字可选中) | PyMuPDF |
| 复杂 PDF(含表格/多栏) | Unstructured hi_res 模式 或 MinerU |
| 扫描件 PDF | pytesseract OCR 或多模态大模型 |
| 高质量 PDF 解析 | LlamaParse(云端付费)或 MinerU(开源免费,需 GPU) |
| 学术论文/技术文档 | MinerU(公式识别强,可本地部署) |
| PDF 表格提取 | pdfplumber(免费)或 LlamaParse(高质量) |
| 数据库数据 | LlamaIndex SQLDatabase |
| 图片/OCR | UnstructuredImageLoader 或多模态 VLM |
六、端到端实战 --- 从 DataLoader 到 RAG
以一个典型的 PDF → RAG 流程为例,展示 DataLoader 在整个管道中的位置:
PDF 文件
↓
[DataLoader] Unstructured partition_pdf (hi_res)
↓
Document 对象(含元素类型、父子关系、坐标)
↓
[Chunking] Small2Big 句子窗口策略
↓
[Embedding] 文本向量化
↓
[VectorStore] 存入向量数据库
↓
[Retrieval] 相似度检索 + Rerank
↓
[Generation] LLM 生成回答
关键点:DataLoader 的输出质量决定了后续所有环节的效果上限。
Small2Big(句子窗口)策略与 DataLoader 的父子关系天然契合:检索时用小粒度的子元素(比如一个段落)匹配查询,送入 LLM 时用大粒度的父元素(整个章节)提供上下文。Rerank 则在检索结果送入 LLM 之前做二次排序,进一步提升相关性。
一个典型的端到端实现:
python
from unstructured.partition.pdf import partition_pdf
from langchain_core.documents import Document
# 1. DataLoader
elements = partition_pdf("report.pdf", strategy="hi_res", infer_table_structure=True)
docs = [Document(page_content=el.text, metadata={"type": el.type, "parent_id": el.metadata.parent_id}) for el in elements]
# 2. Chunking + Embedding + Retrieval + Rerank + Generation
# (后续环节使用 LangChain / LlamaIndex 的标准管道)
七、面试 Q&A 速查
以下整理了 15 道高频面试题,每题附有可直接参考的回答模板。
基础概念类
Q1: RAG 系统中 DataLoader 的作用是什么?
DataLoader 是 RAG 管道的第一环,负责将异构数据源(PDF、网页、数据库、图片等)统一转化为结构化的 Document 对象 。它的核心输出是
page_content(文本内容)+metadata(元数据)。DataLoader 的质量直接决定了下游分块、检索和生成的效果上限------如果这一步丢信息(比如表格解析乱码),后面的环节再怎么优化也无济于事。
Q2: LangChain 和 LlamaIndex 的 Document 对象有什么区别?
两者核心结构一致:文本 + 元数据字典。区别在于 LlamaIndex 提供了更精细的控制能力,比如
excluded_llm_metadata_keys可以指定哪些元数据不参与 LLM 提示词拼接,metadata_template控制元数据格式化方式。LangChain 更轻量、上手快,LlamaIndex 更适合需要精细管理元数据流向的生产场景。
Q3: 什么是父子元素关系(Parent-Child)?它在检索中有什么用?
Unstructured 解析文档时会为每个元素分配唯一 ID,通过
parent_id建立层级关系(比如标题 → 段落 → 表格)。检索时的用法是:用小粒度的子元素 匹配查询(检索精度高),命中后通过parent_id回溯到父元素获取完整上下文(送入 LLM 信息全)。这就是 RAG 中「Small Chunk 检索 + Big Chunk 生成」策略的实现基础。
Q4: Unstructured 的元素类型有哪些?分别代表什么?
五种核心类型:Title (标题)、NarrativeText (叙述文本/正文段落)、Table (表格)、Image (图片)、ListItem(列表项)。这种分类的价值在于:检索时可以按类型过滤(比如只搜表格),分块时可以按类型采用不同策略(表格不适合按字数切分)。面试时至少说出 3 种以上即可。
Q5: RAG 数据加载阶段如何保证数据质量?
三个层面:格式层面 ------选择合适的 Loader,比如复杂 PDF 用 Unstructured hi_res 而不是 PyPDF;结构层面 ------保留元素类型和父子关系,不要把所有内容压成纯文本;验证层面------抽样可视化检查(PyMuPDF + matplotlib 渲染 PDF),对比原文确认表格、多栏内容是否被正确提取。生产环境中建议建立解析质量监控指标。
PDF 解析类
Q6: PDF 解析有哪几种主要方案?各自的优缺点?
五种主流方案:PyPDF (简单快速,但只能提取纯文本)、PyMuPDF (可提取图片/链接/坐标,但无法识别表格结构)、OCR (处理扫描件,但丢失结构信息)、Unstructured hi_res (版面分析模型识别结构,质量高但速度慢)、LlamaParse(云端 AI 解析质量最高,但需付费且有数据隐私问题)。选型原则:简单 PDF 用 PyMuPDF,复杂 PDF 用 Unstructured,扫描件用 OCR,追求极致质量用 LlamaParse。
Q7: 扫描件 PDF 怎么处理?
两种方案:传统 OCR 方案 ------用 pdf2image 将 PDF 转为图片,再用 pytesseract 做 OCR 提取文字,优点是免费可本地运行,缺点是无法保留文档结构;多模态大模型方案------用 GPT-4o 等视觉语言模型直接理解图片内容,对图表、流程图等非文字内容的理解能力远超 OCR。实际项目中两者可以结合使用:OCR 提取文字,VLM 处理图表。
Q8: Unstructured 的三种 PDF 解析策略有什么区别?
三种策略各有侧重:fast 直接提取可选中文字,速度最快但无法识别结构;hi_res 使用版面分析模型,能识别标题/段落/表格等元素并保留坐标,质量最高但需要 GPU 支持;ocr_only 纯 OCR 模式,适合扫描件。选择建议:文字型 PDF 用 fast 快速处理,需要结构信息时用 hi_res,扫描件用 ocr_only。
Q9: 如何处理 PDF 中的复杂表格?
四种方案按需选:pdfplumber (免费轻量,基于文本坐标聚合提取表格,适合大多数场景)、camelot (基于线条检测,对有明确边框的表格精度最高)、Unstructured (AI 模型自动识别表格位置并推断结构,适合表格位置不固定的情况)、LlamaParse (云端解析质量最高)。另外要注意表格上下文关联------提取表格时要保留上方的说明文字,否则检索时用户可能无法通过语义找到对应的表格。
工具选型类
Q10: 不同数据源应该怎么选 Loader?
一句话总结:简单场景用 LangChain 内置 Loader,复杂 PDF 用 Unstructured,追求最高质量用 LlamaParse,扫描件/图片用 OCR 或多模态大模型。 具体来说:txt/md 用 DirectoryLoader,JSON 用 JSONLoader + jq 提取特定字段,网页用 WebBaseLoader,普通 PDF 用 PyMuPDF,数据库用 LlamaIndex SQLDatabase。关键是根据数据源的复杂度和对质量的要求做取舍,没有万能方案。
Q11: LlamaParse 和 MinerU 分别适合什么场景?
两者定位不同。LlamaParse 是云端 SaaS,开箱即用,与 LlamaIndex 深度集成,构建 RAG 管线非常顺畅,适合快速构建应用且文档不敏感的场景。每周 7000 页免费,之后按页计费。MinerU 是开源免费的本地工具,可自部署数据不出本机,在学术论文和技术文档的公式/表格识别上表现优异(CVPR 2025 基准),但需要 GPU 才有实用速度,部署门槛较高。选型原则:有 GPU 且重视隐私选 MinerU,快速上手且数据不敏感选 LlamaParse,也可以组合使用------敏感文档本地 MinerU 解析,一般文档云端 LlamaParse 处理。
Q12: 如何从数据库中加载数据用于 RAG?
用 LlamaIndex 的 DatabaseReader + SQLAlchemy 连接数据库,执行 SQL 查询后将结果转为 Document 对象。核心代码就两行:创建 reader 时传入数据库连接字符串(
uri),调用load_data(query)时传入 SQL 查询语句。每行查询结果会成为一个独立的 Document,列名会作为元数据。注意事项:查询结果要控制数量(避免一次加载太多数据),只查需要的字段(减少噪声),考虑增量加载策略。
进阶思考类
Q13: 如果文档量很大(百万级),DataLoader 阶段怎么优化?
三个方向:并行化 ------利用多进程/多线程并行加载文档,LangChain 的 DirectoryLoader 支持
max_concurrency参数;流式处理 ------使用 lazy load 模式(loader.lazy_load()),避免一次性将所有 Document 加载到内存;增量加载------记录已处理的文档(通过文件哈希或修改时间),只加载新增和变更的文档。对于 PDF 解析这种计算密集型任务,可以考虑将解析任务分布式部署。
Q14: 多模态大模型对 RAG 数据加载带来了什么变化?
带来了范式的转变:传统管道是「检测元素类型 → 分别处理(OCR 提文字、规则提取表格)→ 拼接」,多模态大模型可以直接理解图片内容,一步到位。具体变化:扫描件不再需要 OCR 管道,直接用 VLM 理解;图表、流程图等非文字内容可以被准确描述;甚至可以直接对 PDF 页面截图后送给 VLM,跳过传统的文本提取步骤。挑战是成本和延迟,目前适合对质量要求高的场景。
Q15: 如何评估 DataLoader 阶段的解析质量?
三个维度:完整性 ------对比原文,检查是否有内容丢失(比如某些页面或表格没有被提取到);准确性 ------抽样检查提取的文本是否与原文一致,特别是表格数据是否正确;结构性------检查元素类型标注是否正确(标题是否被识别为标题),父子关系是否合理。具体方法:用 PyMuPDF + matplotlib 可视化渲染 PDF,与解析结果对比;对表格类内容,对比提取的表格与原文表格的行列数是否一致;建立自动化测试用例,对已知文档验证解析结果。
总结: RAG DataLoader 的核心思维不是「记住哪个 API 怎么调用」,而是「理解不同数据源的特点,选对工具,保留结构信息」。PDF 五层方案是面试高频考点,建议重点掌握每层方案的适用场景和局限性。面试时先给出整体框架(五层递进),再针对具体问题深入展开,效果最好。