Model bahasa besar (LLM) luar biasa kuat, tetapi pengetahuan mereka terbatas pada kumpulan data pelatihan mereka. Ketika menjawab pertanyaan, terutama tentang informasi yang spesifik, berkembang, atau berpemilik, LLM dapat berhalusinasi atau memberikan jawaban yang umum dan tidak relevan. Retrieval augmented generation (RAG) membantu dengan mengambil informasi yang relevan untuk LLM dari sumber data eksternal.
Namun, tidak semua RAG diciptakan sama. Corrective retrieval augmented generation (cRAG) tidak hanya dibangun di atas RAG yang lebih tradisional, tetapi juga merupakan peningkatan yang signifikan. Metode ini dirancang untuk menjadi lebih kuat dengan mengevaluasi kualitas dan relevansi hasil yang diambil. Jika konteksnya lemah, tidak relevan, atau berasal dari sumber yang tidak dapat dipercaya, cRAG berusaha mencari informasi yang lebih baik melalui tindakan korektif atau secara eksplisit menolak untuk menjawab, alih-alih mengarang jawaban. Teknik ini membuat sistem cRAG lebih dapat diandalkan dan dipercaya untuk aplikasi penting seperti menjawab pertanyaan terkait polis.
Dalam tutorial ini, Anda akan belajar bagaimana membangun sistem korektif RAG (CRag) yang kuat dengan menggunakan model IBM® Granite pada Watsonx dan LangChain. Kerangka kerja serupa seperti LlamaIndex atau LangGraph juga dapat digunakan untuk membangun aliran RAG yang kompleks dengan node yang berbeda. Teknik seperti penyempurnaan dapat lebih meningkatkan kinerja LLM spesifik untuk RAG khusus domain. LLM seperti yang ada di OpenAI (misalnya, model GPT seperti ChatGPT) juga merupakan pilihan populer untuk agen semacam itu, meskipun tutorial ini berfokus pada IBM Granite.
Di sini, kita akan berfokus pada contoh penggunaan: menjawab pertanyaan tentang dokumen polis asuransi tertentu (PDF). Tutorial ini akan memandu Anda dalam menerapkan algoritma RAG canggih yang:
Mengambil informasi dari dokumen PDF Anda sendiri.
Jika dokumen internal tidak cukup untuk menghasilkan jawaban, agen dapat menggunakan pencarian web eksternal (Tavily) sebagai cadangan.
Agen dengan cerdas menyaring hasil eksternal yang tidak relevan sehingga jawabannya disesuaikan dengan kebijakan pribadi.
Agen akan memberikan tanggapan yang jelas dan terbatas dengan informasi parsial jika tersedia, atau penolakan yang jelas jika konteksnya tidak ada.
Tutorial ini merupakan demonstrasi pembuatan agen kueri polis asuransi yang dirancang untuk menganalisis dokumen polis (brosur PDF) dan menjawab pertanyaan pengguna secara akurat. Kami menggunakan model IBM Granite dan LangChain untuk membangun agen dengan langkah-langkah pengambilan dan verifikasi yang kuat yang memastikan jawaban berkualitas tinggi dengan sumber terbatas.
Mari kita pahami bagaimana prinsip-prinsip utama RAG yang andal berlaku dalam contoh penggunaan kami.
Basis pengetahuan internal (PDF): Sumber kebenaran utama agen adalah PDF polis asuransi yang Anda berikan. Ini mengubah dokumen ini menjadi penyimpanan vektor yang dapat dicari.
Cadangan pencarian eksternal (Tavily): Jika basis pengetahuan internal tidak memiliki informasi yang cukup, agen dapat berkonsultasi dengan sumber web eksternal melalui Tavily. Tavily adalah mesin pencari yang dibangun khusus untuk agen AI dan LLM yang menghasilkan pengambilan real-time yang lebih cepat melalui antarmuka pemrograman aplikasi (API) untuk aplikasi berbasis RAG.
Penilaian konteks: Evaluator pengambilan berbasis LLM (bertindak sebagai penilai) akan memberikan skor untuk relevansi item yang diambil dari PDF internal Anda sekaligus memastikan bahwa hanya item berkualitas tinggi yang diambil yang disertakan.
Penulisan ulang kueri: Untuk pencarian web, agen dapat menulis ulang kueri pengguna untuk meningkatkan peluang menemukan informasi eksternal yang relevan.
Verifikasi sumber: Pemeriksaan yang didukung LLM mengevaluasi apakah hasil pencarian web eksternal relevan dengan polis asuransi swasta, menyaring informasi umum, atau detail tentang program kesehatan masyarakat (seperti Medi-Cal). Fungsi ini mencegah dibuatnya jawaban yang menyesatkan dan memungkinkan koreksi diri, sehingga membantu penyempurnaan pengetahuan.
Pembuatan yang dibatasi: Prompt terakhir pada LLM secara tegas menginstruksikan untuk hanya menggunakan konteks yang disediakan, memberikan jawaban yang tepat, menyatakan ketika informasi tidak tersedia, atau memberikan jawaban parsial dengan batasan yang tegas. Fungsi ini meningkatkan kemampuan beradaptasi dan keandalan respons yang dihasilkan.
Anda memerlukan akun IBM Cloud untuk membuat proyek watsonx.ai . Pastikan Anda memiliki akses ke Kunci API watsonx dan ID Proyek Anda. Anda juga memerlukan kunci API untuk Tavily AI untuk kemampuan pencarian web.
Meskipun terdapat pilihan beberapa alat, tutorial ini akan memandu Anda untuk menyiapkan akun IBM menggunakan Jupyter Notebook.
Langkah ini akan membuka lingkungan notebook tempat Anda dapat menyalin kode dari tutorial ini. Sebagai alternatif, Anda dapat mengunduh notebook ini ke sistem lokal Anda dan mengunggahnya ke proyek watsonx.ai Anda sebagai aset. Untuk melihat tutorial Granite lainnya, kunjungi Komunitas IBM Granite. Tutorial ini juga tersedia di Github.
Untuk bekerja dengan kerangka kerja LangChain dan mengintegrasikan IBM WatsonXLLM, kita perlu menginstal beberapa pustaka penting. Mari kita mulai dengan menginstal paket yang diperlukan. Kumpulan ini mencakup langchain untuk kerangka kerja RAG, langchain-ibm untuk integrasi watsonx, faiss-cpu untuk penyimpanan vektor yang efisien, PyPDF2 untuk memproses PDF, transformator kalimat untuk mendapatkan penanaman dan permintaan untuk panggilan API web. Pustaka ini penting untuk menerapkan machine learning dan solusi NLP.
Catatan: Tidak diperlukan GPU, tetapi eksekusi dapat lebih lambat pada sistem berbasis CPU. Langkah ini akan membuka lingkungan notebook tempat Anda dapat menyalin kode dari tutorial ini. Tutorial ini juga tersedia di GitHub.
Selanjutnya, impor semua modul yang diperlukan dan berikan kunci API Anda dengan aman untuk watsonx dan Tavily, bersama dengan ID Proyek watsonx Anda.
os membantu bekerja dengan sistem operasi.
io memungkinkan untuk bekerja dengan aliran data.
getpass menggunakan cara yang aman untuk menangkap informasi sensitif seperti kunci API dan tidak menampilkan input ke layar.
PyPDF2.PdfReader memungkinkan ekstraksi konten dari PDF.
langchain_ibm.WatsonxLLM memungkinkan kita untuk menggunakan IBM Watsonx Granite LLM dengan mudah dalam kerangka kerja LangChain.
langchain.embeddings.HuggingFaceEmbeddings mengambil model HuggingFace dan menghasilkan penanaman tekstual yang penting untuk pencarian semantik.
langchain.vectorstores.FAISS adalah sebuah pustaka untuk penyimpanan vektor yang efisien dan pencarian kemiripan yang memungkinkan kita untuk membuat indeks vektor dan mengajukan kueri.
langchain.text_splitter.RecursiveCharacterTextSplitter membantu membagi konstituen teks yang besar menjadi potongan kecil yang diperlukan untuk memproses dokumen yang tidak muat dalam memori.
langchain.schema.Document menunjukkan unit teks yang berubah-ubah dengan metadata terkait yang menjadikannya sebuah fondasi dalam langchain.
requests digunakan untuk membuat permintaan HTTP secara eksternal ke API.
botocore.client.Config adalah kelas konfigurasi yang digunakan untuk menentukan pengaturan konfigurasi untuk klien AWS/IBM Cloud Object Storage.
ibm_boto3 adalah IBM Cloud Object Storage SDK untuk Python yang membantu berinteraksi dengan cloud object storage.
langchain.prompts.PromptTemplate menawarkan cara untuk membuat prompt terstruktur yang dapat digunakan kembali untuk model bahasa.
langchain.tools.BaseTool adalah kelas dasar tempat Anda membuat alat khusus yang dapat diberikan kepada agen LangChain untuk digunakan.
Langkah ini menyiapkan semua alat dan modul yang kita butuhkan untuk memproses teks, membuat penanaman, menyimpannya dalam basis data vektor, dan berinteraksi dengan IBM watsonx LLM. Ini menetapkan semua bagian yang diperlukan untuk membuat sistem RAG dunia nyata, yang mampu mencari sumber, menanyakan, dan mencari berbagai jenis data.
Dalam langkah ini, kami akan memuat PDF polis asuransi dari IBM Cloud Object Storage. Kode membaca PDF, membaca konten teks, dan membagi teks menjadi potongan yang lebih kecil dan dapat dikelola. Potongan ini diubah menjadi penanaman numerik dan disimpan dalam penyimpanan vektor FAISS yang mempersiapkan kita untuk pencarian kesamaan semantik pada lain waktu dalam konteks lokal untuk mengoptimalkan hasil pengambilan.
ibm_boto3.klien memungkinkan klien untuk berinteraksi dengan IBM Cloud Object Storage.
Bucket adalah nama bucket cloud object storage yang berisi PDF.
object_key adalah nama PDF di bucket cloud object storage.
cos_client.get_object(...).read() mengambil konten file PDF dalam cloud object storage sebagai byte.
io.BytesIO mengubah byte mentah PDF menjadi aliran biner dalam memori dalam format yang dapat digunakan oleh PdfReader.
PdfReader membuat objek yang dapat mengurai dan mengekstraksi teks dari PDF.
page.extract_text() mengekstraksi teks dari satu halaman dalam PDF.
RecursiveCharacterTextSplitter dikonfigurasikan untuk membagi teks yang diekstrak menjadi potongan berisi 500 karakter dengan 50 karakter yang tumpang tindih, oleh karena itu semuanya tetap dalam konteks.
splitter.split_text(text) menjalankan pemisahan semua halaman teks PDF menjadi potongan yang lebih kecil.
HuggingFaceEmbeddings memuat model transformator kalimat yang telah dilatih sebelumnya untuk mengubah potongan teks menjadi representasi vektor yang padat.
FAISS.from_texts(chunks, embeddings) membangun indeks FAISS dalam memori yang memungkinkan potongan teks dapat dicari berdasarkan kemiripan semantiknya.
Langkah ini menangani pengindeksan penuh dokumen PDF dari cloud ke teks yang siap LLM dan pengindeksan yang nyaman untuk pengambilan secara real-time.
Dalam langkah ini, Anda akan mengonfigurasi IBM Granite LLM untuk mendorong penalaran agen Anda dan mengintegrasikannya dengan fungsi pencarian web Tavily. Parameter LLM diatur untuk respons yang faktual dan stabil.
WatsonXLLM membuat instans pembungkus LLM untuk IBM watsonx yang memungkinkan interaksi dengan model Granite.
model_id="ibm/granite-3-2b-instruct" adalah model IBM Granite (model instruksi parameter 2,7 miliar) yang dirancang untuk tugas AI generatif berbasis instruksi.
class TavilySearch(BaseTool) mendefinisikan alat LangChain khusus untuk melakukan pencarian web dengan menggunakan API Tavily.
tavily_tool = TavilySearch() membuat sebuah contoh yang dapat dieksekusi dari alat pencarian Tavily khusus.
Ketika kita menginisialisasi watsonxLLM, nilai url, apikey, dan project_id dari kredensial yang telah kita siapkan sebelumnya akan diteruskan untuk mengautentikasi dan menyambungkan ke layanan. Parameternya, seperti "max_new_token": 300, membatasi panjang respons dan "temperature": 0.2 mengontrol kreativitas output, mendukung hasil yang lebih deterministik.
Definisi kelas TavilySearch mencakup deskripsi fungsinya. Logikanya terdapat di dalam metode def _run(self, query: str). Dalam metode ini, kami membuat permintaan HTTP POST ke titik akhir API Tavily, termasuk TAVILY_API_KEY dan kueri pencarian dalam muatan JSON. Kami kemudian memverifikasi apakah ada kesalahan HTTP dengan response.raise_for_status() dan mengurai respons JSON untuk mengakses cuplikan konten dari hasil pencarian pertama.
Langkah ini menyiapkan model bahasa untuk pembuatan teks dan menyertakan alat pencarian web eksternal sebagai cara untuk menambah pengetahuan model bahasa.
Langkah ini mendefinisikan berbagai templat prompt yang memandu perilaku LLM pada berbagai tahap proses RAG. Pendekatan ini mencakup prompt untuk menilai relevansi potongan dokumen internal, menulis ulang kueri pengguna untuk pencarian web yang lebih baik dan prompt penting untuk memverifikasi sumber hasil pencarian web. Fungsi pembantu untuk menilai potongan dan mengambilnya dari penyimpanan vektor juga ditentukan.
Langkah ini mendefinisikan berbagai templat prompt yang memandu perilaku LLM pada berbagai tahap proses RAG. Permintaan untuk memverifikasi relevansi potongan dokumen internal, menulis ulang kueri pengguna untuk pencarian web yang lebih baik dan prompt penting untuk memverifikasi bahwa sumber hasil pencarian web disertakan. Fungsi pembantu untuk menilai potongan dan mengambilnya dari penyimpanan vektor juga ditentukan.
PromptTemplate.from_template adalah fungsi utilitas dari LangChain untuk membuat templat yang dapat digunakan kembali untuk membuat prompt.
scoring_prompt_template mendefinisikan sebuah prompt yang menginstruksikan LLM untuk bertindak sebagai evaluator dan memberikan skor relevansi (0-5) ke potongan konteks tertentu berdasarkan sebuah pertanyaan.
rewrite_prompt_template mendefinisikan prompt yang memandu LLM untuk meningkatkan atau membuat pertanyaan asli pengguna lebih jelas untuk pencarian.
CONTEXT_SOURCE_VERIFICATION_PROMPT mendefinisikan prompt yang menginstruksikan LLM untuk memverifikasi apakah sepotong teks (misalnya, dari pencarian web) berasal dari konteks polis pribadi atau sumber umum atau publik.
def score_chunks(chunks, query) mendefinisikan sebuah fungsi yang mengambil daftar potongan teks dan sebuah kueri, lalu menilai relevansi setiap potongan menggunakan LLM.
def retrieve_from_vectorstore (query) mendefinisikan fungsi untuk mengambil dokumen yang paling mirip dari penyimpanan vektor FAISS.
Di dalam fungsi score_chunks, sebuah daftar skor kosong diinisialisasi. Untuk setiap potongan, scoring_prompt_template diformat dengan kueri dan potongan tertentu. Prompt yang diformat ini kemudian dikirim ke LLM dan respons disederhanakan. Fungsi ini mencoba mengekstraksi skor integer (skor biner jika disederhanakan menjadi relevan atau tidak relevan) dengan mengidentifikasi baris "Score:" dalam respons model. Potongan bersama dengan skor yang diurai atau defaultnya kemudian ditambahkan ke daftar skor. Bagian sistem ini bertindak sebagai evaluator pengambilan atau penilai.
Fungsi retrieve_from_vectorstore mengimplementasikan vectorstore.similarity_search untuk menemukan 8 potongan dokumen yang paling relevan berdasarkan kueri dan mengambil page_content dari objek Dokumen LangChain yang diambil ini.
Langkah ini membangun penopang konseptual untuk sistem RAG korektif sehingga LLM akan mengevaluasi konteks dan cara mengambil pengetahuan dari sumber pengetahuan internal dan eksternal.
Pengambilan awal adalah fungsi yang memindai penyimpanan vektor PDF.
Penilaian konteks mengambil potongan PDF yang telah diambil untuk menilai konteks sesuai dengan relevansinya.
Kembali ke tavily jika tidak ada konteks yang cukup relevan dari PDF, kemudian mengajukan kueri kepada Tavily (pencarian web).
Verifikasi sumber adalah langkah yang didukung oleh LLM yang memeriksa apakah hasil Tavily relevan dengan polis pribadi sebelum menggunakannya. Fungsi ini mencegah jawaban yang menyesatkan dari program kesehatan masyarakat.
Penulisan ulang kueri dan pencarian tavily kedua jika masih belum ada konteks yang baik, kueri akan ditulis ulang dan pencarian Tavily dicoba lagi.
Keputusan akhir ketika ada konteks yang relevan, maka akan dikirim ke LLM dengan prompt (yang ketat) untuk membuat jawabannya. Jika tidak ada konteks yang relevan setelah semua upaya yang layak, maka penolakan yang sopan akan dikirimkan.
Bagian pertama dari parameter policy_context_keywords memungkinkan Anda untuk menambahkan istilah spesifik dari polis Anda (misalnya, nama, perusahaan asuransi) untuk membantu mempersempit pencarian Tavily.
MIN_CONTEXT_LENGTH mendefinisikan panjang minimum yang dapat diterima dari konteks yang diambil.
SIMILARITY_THRESHOLD mendefinisikan skor relevansi minimum yang harus dimiliki oleh sebuah potongan untuk dianggap "baik."
def corrective_rag(...) mendefinisikan fungsi utama yang mengatur seluruh alur kerja RAG korektif.
Fungsi corrective_rag dimulai dengan membuat retrieved_context_pieces untuk mengumpulkan konteks yang relevan. Pertama-tama, ia mengambil dan menilai chunks_from_vectorstore dari penyimpanan vektor PDF berdasarkan kueri, kemudian scored_chunks_vector mengevaluasi relevansinya dengan menggunakan model bahasa. Hanya good_chunks_vector yang memenuhi SIMILARITY_THRESHOLD yang disimpan. Current_context kemudian dikompilasi dari semua potongan ini.
Jika current_context kurang dari MIN_CONTEXT_LENGTH, sistem akan mencoba pencarian web. Ini membuat tavily_search_query, berpotensi menggabungkan policy_context_keywords. Pencarian langsung(tavily_context_direct) dilakukan. Yang terpenting, sebuah verification_prompt dibuat dan dikirimkan ke LLM untuk menentukan apakah hasil pencarian web(is_relevant_source) berasal dari polis pribadi dan bukan program publik. Jika YA, konteks ditambahkan.
Jika konteks tetap tidak mencukupi, sistem bersiap untuk menulis ulang kueri. Sistem menggunakan rewrite_prompt untuk mendapatkan improved_query dari LLM, lalu melakukan pencarian web kedua (tavily_context_rewritten). Konteks baru ini juga mengalami verifikasi sumber yang sama.
Terakhir, apakah len(current_context.strip()) == 0 adalah pemeriksaan terakhir. Jika tidak ada konteks relevan yang ditemukan setelah semua upaya, pesan penolakan yang telah ditentukan ditampilkan. Jika tidak, final_prompt dibuat dengan semua konteks yang telah diverifikasi dan dikirim ke model bahasa untuk menghasilkan jawaban akhir.
Seluruh fungsi corrective_rag menangani pengambilan, penilaian, dan memverifikasi fungsi RAG korektif yang telah diatur secara mendetail. Hal ini memungkinkan pembaruan basis pengetahuan dan aliran pengetahuan secara konstan dan memberikan manfaat berupa jawaban yang kuat dan sadar konteks.
Terakhir, jalankan fungsi corrective_rag dengan kueri sampel. Sangat penting untuk memberikan policy_context_keywords yang spesifik untuk dokumen PDF Anda. Kata kunci ini akan membantu pencarian web Tavily menjadi lebih relevan dengan polis Anda yang sebenarnya, mencegah informasi program kesehatan umum atau publik mencemari konteks Anda.
Amati pernyataan cetak untuk panjang konteks dan hasil verifikasi untuk memahami aliran informasi.
policy_specific_keywords = ["Super Star Health", "Care Health Insurance"] mendefinisikan daftar kata kunci yang relevan dengan polis asuransi yang diunggah, membantu mempersempit hasil pencarian web.
query = "..." mendefinisikan pertanyaan khusus yang mungkin diajukan pengguna.
result = corrective_rag(query, policy_context_keywords=policy_specific_keywords) memanggil fungsi corrective_rag yang utama dan meneruskan kueri pengguna dan kata sandi khusus polis untuk memulai seluruh proses RAG.
print("\n FINAL ANSWER (...)") menampilkan tajuk yang jelas sebelum mencetak jawaban yang dihasilkan.
print(result) menghasilkan jawaban akhir yang ditampilkan oleh sistem corrective_rag.
Langkah ini menunjukkan cara menggunakan sistem RAG korektif lengkap dengan contoh kueri dan kata kunci, yang mendemonstrasikan seluruh fungsionalitas dalam skenario dunia nyata.
RAG korektif yang diterapkan sepenuhnya mengoordinasikan basis pengetahuan PDF internal dengan layanan eksternal (Tavily) untuk mendapatkan informasi yang komprehensif untuk permintaan yang kompleks.
Sistem ini secara akurat mengevaluasi dan menyaring konteks yang diambil dengan menggunakan penilaian berbasis LLM dan verifikasi sumber penting untuk memastikan bahwa digunakan informasi yang valid dan dapat diandalkan.
Sistem ini menunjukkan kemampuan untuk meningkatkan pencarian eksternal dengan menulis ulang pertanyaan pengguna secara cerdas untuk meminta informasi yang lebih ditargetkan dan berkualitas lebih tinggi.
Dengan menggunakan pembuatan yang dibatasi, jawaban yang dapat diandalkan dan akurat secara kontekstual biasanya dihasilkan dan sistem dengan sopan menolak untuk menjawab jika tidak ada cukup informasi terverifikasi yang diketahui.
Contoh ini menunjukkan bagaimana LangChain dan IBM Granite LLM di watsonx dapat digunakan untuk mengembangkan aplikasi berbasis AI yang kuat dan dapat dipercaya di domain sensitif seperti mengajukan pertanyaan tentang polis asuransi.
Bangun, terapkan, dan kelola asisten dan agen AI yang kuat yang mengotomatiskan alur kerja dan proses dengan AI generatif.
Bangun masa depan bisnis Anda dengan solusi AI yang dapat Anda percaya.
Layanan IBM Consulting AI membantu merancang ulang cara kerja bisnis dengan AI untuk transformasi.