04. RAPTOR: Ringkasan Konteks Panjang
Instalasi
pip install -qU langchain umap-learn scikit-learn langchain_community tiktoken langchain-openai langchainhub chromadb langchain-anthropicRAPTOR: Recursive Abstractive Processing for Tree-Organized Retrieval
Makalah RAPTOR menyajikan pendekatan yang menarik untuk pengindeksan dan pengambilan dokumen.
Leafs adalah kumpulan dokumen awal.
Leafs di-embedding dan dikelompokkan.
Kemudian, klaster tersebut meringkas informasi antara dokumen-dokumen serupa pada tingkat yang lebih tinggi (lebih abstrak).
Proses ini dilakukan secara rekursif, membentuk "pohon" yang mengarah dari dokumen asli (leafs) ke ringkasan yang lebih abstrak.
Ini dapat diterapkan pada berbagai skala; leafs dapat berupa:
Potongan teks dalam satu dokumen (seperti yang ditunjukkan dalam makalah)
Seluruh dokumen (seperti yang ditunjukkan di bawah ini)
Dengan LLM yang memiliki konteks lebih panjang, ini dapat diterapkan pada seluruh dokumen.
Dokumen
Mari kita terapkan ini pada dokumen LCEL di LangChain.
Dalam hal ini, setiap dokumen adalah halaman web unik dari dokumen LCEL.
Konteksnya bervariasi dari kurang dari 2.000 token hingga lebih dari 10.000 token.
Ini menjelaskan proses mengekstraksi data teks dari dokumen web, menghitung jumlah token dalam teks, dan memvisualisasikannya dalam bentuk histogram.
Pustaka tiktoken digunakan untuk menghitung jumlah token dalam sebuah string berdasarkan nama encoding yang diberikan.
Kelas RecursiveUrlLoader digunakan untuk memuat dokumen web secara rekursif dari URL yang ditentukan. Dalam proses ini, BeautifulSoup digunakan untuk mengekstrak teks dari dokumen HTML.
Dokumen dimuat dari beberapa URL dan semua data teks dikumpulkan ke dalam satu daftar.
Untuk setiap teks dokumen, fungsi num_tokens_from_string dipanggil untuk menghitung jumlah token, dan hasilnya disimpan dalam daftar.
Matplotlib digunakan untuk memvisualisasikan distribusi jumlah token yang dihitung sebagai histogram. Histogram menunjukkan jumlah token di sumbu x dan frekuensi dokumen dengan jumlah token tersebut di sumbu y.
Histogram membantu memahami distribusi data dan memberikan representasi visual dari distribusi panjang data teks
Ini menjelaskan proses mengurutkan dan menggabungkan teks dokumen serta menghitung jumlah token:
Urutkan dokumen (docs) berdasarkan kunci "source" di metadata.
Balikkan urutan daftar dokumen yang telah diurutkan.
Gabungkan konten dokumen yang dibalik menggunakan pemisah khusus (
"\n\n\n --- \n\n\n").Hitung jumlah token dari konten yang digabungkan menggunakan fungsi num_tokens_from_string, dan cetak hasilnya. Dalam hal ini, digunakan model "cl100k_base".

Proses membagi teks menggunakan RecursiveCharacterTextSplitter dijelaskan sebagai berikut:
Tetapkan variabel chunk_size_tok untuk menentukan ukuran setiap potongan teks menjadi 2000 token.
Gunakan metode from_tiktoken_encoder dari RecursiveCharacterTextSplitter untuk menginisialisasi pembagi teks. Pada langkah ini, atur chunk_size dan chunk_overlap menjadi 0.
Panggil metode split_text dari pembagi teks yang telah diinisialisasi untuk membagi teks yang telah digabungkan dan disimpan di variabel concatenated_content. Hasil dari pembagian ini disimpan dalam variabel texts_split.
Model
Anda dapat menguji berbagai model, termasuk seri Claude3 yang baru.
Jangan lupa untuk mengatur API key terkait:
OPENAI_API_KEY untuk OpenAI, dan ANTHROPIC_API_KEY jika menggunakan Anthropic.
Gunakan ChatOpenAI atau ChatAnthropic + OpenAIEmbeddings untuk mengimplementasikan model chatbot.
Instansiasi OpenAIEmbeddings untuk menginisialisasi fungsionalitas embedding dari OpenAI.
Gunakan ChatOpenAI atau ChatAnthropic, atur temperature menjadi 0, dan inisialisasi model chatbot.
Menggunakan Cache Embedding.
Inisialisasi model.
Membangun Tree
Pendekatan klastering dalam pembangunan pohon mencakup beberapa ide menarik:
GMM (Gaussian Mixture Model):
Memodelkan distribusi titik data di berbagai klaster.
Mengevaluasi Bayesian Information Criterion (BIC) model untuk menentukan jumlah klaster yang optimal.
UMAP (Uniform Manifold Approximation and Projection)
Mendukung klastering.
Mengurangi dimensi dari data berdimensi tinggi.
UMAP membantu menekankan pengelompokan alami berdasarkan kesamaan titik data.
Klastering Lokal dan Global
Digunakan untuk menganalisis data dalam berbagai skala.
Secara efektif menangkap pola-pola halus dan pola yang lebih luas dalam data.
Penetapan Ambang Batas
Diterapkan dalam konteks GMM untuk menentukan keanggotaan klaster.
Berdasarkan distribusi probabilitas (menetapkan titik data ke ≥ 1 klaster).
Kode untuk GMM dan pengaturan ambang batas berasal dari Sarthi et al., seperti yang disebutkan di dua sumber berikut:
Penghargaan penuh diberikan kepada kedua penulis.
Fungsi global_cluster_embeddings menggunakan UMAP untuk melakukan reduksi dimensi global dari embeddings.
Mengurangi dimensi embeddings yang dimasukkan ke dimensi yang ditentukan (dim) menggunakan UMAP.
n_neighbors menentukan jumlah tetangga yang dipertimbangkan untuk setiap titik; jika tidak disediakan, pengaturan defaultnya adalah akar kuadrat dari jumlah embeddings.
metric menentukan metrik jarak yang akan digunakan oleh UMAP.
Hasilnya, embeddings dikembalikan sebagai array numpy dengan dimensi yang dikurangi sesuai dengan yang ditentukan.
Mengimplementasikan fungsi local_cluster_embeddings untuk melakukan reduksi dimensi lokal pada data embedding.
Embedding yang dimasukkan direduksi ke dimensi yang ditentukan (dim) menggunakan UMAP. Selama proses reduksi dimensi, jumlah tetangga (num_neighbors) dan metrik jarak (metric) untuk setiap titik digunakan sebagai parameter. Akhirnya, embedding yang telah direduksi dimensinya dikembalikan sebagai array numpy.
Fungsi get_optimal_clusters digunakan untuk menentukan jumlah klaster optimal berdasarkan data embedding yang diberikan. Proses ini dilakukan dengan menghitung Bayesian Information Criterion (BIC) menggunakan Gaussian Mixture Model (GMM).
Embedding yang dimasukkan disediakan dalam bentuk array numpy.
max_clusters menentukan jumlah maksimum klaster yang dipertimbangkan. Nilai default adalah 50.
random_state menggunakan nilai tetap untuk reprodusibilitas.
Fungsi ini mencoba beberapa jumlah klaster untuk embedding yang dimasukkan dan menghitung nilai BIC untuk setiap jumlah.
Jumlah klaster dengan nilai BIC minimum ditentukan sebagai jumlah klaster optimal dan dikembalikan.
Fungsi ini dapat digunakan untuk secara otomatis menemukan jumlah klaster yang paling baik menjelaskan data dalam masalah klastering.
Fungsi GMM_cluster mengelompokkan embedding menggunakan Gaussian Mixture Model (GMM) berdasarkan ambang batas probabilitas.
Embedding yang dimasukkan disediakan dalam bentuk array numpy.
threshold adalah ambang batas probabilitas yang digunakan untuk menetapkan embedding ke klaster tertentu.
random_state adalah nilai seed yang digunakan untuk reprodusibilitas hasil.
Fungsi
get_optimal_clustersdipanggil untuk menentukan jumlah klaster yang optimal.Berdasarkan jumlah klaster yang ditentukan, Gaussian Mixture Model diinisialisasi dan dilatih pada embedding yang dimasukkan.
Probabilitas penetapan klaster untuk setiap embedding dihitung, dan jika probabilitas melebihi ambang batas yang diberikan, embedding ditetapkan ke klaster.
Akhirnya, fungsi ini mengembalikan tuple yang berisi label klaster untuk embedding dan jumlah klaster yang ditentukan.
Fungsi perform_clustering melakukan reduksi dimensi, klastering global menggunakan Gaussian Mixture Model (GMM), dan klastering lokal di dalam setiap klaster global pada embedding, serta mengembalikan hasil klastering.
Reduksi Dimensi:
Fungsi ini melakukan reduksi dimensi pada embedding yang dimasukkan menggunakan UMAP, mengurangi dimensi embedding ke dimensi yang ditentukan (dim).
Klastering Global:
Fungsi ini melakukan klastering global pada embedding berdimensi rendah menggunakan GMM. Penetapan klaster ditentukan berdasarkan ambang batas probabilitas yang diberikan (threshold).
Klastering Lokal:
Dalam setiap klaster global, dilakukan klastering lokal lebih lanjut. Berdasarkan hasil klastering global, reduksi dimensi dan klastering GMM diterapkan lagi pada embedding di dalam setiap klaster global.
Output Akhir:
Fungsi ini menetapkan ID klaster global dan lokal ke semua embedding dan mengembalikan daftar yang berisi ID klaster untuk setiap embedding dalam urutan munculnya. Daftar ini mencakup array ID klaster yang sesuai dengan setiap embedding.
Fungsi ini menggabungkan klastering global dan lokal untuk data berdimensi tinggi, memungkinkan hasil klastering yang lebih rinci dan memberikan analisis yang lebih efektif dari struktur data yang kompleks.
Mengimplementasikan fungsi embed untuk menghasilkan embedding dari daftar dokumen teks.
Menerima daftar dokumen teks (texts) sebagai input.
Menggunakan metode
embed_documentsdari objekembduntuk menghasilkan embedding dari dokumen teks.Mengonversi embedding yang dihasilkan ke dalam format
numpy.ndarraydan mengembalikannya.
Fungsi embed_cluster_texts menghasilkan embedding dan klasterisasi dari daftar teks, mengembalikan pandas.DataFrame yang berisi teks asli, embedding yang sesuai, dan label klaster yang diberikan.
Menghasilkan embedding untuk daftar teks yang diberikan.
Melakukan klasterisasi berdasarkan embedding yang dihasilkan menggunakan fungsi
perform_clusteringyang telah didefinisikan sebelumnya.Menginisialisasi pandas.DataFrame untuk menyimpan hasilnya.
Menyimpan teks asli, daftar embedding, dan label klaster di DataFrame.
Fungsi ini menggabungkan pembuatan embedding dan klasterisasi dalam satu langkah, memudahkan analisis struktural dan pengelompokan data teks.
Fungsi fmt_txt memformat dokumen teks dari pandas DataFrame menjadi satu string.
Menerima DataFrame sebagai parameter input, di mana DataFrame harus berisi kolom 'text' dengan dokumen teks yang akan diformat.
Semua dokumen teks digabungkan menggunakan pemisah khusus ("--- --- \n --- ---") dan dikembalikan sebagai satu string.
Fungsi ini mengembalikan satu string yang berisi dokumen teks yang telah digabungkan.
Proses ini melibatkan pembuatan embedding dari data teks, pengelompokan (clustering), dan pembuatan ringkasan untuk setiap klaster.
Embedding dihasilkan untuk daftar teks yang diberikan, dan klasterisasi berdasarkan kemiripan dilakukan. Hasilnya adalah sebuah DataFrame bernama
df_clusters, yang berisi teks asli, embedding, dan informasi penugasan klaster.Untuk mempermudah penanganan penugasan klaster, entri DataFrame diperluas. Setiap baris diubah menjadi DataFrame baru yang berisi teks, embedding, dan klaster.
Identifikator klaster unik diekstraksi dari DataFrame yang diperluas, dan teks untuk setiap klaster diformat untuk menghasilkan ringkasan. Ringkasan ini disimpan dalam DataFrame
df_summary, yang berisi ringkasan setiap klaster, tingkat detail yang ditentukan, dan identifikator klaster.Akhirnya, fungsi ini mengembalikan tuple yang berisi dua DataFrame. DataFrame pertama mencakup teks asli, embedding, dan informasi penugasan klaster, sedangkan DataFrame kedua berisi ringkasan untuk setiap klaster, tingkat detail, dan identifikator klaster.
Fungsi ini mengimplementasikan proses embedding, klasterisasi, dan peringkasan data teks secara rekursif.
Menghasilkan embedding, melakukan klasterisasi, dan merangkum daftar teks yang diberikan, serta menyimpan hasilnya di setiap langkah.
Fungsi ini berjalan hingga mencapai level rekursi maksimum yang ditentukan, atau hingga jumlah klaster unik menjadi 1.
Pada setiap langkah rekursif, hasil klasterisasi dan peringkasan di level saat ini dikembalikan dalam bentuk DataFrame dan disimpan dalam kamus hasil.
Jika level saat ini lebih kecil dari level rekursi maksimum dan jumlah klaster unik lebih besar dari 1, hasil peringkasan di level saat ini digunakan sebagai input teks untuk level berikutnya, dan fungsi ini dipanggil secara rekursif.
Akhirnya, fungsi ini mengembalikan kamus yang berisi DataFrame klaster dan DataFrame ringkasan untuk setiap level.
Dalam makalah ini, collapsed tree retrieval melaporkan kinerja terbaik.
Ini melibatkan perataan struktur tree menjadi satu layer, diikuti dengan menerapkan k-nearest neighbor (kNN) search ke semua node secara bersamaan.
Berikut adalah proses sederhana untuk melakukannya.
Proses membangun penyimpanan yang telah di-vektorisasi dan dapat dicari menggunakan Chroma vector store untuk data teks dijelaskan.
Awalnya, salin data teks yang disimpan di leaf_texts ke dalam variabel all_texts.
Iterasi melalui data results, ekstraksi teks yang diringkas di setiap level, dan tambahkan ke all_texts.
Konversikan nilai-nilai dalam kolom summaries dari DataFrame setiap level menjadi daftar dan ekstrak mereka.
Tambahkan ringkasan yang diekstraksi ke all_texts.
Bangun Chroma vector store menggunakan semua data teks (all_texts).
Panggil Chroma.from_texts untuk membuat vektor dari data teks dan membuat vector store.
Untuk membuat penyimpanan vektor yang dibuat dapat dicari, inisialisasi retriever dengan memanggil metode .as_retriever().
Melalui proses ini, data teks, termasuk ringkasan dari berbagai level, di-vektorisasi dan Chroma vector store yang dapat dicari dibangun berdasarkan hal tersebut.
Simpan DB secara lokal.
Mengimplementasikan proses untuk mendefinisikan Retrieval Augmented Generation (RAG) chain dan menangani permintaan untuk contoh kode spesifik.
Mengambil prompt RAG menggunakan
hub.pull.Mendefinisikan fungsi
format_docsuntuk memformat dokumen. Fungsi ini menggabungkan konten halaman dokumen dan mengembalikannya.Membangun RAG chain. Chain ini mengambil konteks dari retriever, memformatnya menggunakan fungsi
format_docs, dan memproses pertanyaan.Gunakan
RunnablePassthrough()untuk meneruskan pertanyaan sebagaimana adanya.Chain ini mem-parsing output akhir sebagai string melalui prompt, model, dan StrOutputParser().
Gunakan metode
rag_chain.invokeuntuk menangani pertanyaan: "How to define a RAG chain? Give me a specific code example."
Last updated