第十五节:LlamaIndex框架使用2(文件解析器、分割器)

一.  基础解析器:简单文件与 Markdown

1. SimpleFileNodeParser —— 通用文本切分

    适用场景:纯文本文件(如 .txt)的基础切分,按段落和空行自动分割。

from llama_index.core.node_parser import SimpleFileNodeParser
from llama_index.readers.file import FlatReader
from pathlib import Path

# 读取文本文件
md_docs = FlatReader().load_data(Path('data/小说.txt'))

# 创建解析器并切分
parser = SimpleFileNodeParser()
nodes = parser.get_nodes_from_documents(md_docs)

print(nodes)

核心特点:

  • 按文件内容结构(段落、空行)自动切分
  • 无需配置,开箱即用
  • 适合小说、文章等纯文本场景

2. MarkdownNodeParser —— Markdown 结构切分

    适用场景:Markdown 文档,按标题层级(#、##、###)拆分章节。

from llama_index.core.node_parser import MarkdownNodeParser
from llama_index.readers.file import FlatReader
from pathlib import Path

# 读取 Markdown 文件
md_docs = FlatReader().load_data(Path('data/test.md'))

# 创建解析器,自动识别标题层级
parser = MarkdownNodeParser()
nodes = parser.get_nodes_from_documents(md_docs)

print(nodes)

核心特点:

  • 智能识别 Markdown 标题层级
  • 每个章节成为独立节点,保持逻辑完整性
  • 适合技术文档、知识库等结构化内容

 

二.  结构化解释器

1. MarkdownElementNodeParser —— Markdown 元素智能解析

    适用场景:包含表格、代码块等复杂结构的 Markdown 文档,需要用 LLM 自动生成元素摘要。

代码分享:

from llama_index.core.node_parser import MarkdownElementNodeParser
from llama_index.readers.file import FlatReader
from llama_index.llms.dashscope import DashScope
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
from llama_index.core import Settings, VectorStoreIndex
from llama_index.core.query_engine import RetrieverQueryEngine
from pathlib import Path

# 配置全局 LLM 与 Embedding
Settings.llm = DashScope(model="your-model", api_key="your-api-key")
Settings.embed_model = HuggingFaceEmbedding(model_name="bge-large-zh-v1.5")

# 自定义摘要提示词
MY_CUSTOM_SUMMARY_QUERY = (
    "你是一个技术文档解析助手。请提取以下 Markdown 表格或内容的极简摘要。"
    "要求:1. 严禁啰嗦;2. 必须包含表格中的关键实体词;"
    "3. 如果是代码相关内容,请保留具体的命令名称。请用中文摘要"
)

# 创建解析器
parser = MarkdownElementNodeParser(
    include_prev_next_rel=True,  # 保留前后节点关联
    summary_query_str=MY_CUSTOM_SUMMARY_QUERY,
)
nodes = parser.get_nodes_from_documents(md_docs)

# 构建索引与查询引擎
index = VectorStoreIndex(nodes)
query_engine = index.as_query_engine(similarity_top_k=5)

# 测试查询
response = query_engine.query("张三多少岁?")
print(response)

核心特点:

  • 识别表格、代码块、列表等元素
  • 利用 LLM 为每个元素生成摘要
  • 保留元素间的上下文关联
  • 适合复杂技术文档的 RAG 场景

 

2 CodeSplitter —— 代码专用分割器

适用场景:源代码文件的智能切分,按语法结构保持代码完整性。

代码分享:

from llama_index.core.node_parser import CodeSplitter
from llama_index.core import SimpleDirectoryReader

# 读取代码文件
documents = SimpleDirectoryReader(input_files=['./example.py']).load_data()

# 初始化代码分割器
splitter = CodeSplitter(
    language="python",          # 支持多种编程语言
    chunk_lines=50,             # 每块行数
    chunk_lines_overlap=10,     # 重叠行数(保持上下文)
    max_chars=300,              # 最大字符数
)

# 切分文档
nodes = splitter.get_nodes_from_documents(documents)
for node in nodes:
    print(f"Type: {node.metadata}\nText: {node.text}\n{'='*50}")

核心特点:

  • 基于 Tree-sitter 的语法感知切分
  • 支持 Python、Java、JavaScript 等主流语言
  • 保持函数、类等代码结构的完整性
  • 通过重叠机制避免代码逻辑断裂

 

3. SentenceSplitter —— 句子级精细切分

适用场景:需要精确控制节点大小,同时保持语义完整性的文本分割。

from llama_index.core import SimpleDirectoryReader
from llama_index.core.node_parser import SentenceSplitter

# 初始化分割器
splitter = SentenceSplitter(
    chunk_size=512,              # 每个节点最大字符数
    chunk_overlap=50,            # 相邻节点重叠字符数
    paragraph_separator="\r\n\r\n",  # 第一优先级:段落分割
    secondary_chunking_regex="[^,。;!?]+[,。;!?]?",  # 第二优先级:中文句子
)

# 读取并切分文档
documents = SimpleDirectoryReader(input_files=['data/小说.txt']).load_data()
nodes = splitter.get_nodes_from_documents(documents)

# 打印结果
for node in nodes:
    print(node.text, "---" * 10)

核心特点:

  • 三级分割策略(段落 → 句子 → 硬截断)
  • 支持中英文混合文本
  • 精细控制每个节点的 Token 数量
  • 通过重叠保持上下文连贯性

 

 

 

三. 语义增强解释器

1. SentenceWindowNodeParser —— 句子窗口解析器

适用场景:RAG 检索时需要保留句子上下文,提升回答准确性。

核心原理:每个 Node 只保存单个句子(用于索引),但在 metadata 中附带其相邻句子的上下文窗口。检索时匹配单个句子,但交给 LLM 时能看到更完整的上下文。

from llama_index.core.node_parser import SentenceWindowNodeParser
from llama_index.core import Document

# 创建示例文档
document = Document(text="这是第一个句子. 这是第二个句子. 这是第三个句子. 这是第四个句子. ")

# 创建句子窗口解析器
node_parser = SentenceWindowNodeParser(
    window_size=1,                    # 前后各保留 N 个句子
    window_metadata_key="window",     # 上下文窗口的 metadata key
    original_text_metadata_key="original_text",  # 原始句子的 metadata key
)

# 切分文档
nodes = node_parser.get_nodes_from_documents([document])

# 查看每个节点的文本和上下文
for node in nodes:
    print(f"文本: {node.text}")
    print(f"上下文: {node.metadata['window']}")
    print()

核心特点:

  • 索引粒度细(单个句子),检索精度高
  • 推理时上下文完整,避免信息丢失
  • 通过 window_size 灵活控制上下文范围
  • 适合需要精确匹配的问答场景

 

2. HierarchicalNodeParser —— 层次节点解析器

适用场景:长文档的多级切分,支持自动合并相关节点。

核心原理:将文档切分为多层级结构(如 512-token 的粗粒度块包含多个 300-token 的细粒度块),检索时先找到相关的细粒度节点,再自动合并其父节点,确保上下文完整性。

from llama_index.core.node_parser import HierarchicalNodeParser, get_leaf_nodes
from llama_index.core.retrievers import AutoMergingRetriever
from llama_index.core import SimpleDirectoryReader, StorageContext, VectorStoreIndex, Settings
from llama_index.embeddings.huggingface import HuggingFaceEmbedding

# 配置 Embedding
Settings.embed_model = HuggingFaceEmbedding(model_name="bge-large-zh-v1.5")

# 读取数据
documents = SimpleDirectoryReader(input_files=['data/公司规章制度.txt']).load_data()

# 创建层次解析器(chunk_sizes 从粗到细)
node_parser = HierarchicalNodeParser.from_defaults(chunk_sizes=[512, 300], chunk_overlap=70)
nodes = node_parser.get_nodes_from_documents(documents)

# 获取叶节点(最细粒度)
leaf_nodes = get_leaf_nodes(nodes)

# 构建存储上下文
from llama_index.core.storage.docstore import SimpleDocumentStore
docstore = SimpleDocumentStore()
docstore.add_documents(nodes)
storage_context = StorageContext.from_defaults(docstore=docstore)

# 构建向量索引(仅对叶节点)
base_index = VectorStoreIndex(leaf_nodes, storage_context=storage_context)
base_retriever = base_index.as_retriever(similarity_top_k=6)

# 构建自动合并检索器
retriever = AutoMergingRetriever(
    vector_retriever=base_retriever,
    storage_context=storage_context,
    simple_ratio_thresh=0.5,  # 合并阈值
    verbose=True,
)

# 查询
query_str = "公司形象有哪几条?"
nodes_returned = retriever.retrieve(query_str)
for node in nodes_returned:
    print("---")
    print(node.get_content())

核心特点:

  • 多级粒度切分,兼顾检索精度与上下文完整性
  • AutoMergingRetriever 自动合并相关父节点
  • 适合长文档(如规章制度、合同)的问答场景
  • 通过阈值控制合并策略,灵活调整检索效果

解析器选型对照表

解析器名称 核心功能 适用场景 关键依赖
SimpleFileNodeParser 按段落/空行切分 纯文本文件、小说、文章 无
MarkdownNodeParser 按标题层级切分 Markdown 文档、技术文档 无
MarkdownElementNodeParser 元素识别 + LLM 摘要 复杂 Markdown(含表格、代码) LLM
CodeSplitter 语法感知代码切分 源代码文件 tree_sitter
SentenceSplitter 句子级精细切分 需要精确控制节点大小 无
SentenceWindowNodeParser 句子上下文窗口 需要保留上下文的问答 无
HierarchicalNodeParser 层次切分 + 自动合并 长文档、合同、规章制度 Embedding

总结与建议

选择合适的节点解析器是构建高效 RAG 系统的第一步,以下是选型建议:

  1. 简单文本 → SimpleFileNodeParser 或 SentenceSplitter
  2. 技术文档 → MarkdownNodeParser 或 MarkdownElementNodeParser
  3. 代码仓库 → CodeSplitter
  4. 需要上下文 → SentenceWindowNodeParser
  5. 长文档 → HierarchicalNodeParser + AutoMergingRetriever

最佳实践:

  • 先从简单解析器开始,观察检索效果
  • 根据实际场景调整 chunk_size 和 overlap 参数
  • 对于复杂文档,考虑组合使用多种解析器
  • 在生产环境中,建议对切分结果进行质量评估

 

 

 

 

 

!

  • 作       者 : Yaopengfei(姚鹏飞)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 声     明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
  • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 
posted @ 2026-06-18 09:26  Yaopengfei  阅读(49)  评论(0)    收藏  举报