![見出し画像](https://assets.st-note.com/production/uploads/images/126782286/rectangle_large_type_2_0458d5e3164589c2bd453f25bc7a5d9a.jpeg?width=800)
LlamaIndexのインデックスに含まれるドキュメントとノードの確認と管理
「LlamaIndex」のインデックスに含まれる「ドキュメント」と「ノード」の確認と管理の手順をまとめました。
・LlamaIndex v0.9.26
1. LlamaIndexによるRAGの作成
はじめに、「LlamaIndex」でシンプルなRAGを作成します。
(1) パッケージのインストール。
# パッケージのインストール
!pip install llama-index==0.9.26
(2) 環境変数の準備。
左端の鍵アイコンで「OPENAI_API_KEY」に自分のOpenAI APIキーを設定してからセルを実行してください。
import os
from google.colab import userdata
# 環境変数の準備 (左端の鍵アイコンでOPENAI_API_KEYを設定)
os.environ["OPENAI_API_KEY"] = userdata.get("OPENAI_API_KEY")
(3) ログレベルの設定。
import logging
import sys
# ログレベルの設定
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG, force=True)
(4) ドキュメントの読み込み。
左端のフォルダアイコンでdataフォルダとadd_dataフォルダを作成して、ドキュメントをアップロードしてからセルを実行してください。
![](https://assets.st-note.com/img/1704514369282-IIeQfoQBn5.png?width=800)
・data : ChatGPTに書かせた7章構成のサイバーパンク赤ずきんの物語
・add_data : 追加の第8章 (実験で利用)
from llama_index import SimpleDirectoryReader
# ドキュメントの読み込み
documents = SimpleDirectoryReader("data").load_data()
(5) インデックスとクエリの作成。
from llama_index import ServiceContext, VectorStoreIndex
# ServiceContextの準備
service_context = ServiceContext.from_defaults(
chunk_size=250 # チャンクの最大サイズ
)
# インデックスの作成
index = VectorStoreIndex.from_documents(
documents,
show_progress=True,
service_context=service_context
)
# クエリエンジンの作成
query_engine = index.as_query_engine(
similarity_top_k=2 # 取得するチャンク数
)
(6) 質問応答。
正解です。
# 質問応答
print(query_engine.query("ミコの幼馴染の名前は?"))
リョウ
2. インデックスの読み書き
インデックスの読み書きの手順は、次のとおりです。
2-1. インデックスの書き込み
# インデックスの書き込み
index.storage_context.persist()
storageフォルダに以下のファイルが保存されます。
・default__vector_store.json : 埋め込み
・docstore.json : ドキュメントストア
・graph_store.json : グラフストア
・image__vector_store.json : 画像ベクトルストア
・index_store.json : ノード情報
2-2. インデックスの読み込み
from llama_index import StorageContext, load_index_from_storage
# インデックスの読み込み
storage_context = StorageContext.from_defaults(persist_dir="./storage")
index = load_index_from_storage(storage_context)
3. ドキュメントとノードの確認
インデックスに含まれるドキュメントとノードの確認の手順は、次のとおりです。
3-1. ドキュメント群に含まれるドキュメント情報の確認
ドキュメントIDとドキュメント先頭20文字を出力しています。
# ドキュメント群に含まれるドキュメント情報の確認
for document in documents:
print(document.id_, ":", document.text[:20].replace("\n", " "))
b653520b-a020-4ffd-8d90-7637acf403ee : 第1章:データフロント 夜の煌びやかな
3988d560-334f-4a39-b656-1e88860e78ec : 第2章:ウルフ・コーポレーションの罠
f0580902-f08f-4b0d-b534-c6cd2f404efe : 第3章:裏切りと再会 バー「グランマズ
0786d647-a1c6-4e38-b754-f7c9c4c2f616 : 第4章:ウルフ・コーポレーションの崩壊
c83c7785-f69b-4cd7-8db4-bb8ebe11ad2d : 第5章:決戦の時 ミコとリョウはついに
03645b40-a90c-4556-8829-e515c3fe44f2 : 第6章:真実の解放 ミコはウルフ博士の
4c33528c-f1a5-4914-945a-213057ac55fc : 第7章:新たなる旅立ち ウルフ・コーポ
3-2. インデックスに含まれるドキュメント情報の確認
ドキュメントIDとノードID群を出力しています。1章と3章が2つのノードに分割されていることがわかります。
# インデックスに含まれるドキュメント情報の確認
for doc_id, doc_info in index.ref_doc_info.items():
print(doc_id, ":", doc_info.node_ids)
b653520b-a020-4ffd-8d90-7637acf403ee : ['a5789477-5c19-477b-bd8c-9dc90e1a50ee', 'b8471cee-d258-4eea-bd23-8efa43a166b4']
3988d560-334f-4a39-b656-1e88860e78ec : ['29449bcb-4387-4904-b78b-3287b5fecb14']
f0580902-f08f-4b0d-b534-c6cd2f404efe : ['516fee3a-f537-4bd3-9264-558103bb030e', '6f07f7da-3392-4f24-8214-b7563627a081']
0786d647-a1c6-4e38-b754-f7c9c4c2f616 : ['9e0df461-d7f0-4ddc-96b5-67c75ae12787']
c83c7785-f69b-4cd7-8db4-bb8ebe11ad2d : ['bcc78a65-6736-4dda-a3cd-c2ab4f55b515']
03645b40-a90c-4556-8829-e515c3fe44f2 : ['07dc2a7a-fb5c-48b0-98ff-cfe3a20a6d8c']
4c33528c-f1a5-4914-945a-213057ac55fc : ['7aba730d-1aef-497c-af3e-bc2c25db16b9']
3-3. インデックスに含まれるノード情報の確認
ノードIDとテキスト先頭20文字を出力しています。
# インデックスに含まれるノード情報の確認
node_doc_ids = index.index_struct.nodes_dict.values()
for node in index.docstore.get_nodes(node_doc_ids):
print(node.id_, ":", node.text[:20].replace("\n", " "))
a5789477-5c19-477b-bd8c-9dc90e1a50ee : 第1章:データフロント 夜の煌びやかな
b8471cee-d258-4eea-bd23-8efa43a166b4 : その街で、赤いフードをかぶった少女・ミコ
29449bcb-4387-4904-b78b-3287b5fecb14 : 第2章:ウルフ・コーポレーションの罠
516fee3a-f537-4bd3-9264-558103bb030e : 第3章:裏切りと再会 バー「グランマズ
6f07f7da-3392-4f24-8214-b7563627a081 : リョウは彼女の幼馴染であり、彼もまたウル
9e0df461-d7f0-4ddc-96b5-67c75ae12787 : 第4章:ウルフ・コーポレーションの崩壊
bcc78a65-6736-4dda-a3cd-c2ab4f55b515 : 第5章:決戦の時 ミコとリョウはついに
07dc2a7a-fb5c-48b0-98ff-cfe3a20a6d8c : 第6章:真実の解放 ミコはウルフ博士の
7aba730d-1aef-497c-af3e-bc2c25db16b9 : 第7章:新たなる旅立ち ウルフ・コーポ
3-4. インデックスに含まれるノードの埋め込みの確認
ノードIDと埋め込みを出力しています。
from llama_index.indices.utils import async_embed_nodes, embed_nodes
# インデックスに含まれるノードの埋め込みの確認
id_to_embed_map = embed_nodes(
index.docstore.get_nodes(node_doc_ids),
index._service_context.embed_model,
show_progress=True
)
for node_id, node_embed in id_to_embed_map.items():
print(node_id, ":", node_embed)
a5789477-5c19-477b-bd8c-9dc90e1a50ee : [0.00018566509243100882, -0.0021640199702233076, ...]
b8471cee-d258-4eea-bd23-8efa43a166b4 : [-0.00792342983186245, -0.007546788081526756, ...]
29449bcb-4387-4904-b78b-3287b5fecb14 : [-0.02438954822719097, -0.014492749236524105, ...]
516fee3a-f537-4bd3-9264-558103bb030e : [-0.01839890517294407, -0.00596889853477478, ...]
6f07f7da-3392-4f24-8214-b7563627a081 : [-0.018981723114848137, -0.004142286255955696, ...]
9e0df461-d7f0-4ddc-96b5-67c75ae12787 : [-0.020520830526947975, -0.006756193935871124, ...]
bcc78a65-6736-4dda-a3cd-c2ab4f55b515 : [-0.018631653860211372, -0.008409645408391953, ...]
07dc2a7a-fb5c-48b0-98ff-cfe3a20a6d8c : [-0.010659953579306602, 0.0013720471179112792, ...]
7aba730d-1aef-497c-af3e-bc2c25db16b9 : [-0.01590215414762497, -0.005675919819623232, ...]
3-5. レスポンスのソースノードの確認
# 質問応答
response = query_engine.query("ミコの幼馴染の名前は?")
print(response)
# ソースノードの確認
for node in response.source_nodes:
print(node.id_, ":", node.text[:20].replace("\n", " "), "(Score:", node.score, ")")
リョウ
516fee3a-f537-4bd3-9264-558103bb030e : 第3章:裏切りと再会 バー「グランマズ (Score: 0.8254593648709416 )
29449bcb-4387-4904-b78b-3287b5fecb14 : 第2章:ウルフ・コーポレーションの罠 (Score: 0.8199444604824183 )
4. ドキュメントとノードの管理
4-1. ドキュメントの追加
ドキュメントの追加手順は、次のとおりです。
(1) ドキュメントの追加。
from llama_index import SimpleDirectoryReader
# ドキュメントの読み込み
documents = SimpleDirectoryReader("add_data").load_data()
# ドキュメントの追加
for document in documents:
index.insert(document)
(2) インデックスに含まれるドキュメント情報の確認。
8章が4つのノードとして追加されていることがわかります。
# インデックスに含まれるドキュメント情報の確認
for doc_id, doc_info in index.ref_doc_info.items():
print(doc_id, ":", doc_info.node_ids)
b653520b-a020-4ffd-8d90-7637acf403ee : ['a5789477-5c19-477b-bd8c-9dc90e1a50ee', 'b8471cee-d258-4eea-bd23-8efa43a166b4']
3988d560-334f-4a39-b656-1e88860e78ec : ['29449bcb-4387-4904-b78b-3287b5fecb14']
f0580902-f08f-4b0d-b534-c6cd2f404efe : ['516fee3a-f537-4bd3-9264-558103bb030e', '6f07f7da-3392-4f24-8214-b7563627a081']
0786d647-a1c6-4e38-b754-f7c9c4c2f616 : ['9e0df461-d7f0-4ddc-96b5-67c75ae12787']
c83c7785-f69b-4cd7-8db4-bb8ebe11ad2d : ['bcc78a65-6736-4dda-a3cd-c2ab4f55b515']
03645b40-a90c-4556-8829-e515c3fe44f2 : ['07dc2a7a-fb5c-48b0-98ff-cfe3a20a6d8c']
4c33528c-f1a5-4914-945a-213057ac55fc : ['7aba730d-1aef-497c-af3e-bc2c25db16b9']
dde82b24-70d8-4299-aaa6-58d3c61107d6 : ['a5bc1535-09b5-44b1-8aed-b41d1d111a6e', '3fa560e4-e837-40a5-8775-31ff0671682a', 'bb85bf11-6fce-407c-b2d7-5068ad2f6978', '8c60010b-036f-45a5-a584-16caea865796']
(3) インデックスに含まれるノード情報の確認。
8章が4つのノードとして追加されていることがわかります。
# インデックスに含まれるノード情報の確認
node_doc_ids = index.index_struct.nodes_dict.values()
for node in index.docstore.get_nodes(node_doc_ids):
print(node.id_, ":", node.text[:20].replace("\n", " "))
a5789477-5c19-477b-bd8c-9dc90e1a50ee : 第1章:データフロント 夜の煌びやかな
b8471cee-d258-4eea-bd23-8efa43a166b4 : その街で、赤いフードをかぶった少女・ミコ
29449bcb-4387-4904-b78b-3287b5fecb14 : 第2章:ウルフ・コーポレーションの罠
516fee3a-f537-4bd3-9264-558103bb030e : 第3章:裏切りと再会 バー「グランマズ
6f07f7da-3392-4f24-8214-b7563627a081 : リョウは彼女の幼馴染であり、彼もまたウル
9e0df461-d7f0-4ddc-96b5-67c75ae12787 : 第4章:ウルフ・コーポレーションの崩壊
bcc78a65-6736-4dda-a3cd-c2ab4f55b515 : 第5章:決戦の時 ミコとリョウはついに
07dc2a7a-fb5c-48b0-98ff-cfe3a20a6d8c : 第6章:真実の解放 ミコはウルフ博士の
7aba730d-1aef-497c-af3e-bc2c25db16b9 : 第7章:新たなる旅立ち ウルフ・コーポ
a5bc1535-09b5-44b1-8aed-b41d1d111a6e : 第8章:未来への道 ネオ東京、ウルフ・
3fa560e4-e837-40a5-8775-31ff0671682a : ミコとリョウは、市民を支え、ネットワーク
bb85bf11-6fce-407c-b2d7-5068ad2f6978 : その平穏な生活に一石を投じるように、ミコ
8c60010b-036f-45a5-a584-16caea865796 : このメッセージは彼女の過去に繋がり、新た
(4) 質問応答。
インデックス更新したらクエリエンジンの更新も必要です。
# クエリエンジンの作成
query_engine = index.as_query_engine(
similarity_top_k=2
)
# 質問応答
print(query_engine.query("8章のタイトルは?"))
未来への道
4-2. ドキュメントの更新
ドキュメントの更新手順は、次のとおりです。
(1) ドキュメントの更新。
今回は、「akazukin8.txt」の1行目のタイトルを変更します。
第8章:未来への道
↓
第8章:暗号メッセージ
(2) ドキュメントの更新。
ドキュメントIDには自身の8章のIDを指定してください。
from llama_index import SimpleDirectoryReader
# ドキュメントの読み込み
documents = SimpleDirectoryReader("add_data").load_data()
# ドキュメントの更新
documents[0].id_ = "dde82b24-70d8-4299-aaa6-58d3c61107d6" # 自身の8章のIDを指定
index.update_ref_doc(
documents[0],
update_kwargs={"delete_kwargs": {"delete_from_docstore": True}},
)
(3) インデックスに含まれるドキュメント情報の確認。
# インデックスに含まれるドキュメント情報の確認
for doc_id, doc_info in index.ref_doc_info.items():
print(doc_id, ":", doc_info.node_ids)
b653520b-a020-4ffd-8d90-7637acf403ee : ['a5789477-5c19-477b-bd8c-9dc90e1a50ee', 'b8471cee-d258-4eea-bd23-8efa43a166b4']
3988d560-334f-4a39-b656-1e88860e78ec : ['29449bcb-4387-4904-b78b-3287b5fecb14']
f0580902-f08f-4b0d-b534-c6cd2f404efe : ['516fee3a-f537-4bd3-9264-558103bb030e', '6f07f7da-3392-4f24-8214-b7563627a081']
0786d647-a1c6-4e38-b754-f7c9c4c2f616 : ['9e0df461-d7f0-4ddc-96b5-67c75ae12787']
c83c7785-f69b-4cd7-8db4-bb8ebe11ad2d : ['bcc78a65-6736-4dda-a3cd-c2ab4f55b515']
03645b40-a90c-4556-8829-e515c3fe44f2 : ['07dc2a7a-fb5c-48b0-98ff-cfe3a20a6d8c']
4c33528c-f1a5-4914-945a-213057ac55fc : ['7aba730d-1aef-497c-af3e-bc2c25db16b9']
dde82b24-70d8-4299-aaa6-58d3c61107d6 : ['7205b543-0de5-404e-9673-d6884a209a09', 'ddb20c92-abba-4beb-b6ca-2ae44131a9b7', '1dbdc072-a2a6-450f-ae23-1a88ac92b6dc', '0b5e16e4-5321-49e5-ae16-e8739867568c']
(4) インデックスに含まれるノード情報の確認。
タイトルが更新されていることがわかります。
# インデックスに含まれるノード情報の確認
node_doc_ids = index.index_struct.nodes_dict.values()
for node in index.docstore.get_nodes(node_doc_ids):
print(node.id_, ":", node.text[:20].replace("\n", " "))
a5789477-5c19-477b-bd8c-9dc90e1a50ee : 第1章:データフロント 夜の煌びやかな
b8471cee-d258-4eea-bd23-8efa43a166b4 : その街で、赤いフードをかぶった少女・ミコ
29449bcb-4387-4904-b78b-3287b5fecb14 : 第2章:ウルフ・コーポレーションの罠
516fee3a-f537-4bd3-9264-558103bb030e : 第3章:裏切りと再会 バー「グランマズ
6f07f7da-3392-4f24-8214-b7563627a081 : リョウは彼女の幼馴染であり、彼もまたウル
9e0df461-d7f0-4ddc-96b5-67c75ae12787 : 第4章:ウルフ・コーポレーションの崩壊
bcc78a65-6736-4dda-a3cd-c2ab4f55b515 : 第5章:決戦の時 ミコとリョウはついに
07dc2a7a-fb5c-48b0-98ff-cfe3a20a6d8c : 第6章:真実の解放 ミコはウルフ博士の
7aba730d-1aef-497c-af3e-bc2c25db16b9 : 第7章:新たなる旅立ち ウルフ・コーポ
7205b543-0de5-404e-9673-d6884a209a09 : 第8章:暗号メッセージ ネオ東京、ウル
ddb20c92-abba-4beb-b6ca-2ae44131a9b7 : ミコとリョウは、市民を支え、ネットワーク
1dbdc072-a2a6-450f-ae23-1a88ac92b6dc : その平穏な生活に一石を投じるように、ミコ
0b5e16e4-5321-49e5-ae16-e8739867568c : このメッセージは彼女の過去に繋がり、新た
(5) 質問応答。
# クエリエンジンの作成
query_engine = index.as_query_engine(
similarity_top_k=2
)
# 質問応答
print(query_engine.query("8章のタイトルは?"))
暗号メッセージ
4-3. ドキュメントの削除
ドキュメントの削除手順は、次のとおりです。
(1) ドキュメントの削除。
ドキュメントIDには自身の8章のIDを指定してください。
# ドキュメントの削除
index.delete_ref_doc(
"dde82b24-70d8-4299-aaa6-58d3c61107d6",
delete_from_docstore=True
)
(2) インデックスに含まれるドキュメント情報の確認。
# インデックスに含まれるドキュメント情報の確認
for doc_id, doc_info in index.ref_doc_info.items():
print(doc_id, ":", doc_info.node_ids)
b653520b-a020-4ffd-8d90-7637acf403ee : ['a5789477-5c19-477b-bd8c-9dc90e1a50ee', 'b8471cee-d258-4eea-bd23-8efa43a166b4']
3988d560-334f-4a39-b656-1e88860e78ec : ['29449bcb-4387-4904-b78b-3287b5fecb14']
f0580902-f08f-4b0d-b534-c6cd2f404efe : ['516fee3a-f537-4bd3-9264-558103bb030e', '6f07f7da-3392-4f24-8214-b7563627a081']
0786d647-a1c6-4e38-b754-f7c9c4c2f616 : ['9e0df461-d7f0-4ddc-96b5-67c75ae12787']
c83c7785-f69b-4cd7-8db4-bb8ebe11ad2d : ['bcc78a65-6736-4dda-a3cd-c2ab4f55b515']
03645b40-a90c-4556-8829-e515c3fe44f2 : ['07dc2a7a-fb5c-48b0-98ff-cfe3a20a6d8c']
4c33528c-f1a5-4914-945a-213057ac55fc : ['7aba730d-1aef-497c-af3e-bc2c25db16b9']
(3) インデックスに含まれるノード情報の確認。
# インデックスに含まれるノード情報の確認
node_doc_ids = index.index_struct.nodes_dict.values()
for node in index.docstore.get_nodes(node_doc_ids):
print(node.id_, ":", node.text[:20].replace("\n", " "))
a5789477-5c19-477b-bd8c-9dc90e1a50ee : 第1章:データフロント 夜の煌びやかな
b8471cee-d258-4eea-bd23-8efa43a166b4 : その街で、赤いフードをかぶった少女・ミコ
29449bcb-4387-4904-b78b-3287b5fecb14 : 第2章:ウルフ・コーポレーションの罠
516fee3a-f537-4bd3-9264-558103bb030e : 第3章:裏切りと再会 バー「グランマズ
6f07f7da-3392-4f24-8214-b7563627a081 : リョウは彼女の幼馴染であり、彼もまたウル
9e0df461-d7f0-4ddc-96b5-67c75ae12787 : 第4章:ウルフ・コーポレーションの崩壊
bcc78a65-6736-4dda-a3cd-c2ab4f55b515 : 第5章:決戦の時 ミコとリョウはついに
07dc2a7a-fb5c-48b0-98ff-cfe3a20a6d8c : 第6章:真実の解放 ミコはウルフ博士の
7aba730d-1aef-497c-af3e-bc2c25db16b9 : 第7章:新たなる旅立ち ウルフ・コーポ
(4) 質問応答。
英語ですが正解です。デフォルトのプロンプトテンプレートが英語なのが原因と思われます。
# クエリエンジンの作成
query_engine = index.as_query_engine(
similarity_top_k=2
)
# 質問応答
print(query_engine.query("8章のタイトルは?"))
I'm sorry, but I cannot answer the query as it requires prior knowledge of the content in Chapter 8.
【翻訳】申し訳ありませんが、第8章の内容についての事前知識が必要なため、お答えできません。
この記事が気に入ったらサポートをしてみませんか?