定义和自定义节点(Defining and Customizing Nodes)
概念解释
节点(Nodes)表示源文档的“块”,无论是文本块、图像还是其他。它们还包含元数据和与其他节点及索引结构的关系信息。
节点是 LlamaIndex 中的一等公民。你可以选择直接定义节点及其所有属性,也可以选择通过我们的 NodeParser
类将源文档解析为节点。
使用模式
通过 NodeParser 解析节点
你可以使用 NodeParser
类将文档解析为节点。例如,使用 SentenceSplitter
:
from llama_index.core.node_parser import SentenceSplitter
parser = SentenceSplitter()
nodes = parser.get_nodes_from_documents(documents)
手动构造节点
你也可以选择手动构造节点对象并跳过第一个部分。例如:
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>")
# 设置关系
node1.relationships[NodeRelationship.NEXT] = RelatedNodeInfo(
node_id=node2.node_id
)
node2.relationships[NodeRelationship.PREVIOUS] = RelatedNodeInfo(
node_id=node1.node_id
)
nodes = [node1, node2]
RelatedNodeInfo
类还可以存储额外的元数据,如果需要的话:
node2.relationships[NodeRelationship.PARENT] = RelatedNodeInfo(
node_id=node1.node_id, metadata={"key": "val"}
)
自定义节点 ID
每个节点都有一个 node_id
属性,如果未手动指定,则会自动生成。这个 ID 可以用于多种目的,包括能够在存储中更新节点、能够定义节点之间的关系(通过 IndexNode
)等。
你也可以直接获取和设置任何 TextNode
的 node_id
:
print(node.node_id)
node.node_id = "My new node_id!"
编程示例
以下是一个完整的示例,展示了如何定义和自定义节点:
from llama_index.core.schema import TextNode, NodeRelationship, RelatedNodeInfo
# 手动构造节点
node1 = TextNode(text="这是第一个文本块", id_="node1")
node2 = TextNode(text="这是第二个文本块", id_="node2")
# 设置节点关系
node1.relationships[NodeRelationship.NEXT] = RelatedNodeInfo(
node_id=node2.node_id
)
node2.relationships[NodeRelationship.PREVIOUS] = RelatedNodeInfo(
node_id=node1.node_id
)
# 添加额外的元数据
node2.relationships[NodeRelationship.PARENT] = RelatedNodeInfo(
node_id=node1.node_id, metadata={"source": "example_document"}
)
# 打印节点信息
for node in [node1, node2]:
print(f"Node ID: {node.node_id}")
print(f"Node Text: {node.text}")
print("Relationships:")
for relationship, related_info in node.relationships.items():
print(f" {relationship}: {related_info.node_id}, Metadata: {related_info.metadata}")
拓展
多模态节点
除了文本节点,LlamaIndex 还支持多模态节点,例如图像节点。以下是一个示例,展示如何定义图像节点:
from llama_index.core.schema import ImageNode
# 定义图像节点
image_node = ImageNode(
text="描述图像的文本",
id_="image_node1",
image="<image_bytes>" # 图像字节数据
)
# 打印节点信息
print(f"Node ID: {image_node.node_id}")
print(f"Node Text: {image_node.text}")
print(f"Image Size: {len(image_node.image)} bytes")
自定义节点解析器
你可以创建自定义的节点解析器,以满足特定需求。例如,按段落分割文本:
from llama_index.core.node_parser import NodeParser
from llama_index.core.schema import TextNode
class ParagraphSplitter(NodeParser):
def get_nodes_from_documents(self, documents):
nodes = []
for doc in documents:
paragraphs = doc.text.split('\n\n')
for para in paragraphs:
nodes.append(TextNode(text=para, id_=f"node_{len(nodes)}"))
return nodes
# 使用自定义解析器
parser = ParagraphSplitter()
nodes = parser.get_nodes_from_documents(documents)
通过这些示例和拓展,希望你能更好地理解和使用 LlamaIndex 中的节点定义和自定义功能。