Skip to content

节点解析模块#

基于文件的节点解析器#

有几种基于文件的节点解析器,将根据被解析内容的类型(JSON、Markdown 等)创建节点。

最简单的流程是将 FlatFileReaderSimpleFileNodeParser 结合起来,自动为每种内容类型使用最佳的节点解析器。然后,您可能希望将基于文件的节点解析器与基于文本的节点解析器链接起来,以考虑文本的实际长度。

SimpleFileNodeParser#

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("./test.md"))

parser = SimpleFileNodeParser()
md_nodes = parser.get_nodes_from_documents(md_docs)

HTMLNodeParser#

该节点解析器使用 beautifulsoup 解析原始 HTML。

默认情况下,它会解析一组选定的 HTML 标签,但您可以覆盖这一设置。

默认标签包括:["p", "h1", "h2", "h3", "h4", "h5", "h6", "li", "b", "i", "u", "section"]

from llama_index.core.node_parser import HTMLNodeParser

parser = HTMLNodeParser(tags=["p", "h1"])  # 可选的标签列表
nodes = parser.get_nodes_from_documents(html_docs)

JSONNodeParser#

JSONNodeParser 用于解析原始 JSON。

from llama_index.core.node_parser import JSONNodeParser

parser = JSONNodeParser()

nodes = parser.get_nodes_from_documents(json_docs)

MarkdownNodeParser#

MarkdownNodeParser 用于解析原始 Markdown 文本。

from llama_index.core.node_parser import MarkdownNodeParser

parser = MarkdownNodeParser()

nodes = parser.get_nodes_from_documents(markdown_docs)

文本分割器#

CodeSplitter#

根据编写语言拆分原始代码文本。

查看完整的支持语言列表这里

from llama_index.core.node_parser import CodeSplitter

splitter = CodeSplitter(
    language="python",
    chunk_lines=40,  # 每个块的行数
    chunk_lines_overlap=15,  # 块之间的行重叠
    max_chars=1500,  # 每个块的最大字符数
)
nodes = splitter.get_nodes_from_documents(documents)

LangchainNodeParser#

您还可以使用节点解析器包装 langchain 中的任何现有文本分割器。

from langchain.text_splitter import RecursiveCharacterTextSplitter
from llama_index.core.node_parser import LangchainNodeParser

parser = LangchainNodeParser(RecursiveCharacterTextSplitter())
nodes = parser.get_nodes_from_documents(documents)

SentenceSplitter#

SentenceSplitter 尝试在尊重句子边界的同时拆分文本。

from llama_index.core.node_parser import SentenceSplitter

splitter = SentenceSplitter(
    chunk_size=1024,
    chunk_overlap=20,
)
nodes = splitter.get_nodes_from_documents(documents)

SentenceWindowNodeParser#

SentenceWindowNodeParser 类似于其他节点解析器,不同之处在于它将所有文档拆分为单独的句子。生成的节点还包含每个节点周围句子的“窗口”在元数据中。请注意,此元数据对于 LLM 或嵌入模型不可见。

这对于生成具有非常特定范围的嵌入最为有用。然后,结合 MetadataReplacementNodePostProcessor,您可以在将节点发送到 LLM 之前用周围上下文替换句子。

以下是使用默认设置设置解析器的示例。在实践中,您通常只需要调整句子窗口的大小。

import nltk
from llama_index.core.node_parser import SentenceWindowNodeParser

node_parser = SentenceWindowNodeParser.from_defaults(
    # 捕获两侧句子的数量
    window_size=3,
    # 包含周围句子的窗口的元数据键
    window_metadata_key="window",
    # 包含原始句子的元数据键
    original_text_metadata_key="original_sentence",
)

可以在此处与 MetadataReplacementNodePostProcessor 结合使用的示例中找到完整示例。

SemanticSplitterNodeParser#

“语义分块”是格雷格·卡姆拉特在他的视频教程中提出的一个新概念,该视频讲解了 5 级嵌入分块:https://youtu.be/8OJC21T2SL4?t=1933。

与使用固定块大小分块文本不同,语义分割器会自适应地选择句子之间的断点,使用嵌入相似性。这确保了“块”包含语义相关的句子。

我们将其改编为 LlamaIndex 模块。

快来查看我们的笔记本吧!

注意事项:

  • 正则表达式主要适用于英文句子
  • 您可能需要调整断点百分位阈值。
    from llama_index.core.node_parser import SemanticSplitterNodeParser
    from llama_index.embeddings.openai import OpenAIEmbedding
    
    embed_model = OpenAIEmbedding()
    splitter = SemanticSplitterNodeParser(
        buffer_size=1, breakpoint_percentile_threshold=95, embed_model=embed_model
    )
    
    在我们的使用SemanticSplitterNodeParser的指南中可以找到一个完整的示例。

TokenTextSplitter#

TokenTextSplitter尝试根据原始标记计数来将文本分割为一致的块大小。

from llama_index.core.node_parser import TokenTextSplitter

splitter = TokenTextSplitter(
    chunk_size=1024,
    chunk_overlap=20,
    separator=" ",
)
nodes = splitter.get_nodes_from_documents(documents)

基于关系的节点解析器#

HierarchicalNodeParser#

此节点解析器将节点分块为分层节点。这意味着单个输入将被分块为多个不同大小的层次结构,每个节点都包含对其父节点的引用。

当与AutoMergingRetriever结合使用时,这使我们能够在检索到大多数子节点时自动用它们的父节点替换检索到的节点。这个过程为LLM提供了更完整的上下文来进行响应合成。

from llama_index.core.node_parser import HierarchicalNodeParser

node_parser = HierarchicalNodeParser.from_defaults(
    chunk_sizes=[2048, 512, 128]
)

这里与AutoMergingRetriever结合使用的完整示例中可以找到。