Umut ABALI
← Projelere dön

Agentic RAG Sistemi

LangGraph supervisor, hibrit retrieval ve vLLM üzerinde kendi sunucumuzda çalışan bir LLM ile çoklu-agent RAG platformu.

Problem

Ekipler kendi dokümanları üzerinde soru sormak istiyor. Bazen buna canlı web verisi ya da dosya okuma, veritabanı sorgulama gibi aksiyonlar da ekleniyor. Tek bir prompt + vektör araması bu aksiyon tarafını da, tam eşleşme gerektiren soruları (sayılar, isimler, süreler) da iyi karşılamıyor.

Sistemin ayrıca kendi altyapımızda çalışması ve her departmanın doküman ile hafızasını birbirinden ayırması gerekiyor.

Mimari

Agentic RAG Sistemi mimari diyagramıNext.js UIchat · settings · departmentFastAPI gatewayJWT / API key · rate limit · SSESupervisor[MCP] prefix → executionResearch agentLangGraph ReActExecution agentMCP toolsHybrid retrievalbge-m3 dense ∥ BM25 → RRFvLLMQwen3-8B-AWQPolicy enginedepartment × roleCross-encoder rerankbge-reranker-baseMemory + auditRedis · Qdrant · Postgres
api/app.py, src/agent.py, src/retriever.py, src/reranker.py, src/policy.py ve docker-compose.yml dosyalarından çıkarıldı.
  • FastAPI gateway istekleri doğruluyor (JWT veya API key), rate limit uyguluyor ve yanıtları stream ediyor.
  • Supervisor deterministik çalışıyor: [MCP] ile başlayan mesajlar Execution agent'a, geri kalan her şey Research agent'a gidiyor.
  • Research agent search_documents, web_search ve calculator araçlarını kullanıyor. search_documents dense (Qdrant + bge-m3) ve BM25 aramayı paralel çalıştırıyor, sonuçları ağırlıklı RRF ile birleştirip cross-encoder ile yeniden sıralıyor.
  • Execution agent yalnızca MCP araçlarına (dosya, Python, Postgres, hafıza araması) bağlanıyor. Bu araçları departman × rol politika matrisi kontrol ediyor.
  • Hafıza katmanlı: kısa süreli ve entity hafızası için Redis, epizodik hafıza için Qdrant, konuşma özetleri ve append-only audit log için Postgres.

Tasarım kararları

En üstte LLM router yerine prefix ile yönlendirme

Supervisor, agent'ı modele sormak yerine mesajın önekine ([MCP] / [MCP:…]) bakarak seçiyor.

Ödünleşim: Öngörülebilir, test edilebilir ve maliyetsiz. Buna karşılık niyetin kullanıcı (veya frontend) tarafından açıkça belirtilmesi gerekiyor.

Ağırlıklı Reciprocal Rank Fusion

Dense ve BM25 sonuçları sıraya göre birleştiriliyor: skor = w / (60 + sıra). BM25 ağırlığı ayarlanabilir (RAG_BM25_WEIGHT, varsayılan 0.4). Tekrarlar kaynak + chunk'ın ilk 200 karakteriyle ayıklanıyor.

Ödünleşim: Uyumsuz skor ölçeklerini normalize etmek gerekmiyor, ama gerçek benzerlik büyüklükleri kayboluyor.

Daha geniş aday havuzunu yeniden sıralamak

Reranking açıkken retrieval max(rerank_top_n, 2k) aday getiriyor (rerank_top_n varsayılan 20), son k'yı cross-encoder (bge-reranker-base, hızlı modda MiniLM) seçiyor. Rerank sonuçları 10 dakika cache'leniyor.

Ödünleşim: Belirsiz sorgularda daha iyi sıralama sağlıyor ama sorgu başına ek GPU/CPU süresi getiriyor. Hızlı mod bu adımı atlayabiliyor.

Soruya göre k ve strateji

k, sorunun karmaşıklığına göre (Türkçe ve İngilizce ipucu kelimeleri) artıyor. Strateji de soru tipine göre similarity, MMR, hybrid ve score-threshold arasında değişiyor.

Ödünleşim: Ek model çağrısı gerektirmeyen ucuz sezgiler, ama alışılmadık ifadeleri yanlış sınıflandırabiliyor.

Departman bazlı izolasyon

JWT claim'leri department_id ve role taşıyor. Varsayılan modda tek bir Qdrant koleksiyonu departmana göre filtreleniyor. Strict modda her departmanın ayrı koleksiyonu oluyor ve hafıza anahtarları önekleniyor.

Ödünleşim: Varsayılan mod daha kolay işletiliyor. Strict mod daha sıkı izolasyon sağlıyor ama yönetilecek koleksiyon sayısı artıyor.

Teknolojiler

PythonLangGraphLangChainFastAPIvLLM (Qwen3-8B-AWQ)QdrantBAAI/bge-m3BM25 (rank-bm25)BAAI/bge-reranker-baseRedisPostgreSQLDocker ComposeJWTMCPNext.js

Sırada ne var

  • Sabit bir Türkçe soru setinde retrieval benchmark'ı yayınlamak (dense, hybrid, hybrid + rerank).
  • Keyword tarafını departmana duyarlı hale getirmek: BM25 indeksi her ingest/silmede baştan kurulan tek bir bellek içi korpus, departman filtresi ise yalnızca vektör tarafında uygulanıyor.
  • Prefix kuralını override olarak koruyup yerine hafif bir niyet sınıflandırıcı koymak.

Sonuçlar

Retrieval kalitesi: Recall@5 ve MRR@10Benchmark yakında
Uçtan uca gecikme: p50 / p95Benchmark yakında
Yük altında throughputBenchmark yakında

Notlar