05. Pengambil Dokumen Induk (ParentDocumentRetriever)
Parent Document Retriever
Menyeimbangkan pengambilan dokumen dan segmentasi dokumen
Membagi dokumen menjadi beberapa bagian (potongan) dengan ukuran yang tepat selama pengambilan dokumen merupakan tindakan menyeimbangkan antara dua faktor penting yang sering kali saling bertentangan:
Anda menginginkan dokumen yang kecil: Hal ini memastikan bahwa penyematan dokumen mencerminkan maknanya secara akurat. Jika dokumen terlalu panjang, penyematan dapat kehilangan maknanya.
Anda menginginkan dokumen yang cukup panjang sehingga konteks setiap bagian tetap terjaga.
Peran ParentDocumentRetriever Untuk menyeimbangkan kedua persyaratan ini, alat yang disebut ParentDocumentRetriever digunakan. Alat ini memecah dokumen menjadi bagian-bagian yang lebih kecil dan mengelola bagian-bagian ini. Ketika mencari, alat ini pertama-tama menemukan potongan-potongan kecil ini, dan kemudian menggunakan pengenal (ID) dokumen asli (atau bagian yang lebih besar) yang menjadi bagian dari dokumen tersebut untuk mendapatkan konteks lengkapnya.
Ketika kami mengatakan “dokumen induk”, yang kami maksud adalah dokumen asli yang darinya potongan-potongan kecil tersebut dipisahkan. Ini bisa berupa keseluruhan dokumen, atau bisa juga bagian lain yang lebih besar. Dengan cara ini, Anda dapat menentukan dengan tepat apa yang dimaksud oleh dokumen tersebut, sambil tetap mempertahankan konteks keseluruhan.
Penganturan
Memanfaatkan struktur hirarkis di antara dokumen:
ParentDocumentRetrievermemanfaatkan struktur hirarkis di antara dokumen untuk meningkatkan efisiensi pencarian dokumen.Meningkatkan kinerja pencarian: Anda dapat dengan cepat menemukan dokumen yang relevan dan secara efektif menemukan dokumen yang memberikan jawaban terbaik untuk pertanyaan yang diberikan. Ada dua persyaratan yang saling bertentangan yang sering muncul saat mencari dokumen:
%pip install -qU deeplakeBuat objek TextLoader untuk memuat beberapa file teks dan memuat data.
from langchain.storage import InMemoryStore
from langchain_community.document_loaders import TextLoader
from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain.retrievers import ParentDocumentRetrieverMencari seluruh dokumen
Dalam mode ini, kita ingin mencari seluruh dokumen, jadi kita hanya akan menentukan child_splitter.
Kemudian, kita juga akan menentukan parent_splitter untuk membandingkan hasilnya.
Menambahkan daftar dokumen dengan fungsi retriever.add_documents(docs, ids = None).
Jika
ids = None, maka akan dibuat secara otomatis. Jikaadd_to_docstore = False, dokumen tidak akan ditambahkan sebagai duplikat, namun nilai ids diperlukan untuk memeriksa duplikat.
Kode ini seharusnya mengembalikan dua kunci, karena kita telah menambahkan dua dokumen.
Panggil metode
yield_keys()pada objekstoreuntuk mengubah nilai kunci yang dikembalikan menjadi sebuah daftar.
Sekarang mari kita panggil fungsi pencarian Vector Store.
Karena kita menyimpan potongan-potongan kecil, kita akan melihat potongan-potongan kecil yang dikembalikan dalam hasil pencarian.
Kita menggunakan metode similarity_search dari objek vectorstore untuk melakukan pencarian kemiripan.
Keluaran sub_docs[0].page_content.
Sekarang mari kita cari di seluruh retriever, yang akan mengembalikan dokumen yang relatif besar karena retriever mengembalikan dokumen dengan potongan-potongan kecil di dalamnya.
Gunakan metode get_relevant_documents() pada objek retriever untuk mengambil dokumen yang relevan dengan kueri.
Keluarkan beberapa isi dari dokumen yang diambil (retrieved_docs[0]).
Mencari dari potongan berukuran lebih besar
Seperti hasil sebelumnya, seluruh dokumen mungkin terlalu besar untuk dicari sebagaimana adanya.
Dalam kasus ini, yang sebenarnya ingin kita lakukan adalah pertama-tama membagi dokumen mentah menjadi potongan-potongan yang lebih besar, lalu menjadi potongan-potongan yang lebih kecil.
Kita kemudian mengindeks bagian yang lebih kecil, tetapi saat mencari, kita mengambil bagian yang lebih besar (tetapi tetap tidak seluruh dokumen).
Buat dokumen induk dan anak menggunakan
RecursiveCharacterTextSplitter.Dokumen induk memiliki
chunk_sizeyang disetel ke 1200.Dokumen anak memiliki
chunk_sizeyang disetel ke 300, dan dibuat dengan ukuran yang lebih kecil dari dokumen induk.
Ini adalah kode untuk menginisialisasi ParentDocumentRetriever.
Parameter
vectorstoremenentukan penyimpanan vektor yang menyimpan vektor dokumen.Parameter
docstoremenentukan penyimpanan dokumen yang menyimpan data dokumen.Parameter
child_splittermenentukan pemisah dokumen yang digunakan untuk membagi dokumen anak.Parameter
parent_splittermenentukan pemisah dokumen yang digunakan untuk membagi dokumen induk.
ParentDocumentRetriever menangani struktur dokumen hirarkis, memisahkan dan menyimpan dokumen induk dan anak secara terpisah. Hal ini memungkinkan Anda memanfaatkan dokumen induk dan anak secara efektif saat melakukan pencarian.
Menambahkan docs ke objek retriever, yang berfungsi untuk menambahkan dokumen baru ke kumpulan dokumen yang dapat diambil oleh retriever.
Anda dapat melihat bahwa jumlah dokumen sekarang jauh lebih besar. Dokumen-dokumen ini merupakan potongan-potongan yang lebih besar.
Mari kita periksa apakah penyimpanan vektor default masih mengambil potongan-potongan kecil.
Lakukan pencarian kemiripan menggunakan metode similarity_search pada objek vectorstore.
Kali ini, kita menggunakan metode get_relevant_documents dari objek retriever untuk mengambil dokumen.
Last updated