Program
Yapay zekânızın bildiklerini tekrar etmekten fazlasını yapabilmesini ne sıklıkla diliyorsunuz? Yapay zekâ sistemlerini sayısız saat boyunca ince ayar yapmış biri olarak söyleyebilirim ki, geleneksel modeller etkileyici olsa da çoğu zaman sadece eğitildikleri veri balonunun içinde sıkışıp kalmış gibi hissettirir. İşte burada Agentic RAG devreye giriyor.
Agentic RAG’de, fail bazlı yapay zekânın karar verme yetenekleri, alım destekli üretim (RAG) yaklaşımının uyarlanabilirliğiyle buluşur. Birlikte, bağımsız biçimde bilgiye erişebilen, akıl yürütebilen ve ilgili içerik üretebilen bir sistem oluştururlar.
Daha önce Agentic RAG üzerine, konuyu kuramsal açıdan tüm yönleriyle anlamanıza yardımcı olacak bir makale yazmıştım. Bu yazı ise daha uygulamalı olacak; gelin buna odaklanalım.
Agentic RAG Proje Genel Bakış
Adım adım ne inşa ettiğimizi birlikte inceleyelim. Buradaki mimariye dayalı bir RAG hattı kurmakla ilgili:

Adım 1: Kullanıcı sorgusu
Basit ya da karmaşık olsun, her şey bir kullanıcı sorusuyla başlar. Bu, hattımızı harekete geçiren kıvılcımdır.
Adım 2: Sorgunun yönlendirilmesi
Sıradaki kontrol: Bunu yanıtlayabilir miyim?
Evet mi? Mevcut bilgiden yararlanıp yanıtı anında sunar.
Hayır mı? O hâlde derine inme zamanı! Sorgu bir sonraki adıma yönlendirilir.
Adım 3: Verinin alınması
Yanıt hazır değilse, hat iki olası kaynağa başvurur:
- Yerel belgeler: Bilgi tabanı olarak önceden işlenmiş bir PDF kullanacağız; sistem burada ilgili bilgi parçalarını arar.
- İnternet araması: Daha fazla bağlam gerekirse, hat güncel bilgiyi toplamak için haricî kaynaklara başvurabilir.
Adım 4: Bağlamın oluşturulması
PDF’den ya da web’den alınan veri, tutarlı bir alım bağlamına derlenir. Bunu, birleştirmeden önce tüm yapboz parçalarını toplamaya benzetebilirsiniz.
Adım 5: Nihai yanıtın üretilmesi
Son olarak bu bağlam, açık ve doğru bir yanıt üretmesi için büyük bir dil modeline (LLM) aktarılır. Mesele yalnızca veri almak değil; onu en iyi şekilde anlayıp sunmaktır.
Bunun sonunda, gerçek dünya bağlamıyla dinamik biçimde yanıt verebilen akıllı ve verimli bir RAG hattına sahip olacağız.
Yerel Veri Kaynağı
Başlamak için yerel veri kaynağımız olarak gerçek bir belge kullanacağım. Çalışacağımız belge, Generative AI Principles adlı belgenin ta kendisi. Değerli içgörülerle dolu olduğundan hattımız için mükemmel bir test vakası olacak. Yönlendirme amacıyla kullandığım dosyanın bir özetine de ihtiyacınız olacak. Özet dosyasını buradan edinebilirsiniz.
Başlamak için ihtiyaç duyduğunuz her şey, adım adım burada.
Önkoşullar
Dalış yapmadan önce, hazır etmeniz gereken birkaç şey var:
- Groq API anahtarı: Groq’tan bir API anahtarına ihtiyacınız olacak; buradan alabilirsiniz: Groq API Konsolu
- Gemini API anahtarı: Ajanlarla orkestrasyon yaparken Gemini size yardımcı olacak; Groq çok hızlı yanıtlar verir ancak mevcut hız sınırlamalarıyla takılabilir: Gemini API Konsolu
- Serper.dev API anahtarı: İnternet araması işlevleri için Serper.dev kullanacağız. API anahtarınızı buradan alın: Serper.dev API Anahtarı
Paketlerin Kurulması
Doğru araçların yüklü olduğundan emin olalım. Terminalinizi açın ve gerekli Python paketlerini kurmak için aşağıdaki komutları çalıştırın:
pip install langchain-groq faiss-cpu crewai serper pypdf2 python-dotenv setuptools sentence-transformers huggingface distutils`
Ortamın Ayarlanması
Anahtarlar ve paketler hazır olduğunda başlayabilirsiniz! API anahtarlarınızı bir .env dosyasına ya da kod tabanınızda güvenli bir şekilde saklamanızı öneririm. .env dosyanız şöyle görünebilir:
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")
Ortam değişkenlerini, API anahtarlarını ve hassas verileri kod içine gömmeden güvenli şekilde yönetebilmek için yükledim. Bu, betiğin güvenli kalmasını sağlar ve gerekirse anahtarları tek bir yerden (.env dosyası) değiştirebilirim.
Kısaca, içe aktardığımız bu paket ve işlevler şunları yapacak:
- os: İşletim sistemi arabirimi yardımcıları sağlar.
- dotenv:
.envdosyalarından ortam değişkenlerini yükler. - FAISS: Benzerlik araması ve alım için vektör deposu.
- PyPDFLoader: PDF belgelerinden metin içeriği çıkarır.
- RecursiveCharacterTextSplitter: Metni yönetilebilir parçalara yinelemeli olarak böler.
- HuggingFaceEmbeddings: HuggingFace modelleriyle metin gömme vektörleri üretir.
- ChatGroq: Groq donanım hızlandırmasıyla çalışan sohbet arabirimi.
- SerperDevTool: Web araması yapmak için araç.
- ScrapeWebsiteTool: Web sayfalarından veri çıkarır.
- Agent: Rolleri ve hedefleri olan bir yapay zekâ varlığını tanımlar.
- Task: Bir ajan için belirli bir hedefi ya da eylemi temsil eder.
- Crew: Koordine iş akışları için ajanları ve görevleri orkestre eder.
- LLM: Metin yanıtları üretmek için büyük dil modeli arabirimi.
LLM’lerin Başlatılması
İki dil modelini başlatarak başlıyoruz:
llm: Yönlendirme ve yanıt üretme gibi genel görevler için.llama-3.3-70b-specdecmodelini kullanacağız.crew_llm: Özellikle web kazıma ajanı için; daha yaratıcı çıktılar için sıcaklık gibi farklı bir yapılandırmaya ihtiyaç duyar.gemini/gemini-1.5-flashmodelini kullanacağız.
# 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
)
Karar Vericinin Eklenmesi
Aşağıdaki check_local_knowledge() işlevi bir karar verici olarak çalışır. Kullanıcı sorgusunu ve bazı yerel bağlamı (PDF’den) ilettiğim bir istem oluşturdum. Model bana "Yes" ya da "No" şeklinde yanıt vererek sorguyu yanıtlamak için yerelde yeterli bilgi olup olmadığını söylüyor. Yoksa web kazımaya başvuracağız.
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"
Web Arama ve Kazıma Ajansı
Sırada, crewai kitaplığını kullanarak bir web arama ve kazıma ajanı kuruyoruz. Bu ajan, kullanıcının sorgusuyla ilgili makaleleri bulmak için bir arama aracını (SerperDevTool) kullanır. Görev tanımı, ajanın neyi alması gerektiğini netleştirir ve ilgili web içeriğini özetler. İnternetten veri getiren uzman bir çalışan göndermeye benzer.
Ardından get_web_content() işlevi web kazıma ajanını çalıştırır. Sorguyu girdi olarak gönderir ve en ilgili makalenin kısa bir özetini alır. Yönlendirici yerel bilginin yeterli olmadığına karar verirse, ham sonuç bağlamımız hâline gelir.
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
Vektör Veritabanının Oluşturulması
setup_vector_db() işlevi, bir PDF dosyasından vektör veritabanını kurar. Bunu adım adım şöyle yaptım:
- PDF’yi yükleme: İçeriği çıkarmak için
PyPDFLoaderkullandım. - Metni parçalara ayırma: PDF içeriğini
RecursiveCharacterTextSplitterile (50 karakter örtüşmeli 1000 karakterlik) daha küçük parçalara böldüm. Bu, veriyi yönetilebilir ve aranabilir kılar. - Vektör VT oluşturma: Parçaları bir cümle-dönüştürücü modeliyle gömdüm ve FAISS vektör veritabanında sakladım. Bu sayede ilgili metni verimli biçimde arayabiliyorum.
Ardından get_local_content() işlevi, kullanıcının sorgusuyla ilgili en uygun ilk 5 parçayı vektör veritabanından çeker. Bu parçaları tek bir bağlam dizgesinde birleştirir.
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])
Nihai Yanıtın Üretilmesi
Bağlamı (yerel belgelerden ya da web kazımadan) elde ettikten sonra, kullanıcı sorgusuyla birlikte dil modeline iletirim. LLM, bağlam ve sorguyu konuşma biçiminde birleştirerek nihai yanıtı üretir.
Ana sorgu işleme akışı şöyle işler:
- Yönlendirme: Yerel PDF içeriğinin sorguyu yanıtlamak için yeterli veriye sahip olup olmadığını anlamak için
check_local_knowledge()kullanırım. - Eğer "Yes" ise, ilgili parçaları vektör veritabanından çekerim.
- Eğer "No" ise, ilgili makaleleri web’den kazırım.
- Nihai Yanıt: Bağlamı elde ettiğimde, nihai yanıtı üretmesi için LLM’e aktarırım.
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
Son olarak her şeyi main() işleviyle bir araya getiriyoruz:
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()
Yukarıda şunları yaptık:
- Vektör veritabanını kurduk: PDF’yi yükleyip işledik.
- Yerel bağlamı başlattık: PDF’den bazı genel içerikleri alıp yönlendiriciye bağlam olarak geçtik.
- Örnek bir sorgu çalıştırdık: Örnek bir sorgu (
"What is Agentic RAG?") çalıştırıp nihai yanıtı yazdırdık.
Programın çıktısı şu şekilde:
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.
Çıktı Açıklaması
Belgede açıkça yer almayan "What is Agentic RAG?" sorusunu sorduğumda, sistem esnekliğini ve zekâsını gösterdi. crewAI ajanları, dış bağlam gerektiğini anlayan yönlendiriciden yararlanarak sorguyu doğru şekilde yönlendirdi. Ajanlar web’den en ilgili makaleyi kazımak, içeriğini analiz etmek ve bilgili bir yanıt üretmek için iş birliği yaptı.
Sistem; agentic RAG’i, bileşenlerini (Yapay zekâ ajanları, alım ve üretici unsurlar), faydalarını (doğruluk, kullanıcı deneyimi ve esneklik) ve sınırlamalarını (karmaşıklık, hesaplama gereksinimleri ve eğitim ihtiyaçları) net biçimde açıkladı.
Bu durum, hattın bağlamı dinamik biçimde alıp ilk veri kümesinin ötesindeki sorgularda bile isabetli, öz ve değerli içgörüler sunma becerisini ortaya koyuyor.
Sonuç
Kurduğumuz hat, mevcut ve haricî bilgiyi birleştirerek kullanıcı sorgularını verimli biçimde işleyen dinamik, çok adımlı bir süreçtir.
Sistem, farklı sorgulara dinamik olarak uyum sağlayabilir ve doğru, kullanıcı dostu yanıtlar sunabilir. Yerel veri, canlı internet aramaları ve kesintisiz bir kullanıcı arayüzünün entegrasyonuyla, RAG hattı gerçek dünya uygulamaları için sağlam ve pratik bir çözüm olduğunu kanıtlıyor. Bir sonraki adım olarak, ele aldığımız iş akışını kullanarak kendi çözümünüzü geliştirmeyi deneyin.
GenAI ve veri bilimi üzerine bilgi paylaşarak 20 milyon görüntüleme elde etmiş Kıdemli GenAI Mühendisi ve İçerik Üreticisi.
