LlamaIndex 组件 - Loading

文章目录

    • 一、概览
      • 加载
      • Transformations
      • 将所有内容放在一起
      • 抽象
    • 二、文档/节点概览
      • 1、概念
      • 2、使用模式
          • 文件
          • 节点
    • 三、定义和定制文档
      • 1、定义文档
      • 2、自定义文档
        • 2.1 元数据
        • 2.2 自定义id
        • 2.3 高级 - 元数据定制
          • 1)自定义LLM元数据文本
          • 2)自定义嵌入元数据文本
          • 3)自定义元数据格式
        • 2.4 概括
        • 2.5 高级 - 自动元数据提取
    • 四、使用节点
        • 自定义ID
    • 五、元数据提取使用模式
      • 资源
    • 六、简单目录阅读器
      • 1、支持的文件类型
      • 2、用法
        • 2.1 从子目录读取
        • 2.2 加载文件时对其进行迭代
        • 2.3 限制加载的文件
        • 2.4 指定文件编码
        • 2.5 提取元数据
        • 2.6 扩展到其他文件类型
        • 2.7 对外部文件系统的支持
    • 七、数据连接器 (LlamaHub) 概览
      • 1、概念
      • 2、LlamaHub
      • 3、使用模式
      • 4、模块
    • 八、LlamaParse
      • 1、入门
      • 2、与使用`SimpleDirectoryReader`
      • 3、例子
      • 4、服务条款 & 模块指南
    • 九、节点解析器使用模式
      • 1、入门使用
        • 1.1 独立使用
        • 1.2 转换用法
        • 1.3 索引使用
    • 十、节点解析器模块
      • 1、基于文件的节点解析器
        • 1.1 简单文件节点解析器
        • 1.2 HTML节点解析器
        • 1.3 JSONNode解析器
        • 1.4 MarkdownNode解析器
      • 2、文本分割器
        • 2.1 代码分割器
        • 2.2 Langchain节点解析器
        • 2.3 分句器
        • 2.4 句子窗口节点解析器
        • 2.5 语义分割器节点解析器
        • 2.6 令牌文本分割器
      • 3、基于关系的节点解析器
        • 层次节点解析器
    • 十一、Ingestion Pipeline
      • 1、使用模式
      • 2、连接到矢量数据库
      • 3、计算管道中的嵌入
      • 4、缓存
        • 本地缓存管理
        • 远程缓存管理
      • 5、异步支持
      • 6、文件管理
      • 7、并行处理
      • 8、模块
    • 十二、转换
      • 1、使用模式
      • 2、与索引结合
      • 3、自定义转换


本文翻译整理自:https://docs.llamaindex.ai/en/stable/module_guides/loading/


一、概览

LlamaIndex 中数据摄取的关键是加载和转换。
加载文档后,您可以通过转换和输出节点来处理它们。

一旦您在“理解”部分了解了加载数据的基础知识,您就可以继续阅读以了解更多信息:


加载

  • SimpleDirectoryReader,我们的内置加载器,用于从本地目录加载各种文件类型
  • LlamaParse,LlamaIndex 的 PDF 解析官方工具,作为托管 API 提供。
  • LlamaHub,我们的数百个数据加载库的注册表,用于从任何来源提取数据

Transformations

这包括拆分文本等常见操作。

  • 节点解析器使用模式,向您展示如何使用我们的节点解析器
  • 节点解析器模块,显示我们的文本分割器(句子、标记、HTML、JSON)和其他解析器模块。

将所有内容放在一起

  • 摄取管道允许您设置可重复的、缓存优化的过程来加载数据。

抽象

  • 文档和节点对象以及如何针对更高级的用例自定义它们

二、文档/节点概览


1、概念

Document 和 Node 对象是 LlamaIndex 中的核心抽象。

文档是任何数据源的通用容器 - 例如,PDF、API 输出或从数据库检索的数据**。
**它们可以手动构建,也可以通过我们的数据加载器自动创建。
默认情况下,文档存储文本以及一些其他属性。
下面列出了其中一些。

  • metadata- 可附加到文本的注释字典。
  • relationships- 包含与其他文档/节点的关系的字典。

注意:我们提供了允许文档存储图像的测试版支持,并正在积极致力于改进其多模式功能。


节点表示源文档的一个“块”,无论是文本块、图像还是其他块。
与文档类似,它们包含元数据以及与其他节点的关系信息。

节点是 LlamaIndex 中的一等公民。
您可以选择直接定义节点及其所有属性。
您还可以选择通过我们的NodeParser类将源文档“解析”为节点。
默认情况下,从文档派生的每个节点都将从该文档继承相同的元数据(例如,文档中归档的“file_name”被传播到每个节点)。


2、使用模式

以下是一些开始使用文档和节点的简单片段。


文件
from llama_index.core import Document, VectorStoreIndex

text_list = [text1, text2, ...]
documents = [Document(text=t) for t in text_list]

# build index
index = VectorStoreIndex.from_documents(documents)

节点
from llama_index.core.node_parser import SentenceSplitter

# load documents
...

# parse nodes
parser = SentenceSplitter()
nodes = parser.get_nodes_from_documents(documents)

# build index
index = VectorStoreIndex(nodes)

三、定义和定制文档


1、定义文档

文档可以通过数据加载器自动创建,也可以手动构建。

默认情况下,我们所有的数据加载器(包括 LlamaHub 上提供的数据加载器)都Document通过该函数返回对象load_data

from llama_index.core import SimpleDirectoryReader

documents = SimpleDirectoryReader("./data").load_data()

您还可以选择手动构建文档。 LlamaIndex 公开该Document结构。

from llama_index.core import Document

text_list = [text1, text2, ...]
documents = [Document(text=t) for t in text_list]

为了加快原型设计和开发速度,您还可以使用一些 默认文本快速创建文档:

document = Document.example()

2、自定义文档

本节介绍自定义Document对象的各种方法。
由于该Document对象是我们对象的子类TextNode,因此所有这些设置和详细信息TextNode也适用于该对象类。


2.1 元数据

文档还提供了包含有用元数据的机会。
使用metadata每个文档上的字典,可以包含附加信息来帮助通知响应并跟踪查询响应的来源。
此信息可以是任何内容,例如文件名或类别。
如果您要与矢量数据库集成,请记住,某些矢量数据库要求键必须是字符串,并且值必须是平面( 、strfloatint

每个文档的字典中设置的任何信息metadata都将显示在metadata从该文档创建的每个源节点的 中。
此外,此信息包含在节点中,使索引能够在查询和响应中利用它。
默认情况下,元数据会注入到嵌入和 LLM 模型调用的文本中。


有几种方法可以设置此词典:

1、在文档构造函数中:

document = Document(
    text="text",
    metadata={"filename": "<doc_file_name>", "category": "<category>"},
)

2、文档创建后:

document.metadata = {"filename": "<doc_file_name>"}

3、SimpleDirectoryReader使用和挂钩自动设置文件名file_metadata
这将自动在每个文档上运行挂钩来设置metadata字段:

from llama_index.core import SimpleDirectoryReader

filename_fn = lambda filename: {"file_name": filename}

# automatically sets the metadata of each document according to filename_fn
documents = SimpleDirectoryReader(
    "./data", file_metadata=filename_fn
).load_data()

2.2 自定义id

正如文档管理部分中详细介绍的,它 doc_id 用于实现索引中文档的高效刷新。
使用 时SimpleDirectoryReader,您可以自动将 doc 设置doc_id为每个文档的完整路径:

from llama_index.core import SimpleDirectoryReader

documents = SimpleDirectoryReader("./data", filename_as_id=True).load_data()
print([x.doc_id for x in documents])

您也可以直接设置任何Document doc_id

document.doc_id = "My new document id!"

注意:ID 也可以通过Document 对象上的node_idid_属性来设置,类似于TextNode对象。


2.3 高级 - 元数据定制

上面提到的一个关键细节是,默认情况下,您设置的任何元数据都包含在嵌入生成和 LLM 中。


1)自定义LLM元数据文本

通常,文档可能有许多元数据键,但您可能不希望所有这些键 在响应合成期间 对 LLM 可见。
在上面的例子中,我们可能不希望法学硕士阅读file_name我们的文档。
但是,其中file_name可能包含有助于生成更好嵌入的信息。
这样做的一个关键优势是在不改变法学硕士最终阅读内容的情况下偏向检索的嵌入。

我们可以像这样排除它:

document.excluded_llm_metadata_keys = ["file_name"]

get_content()然后,我们可以使用该函数并指定来测试 LLM 实际上最终会读取什么内容MetadataMode.LLM

from llama_index.core.schema import MetadataMode

print(document.get_content(metadata_mode=MetadataMode.LLM))

2)自定义嵌入元数据文本

与定制LLM可见的元数据类似,我们也可以定制嵌入可见的元数据。
在这种情况下,您可以专门排除嵌入模型可见的元数据,以防您不希望特定文本使嵌入产生偏差。

document.excluded_embed_metadata_keys = ["file_name"]

get_content()然后,我们可以使用该函数并指定来测试嵌入模型最终实际读取的内容MetadataMode.EMBED

from llama_index.core.schema import MetadataMode

print(document.get_content(metadata_mode=MetadataMode.EMBED))

3)自定义元数据格式

正如您现在所知,当发送到 LLM 或嵌入模型时,元数据会被注入到每个文档/节点的实际文本中。
默认情况下,此元数据的格式由三个属性控制:

Document.metadata_seperator-> 默认 ="\n"

连接元数据的所有键/值字段时,此字段控制每个键/值对之间的分隔符。


Document.metadata_template-> 默认 ="{key}: {value}"

此属性控制元数据中每个键/值对的格式。
这两个变量keyvalue字符串键是必需的。


Document.text_template-> 默认 ={metadata_str}\n\n{content}

metadata_seperator使用和将元数据转换为字符串后metadata_template,此模板将控制元数据与文档/节点的文本内容连接时的外观。
和字符串metadatacontent是必需的。


2.4 概括

了解了这一切后,让我们使用所有这些功能创建一个简短的示例:

from llama_index.core import Document
from llama_index.core.schema import MetadataMode

document = Document(
    text="This is a super-customized document",
    metadata={
        "file_name": "super_secret_document.txt",
        "category": "finance",
        "author": "LlamaIndex",
    },
    excluded_llm_metadata_keys=["file_name"],
    metadata_seperator="::",
    metadata_template="{key}=>{value}",
    text_template="Metadata: {metadata_str}\n-----\nContent: {content}",
)

print(
    "The LLM sees this: \n",
    document.get_content(metadata_mode=MetadataMode.LLM),
)
print(
    "The Embedding model sees this: \n",
    document.get_content(metadata_mode=MetadataMode.EMBED),
)

2.5 高级 - 自动元数据提取

我们有使用法学硕士本身来执行元数据提取的初始示例。
***

四、使用节点

节点代表源文档的“块”,无论是文本块、图像还是更多。
它们还包含元数据以及与其他节点和索引结构的关系信息。

节点是 LlamaIndex 中的一等公民。
您可以选择直接定义节点及其所有属性。
您还可以选择通过我们的NodeParser类将源文档“解析”为节点。


例如,你可以这样做

from llama_index.core.node_parser import SentenceSplitter

parser = SentenceSplitter()

nodes = parser.get_nodes_from_documents(documents)

您还可以选择手动构造 Node 对象并跳过第一部分。例如:

from llama_index.core.schema import TextNode, NodeRelationship, RelatedNodeInfo

node1 = TextNode(text="<text_chunk>", id_="<node_id>")
node2 = TextNode(text="<text_chunk>", id_="<node_id>")
# set relationships
node1.relationships[NodeRelationship.NEXT] = RelatedNodeInfo(
    node_id=node2.node_id
)
node2.relationships[NodeRelationship.PREVIOUS] = RelatedNodeInfo(
    node_id=node1.node_id
)
nodes = [node1, node2]

如果需要,该类RelatedNodeInfo还可以存储其他内容:metadata

node2.relationships[NodeRelationship.PARENT] = RelatedNodeInfo(
    node_id=node1.node_id, metadata={"key": "val"}
)

自定义ID

每个节点都有一个node_id属性,如果没有手动指定,该属性会自动生成。
该 ID 可用于多种目的;这包括能够更新存储中的节点、能够定义节点之间的关系(通过IndexNode)等等。

您还可以直接获取和设置node_idany TextNode

print(node.node_id)
node.node_id = "My new node_id!"

五、元数据提取使用模式

您可以使用法学硕士通过我们的模块自动提取元数据Metadata Extractor

我们的元数据提取器模块包括以下“特征提取器”:

  • SummaryExtractor- 自动提取一组节点的摘要
  • QuestionsAnsweredExtractor- 提取每个节点可以回答的一组问题
  • TitleExtractor- 提取每个节点上下文的标题
  • EntityExtractor- 提取每个节点内容中提到的实体(即地名、人物、事物的名称)

然后您可以Metadata Extractor使用我们的节点解析器链接 s:

from llama_index.core.extractors import (
    TitleExtractor,
    QuestionsAnsweredExtractor,
)
from llama_index.core.node_parser import TokenTextSplitter

text_splitter = TokenTextSplitter(
    separator=" ", chunk_size=512, chunk_overlap=128
)
title_extractor = TitleExtractor(nodes=5)
qa_extractor = QuestionsAnsweredExtractor(questions=3)

# assume documents are defined -> extract nodes
from llama_index.core.ingestion import IngestionPipeline

pipeline = IngestionPipeline(
    transformations=[text_splitter, title_extractor, qa_extractor]
)

nodes = pipeline.run(
    documents=documents,
    in_place=True,
    show_progress=True,
)

或插入索引:

from llama_index.core import VectorStoreIndex

index = VectorStoreIndex.from_documents(
    documents, transformations=[text_splitter, title_extractor, qa_extractor]
)

资源

  • SEC Documents Metadata Extraction
  • LLM Survey Extraction
  • Entity Extraction
  • Marvin Metadata Extraction
  • Pydantic Metadata Extraction

六、简单目录阅读器

SimpleDirectoryReader是将本地文件中的数据加载到 LlamaIndex 的最简单方法。
对于生产用例,您更有可能希望使用LlamaHub上提供的众多 Reader 之一,但这SimpleDirectoryReader是一个很好的入门方式。


1、支持的文件类型

默认情况下,SimpleDirectoryReader将尝试读取它找到的任何文件,并将它们全部视为文本。
除了纯文本之外,它还明确支持以下文件类型,这些文件类型是根据文件扩展名自动检测的:

  • .csv - 逗号分隔值
  • .docx - Microsoft Word
  • .epub - EPUB 电子书格式
  • .hwp - 韩文文字处理器
  • .ipynb - Jupyter 笔记本
  • .jpeg、.jpg - JPEG 图像
  • .mbox - MBOX 电子邮件存档
  • .md-Markdown
  • .mp3、.mp4 - 音频和视频
  • .pdf - 便携式文档格式
  • .png - 便携式网络图形
  • .ppt、.pptm、.pptx - Microsoft PowerPoint

您可能希望在这里找到的一种文件类型是 JSON;为此,我们建议您使用我们的JSON Loader。


2、用法

最基本的用法是传递 an input_dir,它将加载该目录中所有支持的文件:

from llama_index.core import SimpleDirectoryReader

reader = SimpleDirectoryReader(input_dir="path/to/directory")
documents = reader.load_data()

如果从目录加载多个文件,也可以通过并行处理加载文档。
请注意,在 Windows 和 Linux/MacOS 计算机上使用时存在差异multiprocessing,整个文档对此进行了解释multiprocessing(例如,请参阅此处)。
最终,Windows 用户可能会看到较少的性能提升或没有性能提升,而 Linux/MacOS 用户在加载完全相同的文件集时会看到这些提升。

...
documents = reader.load_data(num_workers=4)

2.1 从子目录读取

默认情况下,SimpleDirectoryReader只会读取目录顶层的文件。
要从子目录中读取,请设置recursive=True

SimpleDirectoryReader(input_dir="path/to/directory", recursive=True)

2.2 加载文件时对其进行迭代

您还可以使用该iter_data()方法在文件加载时对其进行迭代和处理

reader = SimpleDirectoryReader(input_dir="path/to/directory", recursive=True)
all_docs = []
for docs in reader.iter_data():
    # <do something with the documents per file>
    all_docs.extend(docs)

2.3 限制加载的文件

您可以传递文件路径列表,而不是传递所有文件:

SimpleDirectoryReader(input_files=["path/to/file1", "path/to/file2"])

或者您可以使用以下命令传递要排除的文件路径列表exclude

SimpleDirectoryReader(
    input_dir="path/to/directory", exclude=["path/to/file1", "path/to/file2"]
)

您还可以设置required_exts文件扩展名列表以仅加载具有这些扩展名的文件:

SimpleDirectoryReader(
    input_dir="path/to/directory", required_exts=[".pdf", ".docx"]
)

您可以设置要加载的最大文件数num_files_limit

SimpleDirectoryReader(input_dir="path/to/directory", num_files_limit=100)

2.4 指定文件编码

SimpleDirectoryReader期望对文件进行utf-8编码,但您可以使用参数覆盖它encoding

SimpleDirectoryReader(input_dir="path/to/directory", encoding="latin-1")

2.5 提取元数据

您可以指定一个函数,该函数将读取每个文件并提取附加到Document每个文件的结果对象的元数据,方法是将函数传递为file_metadata

def get_meta(file_path):
    return {"foo": "bar", "file_path": file_path}

SimpleDirectoryReader(input_dir="path/to/directory", file_metadata=get_meta)

该函数应采用单个参数(文件路径)并返回元数据字典。


2.6 扩展到其他文件类型

您可以SimpleDirectoryReader通过将文件扩展名字典传递给BaseReaderas的实例来扩展读取其他文件类型file_extractor
BaseReader 应该读取文件并返回文档列表。
例如,要添加对.myfile文件的自定义支持:

from llama_index.core import SimpleDirectoryReader
from llama_index.core.readers.base import BaseReader
from llama_index.core import Document

class MyFileReader(BaseReader):
    def load_data(self, file, extra_info=None):
        with open(file, "r") as f:
            text = f.read()
        # load_data returns a list of Document objects
        return [Document(text=text + "Foobar", extra_info=extra_info or {})]

reader = SimpleDirectoryReader(
    input_dir="./data", file_extractor={".myfile": MyFileReader()}
)

documents = reader.load_data()
print(documents)

请注意,此映射将覆盖您指定的文件类型的默认文件提取器,因此如果您想支持它们,则需要将它们添加回来。


2.7 对外部文件系统的支持

与其他模块一样,它SimpleDirectoryReader采用一个可选fs参数,可用于遍历远程文件系统。

这可以是协议实现的任何文件系统对象fsspec
fsspec协议具有针对各种远程文件系统的开源实现,包括AWS S3、Azure Blob 和 DataLake、Google Drive、SFTP等。

这是连接到 S3 的示例:

from s3fs import S3FileSystem

s3_fs = S3FileSystem(key="...", secret="...")
bucket_name = "my-document-bucket"

reader = SimpleDirectoryReader(
    input_dir=bucket_name,
    fs=s3_fs,
    recursive=True,  # recursively searches all subdirectories
)

documents = reader.load_data()
print(documents)

可以在此处找到完整的示例笔记本。


七、数据连接器 (LlamaHub) 概览


1、概念

数据连接器(又名Reader)将来自不同数据源和数据格式的数据提取为简单的Document表示形式(文本和简单元数据)。

提示

获取数据后,您可以在顶部构建索引,使用查询引擎提出问题,并使用聊天引擎进行对话。


2、LlamaHub

我们的数据连接器通过LlamaHub 🦙提供。
LlamaHub 是一个开源存储库,包含数据加载器,您可以轻松地将其插入任何 LlamaIndex 应用程序中。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


3、使用模式

简单使用:

from llama_index.core import download_loader

from llama_index.readers.google import GoogleDocsReader

loader = GoogleDocsReader()
documents = loader.load_data(document_ids=[...])

每个数据加载器都包含一个“用法”部分,显示如何使用该加载器。
使用每个加载程序的核心是一个download_loader函数,它将加载程序文件下载到您可以在应用程序中使用的模块中。

用法示例:

from llama_index.core import VectorStoreIndex, download_loader

from llama_index.readers.google import GoogleDocsReader

gdoc_ids = ["1wf-y2pd9C878Oh-FmLH7Q_BQkljdm6TQal-c1pUfrec"]
loader = GoogleDocsReader()
documents = loader.load_data(document_ids=gdoc_ids)
index = VectorStoreIndex.from_documents(documents)
query_engine = index.as_query_engine()
query_engine.query("Where did the author go to school?")

4、模块

一些示例数据连接器:

  • 本地文件目录( SimpleDirectoryReader)。
    可以支持解析多种文件类型:.pdf.jpg.png.docx等。
  • 概念( NotionPageReader)
  • 谷歌文档(GoogleDocsReader
  • 松弛( SlackReader)
  • 不和谐( DiscordReader)
  • Apify 演员( ApifyActor)。
    可以抓取网页、抓取网页、提取文本内容、下载文件,包括.pdf.jpg.png.docx等。

有关更多详细信息,请参阅模块指南。


八、LlamaParse

LlamaParse 是由 LlamaIndex 创建的 API,用于使用 LlamaIndex 框架高效解析和表示文件,以便进行高效检索和上下文增强。

LlamaParse 直接与LlamaIndex集成。

目前免费提供。今天就尝试一下吧!

**注意:**目前仅支持 PDF 文件。


1、入门

首先,登录并从 获取 api-key https://cloud.llamaindex.ai

然后,确保您安装了最新的 LlamaIndex 版本。

**注意:**如果您从 v0.9.X 升级,我们建议您遵循我们的迁移指南,并首先卸载以前的版本。

pip uninstall llama-index  # run this if upgrading from v0.9.x or older
pip install -U llama-index --upgrade --no-cache-dir --force-reinstall

最后,安装包:

pip install llama-parse

现在您可以运行以下命令来解析您的第一个 PDF 文件:

import nest_asyncio

nest_asyncio.apply()

from llama_parse import LlamaParse

parser = LlamaParse(
    api_key="llx-...",  # can also be set in your env as LLAMA_CLOUD_API_KEY
    result_type="markdown",  # "markdown" and "text" are available
    verbose=True,
)

# sync
documents = parser.load_data("./my_file.pdf")

# sync batch
documents = parser.load_data(["./my_file1.pdf", "./my_file2.pdf"])

# async
documents = await parser.aload_data("./my_file.pdf")

# async batch
documents = await parser.aload_data(["./my_file1.pdf", "./my_file2.pdf"])

2、与使用SimpleDirectoryReader

您还可以将解析器集成为默认 PDF 加载器SimpleDirectoryReader

import nest_asyncio

nest_asyncio.apply()

from llama_parse import LlamaParse
from llama_index.core import SimpleDirectoryReader

parser = LlamaParse(
    api_key="llx-...",  # can also be set in your env as LLAMA_CLOUD_API_KEY
    result_type="markdown",  # "markdown" and "text" are available
    verbose=True,
)

file_extractor = {".pdf": parser}
documents = SimpleDirectoryReader(
    "./data", file_extractor=file_extractor
).load_data()

完整的文档可以在LlamaIndex DocumentationSimpleDirectoryReader上找到。


3、例子

可以在示例文件夹中找到几个端到端索引示例

  • 入门
  • 高级 RAG 示例
  • 原始 API 使用情况

4、服务条款 & 模块指南

请参阅此处的服务条款:https://github.com/run-llama/llama_parse/blob/main/TOS.pdf


模块指南:https://docs.llamaindex.ai/en/stable/module_guides/loading/connector/modules/


九、节点解析器使用模式

节点解析器是一个简单的抽象,它获取文档列表,并将它们分块为Node对象,这样每个节点都是父文档的特定块。
当文档被分解为节点时,它的所有属性都被继承到子节点(即metadata,文本和元数据模板等)。
您可以在此处Node阅读有关和Document属性的更多信息。


1、入门使用


1.1 独立使用

节点解析器可以单独使用:

from llama_index.core import Document
from llama_index.core.node_parser import SentenceSplitter

node_parser = SentenceSplitter(chunk_size=1024, chunk_overlap=20)

nodes = node_parser.get_nodes_from_documents(
    [Document(text="long text")], show_progress=False
)

1.2 转换用法

节点解析器可以包含在具有摄取管道的任何转换集中。

from llama_index.core import SimpleDirectoryReader
from llama_index.core.ingestion import IngestionPipeline
from llama_index.core.node_parser import TokenTextSplitter

documents = SimpleDirectoryReader("./data").load_data()

pipeline = IngestionPipeline(transformations=[TokenTextSplitter(), ...])

nodes = pipeline.run(documents=documents)

1.3 索引使用

transformations或者在使用以下命令构建索引时自动使用的内部设置或全局设置.from_documents()

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

documents = SimpleDirectoryReader("./data").load_data()

# global
from llama_index.core import Settings

Settings.text_splitter = SentenceSplitter(chunk_size=1024, chunk_overlap=20)

# per-index
index = VectorStoreIndex.from_documents(
    documents,
    transformations=[SentenceSplitter(chunk_size=1024, chunk_overlap=20)],
)


十、节点解析器模块


1、基于文件的节点解析器

有几个基于文件的节点解析器,它们将根据正在解析的内容类型(JSON、Markdown 等)创建节点

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


1.1 简单文件节点解析器
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)

1.2 HTML节点解析器

该节点解析器用于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"])  # optional list of tags
nodes = parser.get_nodes_from_documents(html_docs)

1.3 JSONNode解析器

解析JSONNodeParser原始 JSON。

from llama_index.core.node_parser import JSONNodeParser

parser = JSONNodeParser()

nodes = parser.get_nodes_from_documents(json_docs)

1.4 MarkdownNode解析器

解析MarkdownNodeParser原始 Markdown 文本。

from llama_index.core.node_parser import MarkdownNodeParser

parser = MarkdownNodeParser()

nodes = parser.get_nodes_from_documents(markdown_docs)

2、文本分割器


2.1 代码分割器

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

在此处查看支持语言的完整列表。

from llama_index.core.node_parser import CodeSplitter

splitter = CodeSplitter(
    language="python",
    chunk_lines=40,  # lines per chunk
    chunk_lines_overlap=15,  # lines overlap between chunks
    max_chars=1500,  # max chars per chunk
)
nodes = splitter.get_nodes_from_documents(documents)

2.2 Langchain节点解析器

您还可以使用节点解析器包装来自 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)

2.3 分句器

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

from llama_index.core.node_parser import SentenceSplitter

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

2.4 句子窗口节点解析器

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

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

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

import nltk
from llama_index.core.node_parser import SentenceWindowNodeParser

node_parser = SentenceWindowNodeParser.from_defaults(
    # how many sentences on either side to capture
    window_size=3,
    # the metadata key that holds the window of surrounding sentences
    window_metadata_key="window",
    # the metadata key that holds the original sentence
    original_text_metadata_key="original_sentence",
)

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


2.5 语义分割器节点解析器

“语义分块”是 Greg Kamradt 在他的关于 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中找到。


2.6 令牌文本分割器

尝试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)

3、基于关系的节点解析器


层次节点解析器

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

与 结合使用时AutoMergingRetriever,这使我们能够在检索到大多数子节点时自动用其父节点替换检索到的节点。
此过程为法学硕士提供了更完整的响应综合背景。

from llama_index.core.node_parser import HierarchicalNodeParser

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

可以在此处结合AutoMergingRetriever找到完整的示例。


十一、Ingestion Pipeline

An使用应用于输入数据IngestionPipeline的概念。
Transformations这些Transformations将应用于您的输入数据,并且结果节点将被返回或插入到向量数据库(如果给定)中。
每个节点+转换对都会被缓存,因此使用相同节点+转换组合的后续运行(如果缓存已持久)可以使用缓存的结果并节省时间。

IngestionPipeline要查看使用的交互式示例,请查看RAG CLI。


1、使用模式

最简单的用法是实例化IngestionPipeline如下:

from llama_index.core import Document
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.core.node_parser import SentenceSplitter
from llama_index.core.extractors import TitleExtractor
from llama_index.core.ingestion import IngestionPipeline, IngestionCache

# create the pipeline with transformations
pipeline = IngestionPipeline(
    transformations=[
        SentenceSplitter(chunk_size=25, chunk_overlap=0),
        TitleExtractor(),
        OpenAIEmbedding(),
    ]
)

# run the pipeline
nodes = pipeline.run(documents=[Document.example()])

请注意,在现实场景中,您可以从SimpleDirectoryReaderLlama Hub 或其他读者处获取文档。


2、连接到矢量数据库

运行摄取管道时,您还可以选择自动将生成的节点插入到远程向量存储中。

然后,您可以稍后从该向量存储构建索引。

from llama_index.core import Document
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.core.node_parser import SentenceSplitter
from llama_index.core.extractors import TitleExtractor
from llama_index.core.ingestion import IngestionPipeline
from llama_index.vector_stores.qdrant import QdrantVectorStore

import qdrant_client

client = qdrant_client.QdrantClient(location=":memory:")
vector_store = QdrantVectorStore(client=client, collection_name="test_store")

pipeline = IngestionPipeline(
    transformations=[
        SentenceSplitter(chunk_size=25, chunk_overlap=0),
        TitleExtractor(),
        OpenAIEmbedding(),
    ],
    vector_store=vector_store,
)

# Ingest directly into a vector db
pipeline.run(documents=[Document.example()])

# Create your index
from llama_index.core import VectorStoreIndex

index = VectorStoreIndex.from_vector_store(vector_store)

3、计算管道中的嵌入

请注意,在上面的示例中,嵌入是作为管道的一部分进行计算的。
如果您将管道连接到向量存储,则嵌入必须是管道的一个阶段,否则稍后的索引实例化将失败。

如果您不连接到向量存储,即仅生成节点列表,则可以省略管道中的嵌入。


4、缓存

在 中IngestionPipeline,每个节点+转换组合都被散列并缓存。
这可以节省使用相同数据的后续运行的时间。

以下部分描述了有关缓存的一些基本用法。


本地缓存管理

一旦有了管道,您可能需要存储和加载缓存。

# save
pipeline.persist("./pipeline_storage")

# load and restore state
new_pipeline = IngestionPipeline(
    transformations=[
        SentenceSplitter(chunk_size=25, chunk_overlap=0),
        TitleExtractor(),
    ],
)
new_pipeline.load("./pipeline_storage")

# will run instantly due to the cache
nodes = pipeline.run(documents=[Document.example()])

如果缓存太大,可以清除它

# delete all context of the cache
cache.clear()

远程缓存管理

我们支持多个远程存储后端的缓存

  • RedisCache
  • MongoDBCache
  • FirestoreCache

这里作为使用的示例RedisCache

from llama_index.core import Document
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.core.node_parser import SentenceSplitter
from llama_index.core.extractors import TitleExtractor
from llama_index.core.ingestion import IngestionPipeline, IngestionCache
from llama_index.core.ingestion.cache import RedisCache

pipeline = IngestionPipeline(
    transformations=[
        SentenceSplitter(chunk_size=25, chunk_overlap=0),
        TitleExtractor(),
        OpenAIEmbedding(),
    ],
    cache=IngestionCache(
        cache=RedisCache(
            redis_uri="redis://127.0.0.1:6379", collection="test_cache"
        )
    ),
)

# Ingest directly into a vector db
nodes = pipeline.run(documents=[Document.example()])

在这里,不需要持久步骤,因为当您进入指定的远程集合时,所有内容都会被缓存。


5、异步支持

IngestionPipeline支持异步操作

nodes = await pipeline.arun(documents=documents)

6、文件管理

将 附加docstore到摄取管道将启用文档管理。

使用document.doc_idnode.ref_doc_id作为接地点,摄取管道将主动查找重复文档。

它的工作原理是:

  • 存储地图doc_id->document_hash
  • 如果附加了矢量存储:
  • 如果检测到重复项doc_id,并且哈希已更改,则将重新处理并更新插入文档
  • 如果检测到重复doc_id且哈希未更改,则跳过该节点
  • 如果仅未附加矢量存储:
  • 检查每个节点的所有现有哈希值
  • 如果发现重复节点,则跳过该节点
  • 否则,处理该节点

**注意:**如果我们不附加向量存储,我们只能检查并删除重复的输入。

from llama_index.core.ingestion import IngestionPipeline
from llama_index.core.storage.docstore import SimpleDocumentStore

pipeline = IngestionPipeline(
    transformations=[...], docstore=SimpleDocumentStore()
)

在我们的演示笔记本中可以找到完整的演练。

另请查看另一篇使用Redis 作为我们整个摄取堆栈的指南。


7、并行处理

run的方法可以IngestionPipeline用并行进程来执行。
它通过将multiprocessing.Pool批量节点分布到多个处理器来实现这一点。

要使用并行处理执行,请设置num_workers您要使用的进程数:

from llama_index.core.ingestion import IngestionPipeline

pipeline = IngestionPipeline(
    transformations=[...],
)
pipeline.run(documents=[...], num_workers=4)

8、模块

  • 转型指南
  • 先进的摄取管道
  • 异步摄取管道
  • 文档管理管道
  • Redis 摄取管道
  • Google Drive 摄取管道
  • 并行执行管道

十二、转换

转换是将节点列表作为输入并返回节点列表的过程。
每个实现Transformation基类的组件都有同步__call__()定义和异步acall()定义。

目前,以下组件是Transformation对象:

  • TextSplitter
  • NodeParser
  • MetadataExtractor
  • Embeddings模型(查看我们支持的嵌入列表)

1、使用模式

虽然转换最好与 一起使用IngestionPipeline,但它们也可以直接使用。

from llama_index.core.node_parser import SentenceSplitter
from llama_index.core.extractors import TitleExtractor

node_parser = SentenceSplitter(chunk_size=512)
extractor = TitleExtractor()

# use transforms directly
nodes = node_parser(documents)

# or use a transformation in async
nodes = await extractor.acall(nodes)

2、与索引结合

转换可以传递到索引或整体全局设置中,并将在调用from_documents()insert()索引时使用。

from llama_index.core import VectorStoreIndex
from llama_index.core.extractors import (
    TitleExtractor,
    QuestionsAnsweredExtractor,
)
from llama_index.core.ingestion import IngestionPipeline
from llama_index.core.node_parser import TokenTextSplitter

transformations = [
    TokenTextSplitter(chunk_size=512, chunk_overlap=128),
    TitleExtractor(nodes=5),
    QuestionsAnsweredExtractor(questions=3),
]

# global
from llama_index.core import Settings

Settings.transformations = [text_splitter, title_extractor, qa_extractor]

# per-index
index = VectorStoreIndex.from_documents(
    documents, transformations=transformations
)

3、自定义转换

您可以通过实现基类来自己实现任何转换。

以下自定义转换将删除文本中的所有特殊字符或标点符号。

import re
from llama_index.core import Document
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.core.node_parser import SentenceSplitter
from llama_index.core.ingestion import IngestionPipeline
from llama_index.core.schema import TransformComponent

class TextCleaner(TransformComponent):
    def __call__(self, nodes, **kwargs):
        for node in nodes:
            node.text = re.sub(r"[^0-9A-Za-z ]", "", node.text)
        return nodes

然后可以直接使用它们或在任何IngestionPipeline.

# use in a pipeline
pipeline = IngestionPipeline(
    transformations=[
        SentenceSplitter(chunk_size=25, chunk_overlap=0),
        TextCleaner(),
        OpenAIEmbedding(),
    ],
)

nodes = pipeline.run(documents=[Document.example()])

2024-04-15(一)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/548833.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

华为配置静态ARP示例

华为配置静态ARP示例 组网图形 图1 配置静态ARP组网图 静态ARP简介配置注意事项组网需求配置思路操作步骤配置文件相关信息 静态ARP简介 静态ARP表项是指网络管理员手工建立IP地址和MAC地址之间固定的映射关系。 正常情况下网络中设备可以通过ARP协议进行ARP表项的动态学习&…

Linux --- 高级IO

目录 1. 什么是IO 2. 阻塞的本质 3. 五种IO模型 3.1. 通过故事认识五种IO模型 3.2. 上述故事的总结 3.3. 具体的五种IO模型 3.3.1. 阻塞IO 3.3.2. 非阻塞轮询式IO 3.3.3. 信号驱动IO 3.3.4. 多路转接IO 3.3.5. 异步IO 4. 非阻塞IO 4.1. fcntl 系统调用 1. 什么是I…

麒麟信安LTF框架上线openEuler社区

麒麟信安LTF框架介绍 LTF&#xff08;Linux Test Framework&#xff09;是麒麟信安自动化组开发的一款面向Linux操作系统测试的自动化测试框架&#xff0c;目前已在openEuler社区开源。LTF工具积极投入国内各评测项目和日常版本测试任务中&#xff0c;汲取了在Linux自动化测试…

C语言预处理操作详解

这篇博客和大家分享一下C语言中的预处理操作。 1. 预定义符号 C语言设置了⼀些预定义符号&#xff0c;可以直接使用&#xff0c;预定义符号也是在预处理期间处理的。 __FILE__ //进行编译的源文件 __LINE__ //文件当前的行号 __DATA__ //文件被编译的日期 __TIME_…

【Android】重温Activity生命周期

前言 Android中用得最多的组件是Activity&#xff0c;而它的生命周期也是最基础的知识&#xff0c;从刚接触Android到工作中会频繁依赖这部分知识。可能大多数人能说出页面新建到页面关闭会走的生命周期&#xff1a;onCreate、onStart、onResume、onPause、onStop、onDestory&…

【五十三】【算法分析与设计】1392. 最长快乐前缀,686. 重复叠加字符串匹配,796. 旋转字符串,KMP算法

目录 1392. 最长快乐前缀 思路 过程 686. 重复叠加字符串匹配 796. 旋转字符串 string内置函数find KMP算法 结尾 1392. 最长快乐前缀 「快乐前缀」 是在原字符串中既是 非空 前缀也是后缀&#xff08;不包括原字符串自身&#xff09;的字符串。 给你一个字符串 s&…

JAVA_类和对象(1)

认识面向对象 Java是一门纯面向对象的语言(Object Oriented Program, OOP)&#xff0c;在面向对象的世界里&#xff0c;一切皆为对象。面向对象是解决问题的一种思想&#xff0c;主要依靠对象之间的交互完成一件事情。  面向过程和面相对象并不是一门语言&#xff0c;而是解决…

OpenStack镜像管理与制作

一、OpenStack镜像服务 1、什么是镜像 镜像通常是指一系列文件或一个磁盘驱动器的精确副本。虚拟机所使用的虚拟磁盘&#xff0c;实际上是一种特殊格式的镜像文件。云环境下尤其需要镜像。镜像就是一个模板&#xff0c;类似于VMware的虚拟机模板&#xff0c;其预先安装基本的…

格雷希尔G80L-T系列大口径快速连接器,在汽车膨胀水箱的气密性测试密封方案

副水箱也有人称作膨胀水箱&#xff0c;是汽车散热系统的一个重要组成部分&#xff0c;当水箱里面的温度过高的时候就会产生一定的压力&#xff0c;而副水箱可以根据热胀冷缩来帮助水箱和发动机排出去多余的水&#xff0c;起到一个调节的作用&#xff0c;副水箱由PP/PE塑料注塑而…

单向链表的实现

前言&#xff1a;继顺序表后的又一个线性结构——链表&#xff0c;这里将单向链表的实现。 目录 链表简介: 多文件实现&#xff1a; SList.h&#xff1a; SList.c实现函数的详解&#xff1a; 因为插入数据需要创建节点&#xff0c;很频繁&#xff0c;所以直接将创建新节点分…

《中医病证分类与代码》-中医疾病分类数据库

《中医病症分类与代码》由国家中医药管理局2020年底修订&#xff0c;目的是为中医疾病及证候的分类提供统一的规范。规定2021年起&#xff0c;各中医机构的临床科室及基层中医药的医师都应按照最新修订的《中医病症分类与代码》规范来填报病案及病历。 中医病证分类与代码数据库…

C++STL详解(一)— string类

string 类对象的常见容量操作 函数名称 功能 size 返回字符串有效字符长度length返回字符串有效字符长度capacity返回空间总大小clear清空有效字符empty检测字符串是否为空串&#xff0c;是返回true,否则返回falsereserve对容量进行改变resize扩容初始化 size和length 文档解…

Linux系统(centos,redhat,龙芯,麒麟等)忘记密码,怎么重置密码

Linux系统&#xff08;centos,redhat,龙芯&#xff0c;麒麟等&#xff09;忘记密码&#xff0c;怎么重置密码&#xff0c;怎么设置新的密码 今天在操作服务器时&#xff0c;DBA忘记了人大金仓数据库的kingbase密码&#xff0c;他的密码试了好多遍&#xff0c;都不行。最后只能…

sublime text中文---功能强大、操作便捷的代码编辑神器

Sublime Text是一款极受欢迎的代码编辑器&#xff0c;以其出色的性能、丰富的功能和优雅的用户界面赢得了广大开发者的青睐。它支持多种编程语言&#xff0c;包括HTML、CSS、JavaScript、Python等&#xff0c;让开发者能够轻松编辑和调试各种代码。Sublime Text拥有强大的自定义…

配置路由器实现互通

1.实验环境 实验用具包括两台路由器(或交换机)&#xff0c;一根双绞线缆&#xff0c;一台PC&#xff0c;一条Console 线缆。 2.需求描述 如图6.14 所示&#xff0c;将两台路由器的F0/0 接口相连&#xff0c;通过一台PC 连接设备的 Console 端口并配置P地址&#xff08;192.1…

SpringBoot是如何实现main方法启动Web项目的?

一、问题解析 在Spring Boot中&#xff0c;通过SpringApplication类的静态方法run来启动Web项目。当我们在main方法中调用run方法时&#xff0c;Spring Boot使用一个内嵌的Tomcat服务器&#xff0c;并将其配置为处理Web请求。 当应用程序启动时&#xff0c;Spring Boot会自动扫…

C#学习笔记11:winform上位机与西门子PLC网口通信_下篇

今日终于到了winform上位机与西门子PLC网口通信的系列收为阶段了&#xff0c;一直没一口气更新完&#xff0c;手头上也没有可以测试用的PLC设备&#xff0c;虚拟仿真用到的博图软件也不想下载&#xff08;会让我电脑变卡&#xff09;。 于是等了些日子购买西门子PLC&#xff0…

JIT在汽车行业中的革命性应用:颠覆传统制造模式,引领智能制造新时代

随着科技的飞速发展和市场竞争的日益激烈&#xff0c;汽车行业正面临着前所未有的变革。其中&#xff0c;准时制生产&#xff08;Just-In-Time&#xff0c;简称JIT&#xff09;作为一种先进的生产管理方式&#xff0c;已经在汽车行业中得到了广泛应用&#xff0c;成为推动汽车产…

密码学 | 椭圆曲线 ECC 密码学入门(三)

目录 7 这一切意味着什么&#xff1f; 8 椭圆曲线密码学的应用 9 椭圆曲线密码学的缺点 10 展望未来 ⚠️ 原文地址&#xff1a;A (Relatively Easy To Understand) Primer on Elliptic Curve Cryptography ⚠️ 写在前面&#xff1a;本文属搬运博客&#xff0c;自己留…

论文略读:Window Attention is Bugged: How not to Interpolate Position Embeddings

iclr 2024 reviewer 打分 6666 窗口注意力、位置嵌入以及高分辨率微调是现代Transformer X CV 时代的核心概念。论文发现&#xff0c;将这些几乎无处不在的组件简单地结合在一起&#xff0c;可能会对性能产生不利影响问题很简单&#xff1a;在使用窗口注意力时对位置嵌入进行插…