什么是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文件的专用加载器,支持两种加载模式:整体加载和元素加载。
fromlangchain_community.document_loadersimportUnstructuredMarkdownLoader# 元素模式加载(按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专门用于加载这种格式的文件。
fromlangchain_community.document_loadersimportCSVLoader loader=CSVLoader(file_path=r'F:\python测试\智谱-langchain\weather_district_id.csv',encoding='utf-8')data=loader.load()# 打印前两条记录forrecordindata[:2]:print(record)特点:
- 自动将CSV中的每行数据转换为一个文档对象
- 支持指定文件编码(如utf-8)
- 适合处理结构化的表格数据(如产品信息、统计数据)
- 加载结果中每条记录包含CSV行的所有字段信息,便于后续按字段筛选
3. HTML文件加载
Web页面通常采用HTML格式,WebBaseLoader可以加载网页内容并提取指定部分。
importbs4fromlangchain_community.document_loadersimportWebBaseLoader 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文件并支持图片提取。
fromlangchain_community.document_loadersimportPyPDFLoader# 启用图片提取功能loader=PyPDFLoader(file_path=r'F:\python测试\智谱-langchain\测试数据\test.pdf',extract_images=True)# 每一页对应一个documentdata=loader.load()print('data:',data,'\n')# 基础用法(不提取图片)# loader = PyPDFLoader(file_path='test.pdf')特点:
- 自动按页码分割文档,每页对应一个文档对象(符合PDF的天然分页结构)
- 支持
extract_images=True参数提取PDF中的图片(需配合OCR工具进一步处理图片内容) - 适合处理多页PDF文档(如报告、论文、合同)
5. JSON文件加载
JSON是一种轻量级数据交换格式,JSONLoader支持通过jq语法提取指定内容。
fromlangchain_community.document_loadersimportJSONLoader# 提取特定字段内容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')# 自定义元数据defcreate_metadata(record:dict,metadata:dict)->dict:metadata['sender_name']=record.get('sender_name')metadata['timestamp_ms']=record.get('timestamp_ms')returnmetadata 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系统的最终效果打下坚实基础。