总结
文末四张思维导图拆解分块全策略,小白也能秒懂!
一、数据加载
概念:在 RAG 系统中,数据加载是整个数据处理流水线的第一步,核心是将非结构化文档转换为程序可处理的结构化数据。
重要性:它是实现高质量检索与生成的前提,输入质量直接决定后续输出效果。
1.1 文档加载器
主要功能
- 解析 PDF、Word、Markdown 等不同格式的原始文档,提取纯文本内容
- 在解析过程中同步抽取文档来源、页码、作者等关键元数据
- 将文本和元数据整理成统一的数据结构,方便后续切分、向量化和入库
当前主流RAG文档加载器
1.2 使用 Unstructured 库
Unstructured文档处理库
- 支持 PDF、Word、Excel、HTML、Markdown 等多种文档格式
- 可以自动识别标题、段落、表格、列表等文档结构,同时保留相应的元数据信息
使用 Unstructured 库加载并解析一个PDF文件
from unstructured.partition.auto import partition
# PDF文件路径
pdf_path = "../../data/C2/pdf/rag.pdf"
# 使用Unstructured加载并解析PDF文档
elements = partition(
filename=pdf_path,
content_type="application/pdf"
)
# 打印解析结果
print(f"解析完成: {len(elements)} 个元素, {sum(len(str(e)) for e in elements)} 字符")
# 统计元素类型
from collections import Counter
types = Counter(e.category for e in elements)
print(f"元素类型: {dict(types)}")
# 显示所有元素
print("\n所有元素:")
for i, element in enumerate(elements, 1):
print(f"Element {i} ({element.category}):")
print(element)
print("=" * 60)
partition 函数参数解析
| 参数名 | 解释 |
|---|---|
| filename | 文档文件路径 |
| content_type | 可选参数,指定MIME类型(如"application/pdf"),可绕过自动文件类型检测 |
| url | 可选参数,远程文档 URL,支持直接处理网络文档 |
| include_page_breaks | 布尔值,是否在输出中包含页面分隔符 |
| strategy | 处理策略,可选 "auto"、"fast"、"hi_res" 等 |
| encoding | 文本编码格式,默认自动检测 |
使用不同处理策略进行解析:hi_res VS ocr_only
from unstructured.partition.pdf import partition_pdf
from collections import Counter
# PDF文件路径
pdf_path = "../../data/C2/pdf/rag.pdf"
def analyze_pdf_elements(elements, strategy_name):
"""分析并打印PDF解析元素的统计信息"""
# 基础统计
total_elements = len(elements)
total_chars = sum(len(str(e)) for e in elements)
print(f"\n===== {strategy_name} 解析结果 =====")
print(f"解析完成: {total_elements} 个元素, {total_chars} 字符")
# 元素类型统计
types = Counter(e.category for e in elements)
print(f"元素类型: {dict(types)}")
# 显示前3个元素示例(避免输出过长)
print("\n前3个元素示例:")
for i, element in enumerate(elements[:3], 1):
print(f"Element {i} ({element.category}):")
print(str(element)[:200] + "..." if len(str(element)) > 200 else str(element))
print("-" * 60)
# 1. 使用 hi_res 策略解析(适合原生PDF,有可复制文本)
print("开始使用 hi_res 策略解析 PDF...")
hi_res_elements = partition_pdf(
filename=pdf_path,
strategy="hi_res" # 高精度解析,优先提取原生文本
)
analyze_pdf_elements(hi_res_elements, "hi_res")
# 2. 使用 ocr_only 策略解析(适合扫描件PDF,无原生文本)
print("\n开始使用 ocr_only 策略解析 PDF...")
ocr_elements = partition_pdf(
filename=pdf_path,
strategy="ocr_only" # 纯OCR解析,将PDF转为图片后识别文本
)
analyze_pdf_elements(ocr_elements, "ocr_only")
# 3. 对比两种策略的核心差异
print("\n===== 两种策略对比 =====")
print(f"hi_res 元素数量: {len(hi_res_elements)}, ocr_only 元素数量: {len(ocr_elements)}")
print(f"hi_res 字符总数: {sum(len(str(e)) for e in hi_res_elements)}, ocr_only 字符总数: {sum(len(str(e)) for e in ocr_elements)}")
- partition_pdf 函数:Unstructured 专门用于 PDF 解析的函数,比通用的 partition 更灵活,支持指定解析策略。
- strategy 参数:
| 维度 | hi_res 策略 | ocr_only 策略 |
|---|---|---|
| 解析速度 | 快(直接提取文本) | 慢(先转图片再 OCR) |
| 元素类型 | 丰富(Title、ListItem、Text 等) | 单一(主要是 Text 类型) |
| 字符准确性 | 高(无识别错误) | 可能有识别错误(如错别字、乱码) |
| 适用场景 | 原生 PDF(可复制文本) | 扫描件 / 图片 PDF(不可复制文本) |
二、文本分块
将加载后的长篇文档,切分成更小、更易于处理的单元。
2.1 作用
满足模型上下文限制
- 嵌入模型 (Embedding Model):负责将文本块转换为向量。这类模型有严格的输入长度上限。任何超出此限制的文本块在输入时都会被截断,导致信息丢失
- 大语言模型 (LLM):负责根据检索到的上下文生成答案。LLM同样有上下文窗口限制。如果单个块过大,可能会导致只能容纳少数几个相关的块,限制了LLM回答问题时可参考的信息广度。
“块”不是越大越好
2.2 常见分块策略
固定大小分块
递归字符分块
语义分块
基于文档结构的分块
学习资料参考:开源组织Datawhale all-in-rag项目