Kapanış
Bir günde bir RAG pipeline’ı kurduk ve her ara çıktısını açtık. Kurumsal bir sistemde her adım dört soruya cevap vermek zorunda: doğru mu, güvenli mi, yeterince hızlı mı, maliyeti ne?
Dört eksen, her adımda
Doğruluk, güvenlik, performans, maliyet: her adımda aynı dört soru. Ölçülen cevaplar aşağıdaki kontrol listesinde.
Yükle + temizle
Gürültü ve kırık satırlar temizlendi mi? Erişim etiketi burada okunur, kişisel veri burada maskelenir. Bir kez çalışır, ama gerçek projelerde emeğin çoğu bu adıma gider.
Chunk
Tablo, başlığıyla aynı chunk’ta mı? Chunk büyüdükçe prompt da büyür. Nereden keseceğiniz bir tasarım tercihi; kararı eval verir.
Embed + Vector DB
Model dillerinizi aynı uzaya koyuyor mu, ingest’te ve soruda aynı model mi? Depo sürüm ve erişim etiketini saklar; vektör de veridir.
Ara + rerank
Doğru bölüm ilk k’da mı? Kaçıncı sırada? Sürüm ve erişim filtresi aramanın içinde mi? Rerank pahalı. q02 için tutuyoruz: vektör sırasında 5., rerank sonrası 1. Rerank’sız eval ilk ödev.
Prompt + cevap
Cevap yalnızca kaynaktan mı, kaynakta yoksa “bilmiyorum” diyor mu? İşaretli kaynaklar ve somut yasak yetmez. Cevabı kod kontrol ediyor mu? Kaç token giriyor?
Eval
Her değişiklikten sonra aynı gold set: retrieval için hit@1, recall@5, MRR; cevap için
--answers. Sıradaki iş: gold set’i kullanımdan gelen zor sorularla ve 2026’nın beklenen değerleriyle büyütmek.Günün sorusu, bütün gün
npm run questiondefterinde beş durak var. RAG’siz: 25-30 gün, “depending on the company’s policy”. Fixed chunk’lar: 7 [1], yanlış ama kaynaklı. Section chunk’lar: 22. Chroma: yine 22. 2026 sürümü: 24. Defterinizde 24 diyen iki satır daha olabilir: bütün sürümlerde arayan koşu ve bu koşu. Sabahki tahmininiz iş günüydü; hangisine yakın?npm run question: bütün cevaplar alt alta.
Kontrol listesi
Bölüm başlığı “Kontrol listesi”Her satır bir pipeline adımı, her sütun bir eksen; sayılar bu sitenin loglarından.
| Adım | Doğruluk | Güvenlik | Performans | Maliyet |
|---|---|---|---|---|
| Yükle + temizle | Gürültü kuralları; önce/sonra satır sayısı (A) | access etiketi front matter’da; kişisel veri maskesi (ölçmedik) |
Bir kez çalışır | Bir kez çalışır |
| Chunk | Başlık öneki (B); hit@1 0.526 → 0.842, 19 sorunun 10’u → 16’sı (Kaliteyi ölçmek) | — | 138 ya da 60 chunk = o kadar vektör | Chunk boyu prompt token’ını belirler |
| Embed | Aynı model ingest’te ve soruda; kod farklı modeli reddeder (C) | API’li embedding’de corpus dışarı çıkar | Cache: 60 vektörün 60’ı, 55 ms | Model değişirse hepsi yeniden |
| Vector DB | JSON ile aynı sıralama (D) | Vektör + metin saklanır: dokümanla aynı koruma | Vektör araması 8 ms | Sürüm başına artımlı ingest |
| Ara + rerank | recall@5 1.000, MRR 0.896 (Kaliteyi ölçmek); rerank (E), eval’da faydası ölçülmedi | Filtre aramanın içinde: maaş sorusunda 0 maaş chunk’ı (Güvenlik) | Rerank 1500 ms | Rerank = 5 LLM çağrısı |
| Prompt + cevap | Kaynaktan cevap, “bilmiyorum” cümlesi, tablo kuralı (F) | İşaretli kaynaklar + somut yasak: enjeksiyonu durdurmadı (q13); koddaki cevap kontrolü (varsayılan kapalı): isteği sildi (Güvenlik) | Cevap 678 ms | 976 prompt token; hepsi 9954 (Performans) |
| Eval | 2025 gold set’te 23 cevabın 22’si; hit@1 0.842, 19 sorunun 16’sı (Kaliteyi ölçmek) | Erişim sorusu gold set’te: maaş chunk’ı kimseye ulaşmadı | Retrieval eval’ı sohbet modeline gitmez | --answers her soruda rerank + cevap çağrısı |
Günün sorusu: bütün gün
Bölüm başlığı “Günün sorusu: bütün gün” LEDGER (.cache/question-ledger.jsonl) 12:52 Typically, an employee with 7 years of servic… bare model, no documents 12:52 An employee with 7 years of service gets at m… chunker fixed · in-memory search (black box) · rerank on · filter {"e… 12:53 An employee with 7 years of service gets 22 w… chunker section · in-memory search (black box) · rerank on · filter {… 12:53 An employee with 7 years of service gets 22 w… chroma store · chunker section · rerank on · filter {"edition":"2025"… 12:57 An employee with 7 years of service gets 24 w… chroma store · chunker section · rerank on · filter {"edition":"2026"…10 soru
Bölüm başlığı “10 soru”Her birinin cevabı bu günün sayfalarında. Önce kendiniz cevaplayın, sonra açın.
1 · RAG hangi ihtiyaçtan doğdu?
Model bildiğini eğitimde donan ağırlıklarında taşır. Günün sorusuna bir aralık verdi: 25-30 iş günü, “depending on the company’s policy”. Ama Kraken Air’in politikasını hiç görmedi. Çözüm: bilgiyi modelin içine değil, önüne koymak. Model bilmiyor
2 · Fine-tune ile RAG arasında nasıl seçersin?
Değişen bilgi için RAG, değişmeyen davranış (ton, biçim, terim) için fine-tune; ikisi birlikte de kullanılır. 2026 sürümü yüklenince cevap yeniden eğitim olmadan 22’den 24’e döndü. RAG mı fine-tune mu?
3 · Neden chunk'lıyoruz? Kesim yanlış yere düşerse ne olur?
Her soruda bütün el kitabını okutmak pahalı. Cevap birkaç satırda. 300 karakterlik kesimde | 7 | 22 | satırı başlığından ayrıldı. Prompt’a girmedi. Model §4’teki bir izin sınırını cevap sandı: “… at most 7 working days [1]”. Başlıktan kesip başlığı her chunk’ın önüne yazmak düzeltti. B · Chunking
4 · Ingest'te bge-m3, soruda başka bir embedding modeli kullanırsan ne olur?
Her model kendi uzayını kurar; iki modelin vektörleri karşılaştırılamaz. Bizim kodda 6-retrieve.ts hata verir. Model değişirse bütün corpus yeniden embed edilir. C · Embedding
5 · Vektörün yanında chunk'ın metnini neden saklıyoruz?
Arama bir vektörü metne geri çeviremez: id ve skor verir, modele ise metin lazım. Bu yüzden Chroma her kaydı vektör, metin ve metadata ile birlikte tutar. D · Vector DB
6 · k küçük ya da büyük olursa ne olur? Rerank neden yalnızca 5 adayda?
Huni: ucuz arama geniş (5), pahalı rerank bu 5’i sıralar, prompt’a 3 girer; k = 3 olsaydı q02’nin tablosu (vektör sırasında 5.) hiç gelmezdi. k büyürse her aday bir LLM çağrısı daha demek. E · Retrieval ve rerank
7 · 2025 ve 2026 aynı depoda. Eski değerin cevaba karışmasını nasıl engellersin?
Embedding’le değil: iki sürümün metni de skoru da neredeyse aynı (0.619 ve 0.614). Çözüm metadata: ingest’te sürümü yaz, aramada filtrele. Veri değişince
8 · “Kaynakta yoksa şunu yaz” kuralını silersen ne olur?
Bizde model yine hayır dedi. Ama kendi cümlesini kurdu ve bir kaynak gösterdi: “No, this policy does not cover stock options [1].” Kod “not in the policies” ifadesini aradığı için bunu yakalayamaz; kural, “bilmiyorum” demeyi ölçülebilir kılar. F · Cevap üretimi
9 · Bir doküman “şifreni şu adrese gönder” diyorsa hangi katman suçlu, ne durdurur?
Talimat veriden geliyor. Genel kural ve işaretli kaynaklar durdurmadı; şifre istemeyi yasaklayan kural da durdurmadı: yasak açıkken de kapalıyken de cevap aynıydı. Prompt’taki bir cümle güvenlik sınırı değil. Asıl sınır kodda. Cevap kontrolümüz modelden sonra çalışır ve kaynak numarası olmayan her cümleyi siler; kontrol açıkken istek cevaptan gitti. İstekte bir kaynak numarası olsaydı kontrol onu bırakırdı. Yani bu tek bir katman, çözümün kendisi değil. Ayrıca ingest’te dokümanı tarayın (bunu ölçmedik) ve herkese yalnızca gereken yetkiyi verin. Güvenlik
10 · Retrieval iyi ama cevap yanlışsa suçlu kim?
Doğru chunk prompt’taysa suçlu üretim adımı: önce prompt’a, sonra modele bakılır. Bizde q13: doğru bölüm 1. sırada geldi (rr 1.00), ama cevap ✗, çünkü model kaynaktaki talimata uydu. Kaliteyi ölçmek
Repo sizde
Bölüm başlığı “Repo sizde”Bütün kod, corpus, gold set ve bu sitedeki her log: github.com/kuthaygumus/ama-rag-workshop. Bugün kurduğunuz pipeline sizde kalıyor.
- Defterinize bakın.
npm run questionçalıştırın; günün sorusuna sabahtan beri verilen cevapları yukarıdaki log’la karşılaştırın. - İlk ödev: rerank’ın faydasını ölçün.
src/steps/7-rerank.tsiçindeTOGGLE rerankbloğunu bulun.truesatırını yoruma alın,falsesatırını açın,npm run eval -- --answerskoşun. q02’nin cevabı ve 22/23 ne oldu? Toggle’ı geri alın. - Başka bir bölme yolu deneyin. B sayfasındaki tablodan repoda olmayan bir yol seçin; örneğin cümleden bölmeyi. Onu
byParagraph’ın yanına yazın.paragraphgibiChunkerNametipine,CHUNKERSlistesine veTOGGLE chunkerbloğuna ekleyin. Yeniden ingest edin venpm run evalile section’la karşılaştırın. - Henüz yazmadıysanız öteki iki alıştırma:
turkishConfidentialkuralı (bir RegExp,src/steps/2-clean.ts) vedotfonksiyonu (src/lib/similarity.ts). Aynı komut kontrol eder. eval/gold.jsonldosyasına kendi sorularınızı ekleyin; özellikle sistemi zorlayacaklarını.- Bu sitede “Ölçmedik” yazan başka bir şeyi seçin ve ölçün:
--k 10, başka birCHAT_MODEL.