什么是RAG?为什么数据加载是关键?
RAG(检索增强生成,Retrieval-Augmented Generation)是一种结合了信息检索与生成式AI的技术。其核心逻辑是:当模型需要回答问题时,先从外部知识库中检索与问题相关的信息,再基于这些信息生成准确、可靠的回答。这种方式解决了大语言模型(LLM)存在的"知识过时""幻觉生成""缺乏领域专业性"等问题,让生成结果更具针对性和可信度。
在RAG流程中,数据加载是构建知识库的第一步,也是后续所有环节的基础。原因在于:
- 现实世界中的知识通常存储在多样化的文件格式中(如PDF文档、Markdown笔记、CSV表格、HTML网页等),必须先将这些异构数据统一转换为模型可处理的格式;
- 加载过程的质量直接影响后续的"文档分割""嵌入向量生成""检索匹配"效果------如果数据加载不完整、格式混乱或关键信息丢失,整个RAG系统的准确性会大打折扣。
数据加载在RAG流程中的位置与后续工作
数据加载并非孤立步骤,而是RAG全流程的起点。完整的RAG流程可简化为:
数据加载 → 文档分割 → 嵌入向量生成 → 向量存储 → 检索 → 生成回答
数据加载后的核心工作:
-
文档分割(Chunking)
加载后的原始文档通常过长(如多页PDF、长文档),需要按语义或固定长度分割为更小的"chunk"。例如:
- 对于PDF,可能按"页+段落"分割;
- 对于Markdown,可按"标题+内容块"分割;
- 分割的目的是让后续检索更精准(小颗粒度内容更容易匹配问题)。
-
嵌入向量生成(Embedding)
将分割后的文本转换为数值向量(通过嵌入模型,如BERT、Sentence-BERT等)。向量的语义相似性对应文本内容的相关性,这是实现"相似检索"的核心。
-
向量存储(Vector Store)
将生成的向量存入专门的向量数据库(如Milvus、Pinecone、FAISS等),以便高效检索(通过向量相似度计算快速找到与问题相关的内容)。
-
检索与生成
当用户提问时,先将问题转换为向量,在向量库中检索最相关的文本片段,最后将这些片段作为"上下文"输入LLM,生成基于知识库的回答。
不同格式文件的处理方法
在RAG(检索增强生成)系统中,数据加载是基础且关键的步骤。不同格式的文件需要使用不同的加载器进行处理,本文将介绍如何加载Markdown、CSV、HTML、PDF和JSON五种常见格式的文件。
1. Markdown文件加载
Markdown是一种轻量级标记语言,常用于撰写文档。UnstructuredMarkdownLoader是处理Markdown文件的专用加载器,支持两种加载模式:整体加载和元素加载。
python
from langchain_community.document_loaders import UnstructuredMarkdownLoader
# 元素模式加载(按Markdown元素分割内容)
loader = UnstructuredMarkdownLoader(
file_path=r'F:\python测试\智谱-langchain\测试数据\test_translated.md',
mode='elements'
)
data = loader.load()
print('data:', data, '\n')
# 整体加载(整个文件作为一个文档)
# loader = UnstructuredMarkdownLoader(file_path='test_translated.md')
特点:
- 支持
mode='elements'参数,可按标题、段落等元素分割文档 - 不指定mode时,默认将整个文件内容作为一个文档对象
- 适合处理包含结构化内容的Markdown文档(如技术文档、笔记)
2. CSV文件加载
CSV(逗号分隔值)文件常用于存储表格数据,CSVLoader专门用于加载这种格式的文件。
python
from langchain_community.document_loaders import CSVLoader
loader = CSVLoader(
file_path=r'F:\python测试\智谱-langchain\weather_district_id.csv',
encoding='utf-8'
)
data = loader.load()
# 打印前两条记录
for record in data[:2]:
print(record)
特点:
- 自动将CSV中的每行数据转换为一个文档对象
- 支持指定文件编码(如utf-8)
- 适合处理结构化的表格数据(如产品信息、统计数据)
- 加载结果中每条记录包含CSV行的所有字段信息,便于后续按字段筛选
3. HTML文件加载
Web页面通常采用HTML格式,WebBaseLoader可以加载网页内容并提取指定部分。
python
import bs4
from langchain_community.document_loaders import WebBaseLoader
loader = WebBaseLoader(
web_paths=('https://fastapi.tiangolo.com/zh/features/',),
encoding='utf-8',
bs_kwargs=dict(parse_only=bs4.SoupStrainer(class_=('md-content',)))
)
docs = loader.load()
print(docs)
特点:
- 支持直接加载网络URL内容(无需手动下载网页)
- 通过
bs_kwargs参数可配合BeautifulSoup进行内容过滤(如提取特定class的正文,忽略广告、导航栏) - 适合从网页中提取结构化信息(如文档、新闻、教程)
4. PDF文件加载
PDF是常用的文档格式,PyPDFLoader可以加载PDF文件并支持图片提取。
python
from langchain_community.document_loaders import PyPDFLoader
# 启用图片提取功能
loader = PyPDFLoader(
file_path=r'F:\python测试\智谱-langchain\测试数据\test.pdf',
extract_images=True
)
# 每一页对应一个document
data = loader.load()
print('data:', data, '\n')
# 基础用法(不提取图片)
# loader = PyPDFLoader(file_path='test.pdf')
特点:
- 自动按页码分割文档,每页对应一个文档对象(符合PDF的天然分页结构)
- 支持
extract_images=True参数提取PDF中的图片(需配合OCR工具进一步处理图片内容) - 适合处理多页PDF文档(如报告、论文、合同)
5. JSON文件加载
JSON是一种轻量级数据交换格式,JSONLoader支持通过jq语法提取指定内容。
python
from langchain_community.document_loaders import JSONLoader
# 提取特定字段内容
loader = JSONLoader(
file_path=r'F:\python测试\智谱-langchain\测试数据\test.json',
jq_schema='.messages[].content',
text_content=False
)
docs = loader.load()
print('docs:', docs, '\n')
# 提取多个字段
loader = JSONLoader(
file_path=r'F:\python测试\智谱-langchain\测试数据\test.json',
jq_schema='.messages[] | {content, sender_name}',
text_content=False
)
docs1 = loader.load()
print('docs1:', docs1, '\n')
# 自定义元数据
def create_metadata(record: dict, metadata: dict) -> dict:
metadata['sender_name'] = record.get('sender_name')
metadata['timestamp_ms'] = record.get('timestamp_ms')
return metadata
loader = JSONLoader(
file_path=r'F:\python测试\智谱-langchain\测试数据\test.json',
jq_schema='.messages[]',
metadata_func=create_metadata,
text_content=False
)
docs2 = loader.load()
print('docs2:', docs2, '\n')
特点:
- 通过
jq_schema参数支持灵活的JSON内容提取(适合嵌套结构,如API返回数据、聊天记录) - 可通过
metadata_func自定义元数据提取逻辑(如保留时间戳、发送者等上下文信息) - 支持提取单个字段、多个字段或完整对象,适配多样化的JSON结构
总结
不同格式的文件需要选择对应的加载器,关键差异点:
| 文件格式 | 加载器 | 核心特点 | 后续处理适配 |
|---|---|---|---|
| Markdown | UnstructuredMarkdownLoader | 支持元素级分割 | 可按标题层级分割chunk |
| CSV | CSVLoader | 按行分割,处理表格数据 | 适合按行或按类别分组分割 |
| HTML | WebBaseLoader | 支持网络加载和内容过滤 | 需清洗HTML标签残留内容 |
| PyPDFLoader | 按页分割,支持图片提取 | 需处理跨页断句问题 | |
| JSON | JSONLoader | 支持jq语法和自定义元数据 | 可按JSON层级或对象分割 |
数据加载的目标是为后续步骤提供"干净、结构化、可分割"的原始素材。选择合适的加载器和参数,能最大限度保留原始信息的完整性和关联性,为RAG系统的最终效果打下坚实基础。