从零开始搭建RAG系统系列(三):数据准备与预处理

步骤一:数据准备与预处理

  • 目标:将我们的原始知识文档(例如,一组关于某个开源项目的介绍文档,可能是TXT或PDF格式)加载进来,并将其分割成适合RAG系统处理的、带有元数据的文本块(chunks)。

具体操作:

1. 数据加载(Data Loading)

我们需要从文件系统中加载文档。Lang Chain提供了多种DocumentLoader`来处理不同类型的文件。

首先,假设我们有一个名为knowledge_base`的文件夹,里面存放了我们的知识文档。例如,可以创建两个简单的.txt文件:

knowledge_base/project_intro.txt:
RAGFlow是一个基于Python的开源检索增强生成框架。

它致力于简化RAG应用的开发、评估和部署流程。

RAGFlow的核心特性包括模块化设计、多种检索策略支持以及易于扩展的接口。

该项目由ABCLab于2024年发起。
knowledge_base/features.txt:
RAGFlow的主要功能包括:

  1. 数据接⼊:⽀持PDF, TXT, Markdown等多种⽂档格式。
  2. 智能分块:提供多种⽂本分割策略,如递归分割、语义分割。
  3. 向量化与索引:集成主流Embedding模型和向量数据库。
  4. 灵活检索:⽀持向量检索、关键词检索及混合检索。
  5. LLM集成:⽅便对接OpenAI、HuggingFace等多种⼤语⾔模型。
  6. 评估套件:内置常⽤RAG评估指标和⼯具。

现在,我们使⽤LangChain的 DirectoryLoaderTextLoader 来加载这些⽂档

ini 复制代码
from langchain_community.document_loaders import DirectoryLoader, TextLoader
from langchain_core.documents import Document # Document type
from typing import List
# 定义知识库⽬录
knowledge_base_path = "./knowledge_base"
# 注意:请确保在Python脚本的同级⽬录下创建 knowledge_base ⽂件夹,并将上述txt⽂件放⼊其
# 使⽤DirectoryLoader加载⽬录下所有.txt⽂件,指定使⽤TextLoader
loader = DirectoryLoader(
knowledge_base_path,
glob="**/*.txt", # 匹配所有txt⽂件
loader_cls=TextLoader, # 使⽤TextLoader加载
loader_kwargs={'encoding': 'utf-8'}, # TextLoader的参数,确保UTF-8编码
use_multithreading=True, # 可以加速加载多个⽂件
show_progress=True # 显⽰加载进度
)
documents: List[Document] = loader.load()
if documents:print(f"成功加载 {len(documents)} 个⽂档.")
for i, doc in enumerate(documents):
print(f"\n--- ⽂档 {i+1}: {doc.metadata.get('source', '未知来源')} ---
print(f"内容预览 (前100字符): {doc.page_content[:100]}")
else:
print(f"未能从 '{knowledge_base_path}' 加载到任何⽂档。请检查路径和⽂件。")
# 对于PDF⽂件加载,可以使⽤PyPDFLoader (需要 pip install pypdf)
# from langchain_community.document_loaders import PyPDFLoader
# pdf_loader = PyPDFLoader("path/to/your/document.pdf")
# pdf_documents = pdf_loader.load()

说明:DirectoryLoader可以方便地加载整个目录的文件。每个加载的Document对象通常包含两部分:page_content(文档的文本内容)和metadata(一个字典,通常包含如 source等元信息,即文件名)。

2.文本分割(Text Splitting)

长文档需要被切分成更小的语义单元(chunks), 以便Embedding模型处理并提高检索的精确性。LangChain的 RecursiveCharacterTextSplitter是一个常用的选择,它会尝试按预设的一系列分隔符(如换行符、句号等)递归地分割文本,以求在满足大小限制的同时尽量保持语义的完整性。

上图展⽰了⽂本分割的过程。⻓⽂档被切分成较⼩的⽂本块 (chunks)。相邻⽂本块之间通常设置重叠(overlap)部分(⽰例中红⾊字体为上⼀块的重叠内容,绿⾊字体为与下⼀块的重叠内容),以确保语义的连续性,避免关键信息在分割点被割裂。

ini 复制代码
from langchain.text_splitter import RecursiveCharacterTextSplitter

# 初始化⽂本分割器

text_splitter = RecursiveCharacterTextSplitter(

chunk_size=200, # 每个块的最⼤字符数。应根据Embedding模型和LLM的上下⽂窗⼝进⾏调

# 对于中⽂,⼀个汉字通常算1个token,但具体取决于模型的分词器。

# BGE等模型通常有512 tokens的输⼊限制。

chunk_overlap=20, # 相邻块之间的重叠字符数,帮助保留上下⽂连贯性。

separators=["\n\n", "\n", "。", "!", "?", ",", "、", " ", ""], # 中⽂场景

length_function=len, # 使⽤字符⻓度计算chunk_size

add_start_index=True # 在metadata中添加块在原⽂中的起始位置,可选

)

if documents: # 确保前⾯加载成功

document_chunks: List[Document] = text_splitter.split_documents(document

print(f"\n⽂档被分割成 {len(document_chunks)} 个⽂本块.")

if document_chunks:

print(f"第⼀个⽂本块预览: {document_chunks[0].page_content}")

print(f"第⼀个⽂本块元数据: {document_chunks[0].metadata}")

else:

print("没有⽂档可供分割。")

document_chunks = [] # 初始化为空列表以防后续代码出错

说明::chunk_size 和 chunk_overlap 的选择对RAG性能有显著影响,需要根据具体数据、Embedding模型的能力以及LLM的上下文窗口大小进行实验调整。对于中文文本,合理设置separators尤为重要,以尽可能在自然的语义边界(如段落、句子)进行切分。

相关推荐
Ama_tor1 小时前
14.AI搭建preparationのBERT预训练模型进行文本分类
人工智能·深度学习·bert
QQ676580081 小时前
基于 PyTorch 的 VGG16 深度学习人脸识别检测系统的实现+ui界面
人工智能·pytorch·python·深度学习·ui·人脸识别
张较瘦_1 小时前
[论文阅读] 人工智能 | 用大语言模型解决软件元数据“身份谜题”:科研软件的“认脸”新方案
论文阅读·人工智能·语言模型
Blossom.1181 小时前
量子通信:从科幻走向现实的未来通信技术
人工智能·深度学习·目标检测·机器学习·计算机视觉·语音识别·量子计算
平凡灵感码头1 小时前
OpenAI 即将推出 GPT-5:开启多模态、持续记忆对话新时代
人工智能·gpt
软件测试小仙女1 小时前
鸿蒙APP测试实战:从HDC命令到专项测试
大数据·软件测试·数据库·人工智能·测试工具·华为·harmonyos
量子位2 小时前
Figure 机器人分拣快递新视频曝光,网友:太像人类
llm·ai编程
三花AI2 小时前
ComfyUI 子工作流功能:一次编辑全局更新
人工智能
大模型铲屎官2 小时前
【深度学习-Day 23】框架实战:模型训练与评估核心环节详解 (MNIST实战)
人工智能·pytorch·python·深度学习·大模型·llm·mnist
Elastic 中国社区官方博客2 小时前
Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合
大数据·人工智能·elasticsearch·搜索引擎·云计算·全文检索·aws