---
title: 'Sorgu Dönüştürme'
source: 'https://academia.sh/tr/kurslar/rag/sorgu-donusturme'
course: 'Gömme Vektörleri ve Erişim Artırılmış Üretim'
language: tr
updated: '2026-08-17T18:06:35+00:00'
license: 'CC BY-SA 4.0'
---

# Sorgu Dönüştürme

Kullanıcının yazdığı sorgunun dizine gitmeden önce tek bir model çağrısıyla belge diline çevrilmesi ve bu adımın kazandırdığı ile kaybettirdiğinin ayrı ayrı sayılması: kırk sorguluk kurgu kümede kısa yazımın tabanı 0,3750 anma ve 0,2000 üretim iken genişletme ikisini 0,7500 ve 0,7000'e çıkarıyor, yani dizin dilinde yazılmış sorgunun bıraktığı yere geliyor. Aynı düzenek uzun yazımda tabanı 0,5500'den 0,3500'e, yeniden yazma ise 0,2500'e düşürüyor, çünkü dönüştürücünün doğru kavramı bulma payı 0,9500'den 0,3500'e iniyor. Bedel her iki kümede de sorgu başına bir çağrı ve dört yüzden iki bin üç yüz altmışa kadar ek belirteçtir; iki koşum farkı anmada 0,0500, üretimde 0,1000 ölçüldü.

Önceki dört ders hattın belge tarafını kurdu: dağarcık hazırlandı, parçalara bölündü, dizinlendi
ve yenilendi. Dördünde de sessiz kalan bir varsayım vardı: **sorgu, kullanıcının yazdığı biçimiyle
dizine gider**.

Abone "hangi dilim" yazar, dağarcıkta "kademe esigi" geçer. Boşluğu kapatmanın bir yolu, sorguyu
dizine göndermeden önce bir modele verip **belge diline çevirtmektir**; bedeli sorgu başına bir
çağrıdır. Dönüştürme **tek adımlıdır**; sonucu görüp yeniden sorgulamak M28/K05'in konusudur.

- **EH41.** Kod bir **benzeticidir**; gerçek bir gömme ya da model uç noktası çağrılmaz. Dağarcık,
  kavramlar, sorgular ve kullanıcı yazımları **kurgudur**, tohum **20260218**.
- **EH42. Hedef iki parçalıdır.** Sorgunun hedefi hem bir **kavram** hem bir **kayıt türüdür**;
  parça ancak ikisini birden taşıyorsa ilgilidir. **Anma@k** ilk k içinde ilgili parça bulunan
  sorgu payı, **kesinlik@k** ilk k'nın ilgili olan payıdır.
- **EH43.** Hat, `gommeler/06`'da ölçülen **karma aramayı** kullanır: açı benzerliğinin yanına
  belirteç örtüşmesi eklenir. Yordamı tekrarlanmaz, ağırlık sabittir. Bu dersin tabanı
  **dönüştürmesiz erişimdir**; erişimsiz çağrının tabanı `erisim-hatti/01`'de kuruldu.
- **EH44.** Üretim benzeticisi bağlamdaki parçalardan birini seçer ve kodunu alıntılar; parçanın
  **yeri** ağırlığı değiştirir. O ağırlık `erisim-hatti/07`'nin konusudur, burada sabittir.
- **EH45.** Aynı kırk sorgunun iki yazımı ölçülür: **kısa yazım** abonenin yazdığı kısaltılmış
  biçim, **uzun yazım** aynı sorunun bağlam cümleleriyle uzatılmışı. Hedef ikisinde de aynıdır.
- **EH46.** Dönüştürme hız sınırına takılırsa hat **ham sorguya döner**; başarısız çağrının
  belirteci yine sayılır.

## Hat ve Hedef

Hat parça düzeyinde çalışır. Aşağıdaki blok dağarcığı, gömme benzeticisini, karma getirmeyi ve
üretim benzeticisini kurar; sonra sorgu **dizinin tanıdığı biçimde** yazıldığında hattın nerede
durduğunu basar: dönüştürmenin ulaşabileceği üst sınır.

```python
# BENZETICI -- KURGUDUR. Gercek bir gomme ya da model uc noktasi cagrilmaz; dagarcik,
# kavramlar ve sorgular kurgudur, tohum 20260218.
import math
TOHUM, M32 = 20260218, 0xFFFFFFFF
BOYUT = 32


def uretec(t):
    x = ((t ^ (t >> 16)) * 2246822507) & M32
    x = ((x ^ (x >> 13)) * 3266489909) & M32
    s = [(x ^ (x >> 16)) & M32]

    def sonraki():
        s[0] = (s[0] * 1664525 + 1013904223) & M32
        return s[0] / 4294967296
    return sonraki


def ayrik(u, w):
    t = 0.0
    for i, x in enumerate(w):
        t += x
        if u < t:
            return i
    return len(w) - 1


def belirtecle(m):
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


# ---- KURGU anlam ekseni: her kavramin belge dilinde ve sorgu dilinde ayri yuzeyi var
SINIF = ["tarife", "ariza", "sayac", "kesinti", "bakim"]
KOD = {"tarife": "TR", "ariza": "AR", "sayac": "SY", "kesinti": "KS", "bakim": "BK"}
KAVRAM = {                       # kavram: (sinif, belge yuzeyi, sorgu yuzeyi)
    "basamak":   ("tarife", "kademe esigi", "hangi dilimdeyim"),
    "birim":     ("tarife", "birim ucret", "metrekup fiyati"),
    "abonetip":  ("tarife", "abone tipi", "mesken mi isyeri mi"),
    "gecis":     ("tarife", "tarife gecisi", "plan degistirme"),
    "arizakod":  ("ariza", "ariza kodu", "hata numarasi"),
    "sizinti":   ("ariza", "hat sizintisi", "su kacagi"),
    "basinc":    ("ariza", "basinc dususu", "zayif akis"),
    "ekip":      ("ariza", "saha ekibi", "gorevli ne zaman gelir"),
    "endeks":    ("sayac", "endeks degeri", "sayac ustundeki rakam"),
    "okuma":     ("sayac", "okuma yordami", "nasil kaydediliyor"),
    "degisim":   ("sayac", "sayac degisimi", "cihaz yenileme"),
    "dogrula":   ("sayac", "okuma dogrulamasi", "yanlis girilmis mi"),
    "planli":    ("kesinti", "planli kesinti", "onceden duyurulan durma"),
    "duyuru":    ("kesinti", "duyuru kanali", "nereden ogrenirim"),
    "sure":      ("kesinti", "kesinti suresi", "ne kadar surer"),
    "geridonus": ("kesinti", "yeniden verme", "ne zaman gelir"),
    "periyot":   ("bakim", "periyodik bakim", "duzenli kontrol"),
    "vana":      ("bakim", "vana kontrolu", "musluk kapatma duzeni"),
    "filtre":    ("bakim", "filtre degisimi", "temizleme parcasi"),
    "kalib":     ("bakim", "kalibrasyon kaydi", "olcum ayari"),
}
ANAHTAR = list(KAVRAM)
ORTAK = ["kayit", "bolge", "donem", "islem", "form", "onay", "not"]

# ---- KURGU dagarcik
BELGE = []
for i in range(200):
    r = uretec(TOHUM + 7919 * i)
    s = SINIF[ayrik(r(), [0.22, 0.24, 0.20, 0.18, 0.16])]
    kav = [k for k in ANAHTAR if KAVRAM[k][0] == s]
    ana = kav[int(r() * len(kav))]
    n = 2 + int(r() * 4)
    par, kavlar = [], [ana]
    for _ in range(n):
        y = kav[int(r() * len(kav))]
        kavlar.append(y)
        o = ORTAK[int(r() * len(ORTAK))]
        par.append(f"{KAVRAM[y][1]} icin {o} tutulur ve {KAVRAM[ana][1]} ile birlikte yazilir")
    BELGE.append({"kod": f"{KOD[s]}{i + 1:03d}", "sinif": s, "ana": ana, "kavram": kavlar,
                  "baslik": f"{KAVRAM[ana][1]} yordami", "par": par})


def metin(d):
    return d["baslik"] + " " + " ".join(d["par"])


# ---- KURGU gomme: yuzey once kavrama, kavram sonra boyuta dusuruluyor
def _kavramla(m, alan=True):
    v = [0.0] * len(ANAHTAR)
    dm = " " + m.lower() + " "
    for i, k in enumerate(ANAHTAR):
        bel, sor = KAVRAM[k][1], KAVRAM[k][2]
        if bel in dm:
            v[i] += 1.0
        if sor in dm:
            v[i] += 1.0 if alan else 0.0      # alan disi gomme sorgu dilini tanimaz
    if not alan:
        for o in ORTAK:
            if " " + o + " " in dm:
                for i in range(len(ANAHTAR)):
                    v[i] += 0.05
    return v


IZDUS = []
for i in range(len(ANAHTAR)):
    r = uretec(TOHUM ^ (i + 1) * 2654435761)
    IZDUS.append([r() * 2 - 1 for _ in range(64)])


def gom(m, boyut=BOYUT, alan=True):
    k = _kavramla(m, alan)
    v = [0.0] * boyut
    for i, a in enumerate(k):
        if a:
            for j in range(boyut):
                v[j] += a * IZDUS[i][j % 64]
    n = sum(x * x for x in v) ** 0.5
    return [x / n for x in v] if n else v


def aci(a, b):
    return sum(x * y for x, y in zip(a, b))


# ---- KURGU sorgu kumesi: sorgu dili belge dilinden ayri
SORGU = []
for i in range(40):
    r = uretec(TOHUM + 104729 * i)
    d = BELGE[int(r() * len(BELGE))]
    SORGU.append({"metin": f"{KAVRAM[d['ana']][2]} {ORTAK[int(r() * len(ORTAK))]}",
                  "sinif": d["sinif"], "kavram": d["ana"]})

# ---- hat: parcalar, karma getirme, hedef tanimi ve uretim
PARCA = [{"kod": d["kod"], "ana": d["ana"], "metin": p} for d in BELGE for p in d["par"]]
for p in PARCA:
    p["vek"], p["bel"] = gom(p["metin"]), set(belirtecle(p["metin"]))
for s in SORGU:
    s["kayit"] = s["metin"].split()[-1]


def getir(q, k=5, w=0.5):
    qv, qb = gom(q), set(belirtecle(q))
    s = sorted(((aci(qv, p["vek"]) + w * len(qb & p["bel"]) / len(qb | p["bel"]), i)
                for i, p in enumerate(PARCA)), key=lambda t: (-t[0], t[1]))
    return [PARCA[i] for _, i in s[:k]]


def ilgili(s, p):
    return KAVRAM[s["kavram"]][1] in p["metin"] and s["kayit"] in p["bel"]


def izno(m):
    h = 2166136261
    for c in m:
        h = ((h ^ ord(c)) * 16777619) & M32
    return h


PENCERE = 240
SAYAC = [0]
YON_Y = "Asagidaki parcalara bakarak yanitla ve kullandigin parcanin kodunu yaz . "


def yanitla(sorgu, parcalar, tohum=TOHUM, sicaklik=0.12):
    """KURGU uretim: baglamdan bir parca secilir, parcanin YERI agirligi degistirir."""
    SAYAC[0] += 1
    istem = YON_Y + " ".join(f"[{p['kod']}] {p['metin']} ." for p in parcalar) + " Soru: " + sorgu
    bel = belirtecle(istem)
    if len(bel) > PENCERE:
        return {"durum": "baglam_asimi", "giris": len(bel), "cikis": 0, "parca": None}
    r, qb, n = uretec(tohum ^ izno(istem)), set(belirtecle(sorgu)), len(parcalar)
    p = [(1.0 if i == 0 else 0.8 if i == n - 1 else 0.45) * (0.3 + len(qb & x["bel"]) / len(qb))
         for i, x in enumerate(parcalar)]
    w = [math.exp(a / sicaklik) for a in p]
    se = parcalar[ayrik(r(), [a / sum(w) for a in w])]
    return {"durum": "tamam", "giris": len(bel), "parca": se,
            "cikis": len(belirtecle(f"{se['kod']} : {se['metin']}"))}


a = u = 0
for s in SORGU:
    g = getir(s["metin"], 5)
    a += any(ilgili(s, p) for p in g)
    u += ilgili(s, yanitla(s["metin"], g)["parca"])
print("dagarcik %d belge %d parca ; ortalama parca %.1f belirtec ; ornek sorgu %r"
      % (len(BELGE), len(PARCA), sum(len(p["bel"]) for p in PARCA) / len(PARCA),
         SORGU[0]["metin"]))
print("hedef parca kumesi ortalama %.1f parca"
      % (sum(len([p for p in PARCA if ilgili(s, p)]) for s in SORGU) / 40))
print("dizin dilinde yazilmis sorgu  k=5  anma %.4f  uretim %.4f" % (a / 40, u / 40))
```

```
dagarcik 200 belge 693 parca ; ortalama parca 15.3 belirtec ; ornek sorgu 'nasil kaydediliyor form'
hedef parca kumesi ortalama 8.9 parca
dizin dilinde yazilmis sorgu  k=5  anma 0.8000  uretim 0.7000
```

Hedef kümesi ortalama **8,9** parçadır, altı yüz doksan üçün yüzde biraz üstü. Sorgu dizin dilinde
yazıldığında ilk beş parça bu kümeden birini **0,8000** payla getiriyor, üretim bunun
**0,7000**'ini yanıta çeviriyor.

## İki Yazım ve Dönüştürücü

Abone bu cümleleri yazmaz. "nasil kaydediliyor form" bir dizin sorgusudur; abone "kaydediliyor mu
form" yazar ya da derdini uzun uzun anlatır. Aşağıdaki blok aynı kırk hedefin iki yazımını kurar
ve üç kurulumu ikisinde de koşturur: **taban** (ham sorgu), **genişletme** (üzerine belge dilindeki
terim eklenir) ve **yeniden yazma** (ham sorgu atılır, yerine belge dilinde bir cümle konur).

```python
# KURGU: kullanicinin yazdigi kisa bicim -- dizinin tanidigi yuzeyi tasimaz
KISA = {"basamak": "hangi dilim", "birim": "metrekup ucreti", "abonetip": "mesken mi isyeri",
        "gecis": "plan degisimi", "arizakod": "hata kodu", "sizinti": "kacagi olabilir",
        "basinc": "akis zayif", "ekip": "gorevli gelmedi", "endeks": "sayac rakami",
        "okuma": "kaydediliyor mu", "degisim": "cihaz yenilendi", "dogrula": "yanlis girilmis",
        "planli": "onceden duyurulan", "duyuru": "nereden bakarim", "sure": "kac saat surer",
        "geridonus": "tekrar gelir mi", "periyot": "duzenli bakim", "vana": "musluk kapatma",
        "filtre": "temizleme filtresi", "kalib": "olcum kalibrasyonu"}
ONEK = ["gecen hafta", "birkac gundur", "sabahtan beri", "dun aksam"]
BAG = ["bir de sunu soracaktim", "ayrica ilgili birime yazdim", "bu arada merak ettim",
       "daha once de aramistim"]
KISASORGU, UZUNSORGU = [], []
for i, s in enumerate(SORGU):
    r = uretec(TOHUM + 31337 * i)
    y, o2 = ANAHTAR[int(r() * 20)], ORTAK[int(r() * 7)]
    z = ANAHTAR[int(r() * 20)]
    KISASORGU.append(dict(s, metin=f"{KISA[s['kavram']]} {s['kayit']}"))
    UZUNSORGU.append(dict(s, metin=f"{ONEK[int(r() * 4)]} {KAVRAM[y][2]} {o2} "
                                   f"{BAG[int(r() * 4)]} {s['metin']} {KAVRAM[z][2]}"))

SORGU_IZ = {}                       # sorgu dili -> kavram
for k in ANAHTAR:
    for t in belirtecle(KAVRAM[k][2]):
        if len(t) > 3:
            SORGU_IZ.setdefault(t, k)
YON_D = "Sorguyu belge diline cevir . Sorgu: "


def donustur(q, kip, tohum=TOHUM, sicaklik=0.5):
    """KURGU donusturucu: tek adimli bir model cagrisi, dongu ve planlama yok."""
    SAYAC[0] += 1
    bel = belirtecle(YON_D + q)
    if SAYAC[0] % 37 == 0:                       # hiz siniri: ham sorgu
        return {"durum": "hiz_siniri", "giris": len(bel), "cikis": 0, "metin": q, "kavram": None}
    r, p = uretec(tohum ^ izno(q)), {}
    for t in bel:
        if t in SORGU_IZ:
            p[SORGU_IZ[t]] = p.get(SORGU_IZ[t], 0.0) + 1.0
    if not p:
        return {"durum": "bos", "giris": len(bel), "cikis": 0, "metin": q, "kavram": None}
    a = sorted(p)
    w = [math.exp(p[x] / sicaklik) for x in a]
    k = a[ayrik(r(), [x / sum(w) for x in w])]
    o = next((t for t in bel if t in ORTAK), "")
    y = f"{KAVRAM[k][1]} icin {o} tutulur" if kip == "yeniden yazma" else f"{q} {KAVRAM[k][1]}"
    return {"durum": "tamam", "giris": len(bel), "cikis": len(belirtecle(y)),
            "metin": y, "kavram": k}


def olc(kume, kip, tohum=TOHUM, k=5):
    SAYAC[0] = 0
    an = ur = ca = bt = ds = dk = 0
    for s in kume:
        q = s["metin"]
        if kip != "taban":
            d = donustur(q, kip, tohum)
            q, ca, bt = d["metin"], ca + 1, bt + d["giris"] + d["cikis"]
            ds, dk = ds + (d["durum"] != "tamam"), dk + (d["kavram"] == s["kavram"])
        g = getir(q, k)
        an += any(ilgili(s, p) for p in g)
        y = yanitla(s["metin"], g, tohum)
        ca, bt = ca + 1, bt + y["giris"] + y["cikis"]
        ur += y["parca"] is not None and ilgili(s, y["parca"])
    return an / 40, ur / 40, ca, bt, ds, dk / 40


print("ortalama sorgu: kisa %.1f  uzun %.1f belirtec"
      % (sum(len(belirtecle(s["metin"])) for s in KISASORGU) / 40,
         sum(len(belirtecle(s["metin"])) for s in UZUNSORGU) / 40))
print("sorgu kurulum        anma@5  uretim  cagri  belirtec  dogru kavram  basarisiz")
fark = [0.0, 0.0]
for ad, kume in (("kisa ", KISASORGU), ("uzun ", UZUNSORGU)):
    for kip in ("taban", "genisletme", "yeniden yazma"):
        a, u, c, b, ds, dk = olc(kume, kip)
        a2, u2 = olc(kume, kip, TOHUM + 1)[:2]
        fark = [max(fark[0], abs(a - a2)), max(fark[1], abs(u - u2))]
        print("%s %-14s %.4f  %.4f  %5d  %8d  %12s  %9d"
              % (ad, kip, a, u, c, b, "-" if kip == "taban" else "%.4f" % dk, ds))
print("iki kosum farki (tohum 20260219): anma en cok %.4f  uretim en cok %.4f"
      % (fark[0], fark[1]))
```

```
ortalama sorgu: kisa 4.5  uzun 21.7 belirtec
sorgu kurulum        anma@5  uretim  cagri  belirtec  dogru kavram  basarisiz
kisa  taban          0.3750  0.2000     40      5366             -          0
kisa  genisletme     0.7500  0.7000     80      6356        0.9500          1
kisa  yeniden yazma  0.7500  0.7000     80      6335        0.9500          1
uzun  taban          0.5500  0.3250     40      6166             -          0
uzun  genisletme     0.3500  0.2000     80      8526        0.3500          1
uzun  yeniden yazma  0.2500  0.0500     80      7842        0.3500          1
iki kosum farki (tohum 20260219): anma en cok 0.0500  uretim en cok 0.1000
```

## Kısa Yazımda Kazanç

Kısa yazımın tabanı **0,3750** anma ve **0,2000** üretimdir. Üst sınırla arasındaki fark hattın
kusuru değil, **sorgunun dizine değmemesidir**: "hangi dilim" hiçbir parçada geçmez, geriye kayıt
türünün örtüşmesi kalır.

Dönüştürme boşluğu kapatıyor. Genişletme anmayı **0,7500**'e, üretimi **0,7000**'e çıkarıyor;
ikisi de iki koşum farkının (0,0500 ve 0,1000) üstünde ve üretim üst sınıra birebir yetişiyor.
Sebep tabloda yazılı: dönüştürücü doğru kavramı **0,9500** payla buluyor.

Genişletme ile yeniden yazmanın burada **aynı** sonucu vermesi rastlantı değildir: ham sorguyu
tutmanın bedeli de kazancı da yoktur, çünkü atılacak bir sinyal yoktur.

## Uzun Yazımda Kayıp

Uzun yazımın tabanı **0,5500**'dür, kısa yazımınkinden yüksektir: abone derdini uzatırken dizinin
tanıdığı ifadeyi de yazıyor. Dönüştürme tabanı **düşürüyor** — genişletmeyle **0,3500**, yeniden
yazmayla **0,2500** — ve ikisi de iki koşum farkının üstünde, ölçülmüş bir kayıptır.

Nedeni yine doğru kavram sütunundadır: isabet **0,3500**'e iniyor. Uzun sorguda üç kavram yüzeyi
ve iki kayıt türü var; tek adımlı bir çağrı hangisinin asıl soru olduğunu seçmek zorunda ve çoğu
kez yanılıyor. Yanıldığında **genişletme** yanlış bir terim ekler ama ham sorgu yerinde kalır;
**yeniden yazma** doğru olan tek şeyi, abonenin yazdığı ifadeyi siler ve üretim **0,0500**'e
iniyor. Kursun ikinci iddiasının bu derse düşen örneği budur: eklenen düzenek işi kötüleştirdi.

## Dönüştürmenin Faturası

**Çağrı** sorgu başına birden ikiye, kırktan seksene çıkıyor. **Belirteç** kısa yazımda 5366'dan
6356'ya, uzun yazımda 6166'dan 8526'ya gidiyor; uzun sorguyu bir de modele okutmak hattın en
pahalı satırıdır ve kırk çağrının biri hız sınırına takılıyor. Gecikme **sınıf** olarak sayılır:
hat tek çağrılık bir adımdan **iki aşamalı bir zincire** dönüşüyor. Sorgu başına yirmi beş ek
belirteç anmayı 0,3750'den 0,7500'e çıkarırken, elli dokuz ek belirteç onu 0,5500'den 0,3500'e
indiriyor.

## Özet

- Sorgunun hedefi hem kavram hem kayıt türüdür; ilk beşte ikisini taşıyan parça bulunma payı
  erişim, o parçanın yanıta dönme payı üretim ölçüsüdür.
- Kullanıcının yazdığı kısa biçim dizine değmediği için taban 0,3750 / 0,2000'dir; dizin dilindeki
  aynı sorgu 0,8000 / 0,7000 veriyor.
- Genişletme kısa yazımda anmayı 0,7500'e, üretimi 0,7000'e çıkarıyor; doğru kavramı bulma payı
  0,9500'dür.
- Uzun yazımda aynı düzenek tabanı 0,5500'den 0,3500'e, yeniden yazma 0,2500'e düşürüyor; doğru
  kavram payı 0,3500'e iner ve yeniden yazma abonenin yazdığı ifadeyi de siler.
- Bedel sorgu başına bir çağrı ve 990 ile 2360 arası ek belirteçtir; hat zincire dönüşür.

## Sonraki Adım

Bu dersin ölçümleri ilk beş parçayı **birlikte** sayıyor: içinde ilgili bir parça varsa anma
yazılıyor, sıra sorulmuyor. Oysa kesinlik@5 ilk beşin çoğunun ilgisiz olduğunu
söylüyor. Sonraki ders getirmeyi ikiye ayırır: geniş bir aday kümesi toplayan ucuz bir aşama ve
her adayı sorguyla birlikte okuyan pahalı bir aşama.
