LlamaIndex 的文档处理模块 是构建索引、实现高效检索问答的基础,其核心目标是将原始文档(如PDF、TXT、Markdown等)转化为结构化、可被索引的节点(Node) 数据。
整个流程的核心步骤可以分为5个阶段:
1. 文档加载
这是处理的第一步,核心是将不同格式的原始文档加载为LlamaIndex统一的Document对象。
- 核心操作:借助LlamaIndex内置的加载器(或自定义加载器)读取文件,提取文本内容,并附加元数据(如文件名、文档路径、创建时间等)。
- 常用加载 器:
(1)SimpleDirectoryReader:加载指定目录下的所有文档(支持PDF、TXT、Markdown)。
(2)PDFReader:专门处理PDF文件,可提取文本和页码信息。
(3)StringReader:直接加载字符串格式的文本。
- 输出 :一个或多个Document对象,每个对象包含文本内容 和元数据。
2. 文档分割
原始文档的文本通常较长,无法直接作为模型输入或索引单元,因此需要切分为更小的语义单元 (即Node),这是文档处理中最关键的一步。
- 核心原则:
(1)保持语义完整性:分割后的片段不能破坏句子、段落的逻辑关联。
(2)适配模型上下文窗口:片段长度需小于大模型的上下文长度限制(如 GPT-4 的 8k/32k 上下文)。
- 常用分割策略:
(1)基于字符 / 单词的分割:按固定字符数(如1000字符)分割,可设置重叠窗口(如200字符),避免片段边界信息丢失。
(2)基于语义的分割:利用嵌入模型(如BERT)计算句子相似度,在语义边界处分割,更符合自然语言逻辑。
(3)基于结构的分割:针对Markdown、HTML等结构化文档,按标题、段落标签分割。
- 核心工具:SentenceSplitter(默认分割器)、TokenTextSplitter(按Token数分割)。
- 输出:多个Node对象,每个Node是一个独立的文本片段,包含自身的元数据(如所属文档 ID、位置索引)。
3. 元数据增强
为了提升后续检索的精准度,需要为Document和Node补 充更丰富的元数据,这一步是可选但非常推荐的。
- 核心操作:
(1)提取文档的结构化信息:如PDF的页码、Markdown的标题层级、网页的URL和标题。
(2)手动添加自定义元数据:如文档分类标签、作者信息、业务相关属性(如 "产品手册""技术文档")。
(3)自动提取元数据:借助大模型对文本内容进行总结,生成 "摘要元数据"。
- 作用:后续检索时,可以通过元数据过滤(如 "只检索产品手册类文档")缩小范围,提升效率。
4. 节点构建
这一步是将分割后的文本片段封装为LlamaIndex标准的Node对象,是连接文档分割和索引构建的桥梁。
- Node 的核心类型:
(1)TextNode:最常用的类型,存储文本片段和元数据。
(2)ImageNode:用于存储图片数据(搭配多模态模型使用)。
(3)IndexNode:用于存储子索引的引用(适用于分层索引场景)。
- 核心属性:每个Node包含text(文本内容)、metadata(元数据)、node_id(唯一标识)、ref_doc_id(关联的原始文档 ID)。
- 输出:一个 Node 列表,是后续构建索引的直接数据源。
5. 文档清洗与预处理
这是可选的优化步骤,目的是提升文本质量,减少噪声对检索和问答的影响。
- 核心操作:
(1)去除无关内容:如PDF的页眉页脚、广告水印、重复文本。
(2)文本标准化:如统一大小写、去除特殊符号、修复乱码。
(3)过滤低信息内容:如空白行、无意义的占位符文本。
- 工具:可借助Python字符串处理函数,或自定义清洗函数实现
核心步骤总结表
|----------|-------------------------|----------------------------------------|----------------------|
| 文档加载 | 读取多格式文档,生成统一 Document对象 | SimpleDirectoryReader、PDFReader | Document 列表 |
| 文档分割 | 切分文本为语义完整的小片段 | SentenceSplitter、TokenTextSplitter | 文本片段列表 |
| 元数据增强 | 补充丰富元数据,提升检索精准度 | 自定义函数、大模型摘要 | 增强元数据的 Document/Node |
| 节点构建 | 封装片段为标准Node对象 | TextNode、NodeParser | Node列表 |
| 文档清洗与预处理 | 去除噪声,标准化文本 | 自定义清洗函数 | 高质量文本片段 |