Ana içeriğe atla

Agentic RAG: Adım Adım Eğitici İçerik ve Demo Proje

Kullanıcı sorgularına bağlama duyarlı yanıtlar üretmek için yerel veri kaynaklarını ve web kazımayı entegre ederek sıfırdan bir Agentic RAG hattı oluşturmayı öğrenin.
Güncel 16 Nis 2026  · 12 dk. oku

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:

agentic rag demo project overview

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:

  1. Yerel belgeler: Bilgi tabanı olarak önceden işlenmiş bir PDF kullanacağız; sistem burada ilgili bilgi parçalarını arar.
  2. İ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:

  1. Groq API anahtarı: Groq’tan bir API anahtarına ihtiyacınız olacak; buradan alabilirsiniz: Groq API Konsolu
  2. 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
  3. 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: .env dosyaları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-specdec modelini 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-flash modelini 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:

  1. PDF’yi yükleme: İçeriği çıkarmak için PyPDFLoader kullandım.
  2. Metni parçalara ayırma: PDF içeriğini RecursiveCharacterTextSplitter ile (50 karakter örtüşmeli 1000 karakterlik) daha küçük parçalara böldüm. Bu, veriyi yönetilebilir ve aranabilir kılar.
  3. 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:

  1. 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.
  2. 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:

  1. Vektör veritabanını kurduk: PDF’yi yükleyip işledik.
  2. Yerel bağlamı başlattık: PDF’den bazı genel içerikleri alıp yönlendiriciye bağlam olarak geçtik.
  3. Ö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.


Bhavishya Pandit's photo
Author
Bhavishya Pandit
LinkedIn
Twitter

GenAI ve veri bilimi üzerine bilgi paylaşarak 20 milyon görüntüleme elde etmiş Kıdemli GenAI Mühendisi ve İçerik Üreticisi.

Konular

Bu kurslarla yapay zekâyı öğrenin!

Program

Yapay Zeka Uygulamaları Geliştirme

21 sa
OpenAI API, Hugging Face ve LangChain dahil olmak üzere en yeni yapay zeka geliştirici araçlarıyla yapay zeka destekli uygulamalar oluşturmayı öğrenin.
Ayrıntıları GörRight Arrow
Kursa Başla
Devamını GörRight Arrow