RAG 数据准备

65 阅读2分钟

RAG 数据准备

文档加载器

各种格式的非结构化文档(如PDF、Word、Markdown、HTML等)转换为程序可以处理的结构化数据。数据加载的质量会直接影响后续的索引构建、检索效果和最终的生成质量。

from unstructured.partition.auto import partition
from unstructured.partition.pdf import partition_pdf
​
# PDF文件路径
pdf_path = "../../data/C2/pdf/rag.pdf"# 使用Unstructured加载并解析PDF文档
# elements = partition(
#     filename=pdf_path,
#     content_type="application/pdf"
# )
​
elements = partition_pdf(
    filename=pdf_path,
    # strategy="hi_res"
    strategy="ocr_only"
)
​
# 打印解析结果
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)

文本分块

上下文限制

确保文本能够被两个模型完整、有效处理。

  • 嵌入模型 (Embedding Model) : 负责将文本块转换为向量。这类模型有严格的输入长度上限。例如,许多常用的嵌入模型(如 bge-base-zh-v1.5)的上下文窗口为512个token。任何超出此限制的文本块在输入时都会被截断,导致信息丢失,生成的向量也无法完整代表原文的语义。因此,文本块的大小必须小于等于嵌入模型的上下文窗口。
  • 大语言模型 (LLM) : 负责根据检索到的上下文生成答案。LLM同样有上下文窗口限制(尽管通常比嵌入模型大得多,从几千到上百万token不等)。检索到的所有文本块,连同用户问题和提示词,都必须能被放入这个窗口中。如果单个块过大,可能会导致只能容纳少数几个相关的块,限制了LLM回答问题时可参考的信息广度。

基础分块策略

  • 固定大小分块
  • 递归字符分块
  • 语义分块
  • 基于文档结构的分块