大模型RAG进阶多格式文档解析

基础认知与准备

常见文档类型与解析需求

|----------|--------------------|-------------|
| 扩展名称 | 支持文件类型 | 适用场景示例 |
| csv | .csv | 表格数据提取 |
| docx | .doc, .docx | Word 文档解析 |
| pdf | .pdf | PDF 文本/布局提取 |
| image | .jpeg .png .tiff 等 | 图片 OCR 文字识别 |
| pptx | .ppt, .pptx | 幻灯片内容提取 |
| xlsx | .xls, .xlsx | Excel 表格解析 |

文档解析挑战认知

  • 布局解析困难:PDF文件的布局可能会因为不同的作者、工具或用途而有所不同,通常具有多列文本,对于图像或表格来说,这些文本可能会突然中断,因此解析其布局是一个具有挑战性的任务。
  • 格式错综复杂 :PDF文件中可能包含各种格式的内容,包括文字图像表格等,因此解析其内容需要考虑到这种多样性和复杂性。
  • 复合表格:纵向/横向合并的复杂表格,在PDF中进行抽象还原是最难处理的问题之一
  • 文本、图片、表格顺序提取:提取PDF文件中的文本、图片和表格,并确保它们的顺序正确性,是一个需要解决的重要问题。
  • 文档结构还原:还原PDF文件的文档结构,包括标题、目录等信息,是实现自动化文档处理和理解的关键步骤之一。
  • 元数据提取:在PDF中隐藏的元数据信息是RAG产品的关键数据,比如链接、目录、字体等等
  • 扫描件:PDF中如果是扫描件,就需要依靠OCR模型来进行有效的提取,这里面还会包含清晰度、模型的稳定性等等问题
  • Latex公式 提取:在一些特殊领域,PDF文本中包含了Latex等数学公式。通过完整的提取和转换是对RAG问答的有效补充

技术选型与工具对比

主流工具对比与选择

技术选型决策

  • 数字原生PDF:优先选择PyMuPDF,利用其渲染效率优势处理纯文本/简单表格批量任务
  • 扫描PDF:必须启用OCR流程,可搭配Unstructured的"ocr_only"策略
  • 复杂学术文档:推荐Marker(代码/公式支持)或MinerU(数学公式识别),但需容忍GPU加速需求

工具性能对比表

|-----------------|---------------|---------------|----------|
| 工具 | 核心优势 | 适用场景 | 性能代价 |
| unstructured.io | 支持50+格式,生态完善 | 多源数据ETL入口 | 处理速度较慢 |
| PyMuPDF | 解析速度>200页/分钟 | 纯文本/简单PDF批量处理 | 无OCR能力 |
| Marker | 代码/公式支持优秀 | 技术白皮书/学术文献 | 需GPU加速 |
| MinerU | 数学公式识别精准 | 科技/专利类文档 | 高计算负载 |
| DoclingAI | 表格提取精度98%+ | 金融财报/科研报告 | 仅专注表格 |
| DeepDoc | 中文优化+端到端方案 | 中文RAG系统建设 | 需API调用 |

文档解析技术差异

PDF解析技术核心差异

PDF解析技术的核心差异体现在对文档结构的处理逻辑上:

  • PyMuPDF :渲染优先策略,高效文本提取,采用渲染优先策略,通过直接解析页面绘制指令实现高效文本提取;并非直接去"寻找"那些对人类而言可读的文字(内容流 ),而是像一名打印机,通过理解和执行模拟页面渲染(绘制)过程 ,执行底层绘制命令,来重建页面的内容,并从中精准定位和识别文本
    • 处理速度可达200页/分钟,尤其在规则表格识别中表现出坐标精度优势
    • 但缺乏OCR能力,无法处理扫描生成的图像型PDF,且对复杂公式和代码块的支持有限
  • OCR技术:处理扫描件的核心能力
    • 针对无文本层的扫描件或多列布局文档,通过OCR提取文字

OCR生态/大模型

OCR(光学字符识别)最终的目的是将非结构化的图像信息,转化为结构化的、可计算和可理解的数据,所以本质上是对图片内容的理解,可以考虑的开源组件如下:

Unstructured.io的集成优势

Unstructured.io作为集成框架,通过strategy参数实现后端自适应切换:

  • "fast"策略:调用PyMuPDF等轻量引擎处理规则文档
  • "hi_res"策略:激活YOLOX目标检测模型进行布局分析,配合detectron2实现表格与图像的精准提取
  • "ocr_only"策略:使用OCR模型进行图文识别
  • "vlm"策略:针对极端复杂场景调用GPT-4o等多模态模型,通过视觉语义理解突破传统解析局限

这种混合架构使其在金融财报(表格提取精度98%+)和科研报告等场景中表现突出。

Unstructured的核心优势

  • 可以和Agent框架集成(LangChain、LlamaIndex)
  • 也可以解析多种不同的文档形式(比较通用)
  • 主流应用的比较多、适用性比较广
  • 生态协同核心地位:Unstructured库通过与LangChain主流框架的深度集成(如UnstructuredLoader组件),与LlamaIndex的深度集成(如UnstructuredReader组件)已成为检索增强生成(RAG)pipeline中的关键预处理节点。其能够将非结构化数据转化为向量数据库可索引的结构化格式,有效解决了RAG系统中"数据输入异构性"这一核心痛点,为下游的知识检索与生成任务提供了标准化数据基础

unstructured.io库入门与实践

环境准备与安装

基本安装

复制代码
pip install unstructured

针对需要处理多类型文档(如PDF、Office格式、图片等)的场景,全量安装会包含docx、pptx、pdf、image等扩展依赖,适合企业级全场景文档处理需求:

复制代码
包含本地推理能力(支持PDF/图片OCR等)
pip install "unstructured[local-inference]"

支持所有文档类型(不含本地推理,需依赖外部API)
pip install "unstructured[all-docs]"

如需进一步精简依赖,可按目标文件类型单独安装扩展模块,格式为unstructured[<extra>],支持同时指定多个扩展,以逗号分隔:

复制代码
仅安装PDF和DOCX处理能力
pip install "unstructured[pdf,docx]"

Serverless API通过优化处理流程,将文档处理启动时间从30分钟缩短至3秒以内,并支持多区域横向扩展,有效提升了高并发场景下的吞吐量:

复制代码
pip install unstructured-client

Docker 安装

复制代码
docker pull downloads.unstructured.io/unstructured-io/unstructured:latest
docker run -dt --name unstructured downloads.unstructured.io/unstructured-io/unstructured:latest
docker exec -it unstructured bash

核心系统依赖配置

Tesseract OCR:图像文本识别

提供图像文本识别能力,是处理扫描版PDF和图片文件的核心组件。

windows安装:

macOS 安装:

brew install tesseract

brew install tesseract-lang

Linux安装:

sudo apt-get install tesseract-ocr sudo apt-get install tesseract-ocr-chi-sim # 中文简体支持

验证安装:

tesseract --list-langs # 查看已安装的语言包

Poppler:PDF内容提取底层引擎

通过pdf2image库将PDF转换为图像格式,为后续OCR处理提供输入。

macOS安装:

brew install poppler

Linux安装:

sudo apt-get install poppler-utils

复制代码
import os

# mac系统
# 设置 poppler 工具路径到环境变量
os.environ["PATH"] = "/opt/homebrew/bin:" + os.environ.get("PATH", "")

# windows系统
# 将此处路径替换为你自己的poppler\bin目录路径
#poppler_path = "C:\\Poppler\\bin"

# 将poppler路径临时添加到当前会话的环境变量中,os.pathsep 是自动添加路径分隔符(在Windows上是分号;)
#os.environ["PATH"] = poppler_path + os.pathsep + os.environ.get("PATH", "")

!pdfinfo -v

Pandoc:富文本格式转换

处理EPUB、RTF等富文本格式的转换工具,必须使用2.14.2及以上版本以确保RTF文件解析兼容性。

libmagic:跨平台文件类型检测

Linux和macOS系统需手动安装,Windows环境可忽略此依赖。

unstructured核心功能理解

一般来说,这些功能分为几类:

  • 分区(Partitioning):将原始文档分解为标准的结构化元素

  • 清理(Cleaning):从文档中删除不需要的文本,例如样板文件和句子片段

  • 暂存(Staging):函数格式化下游任务的数据,例如ML推理和数据标记

  • 分块(Chunking):功能将文档分割成更小的部分,以便在RAG应用程序和相似性搜索中使用

  • 嵌入(Embedding):编码器类提供了一个接口,可以轻松地将预处理的文本转换为向量

    UnstructuredIO核心组件

    from unstructured.partition.auto import partition
    from typing import List
    from unstructured.documents.elements import Element

    使用partition函数自动检测文件类型并解析,默认strategy策略是auto,还会有fast策略,速度比image-to-text models的快100倍

    elements: List[Element] = partition(filename="RAG评估.md", strategy="auto")

    元素的文本内容

    print(elements[0].text)
    print("===========================")

    元素的类型

    print(elements[0].category)
    print("==================")

    元素的元数据

    print(elements[0].metadata.dict)
    print("===========================")

基于元素的方法优势

为什么这种基于元素的方法如此重要?

  • 结构为王:通过将文档分解为这些语义元素,可以保留原始文档的大部分逻辑结构。您获得的不仅仅是原始文本;你得到的是带有上下文的文本
  • 精细控制:您可以迭代这些元素,按类型过滤(例如,"过滤所有Table元素"),或者根据它们的类别以不同的方式处理它们
  • 丰富的元数据:每个元素都包含有用的元数据:其文本内容、它来自的页码、通常是它在页面上的坐标(边界框)、原始文件名、HTML格式的元素以及检测到的语言。这允许精确的下游处理或链接回源

元数据的应用价值

这些元数据让你能够:

  • 精确定位:知道文本在PDF中的确切位置
  • 页面管理:按页码组织和检索内容
  • 多语言处理:根据语言选择合适的处理策略
  • 布局理解:利用坐标信息进行版面分析

从本质上讲,unstructured不仅仅是"读取"PDF文档;它理解文档并进行解构它,这对于基于正则表达式来进行抓取的方式来说,这种解析方式无疑是一种对文档的更强大、更具语义性的理解。

Partition功能实践

partition通用参数如下

  • encoding:指定输入文本/文档读取时使用的字符编码。对于非 UTF-8 文档非常有用

  • include_page_breaks:如果设置为 True,当文档支持 "分页" 时,输出中会包含 PageBreak 元素,以标识不同页的边界

  • strategy:指定解析策略,尤其对于 PDF/Image 文档,控制"快速 vs 高保真 vs OCR"方式

  • ocr_languages/languages:当文档含有图像文字或扫描件时,可指定 OCR 语言包,如 "eng","deu"

  • skip_infer_table_types:可指定跳过表格类型推断的文档类型,减少表格识别错误

  • fields_include:控制输出 JSON 中包含哪些字段。可用于减小输出大小或过滤敏感字段"element_id","text","type","metadata"

  • metadata_include / metadata_exclude:用于控制在输出元素的 metadata 字段中,保留哪些键或者排除哪些键,默认全部输出

  • content_type:在使用 URL 或文件流时,指定 MIME 类型提示,提高文件类型识别准确性

  • starting_page_number:当处理文档是某个较大文档的一部分时,可以指定起始页号,用于 metadata

    from typing import List, Dict, Any, Optional, Sequence
    from pathlib import Path

    自定义解析函数,支持任意类型的文件格式

    def parse_file_with_unstructured(file_path: str):
    """
    使用UnstructuredIO解析单个文件

    复制代码
      Args:
          file_path: 文件路径
    
      Returns:
          Dict: 包含解析结果和统计信息的字典
      """
      print(f"\n 解析文件: {file_path}")
    
      try:
          # 使用partition函数自动检测文件类型并解析,默认strategy策略是auto,还会有fast策略,速度比image-to-text models的快100倍
          elements: List[Element] = partition(filename=file_path, strategy="auto")
    
          # 分析解析结果
          analysis = {
              "file_path": file_path,
              "file_extension": Path(file_path).suffix.lower(),
              "total_elements": len(elements),
              "element_types": {},
              "elements": elements,
              "text_content": "",
              "statistics": {}
          }
    
          # 统计元素类型
          for element in elements:
              element_type = type(element).__name__
              analysis["element_types"][element_type] = analysis["element_types"].get(element_type, 0) + 1
    
          # 提取文本内容
          text_parts = []
    
          for element in elements:
              if hasattr(element, 'text') and element.text:
                  text_parts.append(element.text)
    
          analysis["text_content"] = "\n\n".join(text_parts)
    
          # 计算统计信息
          analysis["statistics"]["total_characters"] = len(analysis["text_content"])
    
          print(f"   解析完成")
          print(f"   元素总数: {analysis['total_elements']}")
          print(f"   元素类型: {analysis['element_types']}")
          print(f"   总字符数: {analysis['statistics']['total_characters']}")
          print(f"   文本内容: {analysis['text_content'][:200]} ")
    
      except Exception as e:
          print(f"文件解析失败: {e}")
          return {}

    parse_file_with_unstructured("RAG评估.md")

Markdown文档解析

复制代码
from unstructured.partition.md import partition_md
from typing import List
from unstructured.documents.elements import Element

# 使用partition_md函数检测markdown文件类型解析,include_page_breaks若希望在 Markdown 中标识页面断点(少见场景)
elements: List[Element] = partition_md(filename="RAG评估.md", languages=["zho"],include_page_breaks=True)

# 元素的元数据
print(elements[0].metadata.__dict__)
print("===========================")

# 元素的文本内容
print(elements[0].text)
print("===========================")

# 元素的类型
print(elements[0].category)
print("===========================")

HTML文档解析

复制代码
from unstructured.partition.html import partition_html
from typing import List
from unstructured.documents.elements import Element

# 使用partition_html函数检测html网页类型解析
elements = partition_html(url="https://docs.unstructured.io/welcome",
                          headers={"User-Agent":"MyBot"},
                          ssl_verify=False,
                          include_page_breaks=False,
                          encoding="utf-8")
#elements: List[Element] = partition_html(url="https://docs.unstructured.io/welcome", languages=["zho"])

# 元素的元数据
print(elements[1].metadata.__dict__)
print("===========================")

# 元素的文本内容
print(elements[1].text)
print("===========================")

# 元素的类型
print(elements[1].category)
print("===========================")

除通用参数外:

  • url:直接给出网页 URL,无需先下载。
  • headers:HTTP 请求头(User-Agent 等)。
  • ssl_verify:是否验证 SSL 证书(False 可用于测试环境)。
  • file/filename/text:支持本地文件、文件流或网页文本输入。
  • content_type:可指定 text/html。

EXCEL文档解析

复制代码
from unstructured.partition.xlsx import partition_xlsx
from typing import List
from unstructured.documents.elements import Element

# 使用partition_xlsx函数检测excel文件类型并解析
elements: List[Element] = partition_xlsx(filename="销售数据统计.xlsx", languages=["zho"])

# 元素的元数据
print(elements[0].metadata.__dict__)
print("===========================")

# 元素的文本内容
print(elements[0].text)
print("===========================")

# 元素的类型
print(elements[0].category)
print("===========================")

CSV文档解析

复制代码
from unstructured.documents.elements import Element

# 使用partition_csv函数检测csv文件类型并解析
elements = partition_csv(filename="训练数据.csv", encoding="utf-8")

# 元素的元数据
#print(elements[0].metadata.__dict__)
print("===========================")

# 元素的文本内容
print(elements[0].text[:400])
print("===========================")

# 元素的类型
print(elements[0].category)
print("===========================")

Word文档解析

复制代码
from unstructured.partition.docx import partition_docx
from unstructured.partition.doc import partition_doc
from typing import List
from unstructured.documents.elements import Element

# 使用partition_docx函数检测word文件类型并解析,include_page_breaks当文档支持 "分页" 时,以标识不同页的边界
elements = partition_docx(filename="数组.docx", encoding="utf-8", include_page_breaks=True)

# 元素的元数据
print(elements[0].metadata.__dict__)
print("===========================")

# 元素的文本内容
print(elements[0].text[:400])
print("===========================")

# 元素的类型
print(elements[0].category)
print("===========================")

Image图片解析

复制代码
from unstructured.partition.image import partition_image
from typing import List
from unstructured.documents.elements import Element

# 使用partition_image函数检测png类型并解析,strategy="ocr_only"使用ocr来进行图片内容文字识别
elements = partition_image(filename="PDF解析截图.png",
                           strategy="ocr_only",
                           languages=["eng","chi_sim"],
                           include_page_breaks=False)

# 元素的元数据
print(elements[0].metadata.__dict__)
print("===========================")

# 元素的文本内容
print(elements[0].text[:400])
print("===========================")

# 元素的类型
print(elements[0].category)
print("===========================")
  • 类似于 PDF 的策略调用,但直接针对单张或多张图片。
  • 特定参数:
    • strategy:可选 "auto", "hi_res", "ocr_only"。
    • languages / ocr_languages:OCR 多语言支持。
    • include_page_breaks:如图片列表可视为 "页"。
  • OCR的识别效果很大程度上取决于原始图像的质量。如果识别结果不理想,可以尝试对图像进行预处理,例如二值化、降噪、倾斜校正

PDF文件解析

复制代码
from unstructured.partition.pdf import partition_pdf
from typing import List
from unstructured.documents.elements import Element

# 使用partition_pdf函数检测pdf类型并解析
elements = partition_pdf(filename="甬兴证券-AI行业点评报告:海外科技巨头持续发力AI,龙头公司中报业绩亮眼.pdf",
                         strategy="hi_res", # 使用hi_res模式进行高精度解析
                         extract_images_in_pdf=True, # 提取pdf中的图片
                         extract_image_block_types=["Table","Image"], # 提取表格和图片
                         extract_image_block_output_dir="./images", # 保存图片到images目录
                         languages=["eng","zho"],
                         split_pdf_page=True, # 大文件分块处理,优化性能
                         infer_table_structure=True, # 是否尝试推断表格结构,会下载一个ocr模型
                         include_page_breaks=True) # 是否包含页码信息


# 元素的元数据
print(elements[0].metadata.__dict__)
print("===========================")

# 元素的文本内容
print(elements[0].text[:400])
print("===========================")

# 元素的类型
print(elements[0].category)
print("===========================")
  • 关键额外参数:
    • strategy:PDF解析策略的选择直接影响提取效果,可选 "auto"(默认)、"hi_res"、"fast"、"ocr_only"。控制解析方式。
      • auto(默认):适用于无图像嵌入文本的标准PDF,解析速度快
      • hi_res:使用布局检测模型(例如 会调用布局检测模型 Detectron2/YOLOX/自研Chipper等)提取结构信息。
      • fast:快速解析,以可提取文本为主。
      • ocr_only:针对扫描件/图像版 PDF,只做 OCR 提取。
      • vlm:VLM模型,如OpenAI/Anthropic等提供的视觉语言模型
    • extract_images_in_pdf(布尔):当 strategy 为 hi_res 时,可控制是否提取嵌入图像块。
    • extract_image_block_types(列表):指定提取哪些类型(如 "Image","Table")的图像块。
    • extract_image_block_to_payload(布尔):是否把提取块转换为 payload(例如 base64)输出。
    • extract_image_block_output_dir(字符串):如果不转换为 payload,可将提取图像块保存到指定目录。
    • max_partition:当使用 ocr_only 策略时,限制单个元素(文本块)最大字符长度。默认为 1500。
    • languages 或 ocr_languages:对 OCR 使用的语言包列表。
    • skip_infer_table_types:可以跳过表格类型推断以提高速度。
    • split_pdf_page:True,大文件分块处理,可实现大文件分块处理,提升解析效率
    • infer_table_structure:True,表格结构推断,是否尝试推断表格结构

Element对象核心字段

返回的Element对象包含以下核心字段:

  • text:元素的文本内容(表格会以Markdown表格格式呈现)
  • category:元素类型,如Title、NarrativeText、ListItem、Table等
  • metadata:元素的元数据

category元素类型详解

  • Title(标题):文档的标题和副标题
  • NarrativeText(叙事文本):纯文本的段落
  • Table(表格):表格数据
  • Text(段落):文本段落
  • Image(图像):所有图片
  • Formula(数学公式):文本 y = Wx + b
  • Header/Footer(页眉/页脚):可以将它们与主要内容区分开来

metadata元数据详解

  • 页码(page_number):该文本块所在的页码(从1开始)
  • 坐标信息(coordinates)
  • points:文本块在页面上的边界框坐标(4个角的坐标点)
    • 格式:[左上, 左下, 右下, 右上]
    • 单位:像素点
  • system:坐标系统类型(PixelSpace = 像素坐标系)
  • layout_width/height:页面的总宽度和高度(像素)
  • 语言(languages) :检测到的文档语言(如["zho"] = 中文,ISO 639-3语言代码)
  • 文件基本信息
  • filename:原始文件名
  • last_modified:文件最后修改时间(ISO 8601格式)
  • filetype :文件MIME类型(如application/pdf

下游RAG应用优化

在检索增强生成(RAG)系统中:

  • 通过category过滤非文本元素(如图像)
  • 或优先使用标题元素构建文档层次结构,提升检索准确性

额外配置:指定OCR Agent

如果你想切换OCR引擎(例如用Paddle OCR做中文识别更好),可以在环境中设置OCR_AGENT

使用Tesseract(默认)

  • export OCR_AGENT="unstructured.partition.utils.ocr_models.tesseract_ocr.OCRAgentTesseract"

或使用Paddle OCR(若已安装)

  • export OCR_AGENT="unstructured.partition.utils.ocr_models.paddle_ocr.OCRAgentPaddle"

并确保你安装了对应依赖(Tesseract二进制+语言包,或Paddle、Google SDK)。这能显著影响中文识别质量。

LlamaIndex框架介绍

大模型开发框架(SDK)是什么?

SDK:Software Development Kit,它是一组软件工具和资源的集合,旨在帮助开发者创建、测试、部署和维护应用程序或软件。 所有开发框架(SDK)的核心价值,都是降低开发、维护成本。 大语言模型开发框架的价值,是让开发者可以更方便地开发基于大语言模型的应用。

主要提供两类帮助:

  • 第三方能力抽象。比如LLM、向量数据库、搜索接口等
  • 常用工具、方案封装
  • 底层实现封装。比如流式接口、超时重连、异步与并行等

好的开发框架,需要具备以下特点:

  • 可靠性、鲁棒性高
  • 可维护性高
  • 可扩展性高
  • 学习成本低

LlamaIndex介绍

LlamaIndex 是一个为开发「上下文增强」的大语言模型应用的框架(也就是 SDK)。上下文增强,泛指任何在私有或特定领域数据基础上应用大语言模型的情况。

LangChain vs LlamaIndex

|----------------|-------------------------------------------------------------|--------------------------------------------------------------------------|
| 对比维度 | LangChain | LlamaIndex(原 GPT Index) |
| 定位与设计 | 通用型 LLM 应用框架(可构建 Agent、Tool、RAG 等各种系统) | 专注文档理解与 RAG 的索引、检索、问答框架 |
| 核心理念 | "链式调用(Chains)" 和 "工具组合(Tools)",强调可编排性 | "数据接口(Data Index + Query Engine)",强调数据到知识的映射 |
| 文档加载能力 | `DocumentLoader` 支持多格式文档(PDF、HTML、TXT) | 深度集成解析器(如 LlamaParse、Unstructured、PandasReader) |
| 数据解析深度 | 主要提取纯文本,结构化需手动实现 | 提供高层结构抽象(Document → Node → Index),保留层级关系 |
| 索引结构 | VectorStore(Chroma、FAISS、Milvus等)为核心,开发者需手动管理 | 提供多种索引:`VectorStoreIndex` , `SummaryIndex` , `KnowledgeGraphIndex` |
| 上下文压缩 / rerank | 需额外配置 Reranker 或 ContextCompressor | 原生支持 Context Compression / Node PostProcessor |
| 多文档检索 | 可通过 `MultiQueryRetriever` 、`ParentDocumentRetriever` 实现 | 内置 `ComposableGraph` 实现多索引融合检索 |
| Agent 能力 | 强(LangChain 是 Agent 生态核心框架) | 弱(更偏向数据检索与知识问答) |
| 生态与扩展性 | 最大的 LLM 生态,插件、工具链最丰富 | 与数据密集型 RAG 项目结合最紧(适合文档知识库类应用) |
| 适用场景 | 多步骤推理、Agent系统、工具调用、企业助手 | 文档问答、知识检索、企业知识库、研究型报告分析 |
| 示例语法简洁度 | 代码偏工程风格,组件组装较多 | 封装层高,一行代码即可构建 query engine |
| 性能优化方向 | 优化在链路编排与检索召回效率 | 优化在文档解析、chunk 切分与上下文压缩 |
| 代表项目 | Chatbot、智能助理、Agent系统、数据问答 | 企业知识库问答、PDF报告分析、学术RAG系统 |

  • LangChain 是"逻辑大脑":强在工作流编排、Agent化、工具集成。
  • LlamaIndex 是"知识记忆":强在文档结构化、RAG索引、检索优化。
    • 两者并不是竞争关系,而是 RAG 系统的天然组合

LlamaIndex集成与进阶

LlamaIndex环境准备

安装核心库

复制代码
pip install llama-index-core llama-index

安装解析库

复制代码
pip install llama-parse unstructured nest-asyncio python-multipart llama-index-readers-file
pip install pytest
pip install "unstructured[md]"

LlamaIndex常用组件

常用组件:

  • SimpleDirectoryReader

  • LlamaParse(针对复杂 PDF)

  • UnstructuredReader(多格式文档)

  • PandasReader(表格类文件)

  • 官方文档申请api_key:https://llamaindex.org.cn/blog/pdf-parsing-llamaparse

    from llama_index.core import SimpleDirectoryReader
    from llama_parse import LlamaParse

    如果文档结构复杂,优先使用 LlamaParse

    parser = LlamaParse(api_key="YOUR_LLAMA_CLOUD_API_KEY")

    documents = parser.load_data("sample.pdf")

    或者使用简单读取器

    documents = SimpleDirectoryReader(input_files=["RAG评估.md"]).load_data()

    print(documents[0].metadata)
    print("===========================")
    print(documents[0].text)
    print("===========================")

LlamaIndex集成unstructured

  • LlamaIndex本身并不专注于文件解析(Parsing),而专注于:
    • "结构化地管理与大模型交互的外部知识(即索引、检索、问答)。"
    • 而Unstructured.io是一个独立的"文档解析引擎",核心职责是:
    • "将各种复杂格式(PDF、DOCX、HTML、Excel、图片等)解析成统一的文本元素(elements)。"

因此:

  • LlamaIndex是知识管理层(Knowledge Layer)
  • Unstructured是文档提取层(Extraction Layer)

|---------------|-------------------------------------------------------------|-----------------------------------------|
| 对比点 | 使用`unstructured.partition`直接解析 | 使用`LlamaIndex UnstructuredReader` |
| **底层调用** | 直接调用`unstructured`官方API(`partition()`) | 内部封装了`partition()`,简化调用 |
| **灵活度** | 可访问所有底层参数(如`strategy`、`hi_res_model`、`ocr_languages`) | 封装后部分参数隐藏,仅暴露常用接口 |
| **可控性** | 可自定义处理流程(过滤、正则、chunk策略) | 自动化程度高,但定制难度大 |
| **集成便捷性** | 需手动将结果转为`Document` | 自动输出为`Document`列表 |
| **依赖管理** | 由开发者决定何时安装哪些后端(pdfminer, tesseract) | 自动导入必要模块,错误提示更友好 |
| **适用场景** | 高级研发/多源异构文档处理 | 快速原型/小规模项目 |

直接使用UnstructuredReader

推荐场景:快速测试/教学/单格式文件读取

优点:

  • 写法极简
  • 自动生成Document对象
  • 无需显式调用partition

缺点:

  • 无法细调OCR、chunk_size、文本清洗

  • 对图片、HTML、公式等复杂结构支持有限

  • Document对象只保留了文本和元数据,没有数据类型

    from llama_index.readers.file.unstructured import UnstructuredReader
    from pathlib import Path

    reader = UnstructuredReader()
    documents = reader.load_data(file=Path("甬兴证券-AI行业点评报告:海外科技巨头持续发力AI,龙头公司中报业绩亮眼.pdf"))

    print("打印列表长度:" + str(len(documents)))
    print("==================================")
    print("打印解析的文本内容:" + documents[0].text[:100])
    print("==================================")
    print("打印元数据信息:" + str(documents[0].metadata))

独立使用unstructured.partition + 自定义逻辑

推荐场景:生产级RAG应用/多格式数据管线/高可控性需求

优点:

  • 可自由控制解析策略(OCR、chunk、去噪、正则)

  • 可在加载前后插入清洗逻辑(例如表格转结构化文本)

  • 易于扩展(批量处理/并行任务/自定义metadata)

    from unstructured.partition.auto import partition

    使用LlamaIndex的Document对象,将解析后的元素转换为Document对象

    from llama_index.core import Document

    使用partition函数自动检测文件类型并解析

    elements = partition(
    filename="甬兴证券-AI行业点评报告:海外科技巨头持续发力AI,龙头公司中报业绩亮眼.pdf",
    strategy="hi_res",
    split_pdf_page=True,
    infer_table_structure=True,
    languages=["eng","chi_sim"])

    将解析后的元素转换为Document对象

    docs = [
    Document(text=e.text,
    metadata={"source":"甬兴证券-AI行业点评报告:海外科技巨头持续发力AI,龙头公司中报业绩亮眼.pdf",
    "type": e.category})
    for e in elements]

最佳混合方案(推荐实践)

复制代码
from llama_index.readers.file.unstructured import UnstructuredReader
from unstructured.partition.auto import partition
from llama_index.core import Document
from pathlib import Path

def smart_load(file_path):
    """
    智能文档加载器:根据文件类型选择最佳解析策略

    Args:
        file_path: 文件路径

    Returns:
        解析后的Document对象列表
    """
    file_path = Path(file_path)
    file_ext = file_path.suffix.lower()

    # 定义复杂文件类型(需要高精度解析)
    complex_types = {
        '.pdf',     # PDF文档(可能包含表格、图像、复杂布局)
        '.png', '.jpg', '.jpeg', '.gif', '.bmp', '.tiff',  # 图片文件(需要OCR)
        '.docx', '.doc',  # Word文档(可能包含复杂格式)
        '.pptx', '.ppt',  # PowerPoint(复杂布局)
        '.xlsx', '.xls'   # Excel(表格结构)
    }

    # 简单文件类型(可以用Reader直接处理)
    simple_types = {
        '.txt', '.md', '.csv', '.html', '.xml', '.json'
    }

    if file_ext in complex_types:
        # 复杂文件使用底层解析,获得更好的结构识别
        print(f"检测到复杂文件类型 {file_ext},使用partition高精度解析")
        try:
            elements = partition(
                filename=str(file_path),
                # 使用hi_res模式进行高精度解析
                strategy="hi_res",
                # 支持中文、英文
                languages=["eng", "chi_sim"],
                # 推断表格结构
                infer_table_structure=True
            )
            # 将解析元素转换为Document对象
            return [Document(text=e.text, metadata={
                "source": str(file_path),
                "element_type": type(e).__name__,
                "file_type": file_ext
            }) for e in elements if e.text.strip()]  # 过滤空文本
        except Exception as e:
            print(f"高精度解析失败,回退到Reader: {e}")
            # 回退到Reader
            reader = UnstructuredReader()
            return reader.load_data(file=file_path)

    else:
        # 简单文件或未知类型优先使用Reader
        print(f"检测到简单文件类型 {file_ext},使用Reader解析")
        try:
            # 直接使用Reader进行简单解析
            reader = UnstructuredReader()
            # 加载解析后的文档,返回 Document 对象列表
            docs = reader.load_data(file=file_path)
            return docs
        except Exception as e:
            print(f"Reader解析失败,回退到partition: {e}")
            # 回退到底层解析
            elements = partition(filename=str(file_path), strategy="auto")
            return [Document(text=e.text, metadata={"source": str(file_path)}) for e in elements]

这种做法在实际RAG框架开发中非常常见:

  • 90%文件走LlamaIndex内置Reader
  • 特殊格式(扫描件、混合HTML、表格)回退到底层unstructured

总结一句话

  • LlamaIndex的UnstructuredReader = 快速封装,适合上层应用
  • unstructured.partition = 底层引擎,适合复杂数据管线
  • 在原型阶段用 UnstructuredReader,在生产阶段直接集成 unstructured

|-------------------|--------------------------|----------------|
| 场景 | 推荐方式 | 理由 |
| 初学者/快速Demo | `UnstructuredReader()` | 封装好,一行搞定 |
| RAG系统 | `UnstructuredReader()` | 输出直接是Document |
| 生产系统/多文件管线 | `partition()` | 可完全控制OCR/分块/过滤 |
| 精细元数据追踪(页码/坐标/字体) | `partition()` | 元数据更丰富 |

特定领域应用

金融领域:财报解析与问答

  • 重点:表格提取精度
  • 推荐工具:DoclingAI(表格提取精度98%+)
  • 策略:使用hi_res策略进行高精度表格解析

医疗领域:文献分析与检索

  • 重点:公式识别与专业术语处理
  • 推荐工具:MinerU(数学公式识别精准)
  • 策略:结合OCR与专业词典

法律领域:合同解析与条款提取

  • 重点:文档结构还原与条款定位
  • 策略:利用标题元素构建文档层次结构
  • 元数据:页码、坐标信息用于精确定位

教育领域:教材内容分析与问答

  • 重点:多模态内容处理(文字、图片、公式)
  • 推荐工具:Marker(代码/公式支持优秀)
  • 策略:使用vlm策略处理复杂版面
相关推荐
冬奇Lab几秒前
Skill 系列(06):Skill 工程化与治理——路由准确率 38%、压缩节省 76%
人工智能·开源·agent
IT_陈寒2 小时前
Vue这个坑我跳了两次,原来问题出在这
前端·人工智能·后端
新新技术迷2 小时前
Node给AI接口做SSE代理与鉴权
人工智能
redreamSo3 小时前
大模型是不是到顶了?瓶颈到底在哪
人工智能·openai
Oo9203 小时前
Tool Use 背后的技术逻辑
人工智能
姗姗来迟了3 小时前
Vue3封装AI流式对话组件踩坑实录
人工智能
码上天下4 小时前
用Pinia管理AI多会话状态
人工智能
用户054324329705 小时前
Next.js接大模型流式SSE实操踩坑
人工智能
Assby5 小时前
从 Function Calling 到 MCP:理解 Agent 工具调用的底层通信机制
人工智能·后端
小星AI5 小时前
Claude Code 从入门到精通,一步到位
人工智能