Skip to content

定义和自定义文档#

定义文档#

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

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

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()

自定义文档#

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

元数据#

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

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

有几种设置此字典的方法:

  1. 在文档构造函数中:
document = Document(
    text="text",
    metadata={"filename": "<doc_file_name>", "category": "<category>"},
)
  1. 在创建文档后:
document.metadata = {"filename": "<doc_file_name>"}
  1. 使用 SimpleDirectoryReaderfile_metadata 钩子自动设置文件名。这将自动运行钩子以设置每个文档的 metadata 字段:
from llama_index.core import SimpleDirectoryReader

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

# 根据 filename_fn 自动设置每个文档的元数据
documents = SimpleDirectoryReader(
    "./data", file_metadata=filename_fn
).load_data()

自定义 id#

文档管理部分所述,doc_id 用于启用索引中文档的高效刷新。使用 SimpleDirectoryReader 时,您可以自动将文档的 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])

您还可以直接设置任何 Documentdoc_id

document.doc_id = "My new document id!"

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

高级 - 元数据自定义#

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

自定义 LLM 元数据文本#

通常,一个文档可能有许多元数据键,但您可能不希望所有这些键都对 LLM 可见。在上面的示例中,我们可能不希望 LLM 读取我们文档的 file_name。但是,file_name 可能包含有助于生成更好嵌入的信息。这样做的一个关键优势是,可以在不改变 LLM 最终阅读内容的情况下,偏置嵌入以进行检索。

我们可以这样排除它:

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

自定义嵌入元数据文本#

类似于自定义 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))

自定义元数据格式#

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

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

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

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

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

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

一旦使用metadata_seperatormetadata_template将您的元数据转换为字符串,此模板控制当与文档/节点的文本内容连接时元数据的外观。需要metadatacontent字符串键。

摘要#

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

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

document = Document(
    text="这是一个超级定制的文档",
    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_str}\n-----\n内容: {content}",
)

print(
    "LLM看到的内容: \n",
    document.get_content(metadata_mode=MetadataMode.LLM),
)
print(
    "嵌入模型看到的内容: \n",
    document.get_content(metadata_mode=MetadataMode.EMBED),
)

高级 - 自动元数据提取#

我们有初始示例展示了使用LLM本身执行元数据提取的方法。