Program
Seberapa sering Anda berharap AI Anda bisa melakukan lebih dari sekadar mengulang apa yang sudah diketahuinya? Sebagai seseorang yang telah menghabiskan banyak waktu menyempurnakan sistem AI, saya bisa katakan bahwa model tradisional, meski mengesankan, sering terasa seperti terjebak dalam gelembung yang terbatas pada data latihannya. Di sinilah Agentic RAG berperan.
Dalam agentic RAG, kemampuan pengambilan keputusan dari agentic AI bertemu dengan adaptabilitas retrieval-augmented generation (RAG). Keduanya membentuk sistem yang dapat secara mandiri mengakses, menalar, dan menghasilkan informasi yang relevan.
Sebelumnya saya menulis artikel tentang agentic RAG yang akan membantu Anda memahami semuanya dari sisi teori. Artikel ini akan lebih praktis, jadi mari fokus ke situ.
Gambaran Proyek Agentic RAG
Saya akan memandu Anda langkah demi langkah membangun proyek ini. Intinya, kita akan membuat pipeline RAG berdasarkan arsitektur berikut:

Langkah 1: Pertanyaan pengguna
Baik itu pertanyaan sederhana maupun masalah kompleks, semuanya dimulai dari pertanyaan pengguna. Inilah pemicu yang menggerakkan pipeline kita.
Langkah 2: Merutekan pertanyaan
Selanjutnya, sistem memeriksa: Bisakah saya menjawab ini?
Jika ya, sistem menarik dari pengetahuan yang ada dan langsung memberikan jawaban.
Jika tidak, saatnya menggali lebih dalam! Pertanyaan diteruskan ke langkah berikutnya.
Langkah 3: Mengambil data
Jika jawabannya belum tersedia, pipeline menelusuri dua sumber berikut:
- Dokumen lokal: Kita akan menggunakan PDF yang telah diproses sebagai basis pengetahuan, tempat sistem mencari potongan informasi yang relevan.
- Pencarian internet: Jika dibutuhkan konteks tambahan, pipeline dapat mengakses sumber eksternal untuk mengambil informasi terbaru.
Langkah 4: Menyusun konteks
Data yang diambil, baik dari PDF maupun web, kemudian disusun menjadi konteks hasil penelusuran yang koheren. Anggap saja seperti mengumpulkan semua potongan puzzle sebelum dirangkai.
Langkah 5: Menghasilkan jawaban akhir
Terakhir, konteks ini diberikan ke large language model (LLM) untuk menyusun jawaban yang jelas dan akurat. Bukan hanya tentang mengambil data, tapi memahami dan menyajikannya sebaik mungkin.
Pada akhirnya, kita akan memiliki pipeline RAG yang cerdas dan efisien yang dapat merespons pertanyaan secara dinamis dengan konteks dunia nyata.
Sumber Data Lokal
Untuk memulai, saya akan menggunakan dokumen dunia nyata sebagai sumber data lokal. Dokumen yang akan kita gunakan tidak lain adalah Generative AI Principles. Dokumen ini penuh dengan wawasan berharga, sehingga cocok sebagai uji coba pipeline kita. Anda juga memerlukan ringkasan berkas yang saya gunakan untuk tujuan perutean. Anda bisa mendapatkan berkas ringkasan dari sini.
Berikut semua yang Anda perlukan untuk memulai, langkah demi langkah.
Prasyarat
Sebelum mulai, ada beberapa hal yang perlu Anda siapkan:
- Kunci API Groq: Anda memerlukan kunci API dari Groq, yang bisa Anda dapatkan di sini: Groq API Console
- Kunci API Gemini: Gemini akan membantu saat mengorkestrasi dengan agen; Groq memberikan respons sangat cepat namun bisa terhambat oleh batas laju saat ini: Gemini API Console
- Kunci API Serper.dev: Untuk fungsi pencarian internet, kita akan menggunakan Serper.dev. Dapatkan kunci API Anda di sini: Serper.dev API Key
Menginstal Paket
Mari pastikan kita memasang alat yang tepat. Buka terminal Anda dan jalankan perintah berikut untuk memasang paket Python yang diperlukan:
pip install langchain-groq faiss-cpu crewai serper pypdf2 python-dotenv setuptools sentence-transformers huggingface distutils`
Menyiapkan Lingkungan
Setelah Anda menyiapkan kunci dan paket, Anda siap melanjutkan! Saya menyarankan menyimpan kunci API Anda dalam berkas.env atau dengan aman di basis kode Anda. Berikut contoh seperti apa berkas .env Anda:
import os from dotenv
import load_dotenv from langchain.vectorstores
import FAISS from langchain.document_loaders
import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_huggingface.embeddings import HuggingFaceEmbeddings
from langchain_groq import ChatGroq
from crewai_tools import SerperDevTool
from crewai import Agent, Task, Crew, LLM
load_dotenv()
GROQ_API_KEY = os.getenv("GROQ_API_KEY")
SERPER_API_KEY = os.getenv("SERPER_API_KEY")
GEMINI=os.getenv("GEMINI")
Saya memuat variabel lingkungan agar dapat mengelola kunci API dan data sensitif secara aman tanpa menuliskannya langsung di kode. Ini memastikan skrip tetap aman, dan saya bisa mengubah kunci di satu tempat (berkas .env) jika diperlukan.
Singkatnya, berikut fungsi paket dan fungsi yang diimpor ini:
- os: Menyediakan utilitas antarmuka sistem operasi.
- dotenv: Memuat variabel lingkungan dari berkas
.env. - FAISS: Vector store untuk pencarian kemiripan dan penelusuran.
- PyPDFLoader: Mengekstrak konten teks dari dokumen PDF.
- RecursiveCharacterTextSplitter: Memecah teks menjadi potongan yang mudah dikelola secara rekursif.
- HuggingFaceEmbeddings: Menghasilkan embedding teks menggunakan model HuggingFace.
- ChatGroq: Antarmuka chat didukung akselerasi perangkat keras Groq.
- SerperDevTool: Alat untuk melakukan pencarian web.
- ScrapeWebsiteTool: Mengekstrak data dari halaman web.
- Agent: Mendefinisikan entitas AI dengan peran dan tujuan.
- Task: Mewakili sasaran atau tindakan spesifik untuk sebuah agen.
- Crew: Mengorkestrasi agen dan tugas untuk alur kerja terkoordinasi.
- LLM: Antarmuka model bahasa besar untuk menghasilkan respons teks.
Inisialisasi LLM
Kita mulai dengan menginisialisasi dua model bahasa:
llm: Untuk tugas umum seperti perutean dan menghasilkan jawaban. Kita akan menggunakan modelllama-3.3-70b-specdec.crew_llm: Khusus untuk agen web scraping, karena membutuhkan konfigurasi berbeda (seperti temperature untuk keluaran yang lebih kreatif). Kita akan menggunakan modelgemini/gemini-1.5-flash.
# Initialize LLM
llm = ChatGroq(
model="llama-3.3-70b-specdec",
temperature=0,
max_tokens=500,
timeout=None,
max_retries=2,
)
crew_llm = LLM(
model="gemini/gemini-1.5-flash",
api_key=GEMINI,
max_tokens=500,
temperature=0.7
)
Menambahkan Pengambil Keputusan
Fungsi check_local_knowledge() di bawah ini bertindak sebagai pengambil keputusan. Saya membuat prompt yang memasukkan pertanyaan pengguna dan beberapa konteks lokal (dari PDF). Model merespons dengan "Yes" atau "No", memberi tahu apakah ada cukup informasi lokal untuk menjawab pertanyaan. Jika tidak, kita akan beralih ke web scraping.
def check_local_knowledge(query, context):
"""Router function to determine if we can answer from local knowledge"""
prompt = '''Role: Question-Answering Assistant
Task: Determine whether the system can answer the user's question based on the provided text.
Instructions:
- Analyze the text and identify if it contains the necessary information to answer the user's question.
- Provide a clear and concise response indicating whether the system can answer the question or not.
- Your response should include only a single word. Nothing else, no other text, information, header/footer.
Output Format:
- Answer: Yes/No
Study the below examples and based on that, respond to the last question.
Examples:
Input:
Text: The capital of France is Paris.
User Question: What is the capital of France?
Expected Output:
Answer: Yes
Input:
Text: The population of the United States is over 330 million.
User Question: What is the population of China?
Expected Output:
Answer: No
Input:
User Question: {query}
Text: {text}
'''
formatted_prompt = prompt.format(text=context, query=query)
response = llm.invoke(formatted_prompt)
return response.content.strip().lower() == "yes"
Agen Pencarian dan Scraping Web
Berikutnya, kita menyiapkan agen pencarian dan scraping web menggunakan crewai library. Agen ini menggunakan alat pencarian (SerperDevTool) untuk menemukan artikel terkait pertanyaan pengguna. Deskripsi tugas memastikan agen mengetahui apa yang harus diambil, dan merangkum konten web yang relevan. Ibarat mengirim pekerja khusus untuk mengambil data dari internet.
Lalu, fungsi get_web_content() menjalankan agen web scraping. Fungsi ini mengirim pertanyaan sebagai masukan dan mengambil ringkasan singkat dari artikel paling relevan. Fungsi ini mengembalikan hasil mentah, yang menjadi konteks kita jika router memutuskan informasi lokal tidak cukup.
def setup_web_scraping_agent():
"""Setup the web scraping agent and related components"""
search_tool = SerperDevTool() # Tool for performing web searches
scrape_website = ScrapeWebsiteTool() # Tool for extracting data from websites
# Define the web search agent
web_search_agent = Agent(
role="Expert Web Search Agent",
goal="Identify and retrieve relevant web data for user queries",
backstory="An expert in identifying valuable web sources for the user's needs",
allow_delegation=False,
verbose=True,
llm=crew_llm
)
# Define the web scraping agent
web_scraper_agent = Agent(
role="Expert Web Scraper Agent",
goal="Extract and analyze content from specific web pages identified by the search agent",
backstory="A highly skilled web scraper, capable of analyzing and summarizing website content accurately",
allow_delegation=False,
verbose=True,
llm=crew_llm
)
# Define the web search task
search_task = Task(
description=(
"Identify the most relevant web page or article for the topic: '{topic}'. "
"Use all available tools to search for and provide a link to a web page "
"that contains valuable information about the topic. Keep your response concise."
),
expected_output=(
"A concise summary of the most relevant web page or article for '{topic}', "
"including the link to the source and key points from the content."
),
tools=[search_tool],
agent=web_search_agent,
)
# Define the web scraping task
scraping_task = Task(
description=(
"Extract and analyze data from the given web page or website. Focus on the key sections "
"that provide insights into the topic: '{topic}'. Use all available tools to retrieve the content, "
"and summarize the key findings in a concise manner."
),
expected_output=(
"A detailed summary of the content from the given web page or website, highlighting the key insights "
"and explaining their relevance to the topic: '{topic}'. Ensure clarity and conciseness."
),
tools=[scrape_website],
agent=web_scraper_agent,
)
# Define the crew to manage agents and tasks
crew = Crew(
agents=[web_search_agent, web_scraper_agent],
tasks=[search_task, scraping_task],
verbose=1,
memory=False,
)
return crew
def get_web_content(query):
"""Get content from web scraping"""
crew = setup_web_scraping_agent()
result = crew.kickoff(inputs={"topic": query})
return result.raw
Membuat Basis Data Vektor
Fungsi setup_vector_db() menyiapkan basis data vektor dari berkas PDF. Berikut langkah-langkah yang saya lakukan:
- Muat PDF: Saya menggunakan
PyPDFLoaderuntuk mengekstrak konten. - Memecah teks: Saya membagi konten PDF menjadi potongan kecil (1.000 karakter dengan tumpang tindih 50 karakter) menggunakan
RecursiveCharacterTextSplitter. Ini membuat data lebih mudah dikelola dan ditelusuri. - Membuat Vector DB: Saya membuat embedding untuk potongan teks menggunakan model sentence-transformer dan menyimpannya di basis data vektor FAISS. Ini memungkinkan saya mencari teks relevan secara efisien.
Setelah itu, fungsi get_local_content() melakukan kueri ke basis data vektor untuk 5 potongan paling relevan terkait pertanyaan pengguna. Fungsi ini menggabungkan potongan tersebut menjadi satu string konteks.
def setup_vector_db(pdf_path):
"""Setup vector database from PDF"""
# Load and chunk PDF
loader = PyPDFLoader(pdf_path)
documents = loader.load()
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=50
)
chunks = text_splitter.split_documents(documents)
# Create vector database
embeddings = HuggingFaceEmbeddings(
model_name="sentence-transformers/all-mpnet-base-v2"
)
vector_db = FAISS.from_documents(chunks, embeddings)
return vector_db
def get_local_content(vector_db, query):
"""Get content from vector database"""
docs = vector_db.similarity_search(query, k=5)
return " ".join([doc.page_content for doc in docs])
Menghasilkan Jawaban Akhir
Setelah saya memiliki konteks (baik dari dokumen lokal maupun web scraping), saya memberikannya kepada model bahasa bersama pertanyaan pengguna. LLM menghasilkan jawaban akhir dengan menggabungkan konteks dan pertanyaan dalam format percakapan.
Berikut alur pemrosesan kueri utama:
- Perutean: Saya menggunakan
check_local_knowledge()untuk memutuskan apakah konten PDF lokal memiliki data yang cukup untuk menjawab pertanyaan. - Jika "Yes", saya mengambil potongan relevan dari basis data vektor.
- Jika "No", saya melakukan scraping web untuk artikel relevan.
- Jawaban Akhir: Setelah saya memiliki konteks, saya memberikannya ke LLM untuk menghasilkan respons akhir.
def generate_final_answer(context, query):
"""Generate final answer using LLM"""
messages = [
(
"system",
"You are a helpful assistant. Use the provided context to answer the query accurately.",
),
("system", f"Context: {context}"),
("human", query),
]
response = llm.invoke(messages)
return response.content
def process_query(query, vector_db, local_context):
"""Main function to process user query"""
print(f"Processing query: {query}")
# Step 1: Check if we can answer from local knowledge
can_answer_locally = check_local_knowledge(query, local_context)
print(f"Can answer locally: {can_answer_locally}")
# Step 2: Get context either from local DB or web
if can_answer_locally:
context = get_local_content(vector_db, query)
print("Retrieved context from local documents")
else:
context = get_web_content(query)
print("Retrieved context from web scraping")
# Step 3: Generate final answer
answer = generate_final_answer(context, query)
return answer
Terakhir, kita merangkai semuanya dengan fungsi main():
def main():
# Setup
pdf_path = "genai-principles.pdf"
# Initialize vector database
print("Setting up vector database...")
vector_db = setup_vector_db(pdf_path)
# Get initial context from PDF for routing
local_context = get_local_content(vector_db, "")
# Example usage
query = "What is Agentic RAG?"
result = process_query(query, vector_db, local_context)
print("\nFinal Answer:")
print(result)
if __name__ == "__main__":
main()
Di atas, kita:
- Menyiapkan basis data vektor: Memuat dan memroses PDF.
- Inisialisasi konteks lokal: Kita mengambil beberapa konten umum dari PDF untuk diberikan sebagai konteks ke router.
- Menjalankan contoh kueri: Kita menjalankan kueri contoh (
"What is Agentic RAG?") dan mencetak jawaban akhir.
Berikut keluaran program:
Agentic RAG is a technique for building Large Language Model (LLM) powered applications that incorporates AI agents. It is an extension of the traditional Retrieval-Augmented Generation (RAG) approach, which uses an external knowledge source to provide the LLM with relevant context and reduce hallucinations.
In traditional RAG pipelines, the retrieval component is typically composed of an embedding model and a vector database, and the generative component is an LLM. At inference time, the user query is used to run a similarity search over the indexed documents to retrieve the most similar documents to the query and provide the LLM with additional context.
Agentic RAG, on the other hand, introduces AI agents that are designed to interact with the user query and provide additional context to the LLM. These agents can be thought of as "virtual assistants" that help the LLM to better understand the user's intent and retrieve relevant documents.
The key components of Agentic RAG include:
1. AI agents: These are the virtual assistants that interact with the user query and provide additional context to the LLM.
2. Retrieval component: This is the component that retrieves the most similar documents to the user query.
3. Generative component: This is the component that uses the retrieved documents to generate the final output.
Agentic RAG has several benefits, including:
1. Improved accuracy: By providing additional context to the LLM, Agentic RAG can improve the accuracy of the generated output.
2. Enhanced user experience: Agentic RAG can help to reduce the complexity of the user interface and provide a more natural and intuitive experience.
3. Increased flexibility: Agentic RAG can be easily extended to support new use cases and applications.
However, Agentic RAG also has some limitations, including:
1. Increased complexity: Agentic RAG requires additional components and infrastructure, which can increase the complexity of the system.
2. Higher computational requirements: Agentic RAG requires more computational resources to handle the additional complexity of the AI agents and the retrieval component.
3. Training requirements: Agentic RAG requires more data and training to learn the behaviour of the AI agents and the retrieval component.
Penjelasan Output
Saat saya menanyakan, "What is Agentic RAG?" yang tidak tersedia secara eksplisit dalam dokumen yang diberikan, sistem menunjukkan fleksibilitas dan kecerdasannya. Agen crewAI merutekan pertanyaan dengan tepat, memanfaatkan pemahaman router bahwa konteks eksternal diperlukan. Agen berkolaborasi untuk mengambil artikel paling relevan dari web, menganalisis isinya, dan menghasilkan respons yang berwawasan.
Sistem memberikan penjelasan yang jelas tentang agentic RAG, komponennya (agen AI, retrieval, dan elemen generatif), manfaatnya (akurasi, pengalaman pengguna, dan fleksibilitas), serta keterbatasannya (kompleksitas, kebutuhan komputasi, dan kebutuhan pelatihan).
Ini menyoroti kemampuan pipeline untuk mengambil konteks secara dinamis dan menyajikan wawasan yang tepat, ringkas, dan bernilai, bahkan ketika menghadapi pertanyaan di luar dataset awalnya.
Penutup
Pipeline yang kita bangun adalah proses dinamis multi-langkah yang secara efisien menangani pertanyaan pengguna dengan menggabungkan pengetahuan internal dan eksternal.
Sistem dapat beradaptasi secara dinamis terhadap beragam pertanyaan dan memberikan jawaban yang akurat serta ramah pengguna. Dengan integrasi data lokal, pencarian internet langsung, dan antarmuka yang mulus, pipeline RAG membuktikan dirinya sebagai solusi tangguh dan praktis untuk aplikasi dunia nyata. Sebagai langkah berikutnya, cobalah membangun sesuatu sendiri menggunakan alur kerja yang telah kita bahas.
Senior GenAI Engineer dan Kreator Konten yang telah meraih 20 juta tayangan dengan berbagi pengetahuan tentang GenAI dan sains data.

