Mert Özen Her Satırda Daha İleri
Yapay Zeka RAG — #13

Agentic RAG ve GraphRAG: Klasik RAG Ne Zaman Yetmez?

Mert Özen 8 Kas 2026 14 dk 2 görüntülenme
Agentic RAG ve GraphRAG: Klasik RAG Ne Zaman Yetmez?

Klasik RAG cevabı tek yerde duran soruların çoğunu çözer; multi-hop sorularda retrieval'ı tool yapan agent doğru kaynağı buldu ama 3 çağrı, 11 kat token ve 30 kat süre harcadı. GraphRAG'in ilk adımı küçük modelde parçalı entity'ler üretti; bütün corpus'u prompt'a koyan long context klasik RAG'le 7/10'da berabere kaldı.

Sürüm notu: Bu yazıdaki kodlar .NET 10, Microsoft.Extensions.AI 10.11.0, OllamaSharp 5.5.2, Entity Framework Core 10 ve PostgreSQL 17 + pgvector 0.8.7 ile derlenip denenmiştir; modeller Ollama'da qwen3:4b (tool calling), gemma3:4b ve nomic-embed-text.

Önce Tahmin Et

Müşteri soruyor: "BKS-50518 kodlu ürünü indirdikten sonra iade edebilir miyim?" Cevap iki dokümana dağılmış: ürün kataloğu BKS-50518'in "Sesli Kitap: Kürk Mantolu Madonna" olduğunu söylüyor, iade politikası da sesli kitapların indirildikten sonra iade edilemeyeceğini. Serinin klasik RAG (Retrieval-Augmented Generation) pipeline'ı (hybrid search, ilk üç chunk, gemma3:4b) bu soruya ne der? Ve aramayı bir tool olarak alıp ne zaman, ne ile arayacağına kendisi karar veren bir model (qwen3:4b) ne yapar?

$ dotnet run -- classic "BKS-50518 kodlu ürünü indirdikten sonra iade edebilir miyim?"
Q: BKS-50518 kodlu ürünü indirdikten sonra iade edebilir miyim?
   retrieved: urun-katalogu#13, kurumsal-satis-sozlesmesi#3, iade-politikasi#2
   model calls: 1, input tokens: 323, output tokens: 31, 1,7s
   A: Kurumsal Satış Sözleşmesi'ndeki 4. maddeye göre, uygulama üzerinden indirilen sesli kitaplar iade edilemez.

$ dotnet run -- agentic "BKS-50518 kodlu ürünü indirdikten sonra iade edebilir miyim?"
Q: BKS-50518 kodlu ürünü indirdikten sonra iade edebilir miyim?
   search 1: BKS-50518 indirilen ürün iade
   search 2: indirilen ürünler iade politikası
   model calls: 3, input tokens: 3684, output tokens: 1540, 54,9s
   A: BKS-50518 kodlu ürünü indirdikten sonra iade edemezsiniz. Bookstore'un iade politikasına göre, e-kitaplar, sesli kitaplar ve dijital kodlar indirildikten veya etkinleştirildikten sonra iade edilemez. ...

Klasik RAG doğru sonuca yanlış yoldan vardı: ürünü buldu, iade politikasının ilgili bölümünü bulamadı ve kurumsal sözleşmenin 4. maddesine, orada hiç yazmayan bir cümle yükledi. Agent ilk aramada eksik bilgiyi fark etti, ikinci bir sorgu yazdı ve cevabı doğru kaynağa dayandırdı. Bedeli: 3 model çağrısı, 11 kat input token ve 1,7 yerine 54,9 saniye. Serinin bu son yazısı bu takası soruyor: klasik RAG ne zaman yetmez ve yetmediğinde agentic RAG, GraphRAG ya da her şeyi prompt'a koyan long context, hangisi gerçekten çözüm?

Klasik RAG'in Tek Atışı

Bu seride kurduğumuz pipeline bir "tek atış": soru bir kez embed edilir, bir kez aranır, sonuç bir kez prompt'a girer. Bu, cevabın tek bir yerde durduğu soruların büyük çoğunluğu için doğru tasarım ve 12. yazıdaki ölçümler bunu gösteriyor. Üç tür soru ise bu yapıyı zorlar. Multi-hop sorular, cevabın bir parçasının ikinci aramanın sorgusunu belirlediği sorulardır: önce "BKS-50518 nedir?", sonra "sesli kitap iade edilir mi?". Global sorular, corpus'un geneline yayılmış bir özeti isteyen sorulardır: "Hangi durumlarda para iadesi alırım?". Bir de bağlamın tamamına ihtiyaç duyan, top-k'ya sığmayan sorular. Her biri için farklı bir araç var.

Retrieval'ı Tool Yapmak: Agentic RAG

Agentic RAG'in özü basit: aramayı pipeline'ın sabit bir adımı olmaktan çıkarıp modele bir tool olarak veriyorsun. Tool calling'in mantığı LLM (Large Language Model) Temelleri serisinin 11–12. yazılarında, agent loop'unun ayrıntıları ilerideki AI (Artificial Intelligence) Agent'ları ve MCP (Model Context Protocol) serisinde. Burada yalnız retrieval tarafı var:

// Retrieval'ı bir tool olarak modele vermek: ne zaman ve ne ile arayacağına model karar verir
public sealed class SearchTool(Retriever retriever)
{
    public List<string> Calls { get; } = [];

    [Description("Searches the Bookstore help center (policies, FAQ, product catalog, corporate sales contract). Returns the 3 most relevant sections.")]
    public async Task<string> SearchDocs([Description("A short Turkish search query about one topic")] string query)
    {
        Calls.Add(query);
        List<Candidate> hits = await retriever.HybridAsync(query, 3);
        return string.Join("\n\n", hits.Select(h => $"[{h.Id}]\n{h.Content}"));
    }
}

SearchTool tool = new(retriever);
IChatClient agent = new ChatClientBuilder(Models.Chat("qwen3:4b"))
    .UseFunctionInvocation(configure: f => f.MaximumIterationsPerRequest = 5)
    .Build();
response = await agent.GetResponseAsync(
[
    new ChatMessage(ChatRole.System, """
        You are the Bookstore help-center assistant. Answer in Turkish.
        Use the SearchDocs tool to find facts; search again with a different query if the first results are not enough.
        Answer only from the search results.
        """),
    new ChatMessage(ChatRole.User, question)
], new ChatOptions { Temperature = 0, Seed = 42, Tools = [AIFunctionFactory.Create(tool.SearchDocs)] });

Tool, önceki yazılardaki hybrid search'ü aynen kullanıyor; yani 11. yazıdaki yetki filtresi de tool'un içinde kalmalı. Kullanıcı kimliğini modelin argümanına bırakmıyoruz; tool'u oluşturan kod, isteğin token'ındaki kimlikle oluşturulmuş bir DbContext'i kullanır. MaximumIterationsPerRequest = 5 da önemli: model aramaktan vazgeçmezse döngüyü biz keseriz. Aynı agent'a iki soru daha sordum:

Q: Okulumuz 120 adet kitap alacak; indirimimiz ne olur ve kredi kartıyla taksit yapabilir miyiz?
   search 1: okul kitap indirim kredi kartı taksit
   model calls: 2, input tokens: 2121, output tokens: 2560, 107,2s
   A: Okulumuz 120 adet kitap alırsa %15 indirim alırsınız. Kredi kartı ile taksit yapabilmek için toplam fiyat 750 TL ve üzeri olmalıdır.
Q: Kargo ücreti ne kadar?
   search 1: Kargo ücreti ne kadar?
   model calls: 2, input tokens: 1123, output tokens: 864, 20,7s
   A: Standart kargo ücreti 400 TL altındaki siparişler için **49,90 TL**dir. ...
SoruYaklaşımModel çağrısıInput tokenSüreSonuç
BKS-50518 iadesiKlasik13231,7 sDoğru sonuç, uydurma gerekçe
BKS-50518 iadesiAgentic33.68454,9 sDoğru, doğru kaynak
120 adet + taksitKlasik13751,2 s%22 yanlış, "taksit yapılamaz" doğru
120 adet + taksitAgentic22.121107,2 s%15 doğru, taksit kısmı yanlış
Kargo ücretiKlasik13301,0 sDoğru
Kargo ücretiAgentic21.12320,7 sDoğru, daha uzun

Tablo, agentic RAG'in bir sihir olmadığını gösteriyor. İkinci soruda agent tek bir birleşik sorguyla aradı, kurumsal sözleşmenin "kurumsal siparişlerde kredi kartıyla taksit yapılamaz" maddesi yerine bireysel müşterilerin taksit kuralını uyguladı. Klasik RAG ise aynı soruda taksit kısmını doğru, indirim oranını yanlış verdi (10. yazıdaki %22 hatasının aynısı). Agent'ın asıl üstünlüğü yalnız ilk soruda, yani gerçekten iki adımlı bir bilgi zincirinde görünüyor. Üçüncü soru, basit bir SSS (Sıkça Sorulan Sorular) sorusunda agent'ın maliyetini gösteriyor: aynı cevap için iki model çağrısı, üç kat token ve 20 kat süre. Süreler, qwen3:4b'nin thinking modunda ürettiği uzun reasoning çıktısını ve aynı Ollama'yı başka işlerin de kullandığı bir makineyi yansıtıyor; oranlara bak, mutlak saniyelere değil.

GraphRAG: Global Sorular İçin Graph ve Community Özeti

Agentic RAG multi-hop sorulara bir çözüm; ama "Hangi durumlarda para iadesi alırım, hangi durumlarda alamam?" gibi bir soru başka bir zorluk. Cevap tek bir chunk'ta değil, dört ayrı bölüme dağılmış: iade politikasının "Para iadesi" ve "Hasarlı veya yanlış ürün" bölümleri, kargo sayfasının "Teslim edilemeyen gönderiler" bölümü ve hediye kartının "Geçerlilik süresi" (süresi dolan kartın bakiyesi iade edilmez). Klasik retrieval'ın bunları ne kadar kapsadığını ölçtüm:

$ dotnet run -- global
top-3: 2/4 relevant  [iade-politikasi#3, iade-politikasi#2, kurumsal-satis-sozlesmesi#2]
top-5: 3/4 relevant  [iade-politikasi#3, iade-politikasi#2, kurumsal-satis-sozlesmesi#2, kargo-ve-teslimat#5, kurumsal-satis-sozlesmesi#0]
top-10: 3/4 relevant  [..., kurumsal-satis-sozlesmesi#3, personel-indirimi#0, iade-politikasi#4, iade-politikasi#0, kurumsal-satis-sozlesmesi#1]

Top-10'da bile hediye kartı bölümü yok, çünkü o bölüm "para iadesi"nden değil kartın geçerlilik süresinden bahsediyor; benzerlik araması onu "iade" sorusuna yakın bulmuyor. Bu, global soruların tipik kaderi: ilgili bilgiler birbirine benzemez, birbirine bağlıdır. Microsoft Research'ün GraphRAG'i (Edge ve arkadaşları, 2024) tam bu sorun için tasarlandı. Indexing aşamasında corpus'u küçük metin birimlerine bölüyor, her birimden bir LLM ile entity'leri, aralarındaki ilişkileri ve önemli iddiaları çıkarıyor, ortaya çıkan graph'ı Leiden algoritmasıyla hiyerarşik community'lere ayırıyor ve her community için aşağıdan yukarıya bir özet yazdırıyor. Sorgu tarafında dört mod var: community summary'leri üzerinden "global search", bir entity'nin komşularına yayılan "local search", local search'e community bilgisi ekleyen DRIFT search ve klasik top-k olan "basic search".

Bunun bedelini küçük ölçekte görmek için GraphRAG'in ilk adımını, entity ve relationship çıkarımını, index'teki bütün public chunk'lar için gemma3:4b'yle structured output kullanarak yaptım:

// GraphRAG'in ilk adımı: her chunk için LLM ile entity ve relationship çıkarımı
public sealed class GraphExtractor(IChatClient chat)
{
    public async Task<(Extraction Result, long InputTokens, long OutputTokens)> ExtractAsync(string text)
    {
        ChatResponse<Extraction> r = await chat.GetResponseAsync<Extraction>(
        [
            new ChatMessage(ChatRole.System, """
                Extract the key entities and the relations between them from the bookstore policy text.
                Use short lowercase Turkish noun phrases for entities (e.g. "hediye kartı", "para iadesi", "ekspres teslimat").
                Relation types: applies_to, costs, takes, excludes, refunds_to, requires, allows.
                """),
            new ChatMessage(ChatRole.User, text)
        ], new ChatOptions { Temperature = 0, Seed = 42 });
        return (r.Result, r.Usage?.InputTokenCount ?? 0, r.Usage?.OutputTokenCount ?? 0);
    }
}
$ dotnet run -- graph
[kargo-ve-teslimat#5] entities: kargo, teslim edilemeyen gönderiler, adrese kimse, kargo firması, en yakın şube, paket, sipariş, ücret iadesi, kargo ücreti
   kargo -applies_to-> teslim edilemeyen gönderiler
   kargo firması -takes-> paket
   kargo firması -attempts-> teslim dener
   kargo firması -waits-> en yakın şube
   paket -refunds_to-> ücret iadesi
   sipariş -results_in-> iptal edilerek
   ücret iadesi -costs-> kargo ücreti
   kargo firması -excludes-> kargo ücreti
...
48 chunks, 379 distinct entities, 349 relations, input 7978 + output 14484 tokens, 338s
  iade: iade-politikasi#1, iade-politikasi#3, kurumsal-satis-sozlesmesi#3
  para iadesi: iade-politikasi#2, sss#3, urun-katalogu#13
  iade tutarı: iade-politikasi#2

Model 48 chunk'tan 349 relation ve 379 farklı entity çıkardı; bunun için 7.978 input ve 14.484 output token harcadı, 338 saniye sürdü. Output'un input'tan büyük olduğuna dikkat et: graph çıkarımı, metni okumaktan çok yeniden yazmaya benziyor ve bulut sağlayıcılarda output token'ları genelde daha pahalıdır. Kalite de sorunlu. Prompt'ta yedi relation tipi verdim; model attempts, waits, results_in gibi kendi tiplerini uydurdu ve kargo firması -excludes-> kargo ücreti gibi anlamsız kenarlar üretti. Asıl sorun entity'lerin parçalanması: aynı kavram "para iadesi", "ücret iadesi", "iade tutarı" ve "iade" diye dört ayrı düğüm oldu. "para iadesi" düğümünün bağlı olduğu üç chunk'tan ikisi (sss#3, urun-katalogu#13) global soruyla ilgisiz, kargo ve hediye kartı bölümleri ise bu düğüme hiç bağlanmamış. GraphRAG'in değeri bu düğümlerin doğru birleştirilmesine (entity resolution) ve community summary'lerinin kalitesine bağlı; küçük bir yerel modelle ilk adım bile güvenilir değil.

Bu yalnız ilk adım. Gerçek GraphRAG, entity'leri birleştirir (aynı kavramın farklı yazılışları), community'leri bulur ve her community için ayrı bir özet üretir; yani çağrı sayısı chunk sayısının üstüne çıkar. Projenin kendi dokümantasyonu da "GraphRAG can consume a lot of LLM resources!" diye uyarıyor ve küçük bir veriyle, ucuz modellerle başlamayı öneriyor. Microsoft Research'ün Kasım 2024'te duyurduğu LazyGraphRAG, önceden özet üretme adımını tamamen atlayıp indexing maliyetini klasik vector RAG düzeyine (tam GraphRAG'in yaklaşık %0,1'ine) indirdiğini raporluyor; ağır işi sorgu anına taşıyor. Bizim 48 chunk'lık corpus'umuzda bu maliyet değmez. Global soruyu önce daha ucuz yollarla dene: konuları ayrı ayrı arayan bir agent ya da daha geniş bir aday havuzunu süzen bir reranker. Bunları ölçmek bu yazının alıştırmalarından biri; hediye kartı bölümünü top-10'un bile yakalayamadığını unutma.

Long Context: Her Şeyi Prompt'a Koymak

gemma3:4b'nin context window'u 128K token. Bizim bütün public corpus'umuz 5.000 token'ın altında. O zaman neden retrieval yapalım? Aynı 10 soruyu iki şekilde sordum: klasik RAG (ilk üç chunk) ve bütün corpus'u system prompt'a koyan long context. Ollama'nın varsayılan context'i 4.096 token olduğu için long context isteklerinde num_ctx'i 16.384'e çıkardım; aksi halde LLM Temelleri'nin context window yazısında gördüğümüz gibi prompt'un başı sessizce kesilirdi.

// Bütün standart index'i prompt'a koy: retrieval yok
List<SourceChunk> all = Corpus.LoadStandard().Where(c => c.Acl == "public").ToList();
string corpus = string.Join("\n\n", all.Select(c => $"<doc id=\"{c.Id}\">\n{c.Content}\n</doc>"));
...
ChatResponse r = await chat.GetResponseAsync(
[
    new ChatMessage(ChatRole.System, "You are the Bookstore help-center assistant. Answer in Turkish in one sentence, using only the documents.\n\n" + corpus),
    new ChatMessage(ChatRole.User, q.Question)
], new ChatOptions { Temperature = 0, Seed = 42, AdditionalProperties = new() { ["num_ctx"] = 16384 } });
$ dotnet run -- classic-batch
q01 + input=386 3,3s  Satın aldığın basılı kitabı teslim tarihinden itibaren 21 gün içinde iade edebilirsin.
q08 - input=324 1,3s  5.000 TL ve üzeri alışverişte Kitapsever seviyesine geçerek ... ücretsiz standart kargodan yararlanabilirsiniz.
q10 - input=452 1,3s  Ekspres teslimat yalnızca İstanbul, Ankara ve İzmir'in merkez ilçelerinde geçerli olduğu için ...
q11 - input=338 0,5s  Bu konuda dokümanlarda bilgi bulunmamaktadır.
q29 + input=379 0,8s  Belediye faturaları genellikle 60 gün içinde havale veya EFT ile ödenmelidir.
...
$ dotnet run -- longcontext
q01 + input=4794 5,7s  Basılı bir kitabı satın aldıktan sonra teslim tarihinden itibaren 21 gün içinde iade edebilirsiniz.
q08 + input=4797 0,5s  400 TL ve üzeri alışverişlerde standart kargo ücretsizdir.
q10 - input=4797 0,8s  Standart kargo ile siparişiniz 3 ila 5 iş günü içinde Van'ın bir köyüne teslim edilebilir.
q11 - input=4794 1,0s  Şu an için Almanya'ya kitap göndermekteyiz, ancak ekspres teslimat seçeneği yalnızca ...
q29 - input=4798 0,5s  Fatura tarihinden itibaren 30 gün vadeli ödeme yapabilirsiniz.
...

Programdaki otomatik kontrol (cevapta beklenen ifade geçiyor mu) burada fazla katıydı; "3 ila 5" cevabını "3-5" aramadığı için kaçırdı. On cevabı elle değerlendirdim: iki yaklaşım da 10'da 7 doğru, ama farklı sorularda. Long context, retrieval'ın kaçırdığı q08 ("kargo bedava") ve q10'u (bölge tablosu) doğru cevapladı; çünkü doğru bölüm prompt'taydı. Buna karşılık klasik RAG'in doğru bildiği q29'da kamu kurumlarının 60 günlük istisnasını atladı ve q11'de, kargo sayfasının "yalnızca KKTC'ye (Kuzey Kıbrıs Türk Cumhuriyeti) gönderim yapıyoruz" cümlesi prompt'ta dururken "Almanya'ya kitap göndermekteyiz" dedi. Her şeyi görmek, doğru şeye bakmak demek değil.

Maliyet tarafı net: soru başına input 330–450 token yerine yaklaşık 4.790 token, yani 12 kat. Süreler ise beklenenden iyi: ilk istek 5,7 saniye, sonrakiler 0,5–1,6 saniye. Sebebi büyük ihtimalle Ollama'nın, aynı başlangıca sahip prompt'larda önceki isteğin hesapladığı kısmı yeniden kullanması; corpus system prompt'ta sabit durduğu için yalnız sorunun kendisi yeniden işleniyor. Bulut sağlayıcıların prompt caching özellikleri de aynı fikre dayanıyor, ama fiyatlandırma ve süre kuralları sağlayıcıya göre değişir; bu yazıda yalnız yerel modelle denedim, bulut sağlayıcıyla koşmadım. Bu ölçek için long context gerçekten makul bir seçenek: corpus küçük, değişmiyor ve istek sayısı düşük. Corpus 50.000 sayfaya, tenant'lara ve doküman bazlı yetkiye çıktığında tablo tersine döner: her soruya bütün corpus'u göndermek hem pahalıdır, hem de 11. yazıdaki yetki filtresini imkânsız kılar.

Hangi Durumda Hangisi?

Seri boyunca ölçtüklerimizi bir karar tablosuna dökersem:

  • Klasik RAG (hybrid + rerank + citation): cevabın bir ya da birkaç bölümde durduğu soruların büyük çoğunluğu. Varsayılan bu olmalı; diğerleri ancak ölçtüğün bir hata sınıfı için eklenir.
  • Agentic RAG: gerçek multi-hop sorular, belirsiz sorularda netleştirme, farklı kaynakları (doküman, sipariş API'si (Application Programming Interface)) birleştirmek. Bedeli çağrı sayısı, gecikme ve kontrol kaybı; adım sınırı, tool yetkisi ve trajectory log'u şart.
  • GraphRAG: büyük, birbirine bağlı bir corpus üzerinde "genel olarak ne söylüyor?" tipi global sorular. Indexing maliyeti yüksek; corpus sık değişiyorsa ve sorular çoğunlukla noktasal ise değmez.
  • Long context: küçük, stabil, tek tenant'lı bir corpus ve düşük trafik. Retrieval hatalarını ortadan kaldırır, ama okuma hatalarını kaldırmaz ve yetkiyi doküman düzeyinde uygulayamazsın.

Üretimde Dikkat

Agent'ın her adımını logla: hangi sorguyla aradı, hangi chunk'lar döndü, kaç iterasyon sürdü, kaç token harcadı. Klasik RAG'de bir hata "yanlış chunk mı, yanlış okuma mı?" sorusuyla çözülürdü; agentic RAG'de üçüncü bir soru eklenir: "yanlış sorgu mu yazdı?" İkinci sorudaki taksit hatası tam olarak bu. Agent'ın yazdığı tek sorguyu ("okul kitap indirim kredi kartı taksit") aynı hybrid search'le tekrar koştum: ilk üç sonuç odeme-secenekleri#1 (bireysel taksit kuralı), kurumsal-satis-sozlesmesi#0 ve hediye-karti#2; "kurumsal siparişlerde kredi kartıyla taksit yapılamaz" cümlesini içeren kurumsal-satis-sozlesmesi#1 beşinci sırada kaldı ve tool ilk üçü döndürdüğü için modele hiç ulaşmadı. Agent'ları değerlendirmenin (trajectory, tool call accuracy) ayrıntısı ilerideki AI Agent'ları ve MCP serisinde.

Maliyet ve süre için sert sınırlar koy: iterasyon sınırı, istek başına token bütçesi ve bir zaman aşımı. Reasoning modelleri (burada qwen3:4b thinking modunda) her adımda yüzlerce token düşünce çıktısı üretir; ikinci soruda 2.560 output token'ın büyük kısmı cevap değil düşünceydi.

Yönlendirmeyi ucuz tut. Her soruyu agent'a göndermek yerine basit bir sınıflandırıcı (ya da 12. yazıdaki ölçümlerin gösterdiği güven sinyalleri) ile çoğu soruyu tek atışta cevapla, yalnız düşük güvenli ya da birden fazla konu içeren soruları agentic yola gönder.

Sık Düşülen Tuzaklar

Basit bir SSS botu için agentic RAG kurmak. Kargo ücreti sorusu aynı cevap için 20 kat süre ve 3 kat token harcadı. Soruların çoğu tek atışlıksa agent yalnız maliyettir.

Agent'a yetkiyi bırakmak. Tool'a "kullanıcı kimliği" diye bir parametre koymak, 11. yazıdaki bütün emeği boşa çıkarır. Tool, kimliği isteğin bağlamından alır; model yalnız sorguyu seçer.

GraphRAG'i küçük ya da hızlı değişen bir corpus için kurmak. Her doküman değişikliğinde entity çıkarımı ve community summary'leri yeniden üretilmeli; 48 chunk'lık bir corpus'ta bu maliyetin karşılığı yok.

"Context window büyük, retrieval'a gerek yok" demek. Long context bu sette 7/10'la klasik RAG'le berabere kaldı ve dokümanda açıkça "yapmıyoruz" yazan bir şeyi "yapıyoruz" diye söyledi. Retrieval'ı kaldırmak hataları kaldırmaz, yerini değiştirir.

Küçük Bir Deneme

★☆☆ Agent'ın system prompt'una "Search each topic separately" satırını ekle ve 120 adet + taksit sorusunu tekrar sor. Agent iki ayrı arama yapıyor mu, taksit kısmı düzeliyor mu?

★★☆ Global soruyu agent'a sor ve kaç arama yaptığını, dört ilgili bölümden kaçını bulduğunu say. Aynı soruyu top-10 + LLM reranker'la cevaplayan klasik pipeline ile karşılaştır.

★★☆ Long context deneyini num_ctx ayarı olmadan (varsayılan 4.096) tekrarla. Input token sayısı ve cevaplar nasıl değişiyor? Hangi dokümanlar sessizce kesiliyor?

★★★ graph çıktısındaki entity'leri normalize et (ör. "kredi kartı iadelerinin" → "kredi kartı"), entity → chunk eşlemesinden bir komşuluk listesi kur ve global soruda "para iadesi" entity'sinin bir ve iki adım komşularındaki chunk'ları getir. Hediye kartı bölümünü yakalayabiliyor musun?

Bu yazıyla RAG serisi bitiyor. Minimal RAG'in neden çöktüğünü sınıflandırarak başladık; embedding modeli seçtik, dokümanları temiz metne çevirip chunk'ladık, pgvector ve Entity Framework Core (EF Core) ile aradık, hybrid search ve reranking ile sıralamayı düzelttik, citation'lı cevap verdik, yetkiyi sorguya koyduk ve hepsini ölçtük. Bu yazıda retrieval'ı bir tool olarak modelin eline verdiğimiz anda, artık bir pipeline değil bir agent yazmaya başladık. Agent loop'unu sıfırdan kurmak, tool tasarımı, context engineering ve tool'ları Model Context Protocol üzerinden sunmak ilerideki AI Agent'ları ve MCP serisinin konusu.