Datawhale AI夏令营 RAG入门 task4 文档节点的一些操作
前面依旧是常规的套路~~~
import os
from dotenv import load_dotenv
from llama_index.core.schema import TextNode
# 加载环境变量
load_dotenv()
# 从环境变量中读取api_key
api_key = os.getenv('ZHIPU_API_KEY')
base_url = "https://open.bigmodel.cn/api/paas/v4/"
chat_model = "glm-4-air"
emb_model = "embedding-2"
# 配置对话模型
from llama_index.llms.zhipuai import ZhipuAI
llm = ZhipuAI(
api_key = api_key,
model = chat_model,
)
# 配置嵌入模型
from llama_index.embeddings.zhipuai import ZhipuAIEmbedding
embedding = ZhipuAIEmbedding(
api_key = api_key,
model = emb_model,
)
emb = embedding.get_text_embedding("测试测试测试")
from llama_index.core import SimpleDirectoryReader,Document
documents = SimpleDirectoryReader(input_files=['../docs/强化学习入门指南.txt']).load_data()
from llama_index.core import VectorStoreIndex
index = VectorStoreIndex.from_documents(documents,embed_model=embedding,show_progress=True)

索引的内部结构与查询
一个 VectorStoreIndex 对象主要由以下几个部分组成:
docstore
这是一个类似字典的存储区,负责存放所有原始的文本块(Nodes)。
它的键是每个节点的唯一IDnode_id,值是完整的 TextNode 对象
- print(index.docstore.docs): 显示 docstore 中存储的所有节点。
- index.docstore.get_node('node_id'): 根据一个具体的 node_id 获取单个节点的详细信息。
print(index.docstore.docs)
图中是我的结果,我用的是之前学过的某个教程里边的强化学习入门指南.txt这个文件

2. index_struct (索引结构)
它定义了索引的结构。对于向量索引,它主要包含一个从 node_id 到向量存储中对应条目ID的映射。简单来说,它记录了“哪个节点在向量数据库的哪个位置”。
print(index.index_struct.nodes_dict):显示这个映射字典
print(index.index_struct.nodes_dict)

- ref_doc_info
它记录了原始文档(Document对象)和由它切分出的所有节点(TextNode)之间的关系。
它的键是原始文档的IDdoc_id,值是一个包含该文档所有node_id列表和元数据的对象。
print(index.ref_doc_info)

得到node_id信息之后,我们就可以根据特定的node_id信息,查看对应的节点的详细信息
index.docstore.get_node('310e8b6d-4fcf-4b42-b92c-44f4e932e9f4')

索引的动态维护
主要是怎么新增节点还有删除节点
- 新增节点
使用index.insert_nodes(nodes)方法,向一个已经存在的索引中添加新的节点。这个方法会自动处理新节点的嵌入计算,并将其存入向量存储和文档存储中。
下面介绍两种构造新节点的方式,一种是手动构造 TextNode,即 直接用 TextNode(text=..., metadata=...) 创建节点,适合添加零散的、非文件来源的信息;
还有一种是从新文档加载并解析,通过 SimpleDirectoryReader 加载新文件,再用 SentenceSplitter 将其解析成 nodes 列表,然后进行插入。这是添加新文档的标准流程。
先来看手动构造:
nodes = [
TextNode(
text="The Shawshank Redemption",
metadata={
"author": "Stephen King",
"theme": "Friendship",
"year": 1994,
},
),
TextNode(
text="The Godfather",
metadata={
"director": "Francis Ford Coppola",
"theme": "Mafia",
"year": 1972,
},
)
]
index.insert_nodes(nodes)
也可以从新文档加载并解析
from llama_index.core import SimpleDirectoryReader,Document
documents = SimpleDirectoryReader(input_files=['../docs/问答手册.txt']).load_data()
from llama_index.core.node_parser import SentenceSplitter
transformations = [SentenceSplitter(chunk_size = 512)]
from llama_index.core.ingestion.pipeline import run_transformations
nodes = run_transformations(documents, transformations=transformations)
index.insert_nodes(nodes)
print(nodes)

2. 删除和修改节点
删除操作是用 index.docstore.delete_document('doc_id') 或 index.delete_ref_doc('doc_id')根据原始文档的ID,从索引中删除这个文档以及由它产生的所有相关节点。
# index.docstore.delete_document('d15f20e9-e94a-46fd-afaf-6cd653a5f67b')
关于修改操作,LlamaIndex没有提供一个直接的方法来修改一个已经存在的节点。如果想修改,可以按照先删除,再新增的操作来替代

浙公网安备 33010602011771号