Okullar için Robotik ve Mühendislik · anaokulundan liseye

5. ünite / 10 · 4 saat

RAG uçtan uca: belgeden kaynaklı cevap

Parçalama, gömme, vektör arama, yeniden sıralama, eşik ve kaynak gösteren cevap. Modelin bilmediği notlardan doğru cevap almak.

Bu ünitenin sonunda

  • RAG hattının beş adımını sırayla açıklamak
  • Parça boyu, örtüşme ve k seçiminin etkisini ölçmek
  • Hibrit yeniden sıralamanın neden işe yaradığını göstermek
  • Cevap notlarda yoksa "bilmiyorum" diyen bir eşik kurmak

Ders notları

Model eğitildiği tarihten sonraki ya da hiç görmediği belgeleri (dersin notları, şirketin yönetmeliği) bilemez. RAG (retrieval-augmented generation) soruyu cevaplamadan önce ilgili belge parçalarını bulur ve prompta koyar; model cevabı bu parçalara dayanarak yazar ve kaynağını gösterir.

Hat

  • Parçala: belgeleri birkaç yüz tokenlık parçalara böl. Örtüşme, bir cümlenin iki parçanın sınırında kaybolmasını önler.
  • Göm: her parçayı bir vektöre çevir ve bir dizinde sakla (bir kez, çevrimdışı).
  • Ara: sorunun vektörüne en yakın k parçayı bul.
  • Yeniden sırala: geniş bir aday kümesini daha pahalı ama daha isabetli bir ölçütle yeniden puanla. Bu derste vektör benzerliği ile anahtar kelime örtüşmesinin karışımı (hibrit) kullanılır; gerçek sistemlerde bir çapraz kodlayıcı model de olabilir.
  • Üret: seçilen parçaları etiketlerle prompta koy, "yalnız bu notlara dayan, kaynağı [kimlik] olarak yaz, notlarda yoksa söyle" kuralıyla modeli çağır.

Eşik ve "bilmiyorum"

En yakın parça bile soruya uzaksa model yine de bir şey yazmaya çalışır. Benzerlik eşiğinin altında kalan parçaları atmak ve hiçbir parça kalmazsa "notlarda yok" demek uydurmayı kökten azaltır. Eşik çok yüksekse doğru cevaplar da kaybolur; doğru değer bir değerlendirme kümesiyle (7. ünite) seçilir.

Bu sayfadaki mini RAG

Sekiz kısa Türkçe ders notu, öğretim gömmesi ve şablonla çalışan bir cevap adımı tarayıcıda çalışır. Cevap adımı gerçek bir model değildir: seçilen parçalardan soruya en çok örtüşen cümleleri alıntılar ve kaynağını ekler. Gerçek bir uygulamada aynı prompt Anthropic API'ye gider; kod örneği bunu gösterir.

Simülasyon

Öğretim modeli: bu sayfadaki simülasyonlar gerçek bir dil modeli değildir. Küçük, deterministik, tarayıcıda çalışan modellerdir; kavramı göstermek için yazıldılar. Site hiçbir dış LLM servisine istek göndermez.

Uçtan uca mini RAG: ders notlarından cevap

Sekiz kısa Türkçe ders notu parçalara bölünür, öğretim gömmesiyle vektöre çevrilir, soruna en yakın parçalar bulunur, isteğe bağlı olarak anahtar kelime örtüşmesiyle yeniden sıralanır ve kaynak gösteren bir cevap kurulur. Parça boyu, örtüşme, k ve eşiği değiştir; eşiğin altında sistem "notlarda yok" der. Cevap adımı gerçek bir model değil, alıntı yapan bir şablondur.

RAG'ı 3B izle: sorgu → komşular → yeniden sıralama → cevap

Mini RAG'ın parçaları 3B gömme uzayında. Oynat'a bas: sorgu merkezden yerine uçar, vektör arama 2k adayı bulur, en yakın k parça seçilir, hibrit yeniden sıralama sırayı değiştirir, eşiği geçen parçalar yeşile döner ve kaynaklı cevap kurulur. k, eşik ve yeniden sıralamayı değiştir; Adım düğmesiyle tek tek ilerle.

Kendin dene

Mini RAG'da dört hazır soruyu dene ve hangisinin "notlarda yok" cevabı aldığını açıkla. Parça boyunu 15'e indir, örtüşmeyi 0 yap: "Motor neden doğrudan pine bağlanmaz?" sorusunun cevabı bozuldu mu? Yeniden sıralamayı kapatıp aç ve tabloda sıranın nasıl değiştiğine bak. Son olarak eşiği 0,5'e çıkar ve hangi doğru cevapların kaybolduğunu yaz.

Kod

Bunları kendi bilgisayarında çalıştır. Anahtar ANTHROPIC_API_KEY ortam değişkeninden okunur; koda asla yazma.

Python: uçtan uca RAG (parçala, göm, ara, yeniden sırala, kaynakla cevapla)
import pathlib, re
import numpy as np
import anthropic
from sentence_transformers import SentenceTransformer  # yerel gömme modeli

client = anthropic.Anthropic()  # anahtar ANTHROPIC_API_KEY ortam değişkeninden
embedder = SentenceTransformer("sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2")

def chunk(text, size=60, overlap=15):
    words = text.split()
    step = size - overlap
    return [" ".join(words[i:i + size]) for i in range(0, max(1, len(words) - overlap), step)]

# 1) Dizinleme: her not parçalanır, her parça kaynağıyla birlikte gömülür
chunks = []
for path in sorted(pathlib.Path("notlar").glob("*.txt")):
    for i, c in enumerate(chunk(path.read_text(encoding="utf-8"))):
        chunks.append({"id": f"{path.stem}#{i}", "text": c})
E = embedder.encode([c["text"] for c in chunks], normalize_embeddings=True)

def words(s): return set(re.findall(r"\w+", s.lower()))

def retrieve(question, k=4, keep=2, threshold=0.35):
    q = embedder.encode([question], normalize_embeddings=True)[0]
    scores = E @ q
    top = [(float(scores[i]), chunks[i]) for i in np.argsort(-scores)[:k]]
    # 2) Yeniden sıralama: vektör puanı + anahtar kelime örtüşmesi
    qw = words(question)
    rer = sorted(top, key=lambda p: -(0.7 * p[0] + 0.3 * len(qw & words(p[1]["text"])) / max(1, len(qw))))
    return [c for s, c in rer[:keep] if s >= threshold]  # eşik altı: kanıt yok

def answer(question):
    found = retrieve(question)
    if not found:
        return "Bu sorunun cevabı notlarda yok."
    context = "\n".join(f'<belge id="{c["id"]}">{c["text"]}</belge>' for c in found)
    response = client.messages.create(
        model="claude-sonnet-5-5", max_tokens=600,
        system="Yalnız <belge> içeriğine dayanarak cevap ver. Her cümlenin sonuna [id] ile kaynak yaz. Belgelerde yoksa bilmediğini söyle.",
        messages=[{"role": "user", "content": f"{context}\n\n<soru>{question}</soru>"}],
    )
    return "".join(b.text for b in response.content if b.type == "text")

print(answer("Dönem projesi ne zaman teslim edilir?"))
JavaScript: örtüşmeli parçalayıcı ve anahtar kelimeyle yeniden sıralama
// Kelime sayısıyla parçala; örtüşme, sınırda bölünen cümleyi iki parçada da tutar
function chunkWords(text, size, overlap) {
  const w = text.split(/\s+/).filter(Boolean)
  const out = []
  for (let start = 0; start < w.length; start += size - overlap) {
    out.push({ start, text: w.slice(start, start + size).join(' ') })
    if (start + size >= w.length) break
  }
  return out
}

const tokens = (s) => new Set(s.toLocaleLowerCase('tr-TR').match(/[\p{L}\p{N}]+/gu) ?? [])

// Vektör puanı gelmiş adayları sorudaki kelimelerle yeniden sırala
function rerank(question, candidates, alpha = 0.7) {
  const q = tokens(question)
  return candidates
    .map((c) => {
      const overlap = [...q].filter((x) => tokens(c.text).has(x)).length / Math.max(1, q.size)
      return { ...c, final: +(alpha * c.score + (1 - alpha) * overlap).toFixed(3) }
    })
    .sort((a, b) => b.final - a.final)
}

const note = "Dönem projesi 12. haftanın cuma günü saat 17.00'ye kadar teslim edilir. Geç teslimde her gün için yüzde 10 kesilir."
console.log(chunkWords(note, 8, 2))
console.log(rerank('proje ne zaman teslim edilir', [
  { id: 'kurallar#0', score: 0.52, text: note },
  { id: 'pwm#1', score: 0.55, text: 'Servo motorlar 50 Hz darbelerle konum alır.' },
]))

Sık yapılan hatalar

  • Parçaları çok küçük seçmek: cevap iki parçaya bölünür ve hiçbiri tek başına yeterli olmaz.
  • Eşik koymamak: ilgisiz parçalarla da cevap üretilir ve uydurma artar.
  • Kaynak göstermemek: kullanıcı cevabı doğrulayamaz, hata ayıklamak zorlaşır.
  • Belgeler güncellenince dizini yeniden üretmeyi unutmak.

Yazılım mühendisliği bağlantısı

RAG bir veri hattıdır: içeri alma, dizinleme ve sorgu ayrı bileşenlerdir ve ayrı test edilir.

  • Arama adımını üretimden bağımsız ölç: altın kümede doğru parça ilk k içinde mi (isabet@k)?
  • Belge sürümü ve dizin oluşturma tarihi her cevabın kaydında bulunsun; yanlış cevabın eski bir dizinden mi geldiği anlaşılsın.

Kendini sına

  1. Parçalar arasında örtüşme neden bırakılır?

  2. Benzerlik eşiğinin altında hiç parça kalmadığında doğru davranış nedir?

  3. Hibrit yeniden sıralama hangi iki sinyali birleştirir?

  4. Arama adımının kalitesini üretimden bağımsız ölçmek için ne kullanılır?

Bu üniteden sonra bitirme projesinde

  • Ara kontrol: RAG hattı: Parçalama, gömme ve arama çalışıyor; isabet@k altın kümede ölçüldü; şemalı cevap ve doğrulama; mimari belgesi (bileşenler, veri akışı).

Macademia'da ilgili

Esc
  • PanelAna sayfaSayfa
  • ModüllerTüm modüllerSayfa
  • ParçalarParça ansiklopedisiSayfa
  • Mühendislik yoluBüyükler için robotik: 128 parça, 7 seviyeSayfa
  • Robotik dersi (ESOF 323)Üniversite robotik dersi, 14 haftaSayfa
  • Drone dersiBüyükler için: parça, simülasyon, yazılım; 10 üniteSayfa
  • Blok atölyesiSerbest blok programlamaAraç
  • Devre laboratuvarıSanal Arduino ve devreAraç
  • Robot arenasıSanal robot sürüşüAraç
  • OyunlarBloklarla 8 öğretici oyunAraç
  • Mikro Kart atölyesiSanal LED kartı bloklarla programlaAraç
  • Robot atölyesiMikro Kart'ı robota tak, bloklarla görev yapAraç