03. Memanfaatkan berbagai modul RAG berdasarkan fungsinya
Menjelajahi RAG di LangChain
- Pemrosesan Pertanyaan
Pada tahap pemrosesan pertanyaan, pertanyaan pengguna diterima dan diproses, serta data yang relevan diambil. Komponen-komponen berikut diperlukan untuk proses ini:
- Menghubungkan ke Sumber Data: Untuk menemukan jawaban dari pertanyaan, berbagai sumber data teks harus dihubungkan. LangChain membantu mengatur koneksi dengan berbagai sumber data secara mudah.
- Pengindeksan dan Pencarian Data: Untuk menemukan informasi yang relevan secara efisien dari sumber data, data harus diindeks. LangChain mengotomatisasi proses pengindeksan dan menyediakan alat untuk mencari data terkait dengan pertanyaan pengguna.
- Pembuatan Jawaban
Setelah menemukan data yang relevan, jawaban harus dihasilkan berdasarkan data tersebut. Komponen-komponen berikut penting pada tahap ini:
- Model Pembuatan Jawaban: LangChain menyediakan fungsionalitas untuk menghasilkan jawaban dari data yang ditemukan menggunakan model pemrosesan bahasa alami (NLP) canggih. Model-model ini menerima pertanyaan pengguna dan data yang ditemukan sebagai input untuk menghasilkan jawaban yang sesuai.
Arsitektur
Seperti yang dijelaskan dalam pengenalan Q&A (opens in a new tab), kita akan membuat aplikasi RAG yang khas. Ini memiliki dua komponen utama:
- Indexing: Sebuah pipeline yang mengumpulkan dan mengindeks data dari sumber. Proses ini biasanya terjadi secara offline.
- Retrieval and Generation: RAG chain yang sebenarnya, yang menerima query dari pengguna saat runtime, mengambil data relevan dari index, kemudian mengirimkan data tersebut ke model.
Urutan keseluruhan dari RAW data hingga menerima jawaban adalah sebagai berikut.
**Pengindeksan (**Indexing)
- Load: Pertama-tama, data harus dimuat. Untuk itu, kita akan menggunakan DocumentLoaders.
- Split: Text splitters membagi Documents besar menjadi potongan-potongan kecil. Ini berguna untuk mengindeks data dan mengirimkannya ke model, karena potongan besar sulit untuk dicari dan tidak sesuai dengan jendela konteks model yang terbatas.
- Store: Kita memerlukan tempat untuk menyimpan dan mengindeks potongan-potongan ini agar bisa dicari di kemudian hari. Hal ini sering dilakukan menggunakan VectorStore dan model Embeddings.
Retrieval and Generation
- Retrieval: Ketika input pengguna diberikan, Retriever digunakan untuk mencari potongan-potongan relevan dalam penyimpanan.
- Generation: ChatModel / LLM menghasilkan jawaban menggunakan prompt yang mencakup pertanyaan dan data yang telah ditemukan.
Dokumen yang digunakan untuk praktik
Penulis: Misnawati Misnawati
Tautan: https://badanpenerbit.org/index.php/mateandrau/article/view/221 (opens in a new tab)
Nama File: ChatGPT: Keuntungan, Risiko, Dan Penggunaan Bijak Dalam Era Kecerdasan Buatan.
Silakan salin file yang telah diunduh ke folder data
untuk praktik.
Setting
Mengatur API KEY
# File pengaturan untuk mengelola API key sebagai environment variable
from dotenv import load_dotenv
# Memuat informasi API key
load_dotenv()
True
Aplikasi yang dibangun dengan LangChain sering kali melibatkan beberapa panggilan LLM di berbagai tahap. Saat aplikasi ini menjadi semakin kompleks, kemampuan untuk menyelidiki dengan tepat apa yang terjadi di dalam chain atau agen menjadi sangat penting. Cara terbaik untuk melakukannya adalah dengan menggunakan LangSmith (opens in a new tab).
Meskipun LangSmith tidak wajib, itu sangat berguna. Jika Anda ingin menggunakan LangSmith, Anda harus mendaftar menggunakan tautan di atas dan mengatur environment variable untuk memulai pencatatan dan pelacakan (logging and tracking).
import os
# Masukkan nama proyek untuk debugging.
os.environ["LANGCHAIN_PROJECT"] = "RAG TUTORIAL"
# Hapus komentar pada kode berikut dan jalankan untuk mengaktifkan tracing.
# os.environ["LANGCHAIN_TRACING_V2"] = true
Melihat lebih detail setiap modul
import bs4
from langchain import hub
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import WebBaseLoader
from langchain_community.vectorstores import Chroma, FAISS
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
Berikut adalah contoh yang menggunakan model RAG dasar yang telah dibahas sebelumnya.
Pada setiap tahap, berbagai opsi dapat dikonfigurasi atau teknik baru dapat diterapkan.
# Langkah 1: Muat Dokumen
# Memuat konten berita, membaginya menjadi potongan-potongan kecil, dan mengindeksnya.
url = "https://tekno.kompas.com/read/2024/08/30/09090077/pengguna-chatgpt-naik-dua-kali-lipat-sekian-jumlahnya"
loader = WebBaseLoader(
web_paths=(url,),
bs_kwargs=dict(
parse_only=bs4.SoupStrainer(
"div",
attrs={"class": ["clearfix", "read__title"]},
)
),
)
docs = loader.load()
# Langkah 2: Membagi Dokumen
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000, chunk_overlap=50)
splits = text_splitter.split_documents(docs)
# Langkah 3: Membuat Vectorstore
# Membuat vectorstore.
vectorstore = FAISS.from_documents(
documents=splits, embedding=OpenAIEmbeddings())
# Langkah 4: Pencarian
# Mencari dan menghasilkan informasi yang terdapat dalam artikel berita.
retriever = vectorstore.as_retriever()
# Langkah 5: Membuat Prompt
# Membuat prompt.
prompt = hub.pull("rlm/rag-prompt")
# Langkah 6: Membuat LLM
# Membuat model (LLM).
llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)
def format_docs(docs):
# Menggabungkan hasil dokumen yang ditemukan menjadi satu paragraf.
return "\n\n".join(doc.page_content for doc in docs)
# Langkah 7: Membuat Chain
rag_chain = (
{"context": retriever | format_docs, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
# Langkah 8: Menjalankan Chain
# Memasukkan pertanyaan tentang dokumen dan menampilkan jawabannya.
question = "Mengapa jumlah pengguna ChatGPT mengalami peningkatan?"
response = rag_chain.invoke(question)
# Menampilkan hasil
print(f"URL: {url}")
print(f"Jumlah dokumen: {len(docs)}")
print("===" * 20)
print(f"[human]\n{question}\n")
print(f"[AI]\n{response}")
URL: https://tekno.kompas.com/read/2024/08/30/09090077/pengguna-chatgpt-naik-dua-kali-lipat-sekian-jumlahnya
Jumlah dokumen: 1
============================================================
[human]
Mengapa jumlah pengguna ChatGPT mengalami peningkatan?
[AI]
Jumlah pengguna ChatGPT mengalami peningkatan karena banyak orang dan perusahaan yang kini menggunakan ChatGPT dalam kehidupan sehari-hari mereka. CEO OpenAI Sam Altman menyatakan bahwa ChatGPT digunakan untuk memperlancar aktivitas sehari-hari dan memicu kreativitas di berbagai bidang. Peningkatan ini juga menunjukkan minat manusia terhadap produk AI untuk membantu menyelesaikan pekerjaan.
Langkah 1: Muat Dokumen (Load Document)
- Tautan Dokumentasi Resmi - Document Loaders: https://python.langchain.com/v0.1/docs/modules/data_connection/document_loaders/ (opens in a new tab)
Halaman Web
WebBaseLoader menggunakan bs4.SoupStrainer untuk mem-parsing hanya bagian yang diperlukan dari halaman web yang ditentukan.
[Catatan]
bs4.SoupStrainer memungkinkan Anda untuk dengan mudah mengambil elemen yang diinginkan dari web.
(Contoh)
bs4.SoupStrainer(
"div",
attrs={"class": ["newsct_article _article_body", "media_end_head_title"]}, # Masukkan nama kelas
)
bs4.SoupStrainer(
"article",
attrs={"id": ["dic_area"]}, # Masukkan nama kelas
)
Berikut adalah artikel berita BBC. Jika Anda ingin mencobanya dengan artikel yang ditulis dalam bahasa Inggris.
# Memuat konten artikel berita, membaginya menjadi potongan-potongan kecil, dan mengindeksnya.
loader = WebBaseLoader(
web_paths=("https://www.bbc.com/news/articles/c897qz1qex9o",),
bs_kwargs=dict(
parse_only=bs4.SoupStrainer(
"main",
attrs={"id": ["main-content"]},
)
),
)
docs = loader.load()
print(f"Jumlah dokumen: {len(docs)}")
docs[0].page_content[:500]
Jumlah dokumen: 1
ChatGPT reveals search feature in Google challenge Getty ImagesOpenAI is working on adding new powers to its artificial intelligence (AI) bot, as it seeks to edge out Google as the go-to search engine.The company said it was trialling a search feature that incorporates real-time information into its ChatGPT product, allowing the bot to respond to user questions with up-to-date information and links. The tool is currently available to a limited number of users in the US. But it is expected to ev
from langchain_community.document_loaders import PyPDFLoader
# Memuat file PDF. Masukkan path file
loader = PyPDFLoader("../data/ChatGPT: Keuntungan, Risiko, Dan Penggunaan Bijak Dalam Era Kecerdasan Buatan.pdf")
# Memuat dokumen per halaman
docs = loader.load()
print(f"Jumlah dokumen: {len(docs)}")
# Menampilkan isi halaman ke-10
print(f"\n[Isi Halaman]\n{docs[10].page_content[:500]}")
print(f"\n[Metadata]\n{docs[10].metadata}\n")
Jumlah dokumen: 14
[Isi Halaman]
Prosiding Seminar Nasional Pendidikan, Bahasa, Sastra, Seni, dan Budaya (Mateandrau)
Volume 2, No. 1 Mei 2023;
E-ISSN : 2963-7945 dan P-ISSN : 2963-7910, Hal 54-67
Selain itu, penting untuk selalu menghargai privasi orang lain dalam penggunaan
ChatGPT. Jangan mengungkapkan informasi pribadi orang lain atau merugikan orang lain
dengan menggunakan informasi yang diberikan oleh ChatGPT. Selalu ingat bahwa ChatGPT
hanya alat dan tidak menggantikan kebijaksanaan dan etika man
[Metadata]
{'source': '../data/ChatGPT: Keuntungan, Risiko, Dan Penggunaan Bijak Dalam Era Kecerdasan Buatan.pdf', 'page': 10}
CSV
CSV mengambil data menggunakan nomor baris, bukan nomor halaman.
Pada bagian ini, anda akan memerlukan file berikut: titanic.csv (opens in a new tab)
from langchain_community.document_loaders.csv_loader import CSVLoader
# Memuat file CSV
loader = CSVLoader(file_path="../data/titanic.csv")
docs = loader.load()
print(f"Jumlah dokumen: {len(docs)}")
# Menampilkan isi baris ke-10
print(f"\n[Isi Baris]\n{docs[10].page_content[:500]}")
print(f"\n[Metadata]\n{docs[10].metadata}\n")
Jumlah dokumen: 891
[Isi Baris]
PassengerId: 11
Survived: 1
Pclass: 3
Name: Sandstrom, Miss. Marguerite Rut
Sex: female
Age: 4
SibSp: 1
Parch: 1
Ticket: PP 9549
Fare: 16.7
Cabin: G6
Embarked: S
[Metadata]
{'source': 'data/titanic.csv', 'row': 10}
File TXT
from langchain_community.document_loaders import TextLoader
loader = TextLoader("../data/appendix-keywords.txt")
docs = loader.load()
print(f"Jumlah dokumen: {len(docs)}")
# Menampilkan isi halaman ke-10
print(f"\n[Isi Halaman]\n{docs[0].page_content[:500]}")
print(f"\n[Metadata]\n{docs[0].metadata}\n")
Jumlah dokumen: 1
[Isi Halaman]
Pencarian Semantik
Definisi: Pencarian semantik adalah metode pencarian yang melampaui pencocokan kata kunci sederhana dengan memahami makna dari pertanyaan pengguna untuk mengembalikan hasil yang relevan.
Contoh: Jika seorang pengguna mencari "planet tata surya," maka akan mengembalikan informasi tentang planet yang terkait seperti "Jupiter" dan "Mars."
Kata Kunci Terkait: Pemrosesan Bahasa Alami, Algoritma Pencarian, Penambangan Data
Embedding
Definisi: Embedding adalah proses mengubah data
[Metadata]
{'source': '../data/appendix-keywords.txt'}
Memuat semua file di dalam folder
Berikut adalah contoh memuat semua file .txt
di dalam folder.
from langchain_community.document_loaders import DirectoryLoader
loader = DirectoryLoader("..",
glob="data/*.txt", show_progress=True)
docs = loader.load()
print(f"Jumlah dokumen: {len(docs)}")
# Menampilkan isi halaman ke-10
print(f"\n[Isi Halaman]\n{docs[0].page_content[:500]}")
print(f"\n[Metadata]\n{docs[0].metadata}\n")
100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 4/4 [00:02<00:00, 1.86it/s]
Jumlah dokumen: 4
[Isi Halaman]
Pencarian Semantik
Definisi: Pencarian semantik adalah metode pencarian yang melampaui pencocokan kata kunci sederhana dengan memahami makna dari pertanyaan pengguna untuk mengembalikan hasil yang relevan. Contoh: Jika seorang pengguna mencari "planet tata surya," maka akan mengembalikan informasi tentang planet yang terkait seperti "Jupiter" dan "Mars." Kata Kunci Terkait: Pemrosesan Bahasa Alami, Algoritma Pencarian, Penambangan Data
Embedding
Definisi: Embedding adalah proses mengubah data
[Metadata]
{'source': '../data/appendix-keywords-CP999.txt'}
Berikut adalah contoh memuat semua file .pdf
di dalam folder
from langchain_community.document_loaders import DirectoryLoader
loader = DirectoryLoader("..", glob="data/*.pdf")
docs = loader.load()
print(f"Jumlah dokumen: {len(docs)}\n")
print("[Metadata]\n")
print(docs[0].metadata)
print("\n========= [Pratinjau] =========\n")
print(docs[0].page_content[2500:3000])
Python
Berikut ini adalah contoh pemuatan file .py.
from langchain_community.document_loaders import PythonLoader
loader = DirectoryLoader(".", glob="**/*.py", loader_cls=PythonLoader)
docs = loader.load()
print(f"Jumlah dokumen: {len(docs)}\n")
print("[Metadata]\n")
print(docs[1].metadata)
print("\n========= [Pratinjau] =========\n")
print(docs[1].page_content[:500])
Jumlah dokumen: 4
[Metadata]
{'source': '02-qa-news-article.py'}
========= [Pratinjau] =========
import bs4
from langchain import hub
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import WebBaseLoader
from langchain_community.vectorstores import FAISS
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
bs4.SoupStrainer(
"div",
attrs={"class": ["clearfix", "read__title"]},
)
# Memuat konten artikel be
Langkah 2: Membagi Dokumen (Split Documents)
# Memuat konten artikel berita, membaginya menjadi potongan-potongan kecil, dan mengindeksnya.
loader = WebBaseLoader(
web_paths=("https://www.bbc.com/news/articles/c897qz1qex9o",),
bs_kwargs=dict(
parse_only=bs4.SoupStrainer(
"main",
attrs={"id": ["main-content"]},
)
),
)
docs = loader.load()
print(f"Jumlah dokumen: {len(docs)}")
docs[0].page_content[:500]
CharacterTextSplitter
Ini adalah metode paling sederhana. Metode ini membagi teks berdasarkan karakter (nilai default adalah "\n\n"), dan panjang setiap potongan diukur berdasarkan jumlah karakter.
- Bagaimana teks dibagi: Berdasarkan unit karakter tunggal.
- Bagaimana ukuran potongan diukur: Panjang karakter.
- Contoh visualisasi: https://chunkviz.up.railway.app/ (opens in a new tab)
Kelas CharacterTextSplitter menyediakan fungsi untuk membagi teks menjadi potongan-potongan dengan ukuran tertentu.
- Parameter separator menentukan string yang digunakan untuk memisahkan potongan; dalam kasus ini, digunakan dua baris baru ("\n\n").
- chunk_size menentukan panjang maksimum setiap potongan.
- chunk_overlap menentukan jumlah karakter yang tumpang tindih antara potongan yang berdekatan.
- length_function menentukan fungsi yang digunakan untuk menghitung panjang potongan; secara default, fungsi
len
digunakan untuk mengembalikan panjang string. - is_separator_regex adalah nilai boolean yang menentukan apakah separator diinterpretasikan sebagai ekspresi reguler.
from langchain.text_splitter import CharacterTextSplitter
text_splitter = CharacterTextSplitter(
separator="\n\n",
chunk_size=100,
chunk_overlap=10,
length_function=len,
is_separator_regex=False,
)
Fungsi ini menggunakan metode create_documents
dari objek text_splitter
untuk membagi teks yang diberikan (state_of_the_union
) menjadi beberapa dokumen dan menyimpan hasilnya dalam variabel texts
. Setelah itu, ia menampilkan dokumen pertama dari texts
. Proses ini dapat dianggap sebagai langkah awal dalam memproses dan menganalisis data teks, dan sangat berguna untuk membagi data teks besar menjadi unit-unit yang lebih mudah dikelola.
# Memuat sebagian konten dari makalah "Chain of Density"
with open("data/chain-of-density.txt", "r") as f:
text = f.read()[:500]
text_splitter = CharacterTextSplitter(
chunk_size=100, chunk_overlap=10, separator="\n\n"
)
text_splitter.split_text(text)
['Memilih jumlah informasi yang “tepat” untuk dimasukkan ke dalam suatu ringkasan adalah tugas yang sulit. \nRingkasan yang baik haruslah terperinci dan berpusat pada entitas tanpa menjadi terlalu padat dan sulit untuk diikuti. Untuk lebih memahami pertukaran ini, kami meminta ringkasan GPT-4 yang semakin padat dengan apa yang kami sebut sebagai “Rantai Kepadatan” (Chain of Density). Secara khusus, GPT-4 menghasilkan ringkasan awal dengan entitas yang jarang sebelum secara berulang-ulang memasukkan']
text_splitter = CharacterTextSplitter(chunk_size=100, chunk_overlap=10, separator="\n")
text_splitter.split_text(text)
['Memilih jumlah informasi yang “tepat” untuk dimasukkan ke dalam suatu ringkasan adalah tugas yang sulit.', 'Ringkasan yang baik haruslah terperinci dan berpusat pada entitas tanpa menjadi terlalu padat dan sulit untuk diikuti. Untuk lebih memahami pertukaran ini, kami meminta ringkasan GPT-4 yang semakin padat dengan apa yang kami sebut sebagai “Rantai Kepadatan” (Chain of Density). Secara khusus, GPT-4 menghasilkan ringkasan awal dengan entitas yang jarang sebelum secara berulang-ulang memasukkan']
text_splitter = CharacterTextSplitter(chunk_size=100, chunk_overlap=10, separator=" ")
text_splitter.split_text(text)
['Memilih jumlah informasi yang “tepat” untuk dimasukkan ke dalam suatu ringkasan adalah tugas yang', 'tugas yang sulit. \nRingkasan yang baik haruslah terperinci dan berpusat pada entitas tanpa menjadi', 'menjadi terlalu padat dan sulit untuk diikuti. Untuk lebih memahami pertukaran ini, kami meminta', 'meminta ringkasan GPT-4 yang semakin padat dengan apa yang kami sebut sebagai “Rantai Kepadatan”', 'Kepadatan” (Chain of Density). Secara khusus, GPT-4 menghasilkan ringkasan awal dengan entitas yang', 'yang jarang sebelum secara berulang-ulang memasukkan']
text_splitter = CharacterTextSplitter(chunk_size=100, chunk_overlap=0, separator=" ")
text_splitter.split_text(text)
['Memilih jumlah informasi yang “tepat” untuk dimasukkan ke dalam suatu ringkasan adalah tugas yang', 'sulit. \nRingkasan yang baik haruslah terperinci dan berpusat pada entitas tanpa menjadi terlalu', 'padat dan sulit untuk diikuti. Untuk lebih memahami pertukaran ini, kami meminta ringkasan GPT-4', 'yang semakin padat dengan apa yang kami sebut sebagai “Rantai Kepadatan” (Chain of Density). Secara', 'khusus, GPT-4 menghasilkan ringkasan awal dengan entitas yang jarang sebelum secara berulang-ulang', 'memasukkan']
from langchain.text_splitter import CharacterTextSplitter
from langchain.docstore.document import Document
file_path = "../data/appendix-keywords.txt"
with open(file_path) as f:
content = f.read()
# Initialize the text splitter
text_splitter = CharacterTextSplitter(
chunk_size=1000, chunk_overlap=100, separator=" ")
# Split the content into chunks
text_splitter.split_text(content)
# Create Document object
docs = [Document(page_content=content, metadata={
'source': file_path})]
# Split documents into chunks
split_docs = text_splitter.split_documents(docs)
len(split_docs)
10
split_docs[0]
page_content='Pencarian Semantik
Definisi: Pencarian semantik adalah metode pencarian yang melampaui pencocokan kata kunci sederhana dengan memahami makna dari pertanyaan pengguna untuk mengembalikan hasil yang relevan.
Contoh: Jika seorang pengguna mencari "planet tata surya," maka akan mengembalikan informasi tentang planet yang terkait seperti "Jupiter" dan "Mars."
Kata Kunci Terkait: Pemrosesan Bahasa Alami, Algoritma Pencarian, Penambangan Data
Embedding
Definisi: Embedding adalah proses mengubah data teks seperti kata atau kalimat menjadi vektor kontinu berdimensi rendah, memungkinkan komputer untuk memahami dan memproses teks.
Contoh: Kata "apel" dapat direpresentasikan sebagai vektor seperti [0.65, -0.23, 0.17].
Kata Kunci Terkait: Pemrosesan Bahasa Alami, Vektorisasi, Pembelajaran Mendalam
Token
Definisi: Token mengacu pada tindakan membagi teks menjadi unit yang lebih kecil, yang biasanya berupa kata, kalimat, atau frasa.
Contoh: Kalimat "Saya pergi ke sekolah" dibagi menjadi "Saya",' metadata={'source': '../data/appendix-keywords.txt'}
# Memuat konten artikel berita, membaginya menjadi potongan-potongan kecil, dan mengindeksnya.
loader = WebBaseLoader(
web_paths=("https://www.bbc.com/news/articles/c897qz1qex9o"),
bs_kwargs=dict(
parse_only=bs4.SoupStrainer(
"main",
attrs={"id": ["main-content"]},
)
),
)
# Mendefinisikan splitter.
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=100, separator=" ")
# Memuat dan membagi dokumen secara bersamaan.
split_docs = loader.load_and_split(text_splitter=text_splitter)
print(f"Jumlah dokumen: {len(docs)}")
docs[0].page_content[:500]
Jumlah dokumen: 1
ChatGPT reveals search feature in Google challenge Getty ImagesOpenAI is working on adding new powers to its artificial intelligence (AI) bot, as it seeks to edge out Google as the go-to search engine.The company said it was trialling a search feature that incorporates real-time information into its ChatGPT product, allowing the bot to respond to user questions with up-to-date information and links. The tool is currently available to a limited number of users in the US. But it is expected to ev
RecursiveTextSplitter
Pemisah teks ini direkomendasikan untuk teks biasa.
- Bagaimana teks dibagi: daftar pemisah (list of separators)
- Bagaimana ukuran potongan diukur: panjang karakter (len of characters)
# Mengimpor kelas RecursiveCharacterTextSplitter dari paket langchain.
from langchain.text_splitter import RecursiveCharacterTextSplitter
Kelas RecursiveCharacterTextSplitter menyediakan fungsi untuk membagi teks secara rekursif. Kelas ini menerima parameter seperti chunk_size untuk menentukan ukuran potongan, chunk_overlap untuk menentukan tumpang tindih antara potongan yang berdekatan, length_function untuk menghitung panjang potongan, dan is_separator_regex untuk menunjukkan apakah pemisah adalah ekspresi reguler. Dalam contoh ini, ukuran potongan diatur menjadi 100, ukuran tumpang tindih menjadi 20, fungsi perhitungan panjang menggunakan len
, dan is_separator_regex diatur ke False
untuk menunjukkan bahwa pemisah bukanlah ekspresi reguler.
recursive_text_splitter = RecursiveCharacterTextSplitter(
# Mengatur ukuran potongan yang sangat kecil.
chunk_size=100,
chunk_overlap=10,
length_function=len,
is_separator_regex=False,
)
# Memuat sebagian konten dari makalah "Chain of Density"
with open("data/chain-of-density.txt", "r") as f:
text = f.read()[:500]
character_text_splitter = CharacterTextSplitter(
chunk_size=100, chunk_overlap=10, separator=" "
)
for sent in character_text_splitter.split_text(text):
print(sent)
print("===" * 20)
recursive_text_splitter = RecursiveCharacterTextSplitter(
chunk_size=100, chunk_overlap=10
)
for sent in recursive_text_splitter.split_text(text):
print(sent)
Daftar separator yang ditentukan dicoba secara berurutan untuk membagi dokumen yang diberikan. Pemisahan dilakukan secara berurutan hingga potongan teks menjadi cukup kecil. Daftar default adalah ["\n\n", "\n", " ", ""]
. Ini umumnya memiliki efek menjaga semua paragraf (dan kalimat, kata) tetap panjang, yang tampak sebagai potongan teks yang paling terkait secara semantik
# Memeriksa separator default yang ditetapkan pada recursive_text_splitter.
recursive_text_splitter._separators
Semantic Similarity
Membagi teks berdasarkan kesamaan semantik.
Pada tingkat tinggi, teks pertama-tama dibagi menjadi kalimat, kemudian dikelompokkan menjadi tiga kalimat, dan akhirnya, kalimat yang mirip digabungkan di ruang embedding.
# Perbarui ke versi terbaru.
# !pip install -U langchain langchain_experimental -q
from langchain_experimental.text_splitter import SemanticChunker
from langchain_openai.embeddings import OpenAIEmbeddings
# Membuat SemanticChunker.
semantic_text_splitter = SemanticChunker(
OpenAIEmbeddings(), add_start_index=True)
# Memuat sebagian konten dari makalah "Chain of Density"
with open("data/chain-of-density.txt", "r") as f:
text = f.read()
for sent in semantic_text_splitter.split_text(text):
print(sent)
print("===" * 20)
Memilih jumlah informasi yang “tepat” untuk dimasukkan ke dalam suatu ringkasan adalah tugas yang sulit. Ringkasan yang baik haruslah terperinci dan berpusat pada entitas tanpa menjadi terlalu padat dan sulit untuk diikuti. Untuk lebih memahami pertukaran ini, kami meminta ringkasan GPT-4 yang semakin padat dengan apa yang kami sebut sebagai “Rantai Kepadatan” (Chain of Density). Secara khusus, GPT-4 menghasilkan ringkasan awal dengan entitas yang jarang sebelum secara berulang-ulang memasukkan entitas penting yang hilang tanpa menambah panjangnya. Ringkasan yang dihasilkan oleh CoD lebih abstrak, menunjukkan lebih banyak perpaduan, dan memiliki lebih sedikit bias utama daripada ringkasan GPT-4 yang dihasilkan oleh prompt vanilla. Kami melakukan studi preferensi manusia terhadap 100 artikel CNN DailyMail dan menemukan bahwa manusia lebih menyukai ringkasan GPT-4 yang lebih padat daripada ringkasan yang dihasilkan oleh vanilla prompt dan hampir sama padatnya dengan ringkasan yang ditulis oleh manusia. Analisis kualitatif mendukung gagasan bahwa ada pertukaran antara informasi dan keterbacaan. 500 ringkasan CoD beranotasi, serta 5.000 ringkasan tanpa anotasi, tersedia secara gratis di HuggingFace. Pendahuluan
Peringkasan otomatis telah berkembang pesat dalam beberapa tahun terakhir, sebagian besar karena pergeseran paradigma dari penyempurnaan yang diawasi pada kumpulan data berlabel ke permintaan tanpa bidikan dengan Large Language Models (LLM), seperti GPT-4 (OpenAI, 2023). Tanpa pelatihan tambahan, pemberian perintah yang cermat dapat memungkinkan kontrol yang baik atas karakteristik ringkasan, seperti panjang (Goyal dkk., 2022), topik (Bhaskar dkk., 2023), dan gaya (Pu dan Demberg, 2023). Aspek yang sering diabaikan adalah kepadatan informasi dari sebuah ringkasan. Secara teori, sebagai kompresi dari teks lain, ringkasan seharusnya lebih padat - mengandung konsentrasi informasi yang lebih tinggi - daripada dokumen sumbernya. Mengingat latensi yang tinggi dari penguraian LLM (Kad-dour et al., 2023), mencakup lebih banyak informasi dengan lebih sedikit kata adalah tujuan yang layak, terutama untuk aplikasi waktu nyata. Namun, seberapa padatnya adalah sebuah pertanyaan terbuka.
============================================================
Sebuah ringkasan tidak informatif jika tidak mengandung detail yang cukup. Namun, jika berisi terlalu banyak informasi, ringkasan tersebut dapat menjadi sulit untuk diikuti tanpa harus menambah panjangnya secara keseluruhan. Menyampaikan lebih banyak informasi sesuai dengan anggaran token yang telah ditetapkan membutuhkan kombinasi abstraksi, kompresi, dan fusi. Ada batasan berapa banyak ruang yang dapat dibuat untuk informasi tambahan sebelum menjadi tidak terbaca atau bahkan salah secara faktual.
============================================================
Langkah 3: Embedding
Referensi: https://python.langchain.com/docs/integrations/text_embedding (opens in a new tab)
Embedding Berbayar (OpenAI)
from langchain_community.vectorstores import FAISS
from langchain_openai.embeddings import OpenAIEmbeddings
# Langkah 3: Membuat Embedding & Vectorstore
# Membuat vectorstore.
vectorstore = FAISS.from_documents(
documents=splits, embedding=OpenAIEmbeddings())
Berikut ini adalah daftar model Embedding yang didukung oleh OpenAI.
- Nilai defaultnya adalah text-embedding-ada-002.
vectorstore = FAISS.from_documents(
documents=splits, embedding=OpenAIEmbeddings(model="text-embedding-3-small")
)
Warning: model not found. Using cl100k_base encoding.
Embedding Berbasis Open Source Gratis
from langchain_community.embeddings import HuggingFaceBgeEmbeddings
# Langkah 3: Membuat Embedding & Vectorstore
# Membuat vectorstore.
vectorstore = FAISS.from_documents(
documents=splits, embedding=HuggingFaceBgeEmbeddings()
)
# !pip install fastembed -q
from langchain_community.embeddings.fastembed import FastEmbedEmbeddings
vectorstore = FAISS.from_documents(
documents=splits, embedding=FastEmbedEmbeddings())
Langkah 4: Membuat Vectorstore
from langchain_community.vectorstores import FAISS
# Menerapkan FAISS DB
vectorstore = FAISS.from_documents(
documents=splits, embedding=OpenAIEmbeddings())
from langchain_community.vectorstores import Chroma
# Chroma DB 적용
vectorstore = Chroma.from_documents(documents=splits, embedding=OpenAIEmbeddings())
Langkah 5: Membuat Retriever
Retriever adalah antarmuka yang mengembalikan dokumen ketika diberikan kueri yang tidak terstruktur.
Retriever hanya mengembalikan (atau mengambil) dokumen tanpa perlu menyimpannya.
- Dokumentasi Resmi: https://python.langchain.com/v0.1/docs/modules/data_connection/retrievers/ (opens in a new tab)
Retriever dibuat dengan memanggil as_retriever()
pada VectorStore yang telah dihasilkan.
Pencarian Berbasis Kemiripan (Similarity-based Search)
Standar yang digunakan adalah similarity yang merupakan cosine similarity.
query = "Apa manfaat menggunakan ChatGPT?"
retriever = vectorstore.as_retriever(search_type="similarity")
search_result = retriever.get_relevant_documents(query)
print(search_result)
[Document(metadata={'source': 'https://tekno.kompas.com/read/2024/08/30/09090077/pengguna-chatgpt-naik-dua-kali-lipat-sekian-jumlahnya'}, page_content='"Orang-orang menggunakan ChatGPT untuk memperlancar aktivitas mereka sehari-hari, dan ini memberikan dampak positif sekaligus memicu kreativitas di berbagai bidang, mulai dari kesehatan, pendidikan, dan lain sebagainya," kata Sam.\nNah, peningkatan jumlah pengguna ChatGPT ini membuktikan bahwa produk AI semakin dilirik oleh manusia untuk membantu menyelesaikan pekerjaan mereka. Peningkatan ini juga menggambarkan bahwa kompetisi model AI yang ada di pasar kini semakin sengit.\nSalah satu chatbot kompetitor OpenAI, yaitu Meta AI buatan Meta, misalnya, kabarnya kini telah memiliki jumlah pengguna aktif yang lebih banyak dari ChatGPT, yaitu mencapai 400 juta. Namun, jumlah pengguna aktif ini merupakan bulanan (monthly), bukan mingguan (weekly).\xa0 \nBaca juga: OpenAI Diretas tapi Diam-diam Saja, Tak Lapor FBI'), Document(metadata={'source': 'https://tekno.kompas.com/read/2024/08/30/09090077/pengguna-chatgpt-naik-dua-kali-lipat-sekian-jumlahnya'}, page_content='KOMPAS.com - Jumlah pengguna aktif mingguan (weekly active users) chatbot buatan OpenAI, yaitu ChatGPT, diklaim sudah menembus angka 200 juta pengguna.\xa0\nHal ini disampaikan OpenAI dalam sebuah pernyataan ke salah satu situs web berita internasional, Axios.\xa0Angka ini meningkat dua kali lipat dari jumlah weekly active users pada November 2023 lalu yang berkisar di angka 100 juta pengguna.\xa0\nOpenAI mengatakan bahwa model AI terbarunya, yaitu GPT-4o Mini yang dirilis pada Juli lalu, berkontribusi pada jumlah peningkatan pengguna ChatGPT. Menurut OpenAI, pemakaian model AI ini (via sistem aplikasi alias API) meningkat dua kali lipat sejak pertama kali dirilis.\xa0\nSelain itu, OpenAI juga mengeklaim ChatGPT kini sudah dipakai banyak perusahaan dunia. Bahkan, 92 persen dari perusahaan-perusahaan kenamaan global yang tergabung dalam kelompok "Fortune 500", lanjut OpenAI, kini telah memakai ChatGPT di dalam produk mereka.\nBaca juga: Pendiri OpenAI Mundur, Hijrah ke Perusahaan Kompetitor'), Document(metadata={'source': 'https://tekno.kompas.com/read/2024/08/30/09090077/pengguna-chatgpt-naik-dua-kali-lipat-sekian-jumlahnya'}, page_content='Tidak disebutkan berapa jumlah weekly active users Meta AI. Namun yang jelas, jumlah pengguna hariannya (daily active users) mencapai 40 juta pengguna, sebagaimana dirangkum KompasTekno dari TheVerge, Jumat (30/8/2024).\nBoleh jadi chatbot bikinan Google, yaitu Gemini, serta produk serupa bikinan Microsoft, yaitu Copilot juga memiliki jumlah peningkatan pengguna aktif. Namun, hal ini belum diketahui pasti lantaran kedua perusahaan belum mengumbar data tersebut ke publik.\nSimak breaking news dan berita pilihan kami langsung di ponselmu. Pilih saluran andalanmu akses berita Kompas.com WhatsApp Channel : https://www.whatsapp.com/channel/0029VaFPbedBPzjZrk13HO3D. Pastikan kamu sudah install aplikasi WhatsApp ya.'), Document(metadata={'source': 'https://tekno.kompas.com/read/2024/08/30/09090077/pengguna-chatgpt-naik-dua-kali-lipat-sekian-jumlahnya'}, page_content='Terkait peningkatan jumlah pengguna ini, CEO OpenAI Sam Altman mengatakan, hal ini bisa terwujud berkat banyaknya orang dan perusahaan yang kini menggunakan ChatGPT di kehidupan sehari-hari mereka.')]
similarity_score_threshold
dalam pencarian berbasis kemiripan hanya mengembalikan hasil yang memiliki skor sama dengan atau lebih besar dari ambang batas.
query = "Apa manfaat menggunakan ChatGPT?"
retriever = vectorstore.as_retriever(
search_type="similarity_score_threshold", search_kwargs={"score_threshold": 0.8}
)
search_result = retriever.get_relevant_documents(query)
print(search_result)
[Document(metadata={'source': 'https://tekno.kompas.com/read/2024/08/30/09090077/pengguna-chatgpt-naik-dua-kali-lipat-sekian-jumlahnya'}, page_content='"Orang-orang menggunakan ChatGPT untuk memperlancar aktivitas mereka sehari-hari, dan ini memberikan dampak positif sekaligus memicu kreativitas di berbagai bidang, mulai dari kesehatan, pendidikan, dan lain sebagainya," kata Sam.\nNah, peningkatan jumlah pengguna ChatGPT ini membuktikan bahwa produk AI semakin dilirik oleh manusia untuk membantu menyelesaikan pekerjaan mereka. Peningkatan ini juga menggambarkan bahwa kompetisi model AI yang ada di pasar kini semakin sengit.\nSalah satu chatbot kompetitor OpenAI, yaitu Meta AI buatan Meta, misalnya, kabarnya kini telah memiliki jumlah pengguna aktif yang lebih banyak dari ChatGPT, yaitu mencapai 400 juta. Namun, jumlah pengguna aktif ini merupakan bulanan (monthly), bukan mingguan (weekly).\xa0 \nBaca juga: OpenAI Diretas tapi Diam-diam Saja, Tak Lapor FBI'), Document(metadata={'source': 'https://tekno.kompas.com/read/2024/08/30/09090077/pengguna-chatgpt-naik-dua-kali-lipat-sekian-jumlahnya'}, page_content='KOMPAS.com - Jumlah pengguna aktif mingguan (weekly active users) chatbot buatan OpenAI, yaitu ChatGPT, diklaim sudah menembus angka 200 juta pengguna.\xa0\nHal ini disampaikan OpenAI dalam sebuah pernyataan ke salah satu situs web berita internasional, Axios.\xa0Angka ini meningkat dua kali lipat dari jumlah weekly active users pada November 2023 lalu yang berkisar di angka 100 juta pengguna.\xa0\nOpenAI mengatakan bahwa model AI terbarunya, yaitu GPT-4o Mini yang dirilis pada Juli lalu, berkontribusi pada jumlah peningkatan pengguna ChatGPT. Menurut OpenAI, pemakaian model AI ini (via sistem aplikasi alias API) meningkat dua kali lipat sejak pertama kali dirilis.\xa0\nSelain itu, OpenAI juga mengeklaim ChatGPT kini sudah dipakai banyak perusahaan dunia. Bahkan, 92 persen dari perusahaan-perusahaan kenamaan global yang tergabung dalam kelompok "Fortune 500", lanjut OpenAI, kini telah memakai ChatGPT di dalam produk mereka.\nBaca juga: Pendiri OpenAI Mundur, Hijrah ke Perusahaan Kompetitor')]
Melakukan pencarian menggunakan maximum marginal search result
query = "Apa manfaat menggunakan ChatGPT?"
retriever = vectorstore.as_retriever(search_type="mmr", search_kwargs={"k": 2})
search_result = retriever.get_relevant_documents(query)
print(search_result)
[Document(metadata={'source': 'https://tekno.kompas.com/read/2024/08/30/09090077/pengguna-chatgpt-naik-dua-kali-lipat-sekian-jumlahnya'}, page_content='"Orang-orang menggunakan ChatGPT untuk memperlancar aktivitas mereka sehari-hari, dan ini memberikan dampak positif sekaligus memicu kreativitas di berbagai bidang, mulai dari kesehatan, pendidikan, dan lain sebagainya," kata Sam.\nNah, peningkatan jumlah pengguna ChatGPT ini membuktikan bahwa produk AI semakin dilirik oleh manusia untuk membantu menyelesaikan pekerjaan mereka. Peningkatan ini juga menggambarkan bahwa kompetisi model AI yang ada di pasar kini semakin sengit.\nSalah satu chatbot kompetitor OpenAI, yaitu Meta AI buatan Meta, misalnya, kabarnya kini telah memiliki jumlah pengguna aktif yang lebih banyak dari ChatGPT, yaitu mencapai 400 juta. Namun, jumlah pengguna aktif ini merupakan bulanan (monthly), bukan mingguan (weekly).\xa0 \nBaca juga: OpenAI Diretas tapi Diam-diam Saja, Tak Lapor FBI'), Document(metadata={'source': 'https://tekno.kompas.com/read/2024/08/30/09090077/pengguna-chatgpt-naik-dua-kali-lipat-sekian-jumlahnya'}, page_content='Tidak disebutkan berapa jumlah weekly active users Meta AI. Namun yang jelas, jumlah pengguna hariannya (daily active users) mencapai 40 juta pengguna, sebagaimana dirangkum KompasTekno dari TheVerge, Jumat (30/8/2024).\nBoleh jadi chatbot bikinan Google, yaitu Gemini, serta produk serupa bikinan Microsoft, yaitu Copilot juga memiliki jumlah peningkatan pengguna aktif. Namun, hal ini belum diketahui pasti lantaran kedua perusahaan belum mengumbar data tersebut ke publik.\nSimak breaking news dan berita pilihan kami langsung di ponselmu. Pilih saluran andalanmu akses berita Kompas.com WhatsApp Channel : https://www.whatsapp.com/channel/0029VaFPbedBPzjZrk13HO3D. Pastikan kamu sudah install aplikasi WhatsApp ya.')]
Membuat Kueri yang berbeda
from langchain.retrievers.multi_query import MultiQueryRetriever
from langchain_openai import ChatOpenAI
query = "Apa risiko dari penggunaan ChatGPT?"
llm = ChatOpenAI(temperature=0, model="gpt-3.5-turbo")
retriever_from_llm = MultiQueryRetriever.from_llm(
retriever=vectorstore.as_retriever(), llm=llm
)
# Set logging for the queries
import logging
logging.basicConfig()
logging.getLogger("langchain.retrievers.multi_query").setLevel(logging.INFO)
unique_docs = retriever_from_llm.get_relevant_documents(query=question)
len(unique_docs)
Ensemble Retriever
from langchain.retrievers import BM25Retriever, EnsembleRetriever
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings
doc_list = [
"Saya makan banyak hari ini, jadi saya merasa sangat kenyang.",
"Apakah bus yang berangkat sekarang adalah yang terakhir hari ini?",
"Minuman favorit saya adalah kopi, teh, dan jus.",
]
# Inisialisasi BM25 retriever dan FAISS retriever
bm25_retriever = BM25Retriever.from_texts(doc_list)
bm25_retriever.k = 2
faiss_vectorstore = FAISS.from_texts(doc_list, OpenAIEmbeddings())
faiss_retriever = faiss_vectorstore.as_retriever(search_kwargs={"k": 2})
# Inisialisasi ensemble retriever
ensemble_retriever = EnsembleRetriever(
retrievers=[bm25_retriever, faiss_retriever], weights=[0.5, 0.5]
)
def pretty_print(docs):
for i, doc in enumerate(docs):
print(f"[{i+1}] {doc.page_content}")
sample_query = "Akhir-akhir ini, perut saya benar-benar bertambah banyak lemak..."
print(f"[Query]\n{sample_query}\n")
relevant_docs = bm25_retriever.get_relevant_documents(sample_query)
print("[BM25 Retriever]")
pretty_print(relevant_docs)
print("===" * 20)
relevant_docs = faiss_retriever.get_relevant_documents(sample_query)
print("[FAISS Retriever]")
pretty_print(relevant_docs)
print("===" * 20)
relevant_docs = ensemble_retriever.get_relevant_documents(sample_query)
print("[Ensemble Retriever]")
pretty_print(relevant_docs)
Langkah 6: Membuat Prompt
Prompt engineering memainkan peran penting dalam menghasilkan hasil yang diinginkan berdasarkan data (konteks) yang diberikan.
[TIP1]
- Jika informasi penting hilang dari hasil yang dihasilkan oleh retriever, Anda perlu mengubah logika retriever.
- Jika hasil yang dihasilkan oleh retriever mengandung banyak informasi, tetapi LLM gagal menemukan informasi penting atau tidak menampilkannya dalam format yang diinginkan, Anda perlu menyesuaikan prompt.
[TIP2]
- Hub LangSmith memiliki banyak prompt yang telah diverifikasi.
- Dengan memanfaatkan atau sedikit memodifikasi prompt yang telah diverifikasi ini, Anda dapat menghemat waktu dan biaya.
- https://smith.langchain.com/hub/search?q=rag (opens in a new tab)
from langchain import hub
prompt = hub.pull("rlm/rag-prompt")
prompt
input_variables=['context', 'question'] metadata={'lc_hub_owner': 'rlm', 'lc_hub_repo': 'rag-prompt', 'lc_hub_commit_hash': '50442af133e61576e74536c6556cefe1fac147cad032f4377b60c436e6cdcb6e'} messages=[HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['context', 'question'], template="You are an assistant for question-answering tasks. Use the following pieces of retrieved context to answer the question. If you don't know the answer, just say that you don't know. Use three sentences maximum and keep the answer concise.\nQuestion: {question} \nContext: {context} \nAnswer:"))]
Langkah 7: Membuat model bahasa besar ( Large Language Model(LLM))
Pilih salah satu model OpenAI
- gpt-3.5-turbo: Model GPT-3.5-turbo OpenAI
- gpt-4-turbo-preview: Model GPT-4-turbo-preview OpenAI
Anda dapat menemukan struktur harga yang terperinci di daftar model / tabel harga API OpenAI.
from langchain_openai import ChatOpenAI
model = ChatOpenAI(temperature=0, model="gpt-3.5-turbo")
Anda dapat memeriksa penggunaan token dengan cara berikut
from langchain_community.callbacks.manager import get_openai_callback
with get_openai_callback() as cb:
result = model.invoke("Apa ibu kota Indonesia?")
print(cb)
Tokens Used: 23
Prompt Tokens: 15
Completion Tokens: 8
Successful Requests: 1
Total Cost (USD): $1.95e-05
Anda dapat dengan mudah mengunduh dan menggunakan model open-source yang tersedia di HuggingFace.
Anda dapat melihat leaderboard open-source yang meningkatkan performa setiap hari pada leaderboard di bawah ini.
# Membuat objek HuggingFaceHub
from langchain.llms import HuggingFaceHub
repo_id = "google/flan-t5-xxl"
t5_model = HuggingFaceHub(
repo_id=repo_id, model_kwargs={"temperature": 0.1, "max_length": 512}
)
t5_model.invoke("Di manakah Ibu kota Indonesia?")
Bereksperimen dengan template RAG
import os
import logging
from langchain_openai import ChatOpenAI
from langchain.retrievers.multi_query import MultiQueryRetriever
import bs4
from langchain import hub
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import WebBaseLoader
from langchain_community.vectorstores import Chroma, FAISS
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_community.embeddings import HuggingFaceBgeEmbeddings
from dotenv import load_dotenv
from langchain_community.document_loaders import PyPDFLoader
from langchain_community.retrievers import BM25Retriever
from langchain.retrievers import EnsembleRetriever
# Langkah 1: Memuat Dokumen
# Memuat dokumen, membaginya menjadi beberapa potongan, dan mengindeksnya.
# Memuat file PDF. Masukkan path file.
file_path = "../data/ChatGPT: Keuntungan, Risiko, Dan Penggunaan Bijak Dalam Era Kecerdasan Buatan.pdf"
loader = PyPDFLoader(file_path=file_path)
docs = loader.load()
# Langkah 2: Membagi Dokumen
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000, chunk_overlap=50)
split_docs = loader.load_and_split(text_splitter=text_splitter)
# splits = text_splitter.split_documents(docs)
# Langkah 3, 4: Membuat Embedding & Vectorstore
# Membuat vectorstore.
vectorstore = FAISS.from_documents(
documents=split_docs, embedding=OpenAIEmbeddings())
# Langkah 5: Membuat Retriever
# Mencari dokumen yang sesuai dengan kueri pengguna.
# Mencari K dokumen dengan kesamaan tertinggi.
k = 3
# Inisialisasi bm25 retriever (Sparse) dan faiss retriever (Dense).
bm25_retriever = BM25Retriever.from_documents(split_docs)
bm25_retriever.k = k
faiss_vectorstore = FAISS.from_documents(split_docs, OpenAIEmbeddings())
faiss_retriever = faiss_vectorstore.as_retriever(search_kwargs={"k": k})
# Inisialisasi ensemble retriever
ensemble_retriever = EnsembleRetriever(
retrievers=[bm25_retriever, faiss_retriever], weights=[0.5, 0.5]
)
# Langkah 6: Membuat Prompt
# Membuat prompt.
prompt = hub.pull("rlm/rag-prompt")
# Langkah 7: Membuat LLM
# Membuat model (LLM).
llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)
def format_docs(docs):
# Menggabungkan hasil dokumen yang ditemukan menjadi satu paragraf.
return "\n\n".join(doc.page_content for doc in docs)
# Langkah 8: Membuat Chain
rag_chain = (
{"context": ensemble_retriever | format_docs, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
# Langkah 9: Menjalankan Chain
# Masukkan pertanyaan tentang dokumen dan tampilkan jawabannya.
question = "Apa keunggulan menggunakan ChatGPT"
response = rag_chain.invoke(question)
print(response)
# Menampilkan hasil
print(f"PDF Path: {file_path}")
print(f"Jumlah dokumen: {len(docs)}")
print("===" * 20)
print(f"[Human]\n{question}\n")
print(f"[AI]\n{response}")
PDF Path: ../data/ChatGPT: Keuntungan, Risiko, Dan Penggunaan Bijak Dalam Era Kecerdasan Buatan.pdf
Jumlah dokumen: 14
============================================================
[Human]
Apa keunggulan menggunakan ChatGPT
[AI]
Keunggulan menggunakan ChatGPT antara lain kemampuan untuk menghasilkan konten berkualitas tinggi, berkomunikasi dengan manusia, dan pembelajaran tanpa pengawasan.
Dokumen: ../data/ChatGPT: Keuntungan, Risiko, Dan Penggunaan Bijak Dalam Era Kecerdasan Buatan.pdf
# Langkah 9: Menjalankan Chain
# Masukkan pertanyaan tentang dokumen dan tampilkan jawabannya.
question = "Apa risiko dari penggunaan ChatGPT?"
response = rag_chain.invoke(question)
print(response)
Risiko dari penggunaan ChatGPT dalam era kecerdasan buatan antara lain adalah keamanan data, bias algoritma, dan kesalahan interpretasi.
Dokumen: ../data/ChatGPT: Keuntungan, Risiko, Dan Penggunaan Bijak Dalam Era Kecerdasan Buatan.pdf
# Langkah 9: Menjalankan Chain
# Masukkan pertanyaan tentang dokumen dan tampilkan jawabannya.
question = "Bagaimana ChatGPT dapat membantu pekerjaan dalam kehidupan sehari-hari"
response = rag_chain.invoke(question)
print(response)
ChatGPT dapat membantu pekerjaan dalam kehidupan sehari-hari dengan cara memberikan informasi akurat dan terkini secara cepat dan efisien, membantu menghemat waktu dan usaha dalam bisnis, serta meningkatkan produktivitas dan kreativitas pengguna.
Dokumen: ../data/ChatGPT: Keuntungan, Risiko, Dan Penggunaan Bijak Dalam Era Kecerdasan Buatan.pdf