Jean's Blog

一个专注软件测试开发技术的个人博客

0%

RAG组件--数据导入之简单文本的读取

数据导入,也可以说文档加载功能,这是实现RAG系统的第一步,文档加载的整体原则如下:

  1. 优先使用通用的解析库或工具
  2. 重要的文件类型如PDF,选择专用工具
  3. 理解文件内容的内部结构
  4. 复杂的文档,可以先将其转化为更易解析的中间格式
  5. 大模型也可以用来辅助解析结构化、半结构化和非结构化数据

用LangChain读取txt文档

安装依赖

1
2
pip install -qU langchain-community
pip install -qU langchain-unstructured

简单的示例如下:

1
2
3
4
5
from langchain_community.document_loaders import TextLoader

loader = TextLoader("../data/黑悟空/设定.txt")
documents = loader.load()
print(documents)
  • 基本方法:使用TextLoader从langchain_community.document_loaders导入,通过指定文件路径加载文本内容
  • 数据结构:加载后的文档存储在Document对象中,包含metadata和page_content两个主要部分

输出内容如下:

1
[Document(metadata={'source': '../data/黑悟空/设定.txt'}, page_content='《黑神话:悟空》的故事可分为六个章节,名为“火照黑云”、“风起黄昏”、“夜生白露”、“曲度紫鸳”、“日落红尘”和“未竟”,并且拥有两个结局,玩家的选择和经历将影响最终的结局。\n\n每个章节结尾,附有二维和三维的动画过场,展示和探索《黑神话:悟空》中的叙事和主题元素。\n\n游戏的设定融合了中国的文化和自然地标。例如重庆的大足石刻、山西省的小西天、南禅寺、铁佛寺、广胜寺和鹳雀楼等,都在游戏中出现。游戏也融入了佛教和道教的哲学元素。')]

返回了一个Document对象,其中的元数据:

  • metadata:即元数据,存储与文档相关的元信息,例如文档的来源路径、作者、如期等。元数据虽然不是文档具体内容,但信息含量丰富,在RAG系统中,很有用武之地
  • page_content:保存文档实际文本内容,是文档的主要数据部分

Document对象的优势:

  • 统一各种文本格式为标准化数据结构
  • 元数据在RAG系统中具有重要作用,可用于后续检索过滤(如通过标签筛选特定类型文档)

用LangChain读取目录中的所有文档

安装包:

  • pip install unstructured:基础文档处理库
  • pip install “unstructured[image]”:图像文件支持
  • pip install “unstructured[md]”:Markdown文件支持
  • pip install “unstructured[pptx]”:PPT文件支持
  • sudo apt-get install tesseract-ocr/brew install tesseract:OCR识别引擎(确认安装:tesseract —version)
  • pip install pytesseract:Python OCR接口

安装说明:当目录中包含图片(image)、Markdown(md)等特殊格式文件时,必须安装对应依赖包,否则会报错提示安装

示例如下:

1
2
3
4
5
6
from langchain_community.document_loaders import DirectoryLoader

loader = DirectoryLoader("../data/黑悟空")
docs = loader.load()
print(f"文档数:{len(docs)}") # 输出文档总数
print(docs[0]) # 输出第一个文档
  • 导入方式:使用from langchain_community.document_loaders import DirectoryLoader导入通用文档加载器
  • 初始化加载器:通过loader = DirectoryLoader(“./data/黑悟空”)指定要加载的目录路径
  • 执行加载:调用docs = loader.load()方法加载所有文档
  • 文档统计:使用print(f”文档数:{len(docs)}”)输出加载的文档总数

输出内容如下

1
2
3
4
5
6
7
8
文档数:8
page_content='2

Pons

BLACK MYTH -

4' metadata={'source': '../data/黑悟空/黑悟空英文.jpg'}
  • 文件类型支持:成功加载包含jpg、csv、pdf、txt、json、pptx等多种格式的7个文档
  • 图像处理能力:对图片文件能进行OCR文字识别(如解析出”悟空”文字内容)
  • 元数据保留:每个文档加载后都包含原始文件路径等元数据信息

LangChain中不同的Loader解析结果不同

image-20250805161227695

  • 格式保留需求: 当需要保留文档原始格式(如Markdown标题层级)时,必须精心选择特定加载器。例如在RAG系统中,保留标题结构有助于大模型更好地理解文档语义关系。
  • 结果差异性: 同一文件使用不同Loader解析可能产生完全不同的结果,这直接影响后续处理效果。

以下示例使用DirectoryLoader和TextLoader对同一文件解析的结果:

使用DirectoryLoader默认加载方式读取目录下的Markdown文件

1
2
3
4
5
6
7
8
9
10
from langchain_community.document_loaders import DirectoryLoader

loader = DirectoryLoader("../data/黑悟空",
glob="**/*.md",
use_multithreading=True, # 开启多线程
show_progress=True, # 显示进度条
)
docs = loader.load()
print(f"文档数:{len(docs)}") # 输出文档总数
print(docs[0]) # 输出第一个文档

执行结果,输出内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
100%|██████████| 1/1 [00:00<00:00, 11.06it/s]
文档数:1
page_content='黑神话:悟空 🐵

黑神话:悟空 是由中国游戏开发团队制作的一款备受瞩目的动作冒险游戏,以《西游记》为背景,重新演绎了经典故事,带来了极具冲击力的视觉和游戏体验。

游戏版本介绍

1. 数字标准版 💻

包含基础游戏

2. 数字豪华版 🎶

包括基础游戏

额外的游戏内内容和精选数字原声音乐

兵器“铜云棒” 🏹

披挂“百戏傩面、百戏衬钱衣、百戏护手、百戏吊腿” 🛡️

珍玩“风铎” 🎐

3. 实体豪华版 📦
...

文化再现:重现了中国传统文化中的神话和传奇故事。

提示:关注游戏的官方网站和社交媒体,获取最新的开发进度和发布信息。 📅' metadata={'source': '../data/黑悟空/黑悟空版本介绍.md'}

使用DirectoryLoader TextLoader加载方式读取目录下的Markdown文件

1
2
3
4
5
6
7
8
9
10
11
from langchain_community.document_loaders import DirectoryLoader, TextLoader

loader = DirectoryLoader("../data/黑悟空",
glob="**/*.md",
loader_cls=TextLoader, # 指定加载工具
use_multithreading=True, # 开启多线程
show_progress=True, # 显示进度条
)
docs = loader.load()
print(f"文档数:{len(docs)}") # 输出文档总数
print(docs[0]) # 输出第一个文档

执行结果,内容输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
100%|██████████| 1/1 [00:00<00:00, 255.31it/s]
文档数:1
page_content='# 黑神话:悟空 🐵

> 黑神话:悟空 是由中国游戏开发团队制作的一款备受瞩目的动作冒险游戏,以《西游记》为背景,重新演绎了经典故事,带来了极具冲击力的视觉和游戏体验。

## 游戏版本介绍

### 1. 数字标准版 💻
- 包含基础游戏

### 2. 数字豪华版 🎶
- 包括基础游戏
- 额外的游戏内内容和精选数字原声音乐
- 兵器“铜云棒” 🏹
- 披挂“百戏傩面、百戏衬钱衣、百戏护手、百戏吊腿” 🛡️
- 珍玩“风铎” 🎐

### 3. 实体豪华版 📦
- 包含数字豪华版的启动码和一系列实体收藏品
- 收藏铁盒、1:1紧箍咒、乱蟠桃画卷、风铎项链、雷榍指环、金乌徽章、邮票和明信片以及保修证书

### 4. 实体收藏版 🏆
- 包含数字豪华版的启动码和独家实体收藏品
- 收藏铁盒、主角1:6可动人偶“直面天命”、受心经画卷、风铎项链、雷榍指环、金乌徽章、邮票和明信片以及保修证书
...

> **提示**:关注游戏的官方网站和社交媒体,获取最新的开发进度和发布信息。 📅

' metadata={'source': '../data/黑悟空/黑悟空版本介绍.md'}

加载方式的差异总结

  • 默认行为差异:

    • DirectoryLoader: 底层使用Unstructured包,将Markdown转为纯文本时会丢失标题标记(如#、##等层级符号)
    • TextLoader: 能完整保留Markdown的格式标签,包括emoji和标题结构
  • 底层机制: DirectoryLoader默认采用UnstructuredMarkdown工具进行解析,而TextLoader是专门处理文本格式的加载器。

  • 标题格式保留的需求

    • 语义保持: 标题层级(如#代表大标题,##代表小标题)反映了文档的父子关系结构,这对RAG系统的检索和生成质量至关重要。
    • 案例对比: 当输入带标题结构的文档(B)和纯文本(A)给大模型时,前者能产生更符合预期的输出结果,因为保留了原始语义关系。
  • TextLoader的优势展示

    • 配置方法: 需要显式指定loader_cls=TextLoader参数,强制对Markdown文件使用文本加载器。
    • 效果验证: 对比显示TextLoader能完整保留所有Markdown标签(如# 黑神话:悟空、## 游戏版本介绍等),而默认Loader会丢失这些结构信息。
  • 工具选择的依据

    • 决策原则:

      • 不关注文档结构时可用默认Loader提升效率
      • 需要利用文档层级关系(如建立文本块链接)时必须选用格式保留型Loader

      • 非绝对优劣: TextLoader并非在所有场景都优于DirectoryLoader,选择取决于具体需求:

        • 后续处理是否需要原始格式
        • 是否要利用文档的语义结构关系
        • 系统对解析速度/精度的权衡要求

用LlamaIndex读取目录中的所有文档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from llama_index.core import SimpleDirectoryReader

# 使用 SimpleDirectoryReader 加载目录中的文件
dir_reader = SimpleDirectoryReader("../data/黑悟空")
documents = dir_reader.load_data()
# 查看加载的文档数量和内容
print(f"文档数量: {len(documents)}")
print(documents[0].text[:100]) # 打印第一个文档的前100个字符

# 仅加载某一个特定文件
dir_reader = SimpleDirectoryReader(input_files=["../data/黑悟空/设定.txt"])
documents = dir_reader.load_data()
print(f"文档数量: {len(documents)}")
print(documents[0].text[:100]) # 打印第一个文档的前100个字符

执行结果,输出内容:

1
2
3
4
5
6
7
8
文档数量: 12
《黑神话:悟空》的故事可分为六个章节,名为“火照黑云”、“风起黄昏”、“夜生白露”、“曲度紫鸳”、“日落红尘”和“未竟”,并且拥有两个结局,玩家的选择和经历将影响最终的结局。

每个章节结尾,附有
文档数量: 1
《黑神话:悟空》的故事可分为六个章节,名为“火照黑云”、“风起黄昏”、“夜生白露”、“曲度紫鸳”、“日落红尘”和“未竟”,并且拥有两个结局,玩家的选择和经历将影响最终的结局。

每个章节结尾,附有
  • 批量读取方法:使用SimpleDirectoryReader类,传入目录路径即可读取所有文件,如SimpleDirectoryReader(“data/黑悟空”),通过load_data()方法加载文档。
  • 单文件读取:通过input_files参数指定单个文件路径列表,如input_files=[“../data/黑悟空/设定.txt”],实现精确加载。
  • 文档数量差异:与LangChain不同,LlamaIndex会自动对CSV等结构化文件进行切分处理,导致文档数量可能多于实际文件数(如7个文件生成11个文档)。
  • 性能特点:相比其他工具处理速度更快,底层可能采用自定义的文档解析策略。

用Unstructured工具读取各式类型的文档

  • 格式兼容性:支持包括PPT(.ppt/.pptx)、RTF(.rtf)、TSV(.tsv)、Word(.doc)等20+种文档格式,通过不同partition_*函数处理。
  • 独立使用优势:无需依赖RAG框架,直接调用如partition_text(“data/黑神话/黑神话悟空的设定.txt”)即可解析文档。
  • 数据结构输出:将文档内容转换为标准化的element对象,包含类型、类名、文本内容等元数据,可通过dict查看完整属性。
  • 元数据访问:通过迭代elements可获取每个元素的详细信息,包括:element.class.name获取元素类型,element.text提取文本内容。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from unstructured.partition.text import partition_text

text = "../data/黑悟空/设定.txt"
elements = partition_text(text)
for element in elements:
print(element)

# 通过vars函数查看所有可用的元数据
for i, element in enumerate(elements):
print(f"\n--- Element {i+1} ---")
print(f"类型: {type(element)}")
print(f"元素类型: {element.__class__.__name__}")
print(f"文本内容: {element.text}")

# 元数据展示
if hasattr(element, 'metadata'):
print("元数据:")
metadata = vars(element.metadata)
valid_metadata = {k: v for k, v in metadata.items()
if not k.startswith('_') and v is not None}
for key, value in valid_metadata.items():
print(f" {key}: {value}")

执行结果,输出内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
《黑神话:悟空》的故事可分为六个章节,名为“火照黑云”、“风起黄昏”、“夜生白露”、“曲度紫鸳”、“日落红尘”和“未竟”,并且拥有两个结局,玩家的选择和经历将影响最终的结局。
每个章节结尾,附有二维和三维的动画过场,展示和探索《黑神话:悟空》中的叙事和主题元素。
游戏的设定融合了中国的文化和自然地标。例如重庆的大足石刻、山西省的小西天、南禅寺、铁佛寺、广胜寺和鹳雀楼等,都在游戏中出现。游戏也融入了佛教和道教的哲学元素。

--- Element 1 ---
类型: <class 'unstructured.documents.elements.Title'>
元素类型: Title
文本内容: 《黑神话:悟空》的故事可分为六个章节,名为“火照黑云”、“风起黄昏”、“夜生白露”、“曲度紫鸳”、“日落红尘”和“未竟”,并且拥有两个结局,玩家的选择和经历将影响最终的结局。
元数据:
last_modified: 2025-07-16T19:30:42
languages: ['zho']
file_directory: ../data/黑悟空
filename: 设定.txt
filetype: text/plain

--- Element 2 ---
类型: <class 'unstructured.documents.elements.Title'>
元素类型: Title
文本内容: 每个章节结尾,附有二维和三维的动画过场,展示和探索《黑神话:悟空》中的叙事和主题元素。
元数据:
last_modified: 2025-07-16T19:30:42
languages: ['zho']
file_directory: ../data/黑悟空
filename: 设定.txt
filetype: text/plain
...
languages: ['zho']
file_directory: ../data/黑悟空
filename: 设定.txt
filetype: text/plain
    • 元素解析方法:
      • 使用partition_text()函数将文本分割为多个element
      • 通过dict属性查看所有可用元数据
      • 使用enumerate遍历元素并打印类型、类名和文本内容
    • 元数据提取:
      • 检查元素是否具有metadata属性
      • 过滤掉以下划线开头的元数据字段
      • 提取包括文件路径、语言、修改时间等关键信息
    • 工具特点:
      • 自动根据文件内容进行细粒度拆分
      • 保留完整的文件元数据信息
      • 支持多种元素类型识别(如Title类型)
    • 处理流程:
        1. 导入partition_text函数
        2. 指定文本文件路径
        3. 调用partition_text进行解析
        4. 遍历输出元素信息
    • 元素属性:
      • 类型:如
      • 类名:如”Title”
      • 文本内容:元素包含的实际文本

pdf文档读取示例

1
2
3
4
5
6
7
from unstructured.partition.auto import partition

filename = "../data/黑悟空/黑神话悟空.pdf"
elements = partition(filename=filename,
content_type="application/pdf",
)
print("\n\n".join([str(element) for element in elements][:10]))

执行结果,输出内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
08.20 直面天命

序章

《黑神话:悟空》是一款基于《西游记》改编的中国神话动作角色扮演游戏,玩家化身 “天命之人”,在险象环生的西游冒险中追寻传说背后的秘密。

改编自公元1592年中国神魔小说《西游记》

启程

无惧

历练

逢缘

启程B

L
    • PDF处理方法:
      • 使用partition()函数并指定content_type为”application/pdf”
      • 可限制输出元素数量(如[:10])
      • 自动解析PDF中的文本和结构信息
    • 输出内容:
      • 包含文档标题、章节信息等结构化内容
      • 保留原始文档的格式和布局信息

LangChain中各种Loader

LangChain document_loaders官方文档地址:https://python.langchain.com/docs/integrations/document_loaders/

  • Loader多样性:LangChain支持上百种文件类型的Loader,包括Oracle、Notebook、PDF等常见格式

  • 查找方法:

    • 在langchaincommunity.documentloaders包中查看__init.py文件
    • 使用搜索功能定位特定Loader(如Web、Weather等)
  • 扩展性:若缺少特定Loader,可向社区提交需求,通常几个月内会实现
  • 典型Loader示例:
    • WebBaseLoader(网页)
    • WeatherDataLoader(天气数据)
    • WhatsAppChatLoader(WhatsApp聊天记录)
    • YouTubeLoader(YouTube视频)

LangChain集成了各种Unstructured Loader

image-20250806091647398