---
title: 'İstem Mühendisliği'
source: 'https://academia.sh/tr/kurslar/istem-muhendisligi'
language: tr
updated: '2026-08-17T04:38:33+00:00'
license: 'CC BY-SA 4.0'
lessons: 22
outcomes:
    - 'İstemi girdi, bağlam ve yönerge bileşenlerine ayırarak sistematik yazar ve her bileşenin belirteç payını ölçer'
    - 'Akıl yürütme ve örnek temelli teknikleri uygun göreve uygular ve tekniğin bedelini kazancıyla yan yana yazar'
    - 'Örnekleme parametrelerinin ve çıktı denetiminin belirsizliği ne kadar daralttığını sayıyla gösterir'
---

# İstem Mühendisliği

Model, görev ve küme sabitken değişen tek şeyin metin olduğu ve her metin kararının sayıyı ne kadar oynattığıyla ne kadara mal olduğunun ölçülmesi: istemin üç bileşeninin belirteç payı, sistem yönergesinin her istekte tekrarlanan bedeli, rol belirtmenin kattığı farkın iki koşum farkıyla karşılaştırılması, belirsiz talebin ürettiği yanıt dağılımı, biçim kısıtının ayrıştırılabilirliği, örnek sayısının doyduğu nokta ve sıranın etkisi, yasak bildiriminin ihlali artırdığı durum, yinelemede doğrulama kümesine aşırı uyum, düşünce zincirinin tek adımlı görevde belirteci katlayıp kazanç vermemesi, öz tutarlılıkta çağrı bedeli ve uzlaşmanın kırılması, dallanmanın maliyeti, görünmeyen ara adımların bedeli, istem topluluğunda hataların örtüşmesi, örnekleme ayarlarının iki koşum farkını daraltması, şemaya uyan yanıt oranı ve yeniden denemenin kurtardığı, aynı hatanın yönergeyle mi eksik bilgiyle mi düzeldiği, istemle dengelemenin kapatmadığı alt grup açıklığı.

## İstem Tasarımı

İstemin bileşenlerine ayrılması ve her tasarım kararının sayıyla bedelinin yan yana ölçülmesi: girdi, bağlam ve yönergenin belirteç payı ile bir bileşen çıkarıldığında olan, sistem yönergesinin her istekte tekrarlanmasının büyüttüğü toplam ve kısaltmanın düşürdüğü isabet, rol belirtmenin kattığı farkın iki koşum farkıyla karşılaştırılması, belirsiz bir istemin on koşumda kaç ayrı biçimde yanıtlandığı, biçim kısıtının makinece ayrıştırılabilir yanıt oranı ile uzunluk sınırının bedeli, örnek sayısı sıfırdan sekize çıkarken kazancın doyduğu nokta ve örnek sırasının etkisi, yasak bildiriminin ihlali artırdığı durum ve olumlu bildirimle karşılaştırılması, yineleme sayısı arttıkça doğrulama ile sınama sayılarının ayrışması.

### İstem Nedir

Source: https://academia.sh/tr/kurslar/istem-muhendisligi/istem-nedir

İstemin girdi, bağlam ve yönerge bileşenlerine ayrılması ve her birinin belirteç payının ölçülmesi: 120 kurgu destek talebinde yönerge 0,3945, bağlam 0,3114, girdi 0,2941 pay tutuyor. Tek bir bileşen çıkarıldığında sayı ve bedel yan yana okunuyor. Tam istem 0,7833 etiket isabeti ve 5974 belirteç veriyor; bağlam çıkarıldığında 0,7083 ve 4177, yönerge çıkarıldığında 0,7167 ve 4751, girdi çıkarıldığında 0,1417 ve 4197. İki koşum farkı tam istemde 0,0583 iken bağlamı ya da yönergesi eksik istemlerde 0,2000 ile 0,2583 arasına çıkıyor.

Önceki kurs on dört derste modelin yüzeyini ölçtü ve her sayının yanına bedelini yazdı: kaç
belirteç girdi, kaç belirteç çıktı, sınır neredeydi, aynı girdi iki koşumda ne verdi. Kapanışında
bir eksik duruyordu. Bütün o ölçümler boyunca modele **ne söylendiği** hep aynı kaldı. Yönerge
metni bir kez yazıldı, sonra sabit bir arka plan gibi davranıldı; aynı görevde aynı modele başka
bir metin verildiğinde sayının ne kadar oynadığı hiç sorulmadı.

Bu kurs o metni ölçüm nesnesine dönüştürür. Model, görev ve talep kümesi kurs boyunca sabittir;
değişen tek şey **metindir**. Her derste üç sayı yan yana durur: önceki istem, tek bir tasarım
kararı uygulanmış değiştirilmiş istem ve değişikliğin bedeli. Bedel **belirteçle** yazılır;
belirteç maliyeti ve bütçe önceki kursun kapanış dersinde ölçüldü ve burada tekrarlanmaz.
**Kursun kuralı budur: istem bir tasarım nesnesidir; ölçülmeden değiştirilen istem bir iyileştirme
değil bir tahmindir.** Bu ders o nesneyi parçalarına ayırır.

- **IT1.** Kod gerçek bir model uç noktası çağırmaz; standart kitaplıkla yazılmış bir
  **benzeticiyi** çağırır. Benzetici önceki kursta kurulan tanımın aynısıdır: kurgu
  belirteçleyici, 240 belirteçlik bağlam penceresi, 24 belirteçlik en büyük çıktı, tohuma bağlı
  belirsizlik, hız sınırı ve zaman aşımı.
- **IT2.** Destek talepleri **kurgudur**: 120 kayıt, beş konu, kayıtların bir bölümüne eklenmiş
  yanıltıcı bir cümle. Konu adları saha ekibinin kurgu belge dağarcığından gelir.
- **IT3.** İstem üç bileşene ayrılır ve ayrım metnin **işlevine** göredir. **Yönerge** ne
  yapılacağını söyler, **bağlam** kararın verileceği dünyayı tanımlar, **girdi** o kararın
  uygulanacağı kaydı taşır.
- **IT4.** Ölçüt **etiket isabetidir**. Yanıttan bir etiket okunamazsa kayıt yanlış sayılır ve
  **etiketsiz yanıt payında** ayrıca gösterilir.
- **IT5.** Bedel belirteçtir ve **giriş ile çıkış ayrı ayrı** yazılır. İkisi aynı yöne gitmez;
  bu dersin ana bulgularından biri budur.
- **IT6.** Bir bileşenin katkısı, o bileşen çıkarılarak ölçülür. Kalan iki bileşen, model, tohum
  ve talep kümesi değişmez.
- **IT7.** Her ölçüm iki tohumla koşulur (20260218 ve 20260219). Tohum bir ayar değil,
  belirsizliğin okunduğu yerdir.
- **IT8.** Belirteç, bağlam penceresi ve çıkarım önceki kursun dil modelleri konusunda tanımlandı;
  burada yalnızca kullanılır.

#### İstemin Üç Bileşeni

Bir isteme dışarıdan bakınca tek bir metin görünür. İçeriden bakınca üç ayrı iş yapan üç metin
vardır ve üçünün bedeli de, katkısı da farklıdır. **Yönerge** görevi tanımlar: talebi bir etikete
ata, yanıtı şu biçimde ver. **Bağlam** kararın verileceği dünyayı kurar: etiket kümesi nedir,
hangi seçenekler var. **Girdi** her istekte değişen tek parçadır: sınıflandırılacak talebin
kendisi. Yönerge ve bağlam yüz yirmi istekte aynı kalır, girdi yüz yirmi kez değişir.

İlk blok benzeticiyi ve kurguyu kurar, sonra bu üç bileşeni ayrı ayrı yazıp belirteçlerini sayar.

```python
# BENZETICI. Bu kod gercek bir model uc noktasi cagirmaz; standart kitaplikla yazilmis
# bir dil modeli benzeticisidir. Destek talepleri de KURGU'dur.
import math

TOHUM, M32 = 20260218, 0xFFFFFFFF
PENCERE, EN_UZUN = 240, 24          # baglam penceresi ve en buyuk cikti, belirtec


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):                  # KURGU belirtecleyici: parca en cok bes damga
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


def izno(m):                        # istemin icerigine bagli, kosumdan bagimsiz iz
    h = 2166136261
    for c in m:
        h = ((h ^ ord(c)) * 16777619) & M32
    return h


KONU = ["fatura", "ariza", "sayac", "tarife", "kesinti"]
KALIP = {
    "fatura": ["bu ayki fatura tutari gecen aya gore cok yuksek geldi",
               "faturami odedim ama sistemde borc gorunuyor",
               "fatura ayrintisini nereden gorebilirim"],
    "ariza": ["evde su akmiyor bir ariza var galiba",
              "baglanti bozuk oldu ve hic calismiyor",
              "ariza kaydi actim ama ekip gelmedi"],
    "sayac": ["sayac okumasi yanlis girilmis endeks tutmuyor",
              "sayac degisimi icin randevu istiyorum",
              "sayac uzerindeki endeks ile fatura ayni degil"],
    "tarife": ["hangi tarife basamagindayim ogrenmek istiyorum",
               "tarife degisikligi icin ne yapmam gerekiyor",
               "birim ucret abone tipine gore degisiyor mu"],
    "kesinti": ["mahallede kesinti var ne zaman gelecek",
                "planli kesinti duyurusu nereden takip edilir",
                "aksamdan beri kesinti yasiyoruz"],
}
EK = ["ayrica gecen ay da ayni sorun olmustu", "bu konuda memnun degilim",
      "acil bilgi almam gerekiyor", "kayit numaram elimde yok"]

TALEP = []
for i in range(120):
    r = uretec(TOHUM + i)
    k = KONU[ayrik(r(), [0.24, 0.22, 0.18, 0.20, 0.16])]
    m = KALIP[k][int(r() * 3)]
    if r() < 0.34:
        m += " " + EK[int(r() * 4)]
    TALEP.append({"no": 4001 + i, "metin": m, "konu": k})

KAVRAM = KONU + ["odeme", "sikayet", "bilgi", "genel"]
IZ = {"fatur": "fatura", "tutar": "fatura", "ayrin": "fatura",
      "ariza": "ariza", "bozuk": "ariza", "calis": "ariza", "akmiy": "ariza",
      "sayac": "sayac", "endek": "sayac", "okuma": "sayac",
      "tarif": "tarife", "birim": "tarife", "abone": "tarife", "basam": "tarife",
      "kesin": "kesinti", "duyur": "kesinti", "mahal": "kesinti",
      "borc": "odeme", "odedi": "odeme", "ucret": "odeme",
      "memnu": "sikayet", "sorun": "sikayet", "acil": "sikayet",
      "bilgi": "bilgi", "ogren": "bilgi", "nered": "bilgi"}
TUZAK = {"degis": "tarife", "kayit": "ariza", "yukse": "tarife", "gorun": "fatura",
         "ekip": "kesinti", "takip": "tarife", "giril": "fatura"}   # yaniltici baglar
SERBEST = ["talebiniz {k} konusuyla ilgili gorunuyor",
           "bu kayit {k} basligina girer , ilgili ekibe yonlendirildi",
           "kaydiniz alindi , konuyu inceleyip donus yapacagiz"]
SAYAC = [0]


def cagir(istem, tohum=TOHUM, sicaklik=0.6, en_uzun=EN_UZUN):
    SAYAC[0] += 1
    bel = belirtecle(istem)
    if len(bel) > PENCERE:
        return {"durum": "baglam_asimi", "giris": len(bel), "cikis": 0, "yanit": ""}
    if SAYAC[0] % 37 == 0:
        return {"durum": "hiz_siniri", "giris": len(bel), "cikis": 0, "yanit": ""}
    r = uretec(tohum ^ izno(istem))
    if len(bel) > 90 and r() < 0.04:
        return {"durum": "zaman_asimi", "giris": len(bel), "cikis": 0, "yanit": ""}
    aday = [k for k in KAVRAM if k[:5] in bel]      # istemde adi gecen kavramlar
    if len(aday) < 3:
        aday = KAVRAM
    p = {k: 0.15 for k in aday}
    for t in bel:
        for tablo, w in ((IZ, 1.0), (TUZAK, 1.3)):
            if tablo.get(t) in p:
                p[tablo[t]] += w
    if sicaklik <= 0.0:
        k = max(sorted(p), key=lambda a: p[a])       # en olasi secim
    else:
        e = [math.exp(p[a] / sicaklik) for a in sorted(p)]
        k = sorted(p)[ayrik(r(), [v / sum(e) for v in e])]
    y = k if "tek" in bel else SERBEST[ayrik(r(), [0.42, 0.26, 0.32])].format(k=k)
    cb = belirtecle(y)
    if len(cb) > en_uzun:                            # durdurma kosulu
        cb = cb[:en_uzun]
        y = " ".join(cb)
    return {"durum": "tamam", "giris": len(bel), "cikis": len(cb), "yanit": y}


def oku(y):                                          # yanittan etiket cikarma
    for s in y.lower().split():
        if s in KONU:
            return s
    return None


YONERGE = "Talebi asagidaki etiketlerden birine ata . Yanit olarak tek etiket yaz ."
BAGLAM = "Etiketler: fatura , ariza , sayac , tarife , kesinti ."


def istem(x, y=True, b=True, g=True):       # uc bilesenden secerek istem kurar
    p = []
    if y:
        p.append(YONERGE)
    if b:
        p.append(BAGLAM)
    if g:
        p.append("Talep: " + x["metin"])
    return " ".join(p)


x0 = TALEP[0]
print(f"KURGU talep kumesi: {len(TALEP)} kayit, {len(KONU)} konu")
for ad, m in (("yonerge", YONERGE), ("baglam", BAGLAM),
              ("girdi", "Talep: " + x0["metin"])):
    print(f"{ad:<9} {len(belirtecle(m)):>2} belirtec | {m}")
i0 = istem(x0)
print(f"{'tam istem':<9} {len(belirtecle(i0)):>2} belirtec")
for th in (TOHUM, TOHUM + 1):
    print(f"tohum {th}: {cagir(i0, tohum=th)['yanit']}")
```

```
KURGU talep kumesi: 120 kayit, 5 konu
yonerge   19 belirtec | Talebi asagidaki etiketlerden birine ata . Yanit olarak tek etiket yaz .
baglam    15 belirtec | Etiketler: fatura , ariza , sayac , tarife , kesinti .
girdi     13 belirtec | Talep: planli kesinti duyurusu nereden takip edilir
tam istem 47 belirtec
tohum 20260218: kesinti
tohum 20260219: kesinti
```

Kırk yedi belirteçlik istemin yalnız on üçü asıl işe, yani sınıflandırılacak talebe ait. Geri
kalan otuz dördü, her istekte yeniden gönderilen sabit metindir. İki tohumun aynı yanıtı vermesi
belirsizliğin ortadan kalktığı anlamına gelmez; tek bir kayıtta iki koşumun çakıştığı anlamına
gelir. Kurs boyunca bu karşılaştırma **kümenin tamamında** yapılır.

#### Her Bileşenin Belirteç Payı

Bir bileşenin bedeli, kendi uzunluğu değil, **uzunluğunun istek sayısıyla çarpımıdır**. Katkısı
ise ancak çıkarılarak ölçülebilir. İkinci blok ikisini birden yapar: önce üç bileşenin toplam
giriş belirtecindeki payını çıkarır, sonra her seferinde bir bileşeni düşürüp aynı 120 kaydı
yeniden koşar.

```python
def olc(tohum=TOHUM, **kw):
    SAYAC[0] = 0
    gi = ci = d = bos = 0
    for x in TALEP:
        s = cagir(istem(x, **kw), tohum=tohum)
        gi, ci = gi + s["giris"], ci + s["cikis"]
        e = oku(s["yanit"])
        bos += e is None
        d += e == x["konu"]
    n = len(TALEP)
    return {"isabet": d / n, "bos": bos / n, "giris": gi, "cikis": ci}


ty, tb = len(belirtecle(YONERGE)), len(belirtecle(BAGLAM))
tg = sum(len(belirtecle("Talep: " + x["metin"])) for x in TALEP) / len(TALEP)
top = ty + tb + tg
print(f"{'bilesen':<10} {'belirtec':>9} {'pay':>8}")
for ad, v in (("yonerge", ty), ("baglam", tb), ("girdi", tg), ("toplam", top)):
    print(f"{ad:<10} {v:>9.2f} {v / top:>8.4f}")
print()

DURUM = (("tam istem", {}), ("baglam yok", {"b": False}),
         ("yonerge yok", {"y": False}), ("girdi yok", {"g": False}))
print(f"{'istem':<12} {'isabet':>7} {'kosum 2':>8} {'fark':>7} {'etiketsiz':>10} "
      f"{'giris':>6} {'cikis':>6} {'toplam':>7}")
for ad, kw in DURUM:
    A, B = olc(**kw), olc(tohum=TOHUM + 1, **kw)
    print(f"{ad:<12} {A['isabet']:>7.4f} {B['isabet']:>8.4f} "
          f"{abs(A['isabet'] - B['isabet']):>7.4f} {A['bos']:>10.4f} {A['giris']:>6d} "
          f"{A['cikis']:>6d} {A['giris'] + A['cikis']:>7d}")
```

```
bilesen     belirtec      pay
yonerge        19.00   0.3945
baglam         15.00   0.3114
girdi          14.17   0.2941
toplam         48.17   1.0000

istem         isabet  kosum 2    fark  etiketsiz  giris  cikis  toplam
tam istem     0.7833   0.7250  0.0583     0.0250   5780    194    5974
baglam yok    0.7083   0.5083  0.2000     0.0667   3980    197    4177
yonerge yok   0.7167   0.4583  0.2583     0.2167   3500   1251    4751
girdi yok     0.1417   0.2167  0.0750     0.0250   4080    117    4197
```

İlk tablo kurs boyunca hatırlanacak orantıyı veriyor. Asıl veri, yani sınıflandırılacak talep,
istemin **0,2941 payını** tutuyor. Yönerge ve bağlam birlikte **0,7059** tutuyor ve bu iki metin
yüz yirmi istekte harf harf aynı. Ortalama talep 14,17 belirteç, sabit metin 34 belirteç: her
istekte verinin 2,4 katı kadar sabit metin yeniden gönderiliyor.

#### Bir Bileşen Çıkarıldığında

İkinci tablo bileşenlerin katkısını verir ve üçünün de aynı işi yapmadığını gösterir.

**Bağlam çıkarıldığında** isabet 0,7833'ten 0,7083'e iniyor ve toplam belirteç 5974'ten 4177'ye,
yani 1797 belirteç düşüyor. Kazanç ile kayıp ilk bakışta dengeli görünüyor. Ama etiketsiz yanıt
payı 0,0250'den 0,0667'ye çıkmış: etiket kümesi istemde yazılı değilken model, beş konunun
dışında kalan sözcüklerle de yanıt veriyor ve o yanıtlardan hiçbir etiket okunamıyor. Bağlamın
işi modeli akıllandırmak değil, **cevap uzayını kapatmaktır**.

**Yönerge çıkarıldığında** isabet 0,7167'ye iniyor, giriş belirteci 5780'den 3500'e düşüyor —
ve çıkış belirteci 194'ten **1251'e fırlıyor**. Bu, tablonun en sert satırıdır. Yönerge on dokuz
belirteçlik en uzun bileşendi; onu atmak girişte 2280 belirteç kazandırdı, ama çıkışta 1057
belirteç geri aldı ve net kazanç 1223 belirtece indi. Yanıtlar cümleye dönüştüğü için etiketsiz
pay 0,0250'den **0,2167'ye** çıktı: her beş yanıttan biri makinece okunamaz hâle geldi. Yönerge
bu istemde birim uzunluk başına en pahalı değil, **en getirili** bileşendir.

**Girdi çıkarıldığında** çıkan sayı bu dersin en öğretici satırıdır. İstem hâlâ geçerlidir, hâlâ
4197 belirteç harcar, hâlâ etiketsiz yanıt payı 0,0250'dir — yani çıktı sorunsuz görünür. İsabet
ise 0,1417'ye çöker; yüz yirmi kaydın hepsine aynı istem gittiği için model her seferinde aynı
tahmini üretir ve o tahmin ancak o etiketin kümedeki payı kadar tutar. **Bir istem, veri
taşımadan da düzgün biçimli ve kendinden emin bir yanıt üretir.** İstemi biçimine bakarak
değerlendirmenin niçin ölçüm sayılmadığı buradadır.

#### Ölçülmeden Değiştirilen İstem Bir Tahmindir

Tablonun `fark` sütunu, kursun üçüncü kuralını ilk kez çalıştırıyor. Tam istem iki tohumda 0,7833
ve 0,7250 verdi; **iki koşum farkı 0,0583**. Bağlamın çıkarılmasının isabete etkisi 0,0750,
yönergenin çıkarılmasının etkisi 0,0667. Her iki sayı da iki koşum farkının hemen üstünde duruyor
ve tek başlarına güvenilecek büyüklükte değil. Bu kursta böyle bir sayı **ölçülmüş sayılmaz**;
kural bir sonraki derslerde adıyla işletilir.

Aynı satırların ölçülmüş olan yanı başka yerdedir. Etiketsiz yanıt payı 0,0250'den 0,2167'ye
çıktı, çıkış belirteci altı katına bindi ve bağlamı ya da yönergesi eksik istemlerin **kendi
iki koşum farkı** 0,2000 ile 0,2583 arasına yükseldi. Üç bileşen isabete ekledikleri kadar
isabeti **oturtuyor**: tam istem koşumdan koşuma 0,0583 oynarken, bu iki istem üç dört kat
fazla oynuyor.
İstemin bileşenleri modele bilgi vermekten çok, modelin **serbestlik alanını daraltır**; kazanç
oradan gelir.

Bedel de bu okumadan ayrı yazılır. Tam istem doğru etiket başına 5974 / 0,7833 / 120, yani 63,6
belirteç harcıyor. Bağlamsız istem 49,1 belirteç, yönergesiz istem 55,2 belirteç harcıyor. Yani
en isabetli istem **aynı zamanda en pahalı istemdir** ve bu ikisi ayrı satırlarda durmalıdır.
Bir bileşeni çıkarmak bedeli düşürür; onu çıkarmanın nasıl bir kayıp olduğu ise ancak isabet ve
etiketsiz pay birlikte okununca görünür.

#### Özet

- İstem üç bileşene ayrılır: **yönerge** (ne yapılacak), **bağlam** (hangi dünyada), **girdi**
  (hangi kayıt). 120 kurgu talepte paylar 0,3945 / 0,3114 / 0,2941; asıl veri istemin üçte
  birinden azdır.
- Bağlam cevap uzayını kapatır: çıkarıldığında isabet 0,7833'ten 0,7083'e, etiketsiz yanıt payı
  ise 0,0250'den 0,0667'ye gider ve 1797 belirteç kazanılır.
- Yönerge en uzun ve en getirili bileşendir: çıkarıldığında girişte 2280 belirteç kazanılır ama
  çıkışta 1057 belirteç geri ödenir, etiketsiz pay 0,2167'ye çıkar.
- Girdisiz istem de düzgün biçimli yanıt üretir ve 4197 belirteç harcar; isabeti 0,1417'dir.
  Biçimi doğru bir çıktı, isteminin ölçüldüğü anlamına gelmez.
- Tam istemin iki koşum farkı 0,0583; bağlamı ya da yönergesi eksik istemlerinki 0,2000 ile
  0,2583. Bileşenlerin
  asıl ölçülen katkısı, isabeti yükseltmek kadar **koşumlar arası oynamayı daraltmaktır**.

#### Sonraki Adım

Bu derste yönerge ve bağlam yüz yirmi isteğin her birine yeniden yazıldı ve toplam girişin
0,7059 payını tuttu. Kod bunu tek satırda yaptığı için bedel görünmez kaldı: aynı otuz dört
belirteç yüz yirmi kez gönderildi. Bir davranış tanımı bir kez yazılır ama **her istekte ödenir**
ve istek sayısı büyüdükçe bu tekrar toplam maliyetin baskın kalemi hâline gelir. Sonraki ders bunu
ölçer: kalıcı bir sistem yönergesinin toplam belirteci istek sayısıyla nasıl büyüdüğü, yönergeyi
kısaltmanın kaç belirteç kazandırdığı ve o kısaltmanın isabetten ne kadarını geri aldığı.

### Sistem Yönergesi

Source: https://academia.sh/tr/kurslar/istem-muhendisligi/sistem-yonergesi

Kalıcı davranış tanımının her istekte yeniden gönderildiği ve bedelinin istek sayısıyla çarpıldığı ölçülüyor: 62 belirteçlik bir yönerge tek istemin 0,8378 payını, 120 istekte 7440 belirteci tutuyor. Dört uzunluk yan yana konuyor. Yönergesiz istem 0,4583 etiket isabeti ve 2985 belirteç, kısa yönerge 0,7167 ve 4751, orta yönerge 0,7500 ve 5856, uzun yönerge 0,7417 ve 9343 veriyor. Uzun yönergeyi ortaya indirmek 3487 belirteç kazandırıyor ve isabetten hiçbir şey götürmüyor; ortayı kısaya indirmek 1105 belirteç kazandırıyor ama etiketsiz yanıt payını 0,0250'den 0,2167'ye çıkarıyor.

Önceki ders istemi üç bileşene ayırdı ve yönerge ile bağlamın toplam girişin 0,7059 payını
tuttuğunu ölçtü. O ölçüm tek bir isteğin içinde yapıldı. Kod aynı iki metni yüz yirmi kez
gönderdiğinde bedel tek satırda saklı kaldı, çünkü tekrar döngünün içindeydi ve hiçbir yerde
sayılmadı.

Bu ders o tekrarı sayar. Bir **sistem yönergesi**, modelin her istekte aynı biçimde davranması
için yazılan kalıcı davranış tanımıdır: görev nedir, hangi seçenekler vardır, yanıt hangi biçimde
verilir, belirsizlikte ne yapılır. Adı kalıcıdır ama saklandığı yer istemin kendisidir; model iki
çağrı arasında hiçbir şey hatırlamaz. Yönerge bu yüzden **bir kez yazılır ve her istekte
ödenir**. Ölçülecek olan da budur: tekrarın toplamı, tekrarın payı ve yönergeyi kısaltmanın
isabetten ne kadarını geri aldığı.

- **IT9.** Kod bir **benzeticiyi** çağırır; gerçek bir model uç noktası çağrılmaz. Destek
  talepleri **kurgudur** ve önceki dersteki 120 kayıtla aynıdır.
- **IT10.** Sistem yönergesi ile girdi aynı istemin içindedir. Benzeticide ayrı bir yönerge alanı
  yoktur, çünkü ölçülen şey **belirteç bedelidir** ve alanın adı bedeli değiştirmez.
- **IT11.** Dört yönerge uzunluğu artımlı kurulur: yok, kısa (yalnız etiket kümesi), orta (etiket
  kümesi ve görev ile yanıt biçimi), uzun (buna belirsizlik kuralları eklenmiş hâli).
- **IT12.** Yönergenin bedeli **uzunluk çarpı istek sayısıdır**. Tabloda `tekrar` sütunu bu
  çarpımdır ve toplam giriş belirtecinin içindedir.
- **IT13.** Ölçüt etiket isabetidir; etiketsiz yanıt payı ayrıca basılır. Doğru etiket başına
  belirteç, toplam belirtecin isabete ve kayıt sayısına bölünmesiyle bulunur.
- **IT14.** Her satır iki tohumla koşulur (20260218 ve 20260219). İki koşum farkından küçük kalan
  bir isabet farkı bu kursta ölçülmüş sayılmaz.
- **IT15.** Hız sınırı her otuz yedinci çağrıda tetiklenir ve boş yanıt döndürür. Yüz yirmi
  çağrıda üç kayıt bu yüzden etiketsiz kalır; bu pay istemin değil **yüzeyin** payıdır.
- **IT16.** Belirteç maliyeti ve bütçe önceki kursun kapanış dersinde ölçüldü; burada yalnızca
  belirteç birimi kullanılır.

#### Yönerge Modelde Durmaz

İlk blok benzeticiyi ve kurguyu kurar, dört yönerge uzunluğunu artımlı olarak tanımlar ve her
birinin yüz yirmi istekteki toplam bedelini yazar. Sonunda tek bir kurgu talep, kısa ve orta
yönergeyle, iki ayrı tohumda çağrılır.

```python
# BENZETICI. Bu kod gercek bir model uc noktasi cagirmaz; standart kitaplikla yazilmis
# bir dil modeli benzeticisidir. Destek talepleri de KURGU'dur.
import math

TOHUM, M32 = 20260218, 0xFFFFFFFF
PENCERE, EN_UZUN = 240, 24          # baglam penceresi ve en buyuk cikti, belirtec


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):                  # KURGU belirtecleyici: parca en cok bes damga
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


def izno(m):                        # istemin icerigine bagli, kosumdan bagimsiz iz
    h = 2166136261
    for c in m:
        h = ((h ^ ord(c)) * 16777619) & M32
    return h


KONU = ["fatura", "ariza", "sayac", "tarife", "kesinti"]
KALIP = {
    "fatura": ["bu ayki fatura tutari gecen aya gore cok yuksek geldi",
               "faturami odedim ama sistemde borc gorunuyor",
               "fatura ayrintisini nereden gorebilirim"],
    "ariza": ["evde su akmiyor bir ariza var galiba",
              "baglanti bozuk oldu ve hic calismiyor",
              "ariza kaydi actim ama ekip gelmedi"],
    "sayac": ["sayac okumasi yanlis girilmis endeks tutmuyor",
              "sayac degisimi icin randevu istiyorum",
              "sayac uzerindeki endeks ile fatura ayni degil"],
    "tarife": ["hangi tarife basamagindayim ogrenmek istiyorum",
               "tarife degisikligi icin ne yapmam gerekiyor",
               "birim ucret abone tipine gore degisiyor mu"],
    "kesinti": ["mahallede kesinti var ne zaman gelecek",
                "planli kesinti duyurusu nereden takip edilir",
                "aksamdan beri kesinti yasiyoruz"],
}
EK = ["ayrica gecen ay da ayni sorun olmustu", "bu konuda memnun degilim",
      "acil bilgi almam gerekiyor", "kayit numaram elimde yok"]

TALEP = []
for i in range(120):
    r = uretec(TOHUM + i)
    k = KONU[ayrik(r(), [0.24, 0.22, 0.18, 0.20, 0.16])]
    m = KALIP[k][int(r() * 3)]
    if r() < 0.34:
        m += " " + EK[int(r() * 4)]
    TALEP.append({"no": 4001 + i, "metin": m, "konu": k})

KAVRAM = KONU + ["odeme", "sikayet", "bilgi", "genel"]
IZ = {"fatur": "fatura", "tutar": "fatura", "ayrin": "fatura",
      "ariza": "ariza", "bozuk": "ariza", "calis": "ariza", "akmiy": "ariza",
      "sayac": "sayac", "endek": "sayac", "okuma": "sayac",
      "tarif": "tarife", "birim": "tarife", "abone": "tarife", "basam": "tarife",
      "kesin": "kesinti", "duyur": "kesinti", "mahal": "kesinti",
      "borc": "odeme", "odedi": "odeme", "ucret": "odeme",
      "memnu": "sikayet", "sorun": "sikayet", "acil": "sikayet",
      "bilgi": "bilgi", "ogren": "bilgi", "nered": "bilgi"}
TUZAK = {"degis": "tarife", "kayit": "ariza", "yukse": "tarife", "gorun": "fatura",
         "ekip": "kesinti", "takip": "tarife", "giril": "fatura"}   # yaniltici baglar
SERBEST = ["talebiniz {k} konusuyla ilgili gorunuyor",
           "bu kayit {k} basligina girer , ilgili ekibe yonlendirildi",
           "kaydiniz alindi , konuyu inceleyip donus yapacagiz"]
SAYAC = [0]


def cagir(istem, tohum=TOHUM, sicaklik=0.6, en_uzun=EN_UZUN):
    SAYAC[0] += 1
    bel = belirtecle(istem)
    if len(bel) > PENCERE:
        return {"durum": "baglam_asimi", "giris": len(bel), "cikis": 0, "yanit": ""}
    if SAYAC[0] % 37 == 0:
        return {"durum": "hiz_siniri", "giris": len(bel), "cikis": 0, "yanit": ""}
    r = uretec(tohum ^ izno(istem))
    if len(bel) > 90 and r() < 0.04:
        return {"durum": "zaman_asimi", "giris": len(bel), "cikis": 0, "yanit": ""}
    aday = [k for k in KAVRAM if k[:5] in bel]      # istemde adi gecen kavramlar
    if len(aday) < 3:
        aday = KAVRAM
    p = {k: 0.15 for k in aday}
    for t in bel:
        for tablo, w in ((IZ, 1.0), (TUZAK, 1.3)):
            if tablo.get(t) in p:
                p[tablo[t]] += w
    if sicaklik <= 0.0:
        k = max(sorted(p), key=lambda a: p[a])       # en olasi secim
    else:
        e = [math.exp(p[a] / sicaklik) for a in sorted(p)]
        k = sorted(p)[ayrik(r(), [v / sum(e) for v in e])]
    y = k if "tek" in bel else SERBEST[ayrik(r(), [0.42, 0.26, 0.32])].format(k=k)
    cb = belirtecle(y)
    if len(cb) > en_uzun:                            # durdurma kosulu
        cb = cb[:en_uzun]
        y = " ".join(cb)
    return {"durum": "tamam", "giris": len(bel), "cikis": len(cb), "yanit": y}


def oku(y):                                          # yanittan etiket cikarma
    for s in y.lower().split():
        if s in KONU:
            return s
    return None


E1 = "Etiketler: fatura , ariza , sayac , tarife , kesinti ."
E2 = " Talebi bu etiketlerden birine ata . Yanit olarak tek etiket yaz ."
E3 = (" Birden cok etiket uyuyorsa talebin ana konusunu sec ."
      " Hicbiri uymuyorsa en yakin etiketi sec . Aciklama ekleme .")
YONERGE = (("yok", ""), ("kisa", E1), ("orta", E1 + E2), ("uzun", E1 + E2 + E3))


def kur(s, x):                              # kalici yonerge + her istekte degisen girdi
    return (s + " " if s else "") + "Talep: " + x["metin"]


print(f"{'yonerge':<8} {'belirtec':>9} {'120 istekte':>12}")
for ad, s in YONERGE:
    b = len(belirtecle(s))
    print(f"{ad:<8} {b:>9d} {b * len(TALEP):>12d}")
x0 = TALEP[1]
gb = len(belirtecle("Talep: " + x0["metin"]))
ub = len(belirtecle(YONERGE[3][1]))
print(f"uzun istem: yonerge {ub} + girdi {gb} belirtec, yonergenin payi "
      f"{ub / (ub + gb):.4f}")
print(f"KURGU talep {x0['no']} ({x0['konu']}): {x0['metin']}")
for ad, s in YONERGE[1:3]:
    SAYAC[0] = 0
    for th in (TOHUM, TOHUM + 1):
        print(f"{ad} / tohum {th}: {cagir(kur(s, x0), tohum=th)['yanit']}")
```

```
yonerge   belirtec  120 istekte
yok              0            0
kisa            15         1800
orta            33         3960
uzun            62         7440
uzun istem: yonerge 62 + girdi 12 belirtec, yonergenin payi 0.8378
KURGU talep 4002 (fatura): fatura ayrintisini nereden gorebilirim
kisa / tohum 20260218: talebiniz fatura konusuyla ilgili gorunuyor
kisa / tohum 20260219: bu kayit fatura basligina girer , ilgili ekibe yonlendirildi
orta / tohum 20260218: fatura
orta / tohum 20260219: fatura
```

Son dört satır orta yönergenin ne yaptığını gösteriyor. Kısa yönergede iki koşum aynı etiketi
buluyor ama **iki ayrı cümleyle**; orta yönergede iki koşum da tek sözcük veriyor. Etiket ikisinde
de doğru. Değişen şey isabet değil, yanıtın **okunabilirliğidir** ve bedeli on sekiz belirteçtir.

Üstteki satırlar ise ölçülecek asıl orantıdır. Uzun yönerge 62 belirteç; sınıflandırılacak talep
12 belirteç. Tek bir istemde yönerge **0,8378 pay** tutuyor. Yüz yirmi istekte aynı 62 belirteç
yüz yirmi kez gönderiliyor ve toplam 7440 belirtece çıkıyor. Yönergeden bir belirteç atmak yüz
yirmi istekte yüz yirmi belirteç kazandırır; bu, yönerge yazarken alınan her kararın **istek
sayısıyla çarpıldığı** anlamına gelir.

#### Tekrarın Toplamı

İkinci blok dört yönergeyi aynı 120 kayıtta koşturur, sonra uzun yönergeyi üç ayrı istek sayısıyla
tekrarlar ve son olarak her kısaltmanın kazandırdığı belirteci düşürdüğü isabetle yan yana koyar.

```python
def olc(s, tohum=TOHUM, n=None):
    SAYAC[0] = 0
    kume = TALEP if n is None else TALEP[:n]
    gi = ci = d = bos = 0
    for x in kume:
        c = cagir(kur(s, x), tohum=tohum)
        gi, ci = gi + c["giris"], ci + c["cikis"]
        e = oku(c["yanit"])
        bos += e is None
        d += e == x["konu"]
    m = len(kume)
    return {"isabet": d / m, "bos": bos / m, "giris": gi, "cikis": ci,
            "yonerge": len(belirtecle(s)) * m, "toplam": gi + ci}


R = {ad: olc(s) for ad, s in YONERGE}
print(f"{'yonerge':<8} {'tekrar':>7} {'giris':>6} {'pay':>7} {'cikis':>6} {'isabet':>7} "
      f"{'kosum 2':>8} {'etiketsiz':>10} {'dogru basina':>13}")
for ad, s in YONERGE:
    v, k2 = R[ad], olc(s, tohum=TOHUM + 1)["isabet"]
    print(f"{ad:<8} {v['yonerge']:>7d} {v['giris']:>6d} {v['yonerge'] / v['giris']:>7.4f} "
          f"{v['cikis']:>6d} {v['isabet']:>7.4f} {k2:>8.4f} {v['bos']:>10.4f} "
          f"{v['toplam'] / v['isabet'] / len(TALEP):>13.1f}")
print()
print(f"{'istek':>6} {'yonerge belirteci':>18} {'toplam giris':>13} {'pay':>7}")
for n in (30, 60, 120):
    v = olc(YONERGE[3][1], n=n)
    print(f"{n:>6d} {v['yonerge']:>18d} {v['giris']:>13d} {v['yonerge'] / v['giris']:>7.4f}")
print()
print(f"{'kisaltma':<16} {'kazanilan belirtec':>19} {'isabet farki':>13} "
      f"{'0,01 isabet basina':>19}")
for (a1, _), (a2, _) in zip(YONERGE[1:], YONERGE[:-1]):
    kb = R[a1]["toplam"] - R[a2]["toplam"]
    fi = R[a2]["isabet"] - R[a1]["isabet"]
    o = f"{kb * 0.01 / abs(fi):.0f} belirtec" if fi < 0 else "kayipsiz"
    print(f"{a1 + ' -> ' + a2:<16} {kb:>19d} {fi:>+13.4f} {o:>19}")
```

```
yonerge   tekrar  giris     pay  cikis  isabet  kosum 2  etiketsiz  dogru basina
yok            0   1700  0.0000   1285  0.4583   0.6333     0.2917          54.3
kisa        1800   3500  0.5143   1251  0.7167   0.4583     0.2167          55.2
orta        3960   5660  0.6996    196  0.7500   0.7500     0.0250          65.1
uzun        7440   9140  0.8140    203  0.7417   0.7583     0.0250         105.0

 istek  yonerge belirteci  toplam giris     pay
    30               1860          2295  0.8105
    60               3720          4547  0.8181
   120               7440          9140  0.8140

kisaltma          kazanilan belirtec  isabet farki  0,01 isabet basina
kisa -> yok                     1766       -0.2583         68 belirtec
orta -> kisa                    1105       -0.0333        332 belirtec
uzun -> orta                    3487       +0.0083            kayipsiz
```

İkinci tablo tekrarın nasıl davrandığını gösteriyor. Otuz istekte uzun yönerge 1860, altmış
istekte 3720, yüz yirmi istekte 7440 belirteç ediyor: bedel istek sayısıyla **doğrusal** büyüyor.
Yönergenin toplam giriş içindeki payı ise 0,8105 ile 0,8181 arasında sabit kalıyor. Ölçek büyüdükçe
tekrarın payının seyrelmesi diye bir şey yok; istek sayısı ne olursa olsun girişin dörtte üçünden
fazlası yönergedir. Bir yönerge ne kadar iyi yazılmış olursa olsun, bedeli **kendi uzunluğu değil,
uzunluğunun trafikle çarpımıdır**.

#### Kısaltmanın Bedeli

Birinci tablo isabetin nerede doyduğunu söylüyor. Yönergesiz istem 0,4583 veriyor. Kısa yönerge
0,7167'ye çıkarıyor. Orta yönerge 0,7500'e çıkarıyor. Uzun yönerge ise 0,7417 veriyor, yani
**ortanın altında**. Yirmi dokuz belirteçlik ek — belirsizlik kuralları, ana konu seçimi, açıklama
yasağı — 3487 belirteçlik bir toplam ekledi ve isabetten 0,0083 götürdü. Doğru etiket başına bedel
65,1'den 105,0 belirtece çıktı. Bu kursta böyle bir satır adıyla yazılır: **eklenen metin bedeli
kesin, kazancı belirsizdir.**

Üçüncü tablo kısaltmayı ters yönden okur. Uzun yönergeden ortaya inmek 3487 belirteç kazandırıyor
ve isabetten hiçbir şey götürmüyor; bu **kayıpsız kısaltmadır**. Ortadan kısaya inmek 1105 belirteç
kazandırıyor ve 0,0333 isabet götürüyor, yani her 0,01 isabet için 332 belirteç. Kısadan yönergesize
inmek 1766 belirteç kazandırıyor ve 0,2583 isabet götürüyor, yani her 0,01 isabet için 68 belirteç.
Kısaltmanın karşılığı sabit değildir: yönerge kısaldıkça kalan her belirteç daha pahalı hâle gelir.

Tablonun `etiketsiz` sütunu kısaltmanın asıl kaybını gösteriyor. Yönergesiz istemde yanıtların
0,2917 payından, kısa yönergede 0,2167 payından hiçbir etiket okunamıyor. Orta yönergede bu pay
0,0250'ye iniyor ve orada kalıyor. Kalan üç kayıt istemin değil **yüzeyin** payıdır: hız sınırı
yüz yirmi çağrının üçünü boş döndürüyor. Yani orta yönerge, istemle kapatılabilecek boşluğun
tamamını kapatmış durumda. Uzun yönergenin ekleyecek bir şeyi kalmadığı için yalnız belirteç
ekliyor.

Son olarak `kosum 2` sütunu okunur. Yönergesiz istem iki koşumda 0,4583 ve 0,6333, kısa yönerge
0,7167 ve 0,4583 verdi: ikinci koşumda **yönergesiz istem kısa yönergeli istemi geçti**. Kısa
yönergenin kazancı tek koşumda görünüyor, iki koşumda taşınmıyor. Orta yönerge ise iki koşumda da
0,7500 verdi. Uzun yönerge ise 0,7417 ve 0,7583 verdi; kendi iki koşum farkı 0,0167. Uzun ile orta
arasındaki 0,0083 fark bunun altında kalıyor ve bu kursta **ölçülmemiş sayılır**. Kural bir sonraki
derste adıyla işletilir.

#### Özet

- Sistem yönergesi kalıcı bir davranış tanımıdır ama kalıcılığı modelde değil istemdedir: her
  istekte yeniden gönderilir ve **her istekte yeniden ödenir**.
- 62 belirteçlik uzun yönerge tek istemin 0,8378 payını, 120 istekte 7440 belirteci tutuyor. Pay
  otuz, altmış ve yüz yirmi istekte 0,8105 ile 0,8181 arasında sabit; toplam ise doğrusal büyüyor.
- İsabet orta yönergede doyuyor: yok 0,4583, kısa 0,7167, orta 0,7500, uzun 0,7417. Uzun yönerge
  3487 belirteç ekleyip 0,0083 isabet götürdü ve doğru etiket başına bedeli 65,1'den 105,0'a
  çıkardı.
- Kısaltmanın karşılığı sabit değil: uzundan ortaya inmek kayıpsız, ortadan kısaya inmek 0,01
  isabet başına 332 belirteç, kısadan yönergesize inmek 68 belirteç kazandırıyor.
- Yönergenin kapattığı asıl boşluk etiketsiz yanıt payıdır: 0,2917'den 0,0250'ye iniyor ve orada
  duruyor. Kalan pay hız sınırından gelir, yani istemle kapatılamaz.

#### Sonraki Adım

Orta ile uzun yönerge arasındaki fark, uzunun kendi koşum farkının altında kaldı: eklenen yirmi
dokuz belirteç ölçülebilir bir şey üretmedi. Bu, yönergeye ne ekleneceği sorusunu kapatmıyor.
Sık verilen bir cevap, modele **kim olduğunu** söylemektir: bir uzmanlık, bir görev unvanı, bir
üslup. Bu ekin isabeti yükselttiği yaygın bir kabuldür ve tıpkı belirsizlik kuralları gibi her
istekte ödenir. Sonraki ders bunu ölçer: rol belirtmenin kattığı fark nedir, bedeli kaç belirteçtir
ve o fark aynı istemin iki koşumu arasındaki farktan büyük müdür.

### Rol ve Davranış Belirtme

Source: https://academia.sh/tr/kurslar/istem-muhendisligi/rol-ve-davranis-belirtme

İsteme rol ve davranış öneki eklemenin kattığı farkın ölçülüp aynı istemin koşum farkıyla karşılaştırılması. Aynı 120 kurgu destek talebinde önekli istemlerin isabeti 0,7500 tabana göre -0,0667, -0,0583, -0,2208 ve +0,0125 oynuyor; tabanın dört tohumdaki bandı ise 0,1500. Dört önekten hiçbiri bandın dışına çıkmıyor, yani hiçbirinin farkı ölçülmüş sayılmıyor. Ölçülen tek şey bedeldir: 9 ile 27 belirteç arasındaki önekler 120 istekte 1080 ile 3240 belirteç ekliyor ve doğru etiket başına bedeli 65,1'den 83,6 ile 123,8 arasına çıkarıyor.

Önceki ders yönergenin uzunluğunu ölçtü ve isabetin otuz üç belirteçte doyduğunu buldu; eklenen
yirmi dokuz belirteç bedeli kesin biçimde artırdı, sayıyı ise ölçülebilir biçimde oynatmadı.
Yönergeye ne ekleneceği sorusu orada kapanmadı. En sık verilen cevap modele **kim olduğunu**
söylemektir: bir uzmanlık alanı, bir görev unvanı, bir kıdem. Bu ekin isabeti yükselttiği yaygın
bir kabuldür.

Bu ders o kabulü ölçer ve ölçerken kursun üçüncü kuralını adıyla işletir. **Model belirsiz bir
bileşendir**: aynı istem, tohum değiştiğinde başka bir sayı verir. Bir istem değişikliğinin
kattığı fark, aynı istemin koşumdan koşuma oynadığı aralıktan büyük değilse, o fark bir kazanç
değil bir çakışmadır. Bu kursta öyle bir sayı **ölçülmemiş sayılır**. Ders bu ölçütü kurar, dört
öneke uygular ve sonucu açıkça yazar.

- **IT17.** Kod bir **benzeticiyi** çağırır; gerçek bir model uç noktası çağrılmaz. Destek
  talepleri **kurgudur** ve önceki iki dersteki 120 kayıtla aynıdır.
- **IT18.** Taban istem, önceki dersin ölçtüğü orta yönergedir: etiket kümesi, görev ve yanıt
  biçimi. Bu derste yönerge değişmez; yalnızca önüne bir **önek** eklenir.
- **IT19.** **Rol belirtme**, modele bir kimlik atfeden metindir. **Davranış belirtme**, modelden
  izlemesi istenen adımları yazan metindir. İkisi de yönergenin önüne aynı biçimde konur.
- **IT20.** Her istem **dört tohumla** koşulur (20260218'den 20260221'e). İlk iki tohum **iki
  koşum** sütunlarıdır; dördünün en büyüğü ile en küçüğü arasındaki fark **koşum bandıdır**.
- **IT21.** Bir öneğin **etkisi**, ilk iki koşumun ortalaması ile tabanın ilk iki koşumunun
  ortalaması arasındaki farktır.
- **IT22.** **Ölçülebilirlik ölçütü:** bir etki, karşılaştırılan iki istemin **bantlarının
  büyüğünden** büyük değilse ölçülmemiş sayılır. Ölçüt bu yönüyle tutucudur ve gerekçesi derste
  yazılıdır.
- **IT23.** Bedel belirteçtir. Önek bedeli **önek uzunluğu çarpı istek sayısıdır** ve toplam
  belirtecin içindedir; doğru etiket başına bedel ayrıca basılır.
- **IT24.** Benzeticinin iz tablosu koddadır ve okunabilir. Bir önek metninin hangi etikete ağırlık
  eklediği bu tablodan doğrulanır.
- **IT25.** Bu ders yalnız isabeti ve bedeli ölçer; yanıtın biçimi önceki derste kapatıldı ve
  burada sabittir.

#### Tek Kayıtta Rol İşe Yaramış Görünüyor

İlk blok benzeticiyi ve kurguyu kurar, dört öneki tanımlar, her birinin yüz yirmi istekteki
bedelini yazar ve tek bir kurgu talebi tabanla ve rol önekiyle, iki ayrı tohumda çağırır.

```python
# BENZETICI. Bu kod gercek bir model uc noktasi cagirmaz; standart kitaplikla yazilmis
# bir dil modeli benzeticisidir. Destek talepleri de KURGU'dur.
import math

TOHUM, M32 = 20260218, 0xFFFFFFFF
PENCERE, EN_UZUN = 240, 24          # baglam penceresi ve en buyuk cikti, belirtec


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):                  # KURGU belirtecleyici: parca en cok bes damga
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


def izno(m):                        # istemin icerigine bagli, kosumdan bagimsiz iz
    h = 2166136261
    for c in m:
        h = ((h ^ ord(c)) * 16777619) & M32
    return h


KONU = ["fatura", "ariza", "sayac", "tarife", "kesinti"]
KALIP = {
    "fatura": ["bu ayki fatura tutari gecen aya gore cok yuksek geldi",
               "faturami odedim ama sistemde borc gorunuyor",
               "fatura ayrintisini nereden gorebilirim"],
    "ariza": ["evde su akmiyor bir ariza var galiba",
              "baglanti bozuk oldu ve hic calismiyor",
              "ariza kaydi actim ama ekip gelmedi"],
    "sayac": ["sayac okumasi yanlis girilmis endeks tutmuyor",
              "sayac degisimi icin randevu istiyorum",
              "sayac uzerindeki endeks ile fatura ayni degil"],
    "tarife": ["hangi tarife basamagindayim ogrenmek istiyorum",
               "tarife degisikligi icin ne yapmam gerekiyor",
               "birim ucret abone tipine gore degisiyor mu"],
    "kesinti": ["mahallede kesinti var ne zaman gelecek",
                "planli kesinti duyurusu nereden takip edilir",
                "aksamdan beri kesinti yasiyoruz"],
}
EK = ["ayrica gecen ay da ayni sorun olmustu", "bu konuda memnun degilim",
      "acil bilgi almam gerekiyor", "kayit numaram elimde yok"]

TALEP = []
for i in range(120):
    r = uretec(TOHUM + i)
    k = KONU[ayrik(r(), [0.24, 0.22, 0.18, 0.20, 0.16])]
    m = KALIP[k][int(r() * 3)]
    if r() < 0.34:
        m += " " + EK[int(r() * 4)]
    TALEP.append({"no": 4001 + i, "metin": m, "konu": k})

KAVRAM = KONU + ["odeme", "sikayet", "bilgi", "genel"]
IZ = {"fatur": "fatura", "tutar": "fatura", "ayrin": "fatura",
      "ariza": "ariza", "bozuk": "ariza", "calis": "ariza", "akmiy": "ariza",
      "sayac": "sayac", "endek": "sayac", "okuma": "sayac",
      "tarif": "tarife", "birim": "tarife", "abone": "tarife", "basam": "tarife",
      "kesin": "kesinti", "duyur": "kesinti", "mahal": "kesinti",
      "borc": "odeme", "odedi": "odeme", "ucret": "odeme",
      "memnu": "sikayet", "sorun": "sikayet", "acil": "sikayet",
      "bilgi": "bilgi", "ogren": "bilgi", "nered": "bilgi"}
TUZAK = {"degis": "tarife", "kayit": "ariza", "yukse": "tarife", "gorun": "fatura",
         "ekip": "kesinti", "takip": "tarife", "giril": "fatura"}   # yaniltici baglar
SERBEST = ["talebiniz {k} konusuyla ilgili gorunuyor",
           "bu kayit {k} basligina girer , ilgili ekibe yonlendirildi",
           "kaydiniz alindi , konuyu inceleyip donus yapacagiz"]
SAYAC = [0]


def cagir(istem, tohum=TOHUM, sicaklik=0.6, en_uzun=EN_UZUN):
    SAYAC[0] += 1
    bel = belirtecle(istem)
    if len(bel) > PENCERE:
        return {"durum": "baglam_asimi", "giris": len(bel), "cikis": 0, "yanit": ""}
    if SAYAC[0] % 37 == 0:
        return {"durum": "hiz_siniri", "giris": len(bel), "cikis": 0, "yanit": ""}
    r = uretec(tohum ^ izno(istem))
    if len(bel) > 90 and r() < 0.04:
        return {"durum": "zaman_asimi", "giris": len(bel), "cikis": 0, "yanit": ""}
    aday = [k for k in KAVRAM if k[:5] in bel]      # istemde adi gecen kavramlar
    if len(aday) < 3:
        aday = KAVRAM
    p = {k: 0.15 for k in aday}
    for t in bel:
        for tablo, w in ((IZ, 1.0), (TUZAK, 1.3)):
            if tablo.get(t) in p:
                p[tablo[t]] += w
    if sicaklik <= 0.0:
        k = max(sorted(p), key=lambda a: p[a])       # en olasi secim
    else:
        e = [math.exp(p[a] / sicaklik) for a in sorted(p)]
        k = sorted(p)[ayrik(r(), [v / sum(e) for v in e])]
    y = k if "tek" in bel else SERBEST[ayrik(r(), [0.42, 0.26, 0.32])].format(k=k)
    cb = belirtecle(y)
    if len(cb) > en_uzun:                            # durdurma kosulu
        cb = cb[:en_uzun]
        y = " ".join(cb)
    return {"durum": "tamam", "giris": len(bel), "cikis": len(cb), "yanit": y}


def oku(y):                                          # yanittan etiket cikarma
    for s in y.lower().split():
        if s in KONU:
            return s
    return None


YONERGE = ("Etiketler: fatura , ariza , sayac , tarife , kesinti ."
           " Talebi bu etiketlerden birine ata . Yanit olarak tek etiket yaz .")
ONEK = (("taban", ""),
        ("rol A", "Sen bir abone destek gorevlisisin ."),
        ("rol B", "Sen bir deneyimli saha teknisyenisin ."),
        ("rol C", "Sen dagitim sirketinde on yildir calisan kidemli bir kayit uzmanisin ."),
        ("davranis", "Once talebin ana nesnesini bul , sonra etiketi sec ."
                     " Emin olmadigin durumda talepte gecen ana sozcugu esas al ."))
TOHUMLAR = (TOHUM, TOHUM + 1, TOHUM + 2, TOHUM + 3)


def kur(o, x):
    return (o + " " if o else "") + YONERGE + " Talep: " + x["metin"]


print(f"{'onek':<9} {'belirtec':>9} {'120 istekte':>12}")
for ad, o in ONEK:
    b = len(belirtecle(o))
    print(f"{ad:<9} {b:>9d} {b * len(TALEP):>12d}")
x0 = TALEP[2]
print(f"KURGU talep {x0['no']} ({x0['konu']}): {x0['metin']}")
for ad, o in ONEK[:2]:
    SAYAC[0] = 0
    y = [cagir(kur(o, x0), tohum=t)["yanit"] for t in TOHUMLAR[:2]]
    print(f"{ad:<9} iki kosum: {y[0]} / {y[1]}")
```

```
onek       belirtec  120 istekte
taban             0            0
rol A             9         1080
rol B             9         1080
rol C            17         2040
davranis         27         3240
KURGU talep 4003 (ariza): evde su akmiyor bir ariza var galiba ayrica gecen ay da ayni sorun olmustu
taban     iki kosum: kesinti / ariza
rol A     iki kosum: ariza / ariza
```

Son iki satır bir istem değişikliğinin nasıl kanıtlanmış göründüğünü gösteriyor. Talebin gerçek
konusu `ariza`. Taban istem iki koşumda bir kez yanlış, bir kez doğru cevap verdi; rol öneki
eklenince iki koşumda da doğru cevap geldi. Tek kayda bakan biri buradan "rol isabeti yükseltti"
sonucunu çıkarır. Bu sonucun tek dayanağı, tabanın **zaten koşumdan koşuma oynuyor** olmasıdır.
Aynı gösteri, ters yönde çıkan bir kayıtla da yapılabilirdi.

#### Kümede Ne Oluyor

İkinci blok aynı dört öneki 120 kaydın tamamında ve dört ayrı tohumda koşturur. Her satırda ilk
iki koşum, bu ikisinin ortalamasının tabandan farkı, dört tohumun bandı ve doğru etiket başına
bedel yan yana durur.

```python
def olc(o, tohum):
    SAYAC[0] = 0
    gi = ci = d = 0
    for x in TALEP:
        c = cagir(kur(o, x), tohum=tohum)
        gi, ci = gi + c["giris"], ci + c["cikis"]
        d += oku(c["yanit"]) == x["konu"]
    return {"isabet": d / len(TALEP), "toplam": gi + ci}


S = {ad: [olc(o, t) for t in TOHUMLAR] for ad, o in ONEK}
ti = [v["isabet"] for v in S["taban"]]
tab, tbant = (ti[0] + ti[1]) / 2, max(ti) - min(ti)
print(f"{'istem':<9} {'onek':>5} {'toplam':>7} {'kosum 1':>8} {'kosum 2':>8} {'etki':>8} "
      f"{'iki kosum':>10} {'bant':>7} {'olculur':>8} {'basina':>7}")
for ad, o in ONEK:
    i = [v["isabet"] for v in S[ad]]
    m = (i[0] + i[1]) / 2
    e, ik, bant = m - tab, abs(i[0] - i[1]), max(i) - min(i)
    t = S[ad][0]["toplam"]
    esik = max(bant, tbant)
    print(f"{ad:<9} {len(belirtecle(o)):>5d} {t:>7d} {i[0]:>8.4f} {i[1]:>8.4f} {e:>+8.4f} "
          f"{ik:>10.4f} {bant:>7.4f} {('evet' if abs(e) > esik else 'hayir'):>8} "
          f"{t / m / len(TALEP):>7.1f}")
```

```
istem      onek  toplam  kosum 1  kosum 2     etki  iki kosum    bant  olculur  basina
taban         0    5856   0.7500   0.7500  +0.0000     0.0000  0.1500    hayir    65.1
rol A         9    6940   0.7083   0.6583  -0.0667     0.0500  0.0667    hayir    84.6
rol B         9    6942   0.7250   0.6583  -0.0583     0.0667  0.1417    hayir    83.6
rol C        17    7863   0.6417   0.4167  -0.2208     0.2250  0.2250    hayir   123.8
davranis     27    9105   0.7083   0.8167  +0.0125     0.1083  0.1083    hayir    99.5
```

#### İki Koşum Bandın Alt Sınırıdır

Tablonun ilk satırı ölçütün niçin bu biçimde kurulduğunu gösteriyor. Taban istem iki koşumda da
tam olarak 0,7500 verdi; iki koşum farkı **0,0000**. Bu sayıya bakarak "bu istem kararlıdır"
denebilirdi. Dört tohum koşulduğunda taban 0,7500, 0,7500, 0,8583 ve 0,7083 veriyor ve bandı
**0,1500** çıkıyor. İki koşumun çakışması belirsizliğin yokluğu değil, iki örneğin aynı yere
düşmesidir. **İki koşum bandın ölçüsü değil, alt sınırıdır.**

Ölçüt bu yüzden tutucu kuruldu: bir etki, karşılaştırılan iki istemin bantlarının büyüğünden
büyük değilse ölçülmemiş sayılır. Dört önekten hiçbiri bu eşiği geçemiyor. Rol A'nın etkisi
−0,0667, eşiği 0,1500. Rol B'nin etkisi −0,0583, eşiği 0,1500. Davranış önekinin etkisi +0,0125,
eşiği 0,1500. Rol C'nin etkisi −0,2208 ve eşiği kendi bandı olan 0,2250. Daha gevşek bir okumayla,
yalnız tabanın bandına bakılsaydı rol C eşiği geçerdi — ama geçtiği yön **aşağı** olurdu. Hangi
okuma seçilirse seçilsin sonuç aynıdır: **dört önekten hiçbiri isabeti ölçülebilir biçimde
yükseltmedi.**

Ölçülmüş olan tek şey bedeldir ve bedel bir bant taşımaz. Rol A ve rol B dokuzar belirteç; yüz
yirmi istekte 1080 belirteç ve toplamda 5856'dan 6940 ile 6942'ye çıkış. Rol C on yedi belirteç,
2040 tekrar, toplam 7863. Davranış öneki yirmi yedi belirteç, 3240 tekrar, toplam 9105. Doğru
etiket başına bedel 65,1 belirteçten 84,6, 83,6, 123,8 ve 99,5 belirtece çıkıyor. Doğru etiket
başına en pahalı istem tabanın **1,90 katıdır** ve karşılığında ölçülebilir hiçbir şey vermiyor.

#### Rol Metni Yansız Değildir

Rol öneklerinin etkisi ölçülemez çıktı, ama etkilerinin **yönü** rastgele değil. Benzeticinin iz
tablosu koddadır ve okunabilir. Rol A'nın metnindeki `abone` parçası iz tablosunda `tarife`
etiketine bağlıdır; rol C'nin metnindeki `calis` parçası `ariza`ya, `kayit` parçası ise yanıltıcı
bağlar tablosunda yine `ariza`ya bağlıdır. Yani rol C her talepte, talebin içeriğinden bağımsız
olarak `ariza` etiketine ağırlık ekliyor. Rol B'nin metnindeki hiçbir parça iki tabloda da yer
almıyor; etkisi yalnız koşum gürültüsüdür.

Buradan çıkan yapısal sonuç isteme yazılan her metin için geçerlidir. **Rol metni ayrı bir kanal
değildir**; görev metniyle aynı belirteç dizisine girer ve taşıdığı sözcükler kararın içine
karışır. Bir role hangi sözcüklerin seçildiği, o rolün ne kadar inandırıcı yazıldığından daha çok
şey belirler. Bir istem yazarı rol cümlesini üslup olarak görürken, model onu kanıt olarak okur.

Bu, rol belirtmenin her görevde etkisiz olduğu anlamına gelmez; bu ölçüm tek bir görevde, tek bir
küme ve tek bir benzetici üzerinde yapıldı. Anlamına geldiği şey daha dardır ve kurs boyunca
sürer: **rol eklenmiş bir istem, farkı ölçülene kadar iyileştirilmiş bir istem değildir.** Bedeli
ise ölçüme gerek kalmadan bellidir, çünkü her istekte yeniden ödenir.

#### Özet

- Tek bir kayıtta rol öneki tabanın yanlış verdiği cevabı düzeltti. Aynı önek 120 kayıtta isabeti
  0,7500'den 0,6833'e indirdi. Tek kayıt üzerinden yapılan gösteri, tabanın kendi oynamasını
  kanıt diye sunar.
- Taban istem iki koşumda da 0,7500 verdi, iki koşum farkı 0,0000. Dört tohumda bandı **0,1500**.
  İki koşum, bandın ölçüsü değil **alt sınırıdır**.
- Ölçülebilirlik ölçütü: bir etki, karşılaştırılan iki istemin bantlarının büyüğünden büyük
  değilse ölçülmemiş sayılır. Rol A −0,0667, rol B −0,0583, rol C −0,2208, davranış +0,0125;
  **dördü de eşiğin altında**.
- Bedel bant taşımaz ve tamamen ölçülüdür: önekler 9 ile 27 belirteç, 120 istekte 1080 ile 3240
  belirteç. Doğru etiket başına bedel 65,1'den 84,6, 83,6, 123,8 ve 99,5 belirtece çıkıyor.
- Rol metni ayrı bir kanal değildir. `abone` parçası iz tablosunda `tarife`ye, `calis` ve `kayit`
  parçaları `ariza`ya bağlıdır; rol cümlesi görev metniyle aynı dizide okunur ve karara karışır.

#### Sonraki Adım

Bu derste isteme kimlik ve yordam eklendi, ama **ne istendiği** hiç değişmedi: talep her üç
istemde de aynı cümleydi. Görev tanımının kendisi bir tasarım kararıdır ve belirsiz bırakıldığında
bedeli öneklerinkinden büyüktür. Belirsiz bir talep tek bir yanlış cevap üretmez; **bir dağılım**
üretir ve o dağılım tek koşumda görünmez. Sonraki ders bunu ölçer: aynı belirsiz istem on koşumda
kaç ayrı biçimde yanıtlanıyor, talep ölçülebilir kılındığında bu sayı kaça iniyor ve dağılımın
daralmasının kaç belirtece mal olduğu.

### Açık ve Ölçülebilir Talep

Source: https://academia.sh/tr/kurslar/istem-muhendisligi/acik-ve-olculebilir-talep

Belirsiz bir talebin tek bir yanlış yanıt değil bir dağılım ürettiği ölçülüyor: aynı belirsiz istem on koşumda kayıt başına ortalama 4,81 ayrı yanıt veriyor, en sık yanıt koşumların yalnız 0,3944 payında tekrarlanıyor ve yanıtların 0,4333 payından hiçbir etiket okunamıyor. Dört talep biçimi yan yana konuyor. Fiili açmak iki belirteç ekliyor ve dağılımı 4,53'e indiriyor; seçenek kümesini kapatmak 15 belirteç ekleyip dağılımı 3,89'a, etiketsiz payı 0,2889'a indiriyor; belirsizlik kuralı eklemek 10 belirteç daha ekleyip etiketsiz payı 0,3722'ye geri çıkarıyor. Tek koşumda okunan isabetin bandı 0,2778 ile 0,3333 arasındadır ve dört talebi birbirinden ayıramaz.

Önceki ders isteme kimlik ve yordam ekledi ve dört önekten hiçbirinin farkının ölçülebilir
olmadığını buldu. O ölçüm boyunca bir şey hiç değişmedi: **ne istendiği**. Talep her istemde aynı
cümleydi ve o cümlenin kendisi hiç sorgulanmadı. Oysa görev tanımı istemin en pahalı parçası
değil, en belirleyici parçasıdır.

Belirsiz bir talebin bedeli, belirsiz bir yanıt vermesi değildir. Belirsiz talep tek bir yanlış
cevap üretmez; **bir dağılım** üretir. Aynı istem, aynı kayıt, aynı model — ve on ayrı koşumda
birbirinin yerine geçmeyen birkaç ayrı yanıt. Bu dağılım tek koşuma bakan hiçbir ölçüde görünmez;
tek koşumda görünen şey, o dağılımdan çekilmiş tek bir örnektir. Bu ders dağılımı ölçer ve talebi
ölçülebilir kılmanın onu ne kadar daralttığını sayar.

- **IT26.** Kod bir **benzeticiyi** çağırır; gerçek bir model uç noktası çağrılmaz. Destek
  talepleri **kurgudur** ve önceki derslerdeki kümenin ilk 36 kaydıdır. Küme küçültüldü çünkü her
  kayıt on kez çağrılıyor.
- **IT27.** Her kayıt **on koşumla** ölçülür: tohum 20260218'den 20260227'ye. Dağılım ölçüleri bu
  on yanıtın toplamıdır, tek bir koşumun değil.
- **IT28.** **Ayrı yanıt sayısı**, on koşumda birbirinden farklı çıkan yanıt metinlerinin
  sayısıdır ve kayıt başına ortalanır. En küçük değeri 1, en büyüğü 10'dur.
- **IT29.** **En sık pay**, on koşumda en çok tekrarlanan yanıtın payıdır. Dar bir dağılımda 1'e,
  geniş bir dağılımda 0,1'e yaklaşır.
- **IT30.** Hız sınırı her otuz yedinci çağrıda tetiklenir ve boş yanıt döndürür. Dağılım sayımını
  bozmaması için çağrı sayacı her kaydın on koşumundan önce sıfırlanır; bu bir ölçüm kararıdır ve
  koddadır.
- **IT31.** Dört talep biçimi artımlı kurulur: belirsiz fiil, açık fiil, açık fiil ile kapalı
  seçenek kümesi, buna eklenmiş belirsizlik kuralı.
- **IT32.** Bu derste **yanıtın biçimi hiçbir istemde istenmez**. Ölçülen şey talebin açıklığıdır;
  çıktının biçimi bir sonraki dersin konusudur.
- **IT33.** İsabet, on koşumun her birinde ayrı hesaplanır; tabloda ortalaması ve **bandı** (en
  büyük ile en küçük koşum arasındaki fark) basılır.
- **IT34.** Bedel belirteçtir ve istek başına giriş ile çıkış olarak yazılır; on koşum bedeli on
  katıdır.

#### Belirsiz Talebin Ürettiği Dağılım

İlk blok benzeticiyi ve kurguyu kurar, dört talep biçimini tanımlar ve tek bir kurgu kaydı en
belirsiz biçimle on kez çağırıp çıkan yanıtları sayar.

```python
# BENZETICI. Bu kod gercek bir model uc noktasi cagirmaz; standart kitaplikla yazilmis
# bir dil modeli benzeticisidir. Destek talepleri de KURGU'dur.
import math

TOHUM, M32 = 20260218, 0xFFFFFFFF
PENCERE, EN_UZUN = 240, 24          # baglam penceresi ve en buyuk cikti, belirtec


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):                  # KURGU belirtecleyici: parca en cok bes damga
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


def izno(m):                        # istemin icerigine bagli, kosumdan bagimsiz iz
    h = 2166136261
    for c in m:
        h = ((h ^ ord(c)) * 16777619) & M32
    return h


KONU = ["fatura", "ariza", "sayac", "tarife", "kesinti"]
KALIP = {
    "fatura": ["bu ayki fatura tutari gecen aya gore cok yuksek geldi",
               "faturami odedim ama sistemde borc gorunuyor",
               "fatura ayrintisini nereden gorebilirim"],
    "ariza": ["evde su akmiyor bir ariza var galiba",
              "baglanti bozuk oldu ve hic calismiyor",
              "ariza kaydi actim ama ekip gelmedi"],
    "sayac": ["sayac okumasi yanlis girilmis endeks tutmuyor",
              "sayac degisimi icin randevu istiyorum",
              "sayac uzerindeki endeks ile fatura ayni degil"],
    "tarife": ["hangi tarife basamagindayim ogrenmek istiyorum",
               "tarife degisikligi icin ne yapmam gerekiyor",
               "birim ucret abone tipine gore degisiyor mu"],
    "kesinti": ["mahallede kesinti var ne zaman gelecek",
                "planli kesinti duyurusu nereden takip edilir",
                "aksamdan beri kesinti yasiyoruz"],
}
EK = ["ayrica gecen ay da ayni sorun olmustu", "bu konuda memnun degilim",
      "acil bilgi almam gerekiyor", "kayit numaram elimde yok"]

TALEP = []
for i in range(120):
    r = uretec(TOHUM + i)
    k = KONU[ayrik(r(), [0.24, 0.22, 0.18, 0.20, 0.16])]
    m = KALIP[k][int(r() * 3)]
    if r() < 0.34:
        m += " " + EK[int(r() * 4)]
    TALEP.append({"no": 4001 + i, "metin": m, "konu": k})

KAVRAM = KONU + ["odeme", "sikayet", "bilgi", "genel"]
IZ = {"fatur": "fatura", "tutar": "fatura", "ayrin": "fatura",
      "ariza": "ariza", "bozuk": "ariza", "calis": "ariza", "akmiy": "ariza",
      "sayac": "sayac", "endek": "sayac", "okuma": "sayac",
      "tarif": "tarife", "birim": "tarife", "abone": "tarife", "basam": "tarife",
      "kesin": "kesinti", "duyur": "kesinti", "mahal": "kesinti",
      "borc": "odeme", "odedi": "odeme", "ucret": "odeme",
      "memnu": "sikayet", "sorun": "sikayet", "acil": "sikayet",
      "bilgi": "bilgi", "ogren": "bilgi", "nered": "bilgi"}
TUZAK = {"degis": "tarife", "kayit": "ariza", "yukse": "tarife", "gorun": "fatura",
         "ekip": "kesinti", "takip": "tarife", "giril": "fatura"}   # yaniltici baglar
SERBEST = ["talebiniz {k} konusuyla ilgili gorunuyor",
           "bu kayit {k} basligina girer , ilgili ekibe yonlendirildi",
           "kaydiniz alindi , konuyu inceleyip donus yapacagiz"]
SAYAC = [0]


def cagir(istem, tohum=TOHUM, sicaklik=0.6, en_uzun=EN_UZUN):
    SAYAC[0] += 1
    bel = belirtecle(istem)
    if len(bel) > PENCERE:
        return {"durum": "baglam_asimi", "giris": len(bel), "cikis": 0, "yanit": ""}
    if SAYAC[0] % 37 == 0:
        return {"durum": "hiz_siniri", "giris": len(bel), "cikis": 0, "yanit": ""}
    r = uretec(tohum ^ izno(istem))
    if len(bel) > 90 and r() < 0.04:
        return {"durum": "zaman_asimi", "giris": len(bel), "cikis": 0, "yanit": ""}
    aday = [k for k in KAVRAM if k[:5] in bel]      # istemde adi gecen kavramlar
    if len(aday) < 3:
        aday = KAVRAM
    p = {k: 0.15 for k in aday}
    for t in bel:
        for tablo, w in ((IZ, 1.0), (TUZAK, 1.3)):
            if tablo.get(t) in p:
                p[tablo[t]] += w
    if sicaklik <= 0.0:
        k = max(sorted(p), key=lambda a: p[a])       # en olasi secim
    else:
        e = [math.exp(p[a] / sicaklik) for a in sorted(p)]
        k = sorted(p)[ayrik(r(), [v / sum(e) for v in e])]
    y = k if "tek" in bel else SERBEST[ayrik(r(), [0.42, 0.26, 0.32])].format(k=k)
    cb = belirtecle(y)
    if len(cb) > en_uzun:                            # durdurma kosulu
        cb = cb[:en_uzun]
        y = " ".join(cb)
    return {"durum": "tamam", "giris": len(bel), "cikis": len(cb), "yanit": y}


def oku(y):                                          # yanittan etiket cikarma
    for s in y.lower().split():
        if s in KONU:
            return s
    return None


FIIL = "Su destek talebini konusuna gore etiketle ."
KUME_METNI = " Etiketler: fatura , ariza , sayac , tarife , kesinti ."
TALEP_BICIMI = (("belirsiz fiil", "Su destek talebini degerlendir ."),
                ("acik fiil", FIIL),
                ("kapali kume", FIIL + KUME_METNI),
                ("belirsizlik kurali",
                 FIIL + KUME_METNI + " Birden cok konu varsa ana konuyu sec ."))
KUME = TALEP[:36]
TOHUMLAR = [TOHUM + i for i in range(10)]


def kosumlar(bas, x):
    SAYAC[0] = 0            # hiz siniri dagilim sayimini bozmasin diye her talepte sifirlanir
    return [cagir(bas + " Talep: " + x["metin"], tohum=t) for t in TOHUMLAR]


def dokum(ad, bas, x):
    s = [c["yanit"] for c in kosumlar(bas, x)]
    print(f"{ad}, on kosum -> {len(set(s))} ayri yanit")
    for v in sorted(set(s)):
        print(f"  {s.count(v)}/10  {v}")


print(f"{'talep':<19} {'belirtec':>9}")
for ad, b in TALEP_BICIMI:
    print(f"{ad:<19} {len(belirtecle(b)):>9d}")
x0 = KUME[3]
print(f"KURGU talep {x0['no']} (gercek konu {x0['konu']}): {x0['metin']}")
dokum(TALEP_BICIMI[0][0], TALEP_BICIMI[0][1], x0)
```

```
talep                belirtec
belirsiz fiil               9
acik fiil                  11
kapali kume                26
belirsizlik kurali         36
KURGU talep 4004 (gercek konu ariza): ariza kaydi actim ama ekip gelmedi
belirsiz fiil, on kosum -> 7 ayri yanit
  1/10  bu kayit ariza basligina girer , ilgili ekibe yonlendirildi
  1/10  bu kayit odeme basligina girer , ilgili ekibe yonlendirildi
  1/10  bu kayit sayac basligina girer , ilgili ekibe yonlendirildi
  2/10  kaydiniz alindi , konuyu inceleyip donus yapacagiz
  1/10  talebiniz fatura konusuyla ilgili gorunuyor
  2/10  talebiniz kesinti konusuyla ilgili gorunuyor
  2/10  talebiniz sikayet konusuyla ilgili gorunuyor
```

Tek bir kayıt, on koşumda **yedi ayrı yanıt** verdi. En sık çıkan yanıt yalnız iki koşumda
tekrarlandı. Yanıtlardan biri hiçbir etiket taşımıyor; ikisi ise `odeme` ve `sikayet` etiketlerini
kullanıyor, yani saha ekibinin kurgu belge dağarcığında karşılığı olmayan adlar. İstem
"değerlendir" dedi ve bu fiil hangi kümeden hangi biçimde bir sonuç istendiğini hiç söylemedi.
Model bu boşluğu her koşumda ayrı bir şekilde doldurdu.

Bu tablonun asıl anlamı bir kayıtta değil, kayıtların dağılımındadır. Yedi ayrı yanıttan yalnız
birine bakan bir gözlemci, istemin çalıştığı ya da çalışmadığı sonucuna eşit kolaylıkla varır.

#### Dört Talep Yan Yana

İkinci blok dört talep biçimini otuz altı kayıtta ve on koşumda ölçer. Her satırda kayıt başına
ortalama ayrı yanıt sayısı, en sık yanıtın payı, etiketsiz yanıt payı, on koşumun ortalama isabeti,
isabetin bandı ve belirteç bedeli durur.

```python
def olc(bas):
    ay = ec = bos = gi = ci = 0
    ds = [0] * len(TOHUMLAR)
    for x in KUME:
        c = kosumlar(bas, x)
        s = [v["yanit"] for v in c]
        e = [oku(v) for v in s]
        ay += len(set(s))
        ec += max(s.count(v) for v in s) / len(s)
        bos += sum(v is None for v in e) / len(e)
        for j, v in enumerate(e):
            ds[j] += v == x["konu"]
        gi += sum(v["giris"] for v in c) / len(c)
        ci += sum(v["cikis"] for v in c) / len(c)
    n = len(KUME)
    iso = [v / n for v in ds]
    return (ay / n, ec / n, bos / n, sum(iso) / len(iso), max(iso) - min(iso),
            gi / n, ci / n)


print(f"{'talep':<19} {'bel':>4} {'ayri yanit':>11} {'en sik':>7} {'etiketsiz':>10} "
      f"{'isabet':>7} {'bant':>7} {'giris':>6} {'cikis':>6}")
for ad, b in TALEP_BICIMI:
    ay, ec, bos, d, bant, gi, ci = olc(b)
    print(f"{ad:<19} {len(belirtecle(b)):>4d} {ay:>11.2f} {ec:>7.4f} {bos:>10.4f} "
          f"{d:>7.4f} {bant:>7.4f} {gi:>6.1f} {ci:>6.1f}")
print()
dokum(TALEP_BICIMI[2][0], TALEP_BICIMI[2][1], x0)
```

```
talep                bel  ayri yanit  en sik  etiketsiz  isabet    bant  giris  cikis
belirsiz fiil          9        4.81  0.3944     0.4333  0.4611  0.3333   23.1   11.4
acik fiil             11        4.53  0.4333     0.4500  0.4417  0.3333   25.1   11.3
kapali kume           26        3.89  0.4083     0.2889  0.5306  0.2778   40.1   11.5
belirsizlik kurali    36        3.78  0.4611     0.3722  0.4722  0.3333   50.1   11.6

kapali kume, on kosum -> 4 ayri yanit
  2/10  bu kayit kesinti basligina girer , ilgili ekibe yonlendirildi
  3/10  kaydiniz alindi , konuyu inceleyip donus yapacagiz
  2/10  talebiniz ariza konusuyla ilgili gorunuyor
  3/10  talebiniz kesinti konusuyla ilgili gorunuyor
```

#### Fiili Açmak Ölçülebilirlik Değildir

İkinci satır bu dersin en kolay yanlış anlaşılan sonucudur. "Değerlendir" fiili "konusuna göre
etiketle" ile değiştirildi; talep dilbilgisi olarak açık, eylem olarak nettir. Ayrı yanıt sayısı
4,81'den 4,53'e indi, isabet 0,4611'den 0,4417'ye **düştü**, etiketsiz yanıt payı 0,4333'ten
0,4500'e **çıktı**. İki belirteçlik ek, dağılımı ölçülebilir biçimde daraltmadı.

Sebep yapısaldır. Açık bir fiil ne yapılacağını söyler, **hangi kümeden seçileceğini** söylemez.
"Etiketle" diyen bir istem, etiketin nereden geleceğini modele bırakır ve model her koşumda kendi
sözlüğünden bir ad üretir. Bir talebin ölçülebilir olması, fiilinin net olması değil, **cevabın
alınabileceği kümenin kapalı olmasıdır**.

Üçüncü satır bunu gösteriyor. Beş etiketin adı isteme yazıldığında ayrı yanıt sayısı 3,89'a
iniyor, etiketsiz pay 0,4333'ten 0,2889'a düşüyor ve isabet 0,5306'ya çıkıyor. Bedel açıkça
sayılıdır: istek başına giriş 25,1'den 40,1 belirtece çıkıyor, yani 15 belirteç. Otuz altı kayıtta
540, on koşumda 5400 belirteç. Aynı kaydın kapalı kümeyle alınan on koşumu blok çıktısının
sonundadır: yedi ayrı yanıt dörde inmiş ve küme dışı adlar kaybolmuş durumda. Bu kayıtta yoğunlaşma
yanlış etikette oldu; **dağılımın daralması isabet güvencesi değildir** ve iki sayı ayrı sütunlarda
durmalıdır.

Dördüncü satır kursun ikinci iddiasını ödüyor. "Birden çok konu varsa ana konuyu seç" cümlesi on
belirteç ekliyor ve ayrı yanıt sayısını 3,89'dan 3,78'e indiriyor. Aynı cümle etiketsiz payı
0,2889'dan **0,3722'ye** çıkarıyor ve isabeti 0,5306'dan **0,4722'ye** düşürüyor. Belirsizliği
azaltmak için yazılmış bir cümle, ölçüldüğünde belirsizliği artırmış olabilir.

#### Dağılım Tek Koşumda Görünmez

Tablonun `bant` sütunu bu dersin yöntem sonucudur. Dört talebin on koşumdaki isabet bandı sırasıyla
0,3333, 0,3333, 0,2778 ve 0,3333. Kapalı kümenin isabete etkisi +0,0695; kendi bandının tam dörtte
biri kadar. Önceki dersin ölçütüyle okunduğunda bu fark **ölçülmemiş sayılır**. Yani dört
talebin hangisinin daha iyi olduğu, tek koşumda okunan isabetle **hiçbir biçimde** ayırt edilemez.

Ayırt edebilen sayılar başkadır ve hepsi on koşumun toplamıdır: ayrı yanıt sayısı 4,81'den 3,89'a,
etiketsiz pay 0,4333'ten 0,2889'a iniyor. Bu iki ölçü tek bir koşumdan hesaplanamaz, çünkü tek
koşumda her kaydın bir yanıtı vardır ve o yanıtın kaç olasılıktan biri olduğu görünmez.
**Belirsiz bir talebin bedeli, tek koşumda ölçülemeyen bir bedeldir**; bu yüzden çoğu istem
denemesi onu hiç görmez ve tek bir başarılı örnekle kapanır.

#### Özet

- Belirsiz bir talep tek bir yanlış yanıt değil bir dağılım üretir. Tek kayıt on koşumda yedi
  ayrı yanıt verdi; küme genelinde kayıt başına ortalama **4,81 ayrı yanıt** ve en sık yanıt için
  yalnız **0,3944** pay çıktı.
- Fiili açmak ölçülebilirlik değildir: iki belirteçlik ek ayrı yanıtı 4,53'e indirdi, isabeti
  0,4417'ye düşürdü ve etiketsiz payı 0,4500'e çıkardı.
- Talebi ölçülebilir kılan karar **seçenek kümesini kapatmaktır**: ayrı yanıt 3,89, etiketsiz pay
  0,2889, isabet 0,5306. Bedeli istek başına 15 belirteç, on koşumda 5400 belirteçtir.
- Belirsizlik kuralı eklemek on belirteç ekleyip etiketsiz payı 0,3722'ye, isabeti 0,4722'ye
  götürdü: belirsizliği azaltmak için yazılan cümle ölçüldüğünde belirsizliği artırdı.
- İsabetin on koşumdaki bandı 0,2778 ile 0,3333 arasında; kapalı kümenin +0,0695 etkisi bandın
  içindedir. Dağılım ölçüleri tek koşumdan hesaplanamaz.

#### Sonraki Adım

Dört derste istemin bileşenleri ayrıldı, kalıcı yönergenin tekrar bedeli sayıldı, rol öneklerinin
farkı ölçülemez bulundu ve talep kapalı bir kümeye bağlandı. Buna rağmen kapalı kümeli istem bile
kayıt başına ortalama 3,89 ayrı yanıt üretiyor ve yanıtların 0,2889 payından hiçbir etiket
okunamıyor. Kalan dağılımın kaynağı artık ne istendiği değil, **nasıl söylendiğidir**: aynı etiket
üç ayrı cümle kalıbıyla, bazen de hiçbir etiket adı geçmeden veriliyor. Talep açıldı, ama yanıtın
biçimi hâlâ modele bırakıldı. Sonraki ders bunu ele alır: çıktı biçimi istendiğinde kaç yanıt
makinece ayrıştırılabiliyor ve uzunluk sınırı isabetten ne kadarını geri alıyor.

### Biçim ve Uzunluk Denetimi

Source: https://academia.sh/tr/kurslar/istem-muhendisligi/bicim-ve-uzunluk-denetimi

Açık bir talebin yanıtı hâlâ serbest metindir ve bir program onu okuyamaz. Aynı 120 kurgu destek talebinde üç alanlı bir kayıt isteniyor: serbest yanıtta katı alan ayrıştırıcısının okuduğu oran 0,0000, biçim bildirimi eklendiğinde 0,9750 oluyor ve etiket isabeti 0,3083'ten 0,6833'e çıkıyor. Bedel giriş belirtecinde 6140'tan 8780'e çıkış, çıkış belirtecinde 1392'den 2026'ya artıştır. En büyük çıktı uzunluğu 24'ten 10'a indirildiğinde çıkış belirteci 2026'dan 1170'e iniyor ama ayrıştırılabilir oran 0,9750'den 0,0000'a düşüyor; ara değerlerde eğri kesilen yanıt sayısına birebir bağlı kalıyor.

Önceki ders belirsiz bir talebin kaç ayrı biçimde yanıtlandığını saydı ve talebi ölçülebilir
kılmanın bu dağılımı ne kadar daralttığını gösterdi. Talep artık açıktır: hangi etiket kümesinden
seçileceği istemde yazılıdır, ne istendiği tek cümlede durur. Yine de bir karar hâlâ modele
bırakılmış durumdadır. Model **ne söyleyeceğini** biliyor, ama bunu **hangi biçimde** yazacağını
bilmiyor.

Bu ayrımın bedeli, yanıtı kimin okuyacağına bağlıdır. Bir insan "kaydınız alındı, konuyu
inceleyip dönüş yapacağız" cümlesini sorunsuz okur. Aynı cümleyi bir kayıt alanına yazacak
program okuyamaz: içinde ne etiket alanı vardır, ne arıza kodu, ne de ayrılmış bir gerekçe. Bu
ders yanıtın biçimini bir tasarım kararı olarak ele alır ve iki şeyi ölçer: biçim bildiriminin
**makinece ayrıştırılabilirliğe** kattığı fark ve uzunluk sınırının aynı ölçüden geri aldığı
pay.

- **IT41.** Model bir **benzeticidir**; gerçek bir uç nokta çağrılmaz. Standart kitaplıkla
  yazılmıştır, tohumu **20260218**'dir ve aynı istem aynı tohumda aynı yanıtı verir.
- **IT42.** Destek talepleri **kurgudur**: beş konuda 120 kısa Türkçe kayıt, bir bölümüne
  eklenmiş yanıltıcı bir cümleyle.
- **IT43.** Görev üç alanlı bir **kayıt** ister: etiket, arıza kodu ve kısa gerekçe. Arıza
  kodları da kurgudur.
- **IT44.** İki ayrıştırıcı kullanılır. **Katı alan ayrıştırıcısı** üç alanın da tam ve tutarlı
  olmasını arar; **gevşek okuma** yanıtın herhangi bir yerinde bir etiket sözcüğü arar.
- **IT45.** Üç istemde de etiket kümesi aynıdır ve talep aynı derecede açıktır. **Değişen tek şey
  biçim bildirimidir**; uzunluk sınırı ayrıca ölçülür.
- **IT46.** Uzunluk sınırı benzeticinin **en büyük çıktı uzunluğudur**. Sınır aşıldığında
  durdurma koşulu devreye girer ve yanıt ortasından kesilir.
- **IT47.** Bedel **belirteçle** yazılır: giriş belirteci, çıkış belirteci ve çağrı sayısı.

#### Serbest Yanıt, Programın Okuyamadığı Yanıttır

İlk blok benzeticiyi kurar, üç alanlı kaydı tanımlar ve iki ayrıştırıcıyı yazar. Üç istem yan
yana koşturulur: biçim bildirimi olmayan, biçim bildirimi olan ve biçim bildirimi olup çıktı
uzunluğu on iki belirteçle sınırlanan.

```python
# BENZETICI -- KURGUDUR. Bu kod gercek bir model uc noktasi cagirmaz; standart
# kitaplikla yazilmis bir dil modeli benzeticisidir. Talepler de kurgudur.
import math

TOHUM, M32 = 20260218, 0xFFFFFFFF
PENCERE, EN_UZUN = 240, 24          # baglam penceresi ve en buyuk cikti, belirtec


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):                  # KURGU belirtecleyici: parca en cok bes damga
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


def izno(m):                        # istemin icerigine bagli, kosumdan bagimsiz iz
    h = 2166136261
    for c in m:
        h = ((h ^ ord(c)) * 16777619) & M32
    return h


KONU = ["fatura", "ariza", "sayac", "tarife", "kesinti"]
KOD = {"fatura": "ft-21", "ariza": "ar-14", "sayac": "sy-32", "tarife": "tr-05",
       "kesinti": "ks-40", "odeme": "od-11", "sikayet": "sk-09", "bilgi": "bg-02",
       "genel": "gn-00"}
KALIP = {"fatura": ["bu ayki fatura tutari gecen aya gore cok yuksek geldi",
                    "faturami odedim ama sistemde borc gorunuyor",
                    "fatura ayrintisini nereden gorebilirim"],
         "ariza": ["evde su akmiyor bir ariza var galiba",
                   "baglanti bozuk oldu ve hic calismiyor",
                   "ariza kaydi actim ama ekip gelmedi"],
         "sayac": ["sayac okumasi yanlis girilmis endeks tutmuyor",
                   "sayac degisimi icin randevu istiyorum",
                   "sayac uzerindeki endeks ile fatura ayni degil"],
         "tarife": ["hangi tarife basamagindayim ogrenmek istiyorum",
                    "tarife degisikligi icin ne yapmam gerekiyor",
                    "birim ucret abone tipine gore degisiyor mu"],
         "kesinti": ["mahallede kesinti var ne zaman gelecek",
                     "planli kesinti duyurusu nereden takip edilir",
                     "aksamdan beri kesinti yasiyoruz"]}
EK = ["ayrica gecen ay da ayni sorun olmustu", "bu konuda memnun degilim",
      "acil bilgi almam gerekiyor", "kayit numaram elimde yok"]

TALEP = []
for i in range(120):
    r = uretec(TOHUM + i)
    k = KONU[ayrik(r(), [0.24, 0.22, 0.18, 0.20, 0.16])]
    m = KALIP[k][int(r() * 3)]
    if r() < 0.34:
        m += " " + EK[int(r() * 4)]
    TALEP.append({"no": 4001 + i, "metin": m, "konu": k})

KAVRAM = KONU + ["odeme", "sikayet", "bilgi", "genel"]
IZ = {"fatur": "fatura", "tutar": "fatura", "ayrin": "fatura", "ariza": "ariza",
      "bozuk": "ariza", "calis": "ariza", "akmiy": "ariza", "sayac": "sayac",
      "endek": "sayac", "okuma": "sayac", "tarif": "tarife", "birim": "tarife",
      "abone": "tarife", "basam": "tarife", "kesin": "kesinti", "duyur": "kesinti",
      "mahal": "kesinti", "borc": "odeme", "odedi": "odeme", "ucret": "odeme",
      "memnu": "sikayet", "sorun": "sikayet", "acil": "sikayet", "bilgi": "bilgi",
      "ogren": "bilgi", "nered": "bilgi"}
TUZAK = {"degis": "tarife", "kayit": "ariza", "yukse": "tarife", "gorun": "fatura",
         "ekip": "kesinti", "takip": "tarife", "giril": "fatura"}   # yaniltici baglar
SERBEST = ["talebiniz {k} konusuyla ilgili gorunuyor",
           "bu kayit {k} basligina girer , ilgili ekibe yonlendirildi",
           "kaydiniz alindi , konuyu inceleyip donus yapacagiz"]
SAYAC = [0]


def cagir(istem, ozet, tohum=TOHUM, sicaklik=0.6, en_uzun=EN_UZUN):
    SAYAC[0] += 1
    bel = belirtecle(istem)
    bos = {"giris": len(bel), "cikis": 0, "yanit": "", "kesik": 0}
    if len(bel) > PENCERE:
        return dict(bos, durum="baglam_asimi")
    if SAYAC[0] % 37 == 0:
        return dict(bos, durum="hiz_siniri")
    r = uretec(tohum ^ izno(istem))
    if len(bel) > 90 and r() < 0.04:
        return dict(bos, durum="zaman_asimi")
    aday = [k for k in KAVRAM if k[:5] in bel]      # istemde adi gecen kavramlar
    if len(aday) < 3:
        aday = KAVRAM
    p = {k: 0.15 for k in aday}
    for t in bel:
        for tablo, w in ((IZ, 1.0), (TUZAK, 1.3)):
            if tablo.get(t) in p:
                p[tablo[t]] += w
    if sicaklik <= 0.0:
        k = max(sorted(p), key=lambda a: p[a])       # en olasi secim
    else:
        e = [math.exp(p[a] / sicaklik) for a in sorted(p)]
        k = sorted(p)[ayrik(r(), [v / sum(e) for v in e])]
    if "bicim" in bel:                               # istemde bicim bildirimi var
        y = f"etiket : {k} ; kod : {KOD[k]} ; gerekce : {ozet}"
    else:
        y = SERBEST[ayrik(r(), [0.42, 0.26, 0.32])].format(k=k)
    cb, kesik = belirtecle(y), 0
    if len(cb) > en_uzun:                            # durdurma kosulu
        cb, kesik, y = cb[:en_uzun], 1, " ".join(cb[:en_uzun])
    return {"durum": "tamam", "giris": len(bel), "cikis": len(cb),
            "yanit": y, "kesik": kesik}


def ayristir(y):                    # KATI alan ayristirici: uc alan da tam olmali
    a = {}
    for parca in y.split(";"):
        ad = parca.split(":")
        if len(ad) == 2:
            a[ad[0].strip()] = ad[1].strip()
    tam = a.get("etiket") in KONU and a.get("kod") == KOD.get(a.get("etiket"))
    return a["etiket"] if tam and a.get("gerekce") else None


def oku(y):                         # GEVSEK okuma: yanittaki ilk etiket sozcugu
    for s in y.lower().split():
        if s in KONU:
            return s
    return None


TABAN = ("Talebi su etiketlerden birine ata : fatura , ariza , sayac , tarife , "
         "kesinti . Ilgili ariza kodunu ve kisa gerekcesini de bildir . Talep : ")
BICIM = "Yanitin bicimi : etiket : <deger> ; kod : <deger> ; gerekce : <deger> . "


def olc(bicim, en_uzun=EN_UZUN, tohum=TOHUM):
    SAYAC[0] = 0
    d = {"kati": 0, "gevsek": 0, "isabet": 0, "giris": 0, "cikis": 0, "kesik": 0}
    for x in TALEP:
        s = cagir((BICIM if bicim else "") + TABAN + x["metin"],
                  " ".join(x["metin"].split()[:3]), tohum=tohum, en_uzun=en_uzun)
        for a in ("giris", "cikis", "kesik"):
            d[a] += s[a]
        d["kati"] += ayristir(s["yanit"]) is not None
        d["gevsek"] += oku(s["yanit"]) is not None
        d["isabet"] += oku(s["yanit"]) == x["konu"]
    for a in ("kati", "gevsek", "isabet"):
        d[a] /= len(TALEP)
    d["cagri"] = SAYAC[0]
    return d


A, B, C = olc(False), olc(True), olc(True, en_uzun=12)
ornek = cagir(BICIM + TABAN + TALEP[3]["metin"], " ".join(TALEP[3]["metin"].split()[:3]))
print(f"KURGU: {len(TALEP)} destek talebi. bicimli yanit ornegi ({ornek['cikis']} belirtec)")
print(f"  {ornek['yanit']}")
print(f"\n{'olcu':<26}{'serbest':>10}{'bicim kisiti':>14}{'bicim + 12':>12}")
for ad, k, b in (("ayristirilabilir oran", "kati", "{:.4f}"),
                 ("etiketi okunan oran", "gevsek", "{:.4f}"),
                 ("etiket isabeti", "isabet", "{:.4f}"),
                 ("giris belirteci", "giris", "{:d}"),
                 ("cikis belirteci", "cikis", "{:d}"),
                 ("kesilen yanit", "kesik", "{:d}")):
    print(f"{ad:<26}{b.format(A[k]):>10}{b.format(B[k]):>14}{b.format(C[k]):>12}")
```

```
KURGU: 120 destek talebi. bicimli yanit ornegi (15 belirtec)
  etiket : ariza ; kod : ar-14 ; gerekce : ariza kaydi actim

olcu                         serbest  bicim kisiti  bicim + 12
ayristirilabilir oran         0.0000        0.9750      0.0000
etiketi okunan oran           0.4667        0.9750      0.4833
etiket isabeti                0.3083        0.6833      0.2667
giris belirteci                 6140          8780        8780
cikis belirteci                 1392          2026        1404
kesilen yanit                      0             0         117
```

İlk satır bu dersin asıl sayısıdır. Serbest yanıtta katı alan ayrıştırıcısının okuduğu kayıt
sayısı **sıfırdır**: yüz yirmi yanıtın hiçbiri üç alanlı bir kayıt değildir. Talep açıktı, etiket
kümesi istemde yazılıydı, arıza kodu ve gerekçe ayrıca istenmişti; buna rağmen ortaya çıkan şey
bir cümledir. İkinci satır cümlelerin okunamaz olmadığını gösteriyor: yanıtların **0,4667**
payında gevşek okuma bir etiket sözcüğü buluyor. Aradaki uçurum bu dersin konusudur. Serbest
yanıt insanın okuduğu, programın okuyamadığı bir çıktıdır.

Biçim bildirimi eklendiğinde ayrıştırılabilir oran **0,9750** oluyor. Kalan pay modelin biçimi
bozmasından değil, hız sınırına takılan üç çağrıdan geliyor; benzetici her otuz yedinci çağrıda
boş yanıt döndürür ve boş yanıttan kayıt okunmaz. Etiket isabeti aynı anda **0,3083'ten
0,6833'e** çıkıyor, ama bu artışın kaynağı modelin daha iyi karar vermesi değildir. Serbest
yanıtın yarıdan fazlası hiçbir etiket taşımıyordu ve etiketi okunamayan her kayıt yanlış sayılıyordu.
Biçim bildirimi kararı düzeltmiyor, **kararı görünür kılıyor**.

Bedel iki yönde birden hareket ediyor. Giriş belirteci **6140'tan 8780'e** çıkıyor: biçim
bildirimi yirmi iki belirteçtir ve yüz yirmi isteğin her birinin başına eklenir. Çıkış belirteci de
**1392'den 2026'ya** çıkıyor, çünkü üç alanlı kayıt serbest cümleden uzundur. Buradaki dersin
kendisi budur: biçim kısıtı, bu görevde **her iki belirteç kalemini de büyüten** bir karardır.
Üçüncü sütun ise bu büyümeyi geri almanın maliyetini gösteriyor. Çıktı uzunluğu on iki belirteçle
sınırlandığında çıkış belirteci 1404'e iniyor, ama ayrıştırılabilir oran **0,0000** oluyor:
kesilen yanıt sayısı 117'dir ve kesik bir kayıt eksik kayıttır.

#### Uzunluk Sınırı Bir Eğim Değil, Bir Eşiktir

İkinci blok sınırı geniş bir aralıkta tarar ve kesilen yanıt sayısı ile ayrıştırılabilir oranın
nasıl bağlandığını gösterir.

```python
print("en uzun  kesilen  ayristirilabilir  etiket isabeti  cikis belirteci")
for n in (24, 20, 18, 16, 14, 12, 10):
    d = olc(True, en_uzun=n)
    print(f"{n:>7}  {d['kesik']:>7}  {d['kati']:>16.4f}  {d['isabet']:>14.4f}"
          f"  {d['cikis']:>15}")

kalan = {}
for x in TALEP:
    s = cagir(BICIM + TABAN + x["metin"], " ".join(x["metin"].split()[:3]), en_uzun=12)
    e = oku(s["yanit"])
    kalan[e] = kalan.get(e, 0) + 1
print(f"\nen uzun 12 , kesik yanitta okunabilen etiket: {sorted(k for k in kalan if k)}")
print(f"bes damgayi asan etiket: {[k for k in KONU if len(k) > 5]}")

B2, A2 = olc(True, tohum=TOHUM + 1), olc(False, tohum=TOHUM + 1)
print(f"\nbicim kisitinin katkisi : ayristirilabilir {B['kati'] - A['kati']:+.4f} ,"
      f" isabet {B['isabet'] - A['isabet']:+.4f}")
print(f"iki kosum farki         : ayristirilabilir {B2['kati'] - B['kati']:+.4f} ,"
      f" isabet {B2['isabet'] - B['isabet']:+.4f}")
print(f"serbest istem iki kosum : isabet {A['isabet']:.4f} / {A2['isabet']:.4f}")
```

```
en uzun  kesilen  ayristirilabilir  etiket isabeti  cikis belirteci
     24        0            0.9750          0.6833             2026
     20        0            0.9750          0.6833             2026
     18       30            0.7250          0.4417             1992
     16       78            0.3250          0.3500             1865
     14      117            0.0000          0.2917             1638
     12      117            0.0000          0.2667             1404
     10      117            0.0000          0.2667             1170

en uzun 12 , kesik yanitta okunabilen etiket: ['ariza', 'sayac']
bes damgayi asan etiket: ['fatura', 'tarife', 'kesinti']

bicim kisitinin katkisi : ayristirilabilir +0.9750 , isabet +0.3750
iki kosum farki         : ayristirilabilir +0.0000 , isabet +0.1167
serbest istem iki kosum : isabet 0.3083 / 0.5000
```

Çizelgenin ikinci ve üçüncü sütunu birbirine kilitlidir. Sınır yirmide iken kesilen yanıt yoktur
ve oran 0,9750'dir; on sekizde otuz yanıt kesilir ve oran 0,7250'ye iner; on altıda yetmiş sekiz
yanıt kesilir ve oran 0,3250 olur. Her satırda **ayrıştırılabilir yanıt sayısı, kesilmemiş ve
hata döndürmemiş yanıt sayısına birebir eşittir**. Tek bir kayıt için uzunluk sınırı bir eşiktir:
ya kayıt tamdır ya da hiç yoktur, arası yoktur. Küme düzeyinde eğri yumuşak görünür, çünkü yanıt
uzunlukları kayıttan kayda değişir; eğrinin eğimi modelin değil, **gerekçe alanının uzunluk
dağılımının** özelliğidir.

Belirteç sütunu bu kararın cazibesini açıklıyor. Sınırı yirmi dörtten ona indirmek çıkış
belirtecini **2026'dan 1170'e**, yani kabaca yarıya düşürüyor. Tasarruf gerçektir ve peşindir;
karşılığında elde kalan kayıt sayısı sıfırdır. Uzunluk sınırı bir maliyet ayarıdır ve **doğru
yeri, kaydın tam uzunluğunun hemen üstüdür**; altına inen her belirteç kazancı, kaydın tamamını
siler.

Kesik yanıtta hangi etiketin okunabildiği Türkçeye özgü bir ayrıntı gösteriyor. Sınır on ikide
iken gevşek okuma yalnız `ariza` ve `sayac` etiketlerini buluyor; `fatura`, `tarife` ve `kesinti`
hiç görünmüyor. Nedeni belirteçleyicidir: beş damgayı aşan sözcükler parçalara bölünür ve kesilmiş
bir çıktı yeniden birleştirildiğinde bu parçalar ayrı sözcük olarak kalır. Aynı uzunluk sınırı,
**etiketin damga sayısına göre farklı davranıyor** — sınır bir belirteç eşiğidir ama etkisi
sözcüğün yazımına bağlıdır.

Son üç satır kursun kuralını uyguluyor. Biçim bildiriminin ayrıştırılabilirliğe kattığı fark
**+0,9750**, aynı istemin iki koşumu arasındaki fark ise **+0,0000**. Ölçü koşumdan bağımsızdır
ve kazanç tartışmasızdır. İsabet tarafı aynı derecede rahat değildir: kazanç **+0,3750**, iki
koşum farkı **+0,1167**. Kazanç farkın üç katından büyük olduğu için ölçülmüş sayılır, ama aynı
istemin iki koşumu arasında 0,1167'lik bir oynama varken 0,05'lik bir iyileştirme iddiası bu
düzenekte ölçülmemiş bir tahmindir. **İstem bir tasarım nesnesidir; ölçülmeden değiştirilen istem
bir iyileştirme değil bir tahmindir.**

#### Özet

- Açık bir talep yanıtın biçimini belirlemez. Serbest yanıtta katı alan ayrıştırıcısının okuduğu
  kayıt oranı **0,0000**, gevşek okumanın etiket bulduğu oran **0,4667**: yanıt insan için
  okunabilir, program için okunamazdır.
- Biçim bildirimi ayrıştırılabilir oranı **0,9750**'ye, etiket isabetini **0,3083'ten 0,6833'e**
  taşıyor. Kalan 0,0250 modelin değil, hız sınırına takılan üç çağrının payıdır.
- Bedel çift yönlüdür: giriş belirteci **6140'tan 8780'e**, çıkış belirteci **1392'den 2026'ya**
  çıkıyor. Biçim kısıtı bu görevde iki belirteç kalemini de büyütür.
- En büyük çıktı uzunluğu 24'ten 10'a indirilince çıkış belirteci **2026'dan 1170'e** iniyor ve
  ayrıştırılabilir oran **0,0000** oluyor; her satırda ayrıştırılabilir yanıt sayısı, kesilmemiş
  ve hata döndürmemiş yanıt sayısına eşittir.
- Biçim bildiriminin ayrıştırılabilirliğe kattığı **+0,9750**, iki koşum farkı **+0,0000**;
  isabete kattığı **+0,3750**, iki koşum farkı **+0,1167**. İkinci ölçü daha gürültülüdür ve bu
  düzeneğin ölçebileceği en küçük isabet farkını belirler.

#### Sonraki Adım

Bu derste isteme yazılan şey bir **tarifti**: alanların adı, sırası ve ayracı. Tarif yanıtın
kabını belirledi ve kabı belirlemek isabeti dolaylı olarak yükseltti. Ama modelin **hangi talebin
hangi etikete gittiğine** dair kararı hiç desteklenmedi; istemde bunun tek bir örneği bile yok.
Sonraki ders tarif yerine **örnek** koyar: çözülmüş birkaç talep isteme yazılır ve isabetin nasıl
değiştiği sayılır. Örnek sayısı sıfırdan sekize çıkarılır, her adımda isabet ve belirteç yan yana
basılır, **kazancın doyduğu nokta** yazılır. Aynı ders bir de rahatsız edici bir şey gösterir:
aynı örnekler farklı sırayla yazıldığında sayı değişir, yani örnek kümesi kadar örneklerin
**dizilişi** de bir tasarım kararıdır.

### Örnek Kullanımı

Source: https://academia.sh/tr/kurslar/istem-muhendisligi/ornek-kullanimi

Sıfır, tek ve az örnekli yönlendirme aynı görevde yan yana ölçülüyor. Örnek sayısı sıfırdan sekize çıkarken 112 kurgu destek talebinde isabet 0,8571'den 0,9732'ye gidiyor, ama kazanç üçüncü örnekte doyuyor: sıfırdan üç örneğe +0,1071 isabet 4928 ek giriş belirteciyle geliyor, üçten sekize +0,0089 isabet 8736 ek belirteçle geliyor ve dört ile sekiz arası ortalama 0,9250 ile üç örnekteki 0,9643 sayısının altında kalıyor. Aynı dört örnek yalnız sırası değiştirilerek yazıldığında isabet 0,7679 ile 0,9196 arasında geziniyor ve giriş belirteci her sırada aynı kalıyor.

Önceki ders yanıtın biçimini isteme yazdı ve makinece ayrıştırılabilir yanıt oranını 0,0000'dan
0,9750'ye taşıdı. İsteme konulan şey bir **tarifti**: alanların adı, sırası ve ayracı. Tarif
yanıtın kabını belirledi, ama kararın kendisine dokunmadı. Hangi talebin hangi etikete gittiği
hâlâ yalnız modelin bildiği bir şeydir ve istemde bunun tek bir örneği yoktur.

Bu ders tarif yerine **örnek** koyar. İsteme çözülmüş talepler yazılır ve her biri modele "bu
metin bu etikete gider" der. Ölçülecek olan üç şeydir: örnek başına isabet kazancı, örnek başına
belirteç bedeli ve kazancın **nerede durduğu**. Dersin sonunda ölçü bir kez daha kendi üstüne
döner: aynı örnekler yalnız sırası değiştirilerek yazıldığında sayı oynuyor mu.

- **IT48.** Model bir **benzeticidir**, tohumu **20260218**'dir ve gerçek bir uç nokta
  çağrılmaz. Destek talepleri ve arıza kodları **kurgudur**.
- **IT49.** Önceki dersin **biçim kısıtı sabit tutulur**. Yanıt her koşumda üç alanlı kayıt olarak
  istenir ve aynı katı alan ayrıştırıcısıyla okunur; böylece bu derste değişen tek şey örneklerdir.
- **IT50.** Ölçüm **en olası seçimle** yapılır. Örnekleme kapalıyken etiket kararı koşumdan
  bağımsızdır ve örneğin kattığı fark örnekleme gürültüsüne karışmaz; örnekleme açık koşum ayrıca
  basılır.
- **IT51.** Örnek havuzu ölçüm kümesinden **ayrıdır**: sekiz çözülmüş talep havuza alınır, kalan
  112 talep ölçülür. Havuzun ilk beş örneği beş etiketi birer kez kapsar, kalan üçü ikinci
  kalıpları getirir.
- **IT52.** Benzetici örneği isteme yazılmış bir **eşleşme tablosu** gibi kullanır: örneğin
  metniyle talebin paylaştığı her belirteç, örneğin etiketinin puanını artırır. **Sondaki örnek
  daha ağır basar**; sıra etkisi buradan gelir.
- **IT53.** Bedel **giriş belirteciyle** yazılır. Örnekler her istekte yeniden gönderilir; istek
  başına giriş belirteci örnek sayısıyla doğru orantılı büyür.

#### Örnek Başına Kazanç ve Bedel

```python
# BENZETICI -- KURGUDUR. Gercek bir model uc noktasi cagrilmaz; standart kitaplikla
# yazilmis bir dil modeli benzeticisidir. Destek talepleri de kurgudur.
import math

TOHUM, M32 = 20260218, 0xFFFFFFFF
PENCERE, EN_UZUN = 240, 24


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):                  # KURGU belirtecleyici: parca en cok bes damga
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


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


KONU = ["fatura", "ariza", "sayac", "tarife", "kesinti"]
KOD = {"fatura": "ft-21", "ariza": "ar-14", "sayac": "sy-32", "tarife": "tr-05",
       "kesinti": "ks-40", "odeme": "od-11", "sikayet": "sk-09", "bilgi": "bg-02",
       "genel": "gn-00"}
KALIP = {"fatura": ["bu ayki fatura tutari gecen aya gore cok yuksek geldi",
                    "faturami odedim ama sistemde borc gorunuyor",
                    "fatura ayrintisini nereden gorebilirim"],
         "ariza": ["evde su akmiyor bir ariza var galiba",
                   "baglanti bozuk oldu ve hic calismiyor",
                   "ariza kaydi actim ama ekip gelmedi"],
         "sayac": ["sayac okumasi yanlis girilmis endeks tutmuyor",
                   "sayac degisimi icin randevu istiyorum",
                   "sayac uzerindeki endeks ile fatura ayni degil"],
         "tarife": ["hangi tarife basamagindayim ogrenmek istiyorum",
                    "tarife degisikligi icin ne yapmam gerekiyor",
                    "birim ucret abone tipine gore degisiyor mu"],
         "kesinti": ["mahallede kesinti var ne zaman gelecek",
                     "planli kesinti duyurusu nereden takip edilir",
                     "aksamdan beri kesinti yasiyoruz"]}
EK = ["ayrica gecen ay da ayni sorun olmustu", "bu konuda memnun degilim",
      "acil bilgi almam gerekiyor", "kayit numaram elimde yok"]

TALEP = []
for i in range(120):
    r = uretec(TOHUM + i)
    k = KONU[ayrik(r(), [0.24, 0.22, 0.18, 0.20, 0.16])]
    m = KALIP[k][int(r() * 3)]
    if r() < 0.34:
        m += " " + EK[int(r() * 4)]
    TALEP.append({"no": 4001 + i, "metin": m, "konu": k})

KAVRAM = KONU + ["odeme", "sikayet", "bilgi", "genel"]
IZ = {"fatur": "fatura", "tutar": "fatura", "ayrin": "fatura", "ariza": "ariza",
      "bozuk": "ariza", "calis": "ariza", "akmiy": "ariza", "sayac": "sayac",
      "endek": "sayac", "okuma": "sayac", "tarif": "tarife", "birim": "tarife",
      "abone": "tarife", "basam": "tarife", "kesin": "kesinti", "duyur": "kesinti",
      "mahal": "kesinti", "borc": "odeme", "odedi": "odeme", "ucret": "odeme",
      "memnu": "sikayet", "sorun": "sikayet", "acil": "sikayet", "bilgi": "bilgi",
      "ogren": "bilgi", "nered": "bilgi"}
TUZAK = {"degis": "tarife", "kayit": "ariza", "yukse": "tarife", "gorun": "fatura",
         "ekip": "kesinti", "takip": "tarife", "giril": "fatura"}   # yaniltici baglar
SAYAC = [0]


def coz(istem):                     # istemi ornek listesi ve talep metni olarak ayirir
    ust, _, talep = istem.partition("Talep : ")
    ornek = []
    for parca in ust.split("Ornek : ")[1:]:
        m, _, e = parca.partition(" => ")
        ornek.append((m.strip(), e.split(" .")[0].strip()))
    return ornek, talep


def cagir(istem, ozet, tohum=TOHUM, sicaklik=0.0, en_uzun=EN_UZUN):
    SAYAC[0] += 1
    bel = belirtecle(istem)
    bos = {"giris": len(bel), "cikis": 0, "yanit": ""}
    if len(bel) > PENCERE:
        return dict(bos, durum="baglam_asimi")
    if SAYAC[0] % 37 == 0:
        return dict(bos, durum="hiz_siniri")
    r = uretec(tohum ^ izno(istem))
    if len(bel) > 90 and r() < 0.04:            # uzun istem , zaman asimi
        return dict(bos, durum="zaman_asimi")
    ornek, talep = coz(istem)
    bt = belirtecle(talep)
    aday = [k for k in KAVRAM if k[:5] in bel]
    if len(aday) < 3:
        aday = KAVRAM
    p = {k: 0.15 for k in aday}
    for t in bt:                                 # talep belirtecleri: iz ve tuzak
        for tablo, w in ((IZ, 1.0), (TUZAK, 1.3)):
            if tablo.get(t) in p:
                p[tablo[t]] += w
    for j, (m, e) in enumerate(ornek):           # ic baglamdan ogrenme
        if e in p:
            w = 0.5 + (j + 1) / len(ornek)       # sondaki ornek daha agir basar
            for t in set(belirtecle(m)):
                if t in bt:
                    p[e] += 0.30 * w
    if sicaklik <= 0.0:
        k = max(sorted(p), key=lambda a: p[a])   # en olasi secim
    else:
        e = [math.exp(p[a] / sicaklik) for a in sorted(p)]
        k = sorted(p)[ayrik(r(), [v / sum(e) for v in e])]
    y = f"etiket : {k} ; kod : {KOD[k]} ; gerekce : {ozet}"
    cb = belirtecle(y)
    if len(cb) > en_uzun:
        cb, y = cb[:en_uzun], " ".join(cb[:en_uzun])
    return {"durum": "tamam", "giris": len(bel), "cikis": len(cb), "yanit": y}


def ayristir(y):                    # onceki dersin katı alan ayristiricisi
    a = {}
    for parca in y.split(";"):
        ad = parca.split(":")
        if len(ad) == 2:
            a[ad[0].strip()] = ad[1].strip()
    tam = a.get("etiket") in KONU and a.get("kod") == KOD.get(a.get("etiket"))
    return a["etiket"] if tam and a.get("gerekce") else None


YONERGE = ("Talebi su etiketlerden birine ata : fatura , ariza , sayac , tarife , "
           "kesinti . Yanitin bicimi : etiket : <deger> ; kod : <deger> ; "
           "gerekce : <deger> . ")
SEC = [1, 3, 4, 5, 0, 18, 13, 40]   # once her etiketten bir ornek, sonra ikinci kalip
HAVUZ = [TALEP[i] for i in SEC]
KUME = [t for i, t in enumerate(TALEP) if i not in SEC]


def istem_kur(ornekler, metin):
    o = "".join(f"Ornek : {x['metin']} => {x['konu']} . " for x in ornekler)
    return YONERGE + o + "Talep : " + metin


def olc(ornekler, tohum=TOHUM, sicaklik=0.0):
    SAYAC[0] = 0
    g = c = d = h = 0
    for x in KUME:
        s = cagir(istem_kur(ornekler, x["metin"]), " ".join(x["metin"].split()[:3]),
                  tohum=tohum, sicaklik=sicaklik)
        g, c = g + s["giris"], c + s["cikis"]
        h += s["durum"] != "tamam"
        d += ayristir(s["yanit"]) == x["konu"]
    return {"isabet": d / len(KUME), "giris": g, "cikis": c, "hata": h}


print(f"KURGU: ornek havuzu {len(HAVUZ)} cozulmus talep , olcum kumesi {len(KUME)} talep")
print(f"ornek yazimi: Ornek : {HAVUZ[0]['metin']} => {HAVUZ[0]['konu']} .")
print(f"\n{'ornek':>5}  {'etiket':>7}  isabet  giris belirteci  istek basi  kazanc")
onceki = None
for n in range(9):
    d = olc(HAVUZ[:n])
    kz = "-" if onceki is None else f"{d['isabet'] - onceki:+.4f}"
    ad = HAVUZ[n - 1]["konu"] if n else "-"
    print(f"{n:>5}  {ad:>7}  {d['isabet']:.4f}  {d['giris']:>15}"
          f"  {d['giris'] / len(KUME):>10.1f}  {kz:>7}")
    onceki = d["isabet"]
```

```
KURGU: ornek havuzu 8 cozulmus talep , olcum kumesi 112 talep
ornek yazimi: Ornek : fatura ayrintisini nereden gorebilirim => fatura .

ornek   etiket  isabet  giris belirteci  istek basi  kazanc
    0        -  0.8571             6646        59.3        -
    1   fatura  0.8571             8438        75.3  +0.0000
    2    ariza  0.9018             9782        87.3  +0.0446
    3    sayac  0.9643            11574       103.3  +0.0625
    4   tarife  0.8929            13366       119.3  -0.0714
    5  kesinti  0.9196            15270       136.3  +0.0268
    6   fatura  0.9286            17398       155.3  +0.0089
    7    ariza  0.9107            18854       168.3  -0.0179
    8    sayac  0.9732            20310       181.3  +0.0625
```

Birinci satır **sıfır örnekli yönlendirmedir**: istemde yalnız yönerge ve biçim tarifi vardır,
isabet **0,8571**. İkinci satır **tek örnekli yönlendirmedir** ve kazancı **sıfırdır**. Tek
örnek, kendi etiketinin puanını yükseltmekten başka bir şey yapmaz; öbür dört etiket hakkında
hiçbir şey söylemez ve zaten doğru sınıflanan talepleri biraz daha doğru sınıflar. Bedeli
gerçektir: istek başına giriş belirteci **59,3'ten 75,3'e** çıkar.

Kazanç **az örnekli yönlendirmede** başlar. İkinci örnek +0,0446, üçüncü örnek +0,0625 katar ve
isabet **0,9643** olur. Buraya kadar örnek eklemek karşılığını veriyor: sıfırdan üçe **+0,1071**
isabet, **+4928** giriş belirteci. Dördüncü örnekten sonra çizelge yön değiştirir. Dördüncü örnek
**−0,0714** ile en büyük tek adımlı kaybı üretir, beşinci ve altıncı küçük kazançlar getirir,
yedinci yine düşürür, sekizinci +0,0625 ile en yüksek sayıya çıkarır. Dört ile sekiz arasındaki
beş ölçümün ortalaması **0,9250**, yani üç örnekteki **0,9643'ün altında**.

Doyma noktası bu çizelgede **üçüncü örnektir**. Üçten sekize gitmenin isabete kattığı
**+0,0089**, giriş belirtecine eklediği **+8736**. İlk üç örnek belirteç başına yaklaşık yirmi kat
daha fazla isabet getirdi. Bunun nedeni örneklerin ne öğrettiğinde: ilk üç örnek üç ayrı etiketin
belirteçlerini tanıtır ve daha önce yanlış eşlenen talepleri düzeltir. Sonraki örnekler ya zaten
kapsanmış bir etiketi tekrarlar ya da kendi cümlelerindeki **konu dışı sözcükleri** de öğretir;
"nereden", "gerekiyor" gibi sözcükler etiketle ilgisizdir ve puanı yanlış yöne iter. Örnek
eklemek bir noktadan sonra bilgi değil **gürültü** ekler ve gürültünün bedeli de belirteçtir.

#### Aynı Örnekler, Başka Sıra

```python
SIRA = [(0, 1, 2, 3), (3, 2, 1, 0), (1, 3, 0, 2), (2, 0, 3, 1), (0, 2, 1, 3), (3, 0, 2, 1)]
D = HAVUZ[:4]
print("ayni dort ornek , yalniz sira degisiyor")
v = []
for s in SIRA:
    d = olc([D[i] for i in s])
    v.append(d["isabet"])
    print(f"  {' > '.join(D[i]['konu'] for i in s):<34} isabet {d['isabet']:.4f}"
          f"  giris {d['giris']}")
print(f"  siralama araligi {max(v) - min(v):.4f} , giris belirteci her sirada esit")

print("\nolcunun kendi degiskenligi")
for n in (0, 3, 8):
    a, b = olc(HAVUZ[:n]), olc(HAVUZ[:n], tohum=TOHUM + 1)
    print(f"  n={n} en olasi secim : {a['isabet']:.4f} / {b['isabet']:.4f}"
          f"  fark {b['isabet'] - a['isabet']:+.4f} , basarisiz cagri {a['hata']}")
for n in (0, 3):
    a = olc(HAVUZ[:n], sicaklik=0.6)
    b = olc(HAVUZ[:n], tohum=TOHUM + 1, sicaklik=0.6)
    print(f"  n={n} ornekleme acik : {a['isabet']:.4f} / {b['isabet']:.4f}"
          f"  fark {b['isabet'] - a['isabet']:+.4f}")

s0, s3, s8 = olc(HAVUZ[:0]), olc(HAVUZ[:3]), olc(HAVUZ[:8])
orta = sum(olc(HAVUZ[:n])["isabet"] for n in range(4, 9)) / 5
print(f"\nsifir -> uc ornek  : isabet {s3['isabet'] - s0['isabet']:+.4f} ,"
      f" giris belirteci {s3['giris'] - s0['giris']:+d}")
print(f"uc -> sekiz ornek  : isabet {s8['isabet'] - s3['isabet']:+.4f} ,"
      f" giris belirteci {s8['giris'] - s3['giris']:+d}")
print(f"dort ile sekiz arasi ortalama isabet {orta:.4f} , uc ornekte {s3['isabet']:.4f}")
```

```
ayni dort ornek , yalniz sira degisiyor
  fatura > ariza > sayac > tarife    isabet 0.8929  giris 13366
  tarife > sayac > ariza > fatura    isabet 0.9196  giris 13366
  ariza > tarife > fatura > sayac    isabet 0.8929  giris 13366
  sayac > fatura > tarife > ariza    isabet 0.9196  giris 13366
  fatura > sayac > ariza > tarife    isabet 0.9196  giris 13366
  tarife > fatura > sayac > ariza    isabet 0.7679  giris 13366
  siralama araligi 0.1518 , giris belirteci her sirada esit

olcunun kendi degiskenligi
  n=0 en olasi secim : 0.8571 / 0.8571  fark +0.0000 , basarisiz cagri 3
  n=3 en olasi secim : 0.9643 / 0.9554  fark -0.0089 , basarisiz cagri 3
  n=8 en olasi secim : 0.9732 / 0.9464  fark -0.0268 , basarisiz cagri 3
  n=0 ornekleme acik : 0.7321 / 0.8393  fark +0.1071
  n=3 ornekleme acik : 0.8571 / 0.8750  fark +0.0179

sifir -> uc ornek  : isabet +0.1071 , giris belirteci +4928
uc -> sekiz ornek  : isabet +0.0089 , giris belirteci +8736
dort ile sekiz arasi ortalama isabet 0.9250 , uc ornekte 0.9643
```

Üstteki altı satırın hepsinde **aynı dört örnek** vardır. Etiket kümesi aynı, yönerge aynı, biçim
tarifi aynı, ölçüm kümesi aynı ve **giriş belirteci altı sırada da 13366**. Değişen tek şey
örneklerin yazılma sırasıdır ve isabet **0,7679 ile 0,9196** arasında geziniyor. Aralık
**0,1518**, yani sıfırdan üç örneğe geçmenin kattığı **0,1071'den büyük**. Aynı örnek kümesi,
bedeli kuruşuna kadar aynıyken, iyi bir istemle kötü bir istem arasındaki farkı üretebiliyor.

Nedeni benzeticinin son örneği daha ağır basmasıdır. En kötü sıralamada son örnek `ariza`
etiketlidir ve cümlesindeki `ama` belirteci ölçüm kümesinde sekiz `fatura` talebinde de geçer;
ağırlıklandırıldığında o talepleri de `ariza` tarafına çeker. Aynı örnek listenin başında
dururken bu etkiyi yapmıyor. Sıra bir tasarım kararıdır ve
istem üzerinde **bedelsiz** bir kaldıraçtır: değiştirmek hiçbir belirteç maliyeti getirmez.

Alt bölüm ölçünün kendi değişkenliğini veriyor. En olası seçimle çalışıldığında iki koşum
arasındaki fark en fazla **0,0268**; başarısız çağrı sayısı üç koşumda da üçtür ve hız sınırından
gelir. Bu ölçekte sıfırdan üç örneğe geçişin **+0,1071** kazancı iki koşum farkının dört katıdır
ve **ölçülmüş** sayılır; üçten sekize geçişin **+0,0089** kazancı iki koşum farkının altında
kalır ve **ölçülmemiş** sayılır. Örnekleme açıldığında tablo tersine döner: sıfır örnekte iki
koşum arasındaki fark **0,1071**, yani tam olarak ölçmek istediğimiz kazanç kadar. Aynı sayıyı
örneklemeli koşumda tek seferde ölçmeye çalışan biri, kazancı da gürültüyü de aynı büyüklükte
görür ve ikisini ayıramaz. **Ölçülmeden değiştirilen istem bir iyileştirme değil bir tahmindir**
ve burada ölçmenin bir ön koşulu vardır: ölçünün kendi değişkenliği, aranan farktan küçük
olmalıdır.

#### Özet

- Sıfır örnekli yönlendirme **0,8571**, tek örnekli yönlendirme yine **0,8571** veriyor: tek
  örnek isabete hiçbir şey katmadan istek başına giriş belirtecini 59,3'ten 75,3'e çıkarıyor.
- Kazanç az örnekli yönlendirmede birikiyor ve **üçüncü örnekte doyuyor**: sıfırdan üçe
  **+0,1071** isabet ve **+4928** giriş belirteci, üçten sekize **+0,0089** isabet ve **+8736**
  giriş belirteci.
- Dört ile sekiz örnek arasındaki beş ölçümün ortalaması **0,9250**, üç örnekteki **0,9643'ün**
  altında; doyma noktasından sonra eklenen örnek bilgi değil gürültü taşıyor.
- Aynı dört örnek yalnız sırası değiştirilerek yazıldığında isabet **0,7679 ile 0,9196** arasında
  geziniyor. Aralık **0,1518**, giriş belirteci altı sıralamada da **13366**: sıra bedelsiz bir
  tasarım kaldıracıdır.
- En olası seçimle iki koşum farkı en fazla **0,0268**; örnekleme açıkken sıfır örnekte
  **0,1071**. Aranan kazanç ölçünün kendi değişkenliğinden küçükse ölçüm yapılmamış sayılır.

#### Sonraki Adım

Bu iki derste isteme yazılan her şey **olumluydu**: şunu yap, şu biçimde yaz, şu örneklere bak.
Uygulamada istemlerin büyük bölümü bunun tersini de içerir — bir şeyin yapılmamasını söyleyen
cümleler. Bir etiketi kullanma, tarih verme, kesin konuşma, uydurma. Sezgi bu cümlelerin
zararsız olduğunu söyler: en kötü ihtimalle işe yaramaz. Sonraki ders bu sezginin sayısını alır ve
tersini bulur. Aynı kural iki ayrı biçimde yazılır — **yasak bildirimi** ve olumlu bildirim — ve
her ikisinin ürettiği **ihlal sayısı** yan yana basılır. Yasağın yasakladığı şeyi istemde adıyla
anmanın kendisinin bir bedeli vardır ve bu bedel sayıyla görünür.

### Kısıt ve Yasak Bildirimi

Source: https://academia.sh/tr/kurslar/istem-muhendisligi/kisit-ve-yasak-bildirimi

Aynı kural iki ayrı biçimde yazılıp 120 kurgu destek talebinde ölçülüyor. Hiçbir bildirim yokken ihlal oranı 0,2583; yasak bildirimi eklendiğinde 0,5333'e çıkıyor ve yasaklanan sözcüklerden birinin geçtiği yanıt sayısı 5'ten 35'e yükseliyor. Aynı kuralı olumlu bildiren istem ihlali 0,0167'ye indiriyor ve etiket isabetini 0,6667'den 0,8333'e çıkarıyor. İkisi birlikte yazıldığında ihlal 0,1583 oluyor: yasağı olumlu bildirime eklemek sayıyı yaklaşık on kat kötüleştiriyor. Bedel yan yana yazılıyor; olumlu bildirim önlenen ihlal başına 115,9 giriş belirteci tutuyor.

Önceki iki derste isteme yazılan her şey olumluydu: şunu yap, şu biçimde yaz, şu örneklere bak.
Uygulamada yazılan istemlerin büyük bölümü bunun tersini de içerir. Bir etiketi kullanma, tarih
verme, kesin konuşma, uydurma. Bu cümlelere **yasak bildirimi** denir ve sezgi onların en kötü
ihtimalle etkisiz kalacağını söyler: model uyarsa iyi, uymazsa hiçbir şey değişmez.

Bu ders o sezginin sayısını alır. Aynı kural iki ayrı biçimde yazılır — bir kez neyin
yapılmayacağı, bir kez neyin yapılacağı olarak — ve ikisinin ürettiği **ihlal sayısı** yan yana
konur. Ortaya çıkan sonuç bu kursun ikinci iddiasının ilk örneğidir: **bir istem eklentisi sayıyı
düşürmek yerine yükseltebilir** ve bunu ölçmeden anlamanın yolu yoktur.

- **IT54.** Model bir **benzeticidir**, tohumu **20260218**'dir ve gerçek bir uç nokta
  çağrılmaz. Destek talepleri, yanıt kalıpları ve kural kümesi **kurgudur**.
- **IT55.** Görev **kısa yanıt yazmadır**: model talebi bir etikete atar ve tek cümlelik bir yanıt
  üretir. Yanıt altı kurgu kalıptan biriyle kurulur.
- **IT56.** Kural kümesi üç sözcüktür: yanıtta `hemen`, `yarin` ve `genel` geçmemelidir. Bunlar
  kurgu bir yazım kılavuzunun karşılığıdır — söz verme, tarih verme, belirsiz etiket koyma.
- **IT57.** **İhlal ölçüsü** açıktır: yanıtta bu üç sözcükten biri geçiyorsa kayıt ihlallidir.
  Her sözcüğün kaç yanıtta geçtiği ayrıca sayılır.
- **IT58.** Benzetici yanıt kalıbını **istemde geçen belirteçlere** göre seçer. Her kalıbın kendi
  ayırt edici belirteçleri vardır ve bu belirteçler istemde geçtiğinde o kalıbın puanı yükselir.
  Model belirtecin **olumlu mu olumsuz mu** anıldığını ayırt etmez.
- **IT59.** Dört istem karşılaştırılır: bildirimsiz, yasak bildirimli, olumlu bildirimli ve
  ikisi birlikte. Görev tanımı, etiket kümesi ve talep kümesi dördünde de aynıdır.
- **IT60.** Bedel **giriş belirteciyle** yazılır ve ayrıca **önlenen ihlal başına** birim maliyet
  hesaplanır.

#### Aynı Kuralın İki Yazımı

```python
# BENZETICI -- KURGUDUR. Gercek bir model uc noktasi cagrilmaz; standart kitaplikla
# yazilmis bir dil modeli benzeticisidir. Talepler ve yanit kaliplari da kurgudur.
import math

TOHUM, M32 = 20260218, 0xFFFFFFFF
PENCERE, EN_UZUN = 240, 24


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):                  # KURGU belirtecleyici: parca en cok bes damga
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


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


KONU = ["fatura", "ariza", "sayac", "tarife", "kesinti"]
KALIP = {"fatura": ["bu ayki fatura tutari gecen aya gore cok yuksek geldi",
                    "faturami odedim ama sistemde borc gorunuyor",
                    "fatura ayrintisini nereden gorebilirim"],
         "ariza": ["evde su akmiyor bir ariza var galiba",
                   "baglanti bozuk oldu ve hic calismiyor",
                   "ariza kaydi actim ama ekip gelmedi"],
         "sayac": ["sayac okumasi yanlis girilmis endeks tutmuyor",
                   "sayac degisimi icin randevu istiyorum",
                   "sayac uzerindeki endeks ile fatura ayni degil"],
         "tarife": ["hangi tarife basamagindayim ogrenmek istiyorum",
                    "tarife degisikligi icin ne yapmam gerekiyor",
                    "birim ucret abone tipine gore degisiyor mu"],
         "kesinti": ["mahallede kesinti var ne zaman gelecek",
                     "planli kesinti duyurusu nereden takip edilir",
                     "aksamdan beri kesinti yasiyoruz"]}
EK = ["ayrica gecen ay da ayni sorun olmustu", "bu konuda memnun degilim",
      "acil bilgi almam gerekiyor", "kayit numaram elimde yok"]

TALEP = []
for i in range(120):
    r = uretec(TOHUM + i)
    k = KONU[ayrik(r(), [0.24, 0.22, 0.18, 0.20, 0.16])]
    m = KALIP[k][int(r() * 3)]
    if r() < 0.34:
        m += " " + EK[int(r() * 4)]
    TALEP.append({"no": 4001 + i, "metin": m, "konu": k})

KAVRAM = KONU + ["odeme", "sikayet", "bilgi", "genel"]
IZ = {"fatur": "fatura", "tutar": "fatura", "ayrin": "fatura", "ariza": "ariza",
      "bozuk": "ariza", "calis": "ariza", "akmiy": "ariza", "sayac": "sayac",
      "endek": "sayac", "okuma": "sayac", "tarif": "tarife", "birim": "tarife",
      "abone": "tarife", "basam": "tarife", "kesin": "kesinti", "duyur": "kesinti",
      "mahal": "kesinti", "borc": "odeme", "odedi": "odeme", "ucret": "odeme",
      "memnu": "sikayet", "sorun": "sikayet", "acil": "sikayet", "bilgi": "bilgi",
      "ogren": "bilgi", "nered": "bilgi"}
TUZAK = {"degis": "tarife", "kayit": "ariza", "yukse": "tarife", "gorun": "fatura",
         "ekip": "kesinti", "takip": "tarife", "giril": "fatura"}
SAYAC = [0]

# KURGU kural kumesi: yanitta gecmemesi gereken uc sozcuk.
YASAKLI = ["hemen", "yarin", "genel"]
# Her yanit kalibi bir taban agirlik ve kendi ayirt edici belirtecleriyle gelir.
YANIT = [("kaydiniz {k} konusunda acildi , inceleme suruyor", 1.2, ["incel", "acild"]),
         ("{k} talebiniz ilgili ekibe yonlendirildi", 1.1, ["ilgil", "ekibe"]),
         ("bu {k} kaydi hemen ele alinacak", 0.5, ["hemen"]),
         ("{k} kaydiniz yarin sonuclandirilacak", 0.4, ["yarin"]),
         ("talebiniz genel bir basvuru olarak alindi", 0.3, ["genel", "basvu"]),
         ("{k} kaydiniz durumu inceleniyor", 1.0, ["durum", "incel"])]


def cagir(istem, tohum=TOHUM, sicaklik=0.6, en_uzun=EN_UZUN):
    SAYAC[0] += 1
    bel = belirtecle(istem)
    bos = {"giris": len(bel), "cikis": 0, "yanit": "", "kalip": -1}
    if len(bel) > PENCERE:
        return dict(bos, durum="baglam_asimi")
    if SAYAC[0] % 37 == 0:
        return dict(bos, durum="hiz_siniri")
    r = uretec(tohum ^ izno(istem))
    aday = [k for k in KAVRAM if k[:5] in bel]
    if len(aday) < 3:
        aday = KAVRAM
    p = {k: 0.15 for k in aday}
    for t in bel:
        for tablo, w in ((IZ, 1.0), (TUZAK, 1.3)):
            if tablo.get(t) in p:
                p[tablo[t]] += w
    e = [math.exp(p[a] / sicaklik) for a in sorted(p)]
    k = sorted(p)[ayrik(r(), [v / sum(e) for v in e])]
    # Kalip puani: taban agirlik + kalibin belirteclerinin istemde gecme sayisi.
    puan = [t + 0.85 * sum(a in bel for a in an) for _, t, an in YANIT]
    q = [math.exp(x / sicaklik) for x in puan]
    i = ayrik(r(), [x / sum(q) for x in q])
    y = YANIT[i][0].format(k=k)
    cb = belirtecle(y)
    if len(cb) > en_uzun:
        cb, y = cb[:en_uzun], " ".join(cb[:en_uzun])
    return {"durum": "tamam", "giris": len(bel), "cikis": len(cb),
            "yanit": y, "kalip": i}


def oku(y):
    for s in y.lower().split():
        if s in KONU:
            return s
    return None


GOREV = ("Talebi su etiketlerden birine ata ve kisa bir yanit yaz : fatura , ariza , "
         "sayac , tarife , kesinti . Talep : ")
YASAK = "Yanitinda su sozcukleri kullanma : hemen , yarin , genel . "
OLUMLU = ("Yanitinda yalnizca sunlar olsun : kaydin acildigi , ilgili ekibe "
          "yonlendirildigi ve durumun inceleniyor olmasi . ")
DURUM = (("bildirimsiz", ""), ("yasak bildirimi", YASAK),
         ("olumlu bildirim", OLUMLU), ("yasak + olumlu", YASAK + OLUMLU))


def olc(onek, tohum=TOHUM):
    SAYAC[0] = 0
    d = {"ihlal": 0, "etiketli": 0, "isabet": 0, "giris": 0, "cikis": 0}
    sayim, kalip = {w: 0 for w in YASAKLI}, [0] * len(YANIT)
    for x in TALEP:
        s = cagir(onek + GOREV + x["metin"], tohum=tohum)
        d["giris"], d["cikis"] = d["giris"] + s["giris"], d["cikis"] + s["cikis"]
        if s["kalip"] >= 0:
            kalip[s["kalip"]] += 1
        gecen = [w for w in YASAKLI if w in s["yanit"].split()]
        for w in gecen:
            sayim[w] += 1
        d["ihlal"] += bool(gecen)
        d["etiketli"] += oku(s["yanit"]) is not None
        d["isabet"] += oku(s["yanit"]) == x["konu"]
    for a in ("ihlal", "etiketli", "isabet"):
        d[a] /= len(TALEP)
    return dict(d, sayim=sayim, kalip=kalip, cagri=SAYAC[0])


print(f"KURGU: {len(TALEP)} destek talebi , yasakli sozcukler {YASAKLI}")
print(f"\n{'istem':<17}{'ihlal':>8}{'etiketli':>10}{'isabet':>9}{'giris':>8}"
      f"{'hemen':>7}{'yarin':>7}{'genel':>7}")
O = {}
for ad, onek in DURUM:
    d = O[ad] = olc(onek)
    print(f"{ad:<17}{d['ihlal']:>8.4f}{d['etiketli']:>10.4f}{d['isabet']:>9.4f}"
          f"{d['giris']:>8}" + "".join(f"{d['sayim'][w]:>7}" for w in YASAKLI))
```

```
KURGU: 120 destek talebi , yasakli sozcukler ['hemen', 'yarin', 'genel']

istem               ihlal  etiketli   isabet   giris  hemen  yarin  genel
bildirimsiz        0.2583    0.9000   0.6667    5060      5     17      9
yasak bildirimi    0.5333    0.8583   0.5750    6740     35     16     13
olumlu bildirim    0.0167    0.9667   0.8333    8420      1      0      1
yasak + olumlu     0.1583    0.9417   0.6500   10100     12      3      4
```

Birinci satır taban çizgisidir: hiçbir bildirim yokken yanıtların **0,2583** payı yasaklanan
sözcüklerden birini taşıyor. İkinci satır bu dersin sayısıdır. Yasak bildirimi eklendiğinde ihlal
oranı **0,5333** oluyor, yani **iki katından fazla**. Yasağı yazmak, yasaklanan şeyi
yasaklamıyor; iki misline çıkarıyor. Sağdaki üç sütun artışın nerede toplandığını gösteriyor:
`hemen` sözcüğünü taşıyan yanıt sayısı **5'ten 35'e** çıkıyor, `genel` 9'dan 13'e çıkıyor,
`yarin` 17'den 16'ya iniyor. Artış eşit dağılmıyor ve tek düşüş bir birimlik.

Üçüncü satır aynı kuralın olumlu yazımıdır. İstem hangi sözcüklerin yasak olduğunu hiç anmaz;
bunun yerine yanıtta **neyin bulunacağını** söyler. İhlal oranı **0,0167** oluyor, taban çizgisinin
on beşte biri. Yan etki de olumlu yöndedir: etiketi okunabilen yanıt oranı 0,9000'dan
**0,9667**'ye, etiket isabeti 0,6667'den **0,8333**'e çıkıyor. Aynı kural, aynı model, aynı görev
ve aynı küme; değişen tek şey kuralın cümlesi.

Dördüncü satır uygulamada en sık görülen yazımdır: önce ne isteniyorsa söylenir, sonra "şunları
da yapma" diye eklenir. İhlal oranı **0,1583** oluyor — olumlu bildirimin tek başına verdiği
0,0167'nin yaklaşık **on katı**. Yasak cümlesi olumlu bir istemin yanına eklendiğinde de kendi
zararını taşıyor. Etiket isabeti de 0,8333'ten 0,6500'e geri düşüyor.

#### Yasağın Niçin Ters Çalıştığı

```python
print("kalip                          bildirimsiz  yasak  olumlu  ikisi")
for i, (metin, _, an) in enumerate(YANIT):
    isim = ("yasakli: " + [w for w in YASAKLI if w in metin][0]) if any(
        w in metin for w in YASAKLI) else "uygun: " + an[0]
    print(f"{isim:<30}" + "".join(f"{O[ad]['kalip'][i]:>7}" for ad, _ in DURUM))

print("\nartisin kosumdan bagimsizligi")
for th in (TOHUM, TOHUM + 1, TOHUM + 2):
    v = [olc(onek, tohum=th)["ihlal"] for _, onek in DURUM]
    print(f"  tohum {th}: " + " ".join(f"{x:.4f}" for x in v))
i0 = [olc(onek)["ihlal"] for _, onek in DURUM]
i1 = [olc(onek, tohum=TOHUM + 1)["ihlal"] for _, onek in DURUM]
print("  iki kosum farki: " + " ".join(f"{abs(a - b):.4f}" for a, b in zip(i0, i1)))

n = len(TALEP)
taban = O["bildirimsiz"]
print("\nbedel")
for ad, _ in DURUM[1:]:
    d, fark = O[ad], round((O[ad]["ihlal"] - taban["ihlal"]) * n)
    ek = d["giris"] - taban["giris"]
    birim = f"{ek / abs(fark):.1f}" if fark else "-"
    print(f"  {ad:<16} ihlal {round(taban['ihlal'] * n):>3} -> {round(d['ihlal'] * n):>3}"
          f" ({fark:+d}) , giris belirteci {ek:+d} , ihlal basina {birim}")
```

```
kalip                          bildirimsiz  yasak  olumlu  ikisi
uygun: incel                       39     18     19     52
uygun: ilgil                       26     16     77     23
yasakli: hemen                      5     35      1     12
yasakli: yarin                     17     16      0      3
yasakli: genel                      9     13      1      4
uygun: durum                       21     19     19     23

artisin kosumdan bagimsizligi
  tohum 20260218: 0.2583 0.5333 0.0167 0.1583
  tohum 20260219: 0.2750 0.4167 0.0000 0.1167
  tohum 20260220: 0.3833 0.4917 0.0083 0.1167
  iki kosum farki: 0.0167 0.1167 0.0167 0.0417

bedel
  yasak bildirimi  ihlal  31 ->  64 (+33) , giris belirteci +1680 , ihlal basina 50.9
  olumlu bildirim  ihlal  31 ->   2 (-29) , giris belirteci +3360 , ihlal basina 115.9
  yasak + olumlu   ihlal  31 ->  19 (-12) , giris belirteci +5040 , ihlal basina 420.0
```

Üstteki çizelge mekanizmayı açık ediyor. Bildirimsiz istemde `hemen` kalıbı 5 kez seçiliyor;
yasak bildirimli istemde **35 kez**. Yasak cümlesi bu kalıbın metnindeki belirteci istemin içine
yazdı ve benzetici o belirteci **istemde gördüğü bir sözcük** olarak işledi. Model bir sözcüğün
"kullanma" ile birlikte mi yoksa "kullan" ile birlikte mi anıldığını ayırt etmiyor; gördüğü şey
sözcüğün **orada olmasıdır**. Olumlu bildirim aynı mekanizmayı ters yönde kullanıyor: `ilgil`
belirteçli uygun kalıp 26'dan **77'ye** çıkıyor, çünkü istemde geçen sözcükler bu kez uygun
kalıbın sözcükleri.

Orta bölüm farkın koşumdan bağımsız olup olmadığını sınıyor. Üç tohumda da sıralama aynı: yasak
bildirimi tabanın üstünde, olumlu bildirim tabanın çok altında. İki koşum arasındaki fark
bildirimsiz istemde **0,0167**, olumlu bildirimde **0,0167**, yasak bildiriminde **0,1167**.
Yasak bildiriminin kattığı **+0,2750**, kendi koşum farkının iki katından büyüktür ve ölçülmüş
sayılır. Olumlu bildirimin kattığı **−0,2416**, koşum farkının on dört katıdır ve tartışmasızdır.
Yasak bildiriminin koşum farkının öbür ikisinden yedi kat büyük olması ayrıca bir bulgudur:
yasak, sonucu yalnız kötüleştirmiyor, **daha kararsız** da yapıyor.

Alt bölüm bedeli veriyor. Yasak bildirimi 1680 giriş belirteci ekliyor ve ihlal sayısını 31'den
64'e çıkarıyor; eklenen her belirteç sayıyı yanlış yöne itiyor. Olumlu bildirim 3360 giriş
belirteci ekliyor ve ihlali 31'den 2'ye indiriyor: **önlenen ihlal başına 115,9 giriş belirteci**.
Yasağı olumluya eklemek 5040 belirteç harcayıp yalnız 12 ihlal önlüyor, yani önlenen ihlal başına
**420,0 belirteç** — aynı işi önlenen ihlal başına 115,9 belirteçle yapan bir istem varken.
İki katı belirteç
harcayan istem burada doğru istemdir ve bunu ancak ikisini de koşturup sayarak söylemek mümkün.
**Ölçülmeden değiştirilen istem bir iyileştirme değil bir tahmindir**; bu derste tahmin, sayının
tersi yönde çıktı.

#### Özet

- Aynı kural iki ayrı yazımla ölçüldü. Bildirimsiz istemde ihlal oranı **0,2583**, yasak
  bildirimli istemde **0,5333**: yasağı yazmak ihlali iki katından fazlaya çıkardı.
- Artış yasaklanan sözcüklerde toplanıyor: `hemen` taşıyan yanıt sayısı **5'ten 35'e**, `genel` 9'dan
  13'e çıkıyor; `yarin` yalnız bir birim geriliyor.
- Olumlu bildirim aynı kuralı hiçbir yasaklı sözcüğü anmadan kuruyor ve ihlali **0,0167**'ye
  indiriyor; etiket isabeti de 0,6667'den **0,8333**'e çıkıyor.
- İkisi birlikte yazıldığında ihlal **0,1583** oluyor, yani olumlu bildirimin tek başına verdiğinin
  yaklaşık on katı. Yasak cümlesi olumlu bir istemin içinde de kendi zararını taşıyor.
- Bedel: yasak bildirimi **+1680** giriş belirteciyle 33 ihlal ekliyor, olumlu bildirim **+3360**
  giriş belirteciyle 29 ihlal önlüyor (**önlenen ihlal başına 115,9 belirteç**), ikisi birlikte
  **+5040** belirteçle yalnız 12 ihlal önlüyor.

#### Sonraki Adım

Dört derste dört ayrı tasarım kararı ölçüldü ve her biri tek başına, bir defada denendi. Gerçek
bir istem böyle yazılmaz. Bir istem yazılır, ölçülür, bir yeri değiştirilir, yeniden ölçülür ve
bu döngü sayı iyileşmez olana kadar sürer. Sonraki ders bu döngünün kendisini ölçü altına alır:
kaç yinelemede kazanç doyuyor ve daha rahatsız edici olan soru, yineleme boyunca bakılan kümenin
sayısı ile hiç bakılmayan bir kümenin sayısı **birbirinden ne zaman ayrılmaya başlıyor**. Bu ders
aynı zamanda konunun kapanışıdır ve sekiz dersin toplamını bir soruyla bağlar.

### İstem Yinelemesi

Source: https://academia.sh/tr/kurslar/istem-muhendisligi/istem-yinelemesi

Ölçerek iyileştirme döngüsünün kendisi ölçü altına alınıyor. On aday değişiklik 30 kayıtlık bir doğrulama kümesinde sekiz yineleme boyunca aç gözlü aranıyor: doğrulama isabeti 0,4000'den 1,0000'a çıkıyor ve beşinci yinelemede tavana vuruyor, sınama isabeti aynı noktada 0,9333 ile en yükseğine ulaşıp sekizinci yinelemede 0,8111'e iniyor. Doğrulamadaki iki koşum farkının ortalaması 0,1037, adım kazancının ortalaması 0,0625: sekiz yinelemenin yalnızca ikisi kendi ölçüm gürültüsünden büyük. Arama başka bir koşumda tekrarlandığında sekiz adımın yalnız biri aynı yerde aynı değişikliği seçiyor. Bedel 2640 çağrıdır ve seçilen sekiz değişiklikten üçü görevle ilgisizdir.

Önceki dört derste dört tasarım kararı ölçüldü ve her biri tek başına, bir defada denendi. Gerçek
bir istem böyle yazılmaz. Bir istem yazılır, ölçülür, bir yeri değiştirilir, yeniden ölçülür; bu
döngü sayı iyileşmez olana kadar sürer. Döngünün adı **istem yinelemesidir** ve bu ders döngünün
kendisini ölçü altına alır.

Ölçü altına almak, önceki müfredatın Makine Öğrenmesine Giriş kursunda kurulmuş bir ayrımı buraya
taşımak demektir: bir sayıya **bakarak** karar veriyorsan, o sayı artık senin karar verdiğin
kümenin sayısıdır ve genel başarımı temsil etmez. Orada bu ayrım eğitim, doğrulama ve sınama
kümesiyle kuruldu. Burada model eğitilmiyor, **istem aranıyor**; ama ayrım aynı ayrımdır. Her
yinelemede bakılan küme **doğrulama**, hiç bakılmayan küme **sınamadır**.

- **IT61.** Model bir **benzeticidir**, tohumu **20260218**'dir ve gerçek bir uç nokta
  çağrılmaz. Destek talepleri **kurgudur**.
- **IT62.** 120 kurgu talep ikiye ayrılır: **30 kayıt doğrulama**, **90 kayıt sınama**. Arama
  yalnız doğrulamayı görür; sınama hiçbir karara girmez.
- **IT63.** On **aday değişiklik** vardır. Beşi görevle ilgilidir (etiket kümesi, biçim kısıtı,
  iki örnek, iki örnek daha, olumlu bildirim), beşi ilgisizdir (nazik giriş, kısa yaz, teşekkür,
  not satırı, okuyucu notu). İlgisiz olanlar istemin **yalnız metnini** değiştirir.
- **IT64.** Arama **aç gözlüdür**: her yinelemede kalan bütün adaylar doğrulamada denenir, en iyi
  sayıyı veren seçilir ve isteme kalıcı olarak eklenir.
- **IT65.** Bedel **çağrı sayısıyla** yazılır. Denenen her aday, doğrulama kümesi büyüklüğü kadar
  çağrı harcar ve bu çağrılar geri alınamaz.

#### Sekiz Yinelemenin İki Sayısı

```python
# BENZETICI -- KURGUDUR. Gercek bir model uc noktasi cagrilmaz; standart kitaplikla
# yazilmis bir dil modeli benzeticisidir. Talepler de kurgudur.
import math

TOHUM, M32 = 20260218, 0xFFFFFFFF
PENCERE, EN_UZUN = 240, 24


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):                  # KURGU belirtecleyici: parca en cok bes damga
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


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


KONU = ["fatura", "ariza", "sayac", "tarife", "kesinti"]
KALIP = {"fatura": ["bu ayki fatura tutari gecen aya gore cok yuksek geldi",
                    "faturami odedim ama sistemde borc gorunuyor",
                    "fatura ayrintisini nereden gorebilirim"],
         "ariza": ["evde su akmiyor bir ariza var galiba",
                   "baglanti bozuk oldu ve hic calismiyor",
                   "ariza kaydi actim ama ekip gelmedi"],
         "sayac": ["sayac okumasi yanlis girilmis endeks tutmuyor",
                   "sayac degisimi icin randevu istiyorum",
                   "sayac uzerindeki endeks ile fatura ayni degil"],
         "tarife": ["hangi tarife basamagindayim ogrenmek istiyorum",
                    "tarife degisikligi icin ne yapmam gerekiyor",
                    "birim ucret abone tipine gore degisiyor mu"],
         "kesinti": ["mahallede kesinti var ne zaman gelecek",
                     "planli kesinti duyurusu nereden takip edilir",
                     "aksamdan beri kesinti yasiyoruz"]}
EK = ["ayrica gecen ay da ayni sorun olmustu", "bu konuda memnun degilim",
      "acil bilgi almam gerekiyor", "kayit numaram elimde yok"]

TALEP = []
for i in range(120):
    r = uretec(TOHUM + i)
    k = KONU[ayrik(r(), [0.24, 0.22, 0.18, 0.20, 0.16])]
    m = KALIP[k][int(r() * 3)]
    if r() < 0.34:
        m += " " + EK[int(r() * 4)]
    TALEP.append({"no": 4001 + i, "metin": m, "konu": k})

KAVRAM = KONU + ["odeme", "sikayet", "bilgi", "genel"]
IZ = {"fatur": "fatura", "tutar": "fatura", "ayrin": "fatura", "ariza": "ariza",
      "bozuk": "ariza", "calis": "ariza", "akmiy": "ariza", "sayac": "sayac",
      "endek": "sayac", "okuma": "sayac", "tarif": "tarife", "birim": "tarife",
      "abone": "tarife", "basam": "tarife", "kesin": "kesinti", "duyur": "kesinti",
      "mahal": "kesinti", "borc": "odeme", "odedi": "odeme", "ucret": "odeme",
      "memnu": "sikayet", "sorun": "sikayet", "acil": "sikayet", "bilgi": "bilgi",
      "ogren": "bilgi", "nered": "bilgi"}
TUZAK = {"degis": "tarife", "kayit": "ariza", "yukse": "tarife", "gorun": "fatura",
         "ekip": "kesinti", "takip": "tarife", "giril": "fatura"}
SERBEST = ["talebiniz {k} konusuyla ilgili gorunuyor",
           "bu kayit {k} basligina girer , ilgili ekibe yonlendirildi",
           "kaydiniz alindi , konuyu inceleyip donus yapacagiz"]
SAYAC = [0]


def coz(istem):
    ust, _, talep = istem.partition("Talep : ")
    o = []
    for parca in ust.split("Ornek : ")[1:]:
        m, _, e = parca.partition(" => ")
        o.append((m.strip(), e.split(" .")[0].strip()))
    return o, talep


def cagir(istem, tohum=TOHUM, sicaklik=0.6, en_uzun=EN_UZUN):
    SAYAC[0] += 1
    bel = belirtecle(istem)
    bos = {"giris": len(bel), "cikis": 0, "yanit": ""}
    if len(bel) > PENCERE:
        return dict(bos, durum="baglam_asimi")
    if SAYAC[0] % 37 == 0:
        return dict(bos, durum="hiz_siniri")
    r = uretec(tohum ^ izno(istem))
    ornek, talep = coz(istem)
    bt = belirtecle(talep)
    aday = [k for k in KAVRAM if k[:5] in bel]
    if len(aday) < 3:
        aday = KAVRAM
    p = {k: 0.15 for k in aday}
    for t in bt:
        for tablo, w in ((IZ, 1.0), (TUZAK, 1.3)):
            if tablo.get(t) in p:
                p[tablo[t]] += w
    for j, (m, e) in enumerate(ornek):
        if e in p:
            w = 0.5 + (j + 1) / len(ornek)
            for t in set(belirtecle(m)):
                if t in bt:
                    p[e] += 0.30 * w
    e = [math.exp(p[a] / sicaklik) for a in sorted(p)]
    k = sorted(p)[ayrik(r(), [v / sum(e) for v in e])]
    y = (f"etiket : {k}" if "bicim" in bel
         else SERBEST[ayrik(r(), [0.42, 0.26, 0.32])].format(k=k))
    cb = belirtecle(y)
    if len(cb) > en_uzun:
        cb, y = cb[:en_uzun], " ".join(cb[:en_uzun])
    return {"durum": "tamam", "giris": len(bel), "cikis": len(cb), "yanit": y}


def oku(y):
    for s in y.lower().split():
        if s in KONU:
            return s
    return None


DOGRULAMA, SINAMA = TALEP[:30], TALEP[30:]      # 30 dogrulama , 90 sinama
TABAN = "Su destek talebini yanitla . "
DEGISIKLIK = [
    ("etiket kumesi", "Talebi su etiketlerden birine ata : fatura , ariza , sayac , "
                      "tarife , kesinti . "),
    ("bicim kisiti", "Yanitin bicimi : etiket : <deger> . "),
    ("iki ornek", "Ornek : fatura ayrintisini nereden gorebilirim => fatura . "
                  "Ornek : ariza kaydi actim ama ekip gelmedi => ariza . "),
    ("iki ornek daha", "Ornek : sayac okumasi yanlis girilmis endeks tutmuyor => sayac . "
                       "Ornek : hangi tarife basamagindayim ogrenmek istiyorum => tarife . "),
    ("olumlu bildirim", "Yanitinda yalnizca konu etiketi olsun . "),
    ("nazik giris", "Lutfen dikkatli davran . "),
    ("kisa yaz", "Yanitini kisa tut . "),
    ("tesekkur", "Tesekkurler . "),
    ("not satiri", "Not : kayit sistemine islenecek . "),
    ("okuyucu notu", "Yanit destek ekibi tarafindan okunacak . "),
]


def olc(parcalar, kume, tohum=TOHUM):
    SAYAC[0] = 0
    d = 0
    for x in kume:
        s = cagir(TABAN + "".join(parcalar) + "Talep : " + x["metin"], tohum=tohum)
        d += oku(s["yanit"]) == x["konu"]
    return d / len(kume), SAYAC[0]


def ara(tohum, adim=8):
    """Her yinelemede butun adaylari DOGRULAMA uzerinde dener, en iyisini secer."""
    secili, kalan, cagri, iz = [], list(DEGISIKLIK), 0, []
    for _ in range(adim):
        en, ad = None, None
        for a, parca in kalan:
            v, c = olc(secili + [parca], DOGRULAMA, tohum)
            cagri += c
            if en is None or v > en:
                en, ad = v, (a, parca)
        secili.append(ad[1])
        kalan = [x for x in kalan if x[0] != ad[0]]
        dv, c1 = olc(secili, DOGRULAMA, tohum)
        sv, c2 = olc(secili, SINAMA, tohum)
        cagri += c1 + c2
        iz.append((ad[0], dv, sv, cagri))
    return iz


d0, c0 = olc([], DOGRULAMA)
s0, c1 = olc([], SINAMA)
print("yineleme  secilen degisiklik    dogrulama  sinama  ayrisma  toplam cagri")
print(f"{0:>8}  {'-':<20}  {d0:>9.4f}  {s0:.4f}  {d0 - s0:+.4f}  {c0 + c1:>12}")
IZLEK = ara(TOHUM)
for i, (ad, dv, sv, cg) in enumerate(IZLEK, 1):
    print(f"{i:>8}  {ad:<20}  {dv:>9.4f}  {sv:.4f}  {dv - sv:+.4f}  {cg + c0 + c1:>12}")
```

```
yineleme  secilen degisiklik    dogrulama  sinama  ayrisma  toplam cagri
       0  -                        0.4000  0.3778  +0.0222           120
       1  not satiri               0.7000  0.5889  +0.1111           540
       2  bicim kisiti             0.8000  0.5889  +0.2111           930
       3  iki ornek                0.8333  0.8556  -0.0222          1290
       4  etiket kumesi            0.9667  0.8556  +0.1111          1620
       5  olumlu bildirim          1.0000  0.9333  +0.0667          1920
       6  kisa yaz                 0.9667  0.9111  +0.0556          2190
       7  iki ornek daha           0.9667  0.8667  +0.1000          2430
       8  tesekkur                 0.9000  0.8111  +0.0889          2640
```

Doğrulama sütunu bir arama kaydının olağan görüntüsüdür: **0,4000'den 1,0000'a**, beşinci
yinelemeye kadar kesintisiz yükseliş. Bu sütuna bakan biri aramanın istemi tam isabetli hâle
getirdiğini söyler.
Sınama sütunu aynı hikâyeyi anlatmıyor. En yüksek sınama sayısı **0,9333** ve beşinci yinelemede
geliyor; sonraki üç yineleme onu **0,8111**'e indiriyor. Beşinci yinelemeden sonra yapılan her
değişiklik doğrulamayı korumak için seçildi ve sınamada zarar verdi.

Ayrışma sütunu iki kümenin arasındaki farkı taşıyor. Başlangıçta **+0,0222**, yani iki küme
neredeyse aynı şeyi söylüyor. İkinci yinelemede **+0,2111**'e çıkıyor: doğrulama 0,8000 derken
sınama hâlâ 0,5889. Bu noktada doğrulamaya bakarak verilen her karar, kendisiyle ilgisi olmayan
bir küme hakkında konuşuyor. Ayrışmanın kaynağı kümenin küçüklüğüdür — otuz kayıtta bir kaydın
düzelmesi sayıyı 0,0333 oynatır ve üç kaydın rastgele düzelmesi bir iyileştirme gibi görünür.

Birinci satır bunun en açık örneğidir. Aramanın ilk seçtiği değişiklik **not satırıdır**: göreve
hiçbir bilgi eklemeyen, etiket kümesinden, biçimden ve örnekten söz etmeyen bir cümle.
Doğrulamada **+0,3000** getirdi ve bütün arama boyunca ölçülen en büyük tek adım kazancı oldu.
Sekiz değişiklikten üçü bu türdendir. Aç gözlü arama, sayıyı yükselten şeyi seçer; sayıyı niçin
yükselttiğini sormaz.

#### Aramanın Kendi Güvenilirliği

```python
IKINCI = ara(TOHUM + 1)
print("ayni arama , baska kosum")
for i, ((a1, *_), (a2, d2, s2, _)) in enumerate(zip(IZLEK, IKINCI), 1):
    print(f"{i:>2}  {a1:<18} -> {a2:<18} dogrulama {d2:.4f}  sinama {s2:.4f}")
print(f"iki aramanin ayni sirada sectigi degisiklik: "
      f"{sum(a == b for (a, *_), (b, *_) in zip(IZLEK, IKINCI))}/8")

sec, fd, fs = [], [], []
for ad, *_ in [(None,)] + IZLEK:
    if ad:
        sec.append(dict(DEGISIKLIK)[ad])
    fd.append(abs(olc(sec, DOGRULAMA)[0] - olc(sec, DOGRULAMA, TOHUM + 1)[0]))
    fs.append(abs(olc(sec, SINAMA)[0] - olc(sec, SINAMA, TOHUM + 1)[0]))
gd = sum(fd) / len(fd)
print(f"\niki kosum farki -- dogrulama (30 kayit) ortalama {gd:.4f} , en buyuk {max(fd):.4f}")
print(f"iki kosum farki -- sinama (90 kayit) ortalama {sum(fs) / len(fs):.4f} ,"
      f" en buyuk {max(fs):.4f}")

dv, sv = [d0] + [x[1] for x in IZLEK], [s0] + [x[2] for x in IZLEK]
adim = [dv[i] - dv[i - 1] for i in range(1, 9)]
print(f"adim kazanci iki kosum farkindan buyuk olan yineleme: "
      f"{sum(x > gd for x in adim)}/8 , adim kazanci ortalamasi {sum(adim) / 8:+.4f}")
print(f"\ndogrulama en yuksek {max(dv):.4f} ({dv.index(max(dv))}. yineleme) ,"
      f" sinama en yuksek {max(sv):.4f} ({sv.index(max(sv))}. yineleme)")
print(f"5 -> 8 : dogrulama {dv[5]:.4f} -> {dv[8]:.4f} , sinama {sv[5]:.4f} -> {sv[8]:.4f}")
print(f"ayrisma en buyuk {max(d - s for d, s in zip(dv, sv)):+.4f} , 8. yinelemede "
      f"{dv[8] - sv[8]:+.4f}")
ilgisiz = ("nazik giris", "kisa yaz", "tesekkur", "not satiri", "okuyucu notu")
print(f"arama bedeli {IZLEK[-1][3] + c0 + c1} cagri , secilen sekiz degisiklikten "
      f"{sum(a in ilgisiz for a, *_ in IZLEK)} tanesi gorevle ilgisiz")
```

```
ayni arama , baska kosum
 1  not satiri         -> kisa yaz           dogrulama 0.7000  sinama 0.5667
 2  bicim kisiti       -> etiket kumesi      dogrulama 0.6333  sinama 0.4444
 3  iki ornek          -> bicim kisiti       dogrulama 0.7667  sinama 0.7333
 4  etiket kumesi      -> iki ornek          dogrulama 0.9667  sinama 0.8778
 5  olumlu bildirim    -> nazik giris        dogrulama 0.9667  sinama 0.9111
 6  kisa yaz           -> not satiri         dogrulama 0.8667  sinama 0.7111
 7  iki ornek daha     -> iki ornek daha     dogrulama 0.9000  sinama 0.8889
 8  tesekkur           -> okuyucu notu       dogrulama 0.9333  sinama 0.8333
iki aramanin ayni sirada sectigi degisiklik: 1/8

iki kosum farki -- dogrulama (30 kayit) ortalama 0.1037 , en buyuk 0.1667
iki kosum farki -- sinama (90 kayit) ortalama 0.0728 , en buyuk 0.1778
adim kazanci iki kosum farkindan buyuk olan yineleme: 2/8 , adim kazanci ortalamasi +0.0625

dogrulama en yuksek 1.0000 (5. yineleme) , sinama en yuksek 0.9333 (5. yineleme)
5 -> 8 : dogrulama 1.0000 -> 0.9000 , sinama 0.9333 -> 0.8111
ayrisma en buyuk +0.2111 , 8. yinelemede +0.0889
arama bedeli 2640 cagri , secilen sekiz degisiklikten 3 tanesi gorevle ilgisiz
```

Üstteki çizelge aramayı **aynı düzenekte, yalnız tohumu değiştirerek** yeniden koşturuyor. Sekiz
adımın **yalnız biri** aynı yerde aynı değişikliği seçiyor. İkinci koşum ilk adımda "kısa yaz"ı,
ikinci adımda etiket kümesini seçiyor ve beşinci adımda "nazik giriş"e ulaşıyor. İki arama iki
ayrı istem üretti; ikisi de kendi doğrulama kümesinde iyi görünüyor ve ikisi de aynı düzeneğin
ürünü. **Arama, aradığı şeyi değil, koşumu buluyor.**

Alt bölüm bunun sayısını veriyor. Doğrulama kümesinde aynı istemin iki koşumu arasındaki fark
ortalama **0,1037**, en büyüğü 0,1667. Aramanın adım başına ortalama kazancı **+0,0625**. Sekiz
yinelemenin **yalnız ikisinde** adım kazancı kendi ölçüm gürültüsünden büyük; kalan altı adım,
kursun kuralına göre **ölçülmemiş** sayılır ve buna rağmen isteme kalıcı olarak eklendiler.
Sınama kümesinde aynı fark ortalama **0,0728**, yani üç kat büyük bir kümede ölçü gözle görülür
biçimde daha durgun. Küçük doğrulama kümesi hem daha ucuzdur hem de aramanın kovalayacağı
gürültüyü kendisi üretir.

Doyma noktası **beşinci yinelemedir**: doğrulama orada 1,0000'a vurur ve daha yükselemez, sınama
da orada en yüksek değerini alır. Sonraki üç yineleme **720 ek çağrı** harcayıp doğrulamayı
0,9000'a, sınamayı 0,9333'ten 0,8111'e indiriyor. Aramanın toplam bedeli **2640 çağrıdır** ve bu
çağrıların büyük bölümü seçilmeyen adaylara gitti. Bir istem araması, bir ayar aramasıyla aynı
yasaya tabidir:
bütçe büyüdükçe doğrulamadaki kazanç sınamaya taşınmaz. **Ölçülmeden değiştirilen istem bir
iyileştirme değil bir tahmindir**; ölçülen küme yanlışsa, ölçmek de tahmin etmektir.

#### Özet

- Aç gözlü arama doğrulama isabetini **0,4000'den** beşinci yinelemede **1,0000'a** çıkardı ve
  sekizincide 0,9000'a geriletti; sınama isabeti aynı sürede **0,3778'den** en yüksek
  **0,9333**'e çıkıp **0,8111**'e indi.
- Kazanç **beşinci yinelemede doydu**. Sonraki üç yineleme 720 ek çağrı harcayıp sınamayı 0,1222
  düşürdü; iki küme arasındaki ayrışma en büyük değerini ikinci yinelemede **+0,2111** olarak aldı.
- Aramanın ilk ve en büyük adımı (**+0,3000**) görevle ilgisiz bir cümleden geldi; seçilen sekiz
  değişiklikten **üçü** göreve hiçbir bilgi eklemiyor.
- Doğrulamada iki koşum farkı ortalama **0,1037**, adım kazancı ortalama **+0,0625**: sekiz
  yinelemenin yalnız **ikisi** kendi ölçüm gürültüsünden büyük. Sınamada aynı fark **0,0728**.
- Aynı arama başka bir tohumla koşturulduğunda sekiz adımın **yalnız biri** aynı yerde aynı
  değişikliği seçiyor; toplam bedel **2640 çağrıdır**.

#### Sonraki Adım

Sekiz derste istem bir tasarım nesnesine dönüştü. Bileşenlerine ayrıldı, kalıcı bir yönerge
kazandı, rol ve talep düzeyinde açıldı, biçimi ve uzunluğu belirlendi, örnek aldı, kuralları
olumlu yazıldı ve ölçülerek yinelendi. Her adımda değişen tek şey **metin** oldu ve her adımın
bedeli belirteçle, çağrıyla ya da ihlalle yazıldı. Ortak yanları da açıktır: hepsi modele **ne
söyleneceğini** düzenledi.

Hiçbiri modele **nasıl düşüneceğini** sormadı. Bu sekiz derste model her talebe tek bir hamlede
yanıt verdi: istemi aldı, bir etiket seçti, bir cümle yazdı. Arada bir adım yoktu. Oysa iki
fatura döneminin farkını hesaplayıp hangi tarifeye göre fazla ödendiğini bulmak gibi bir talep
tek hamlede çözülecek bir şey değildir; birkaç ara adım ister ve o adımların modelin kendisi
tarafından üretilmesi gerekir. Sonraki konu bunu ele alır ve ilk dersinde kursun ikinci iddiasını
kurar: ara adım istemek **belirteci katlar** ve her görevde kazandırmaz. Aynı teknik çok adımlı
bir hesapta kazandırırken tek adımlı bir sınıflandırmada bedeli artırıp sayıyı yerinde bırakır
ve ikisi de basılır.

## Akıl Yürütme Teknikleri

Modelden daha çok adım atmasını istemenin ne kazandırdığının ve neye mal olduğunun iki görevde birden ölçülmesi: düşünce zincirinin çok adımlı hesapta kazandırıp tek adımlı sınıflandırmada belirteci katlayarak kazanç vermemesi, öz tutarlılıkta örnek sayısı bir'den dokuz'a çıkarken isabet ile çağrı bedeli ve yanlış cevapta uzlaşmanın kırılması, dallanma çarpanı arttıkça çağrı sayısının büyümesi ve kazancın durduğu yer, önce ilke sonra çözüm soran iki aşamalı istemin farkı, aynı istemde düşünce ve eylem alanının birlikte istenmesinde geçerli eylem üreten yanıt oranı, yanıt öncesi görünmeyen ara adımların belirteç bedeli ve farkın ölçülemez kaldığı görev, farklı istemlerin hatalarının örtüşmesi, arama bütçesi büyüdükçe doğrulamadaki kazancın sınamaya taşınmaması.

### Düşünce Zinciri

Source: https://academia.sh/tr/kurslar/istem-muhendisligi/dusunce-zinciri

Modelden sonucu değil sonuca giden ara adımları istemenin iki ayrı görevde ölçülmesi: çok adımlı kurgu tarife hesabında isabet 0,3000'den 0,8833'e çıkıyor ve doğru yanıt başına belirteç 243,2'den 150,1'e iniyor, tek adımlı destek talebi sınıflandırmasında ise fark üç koşumda -0,0500, -0,0417 ve +0,0750 olarak işaret değiştiriyor ve koşum bandının içinde kalıyor. İki görevde de toplam belirteç yaklaşık 1,8 kat artıyor; sınıflandırmada doğru yanıt başına bedel 59,1'den 114,1 belirtece yükseliyor.

İstem tasarımı konusu sekiz derste isteme **ne söyleneceğini** düzenledi: yönerge, rol, ölçülebilir
talep, biçim, örnek, yasak bildirimi ve hepsinin ölçerek yinelenmesi. Hiçbirinde modelin **nasıl
düşüneceği** istenmedi. Sekizinci dersin bıraktığı istem hâlâ tek bir şey soruyor ve tek bir yanıt
bekliyor.

Düşünce zinciri bu boşluğu doldurur: modelden sonucu değil, sonuca giden **ara adımları** istemek.
Bu ders o tek cümlelik değişikliği **iki görevde** ölçer, çünkü kursun ikinci iddiası burada
kurulur: akıl yürütme teknikleri pahalıdır ve **her görevde kazandırmaz.**

- **AY1.** Kod gerçek bir uç nokta çağırmaz; standart kitaplıkla yazılmış bir dil modeli
  **benzeticisini** çağırır. Tohum **20260218**.
- **AY2.** Destek talepleri ve tarife **kurgudur**: 120 kısa Türkçe talep, 60 hesap kaydı.
- **AY3.** Kurgu tarifenin basamakları 10, 25 ve 40 m³'tür; üstüne sabit bir bedel ve abone tipine
  bağlı bir indirim gelir. Tarife açıklaması istemin içindedir ve belirteç bedeline girer.
- **AY4.** Benzeticinin iki hesap yolu vardır: **tek hamlede** kısayol kalıplarından birini seçen
  yol ve **adım adım** her basamağı ayrı hesaplayan, adım başına 0,05 kayma payı taşıyan yol. Bu
  ayrım bir modelleme varsayımıdır.
- **AY5.** Sınıflandırmada adım adım istemek yalnız yanıtın **biçimini** değiştirir; etiket
  puanlaması aynı kalır. Ölçüt hesapta **kesin eşitlik**, sınıflandırmada **etiket isabetidir**.
- **AY6.** Adımlı yanıt uzundur; en büyük çıktı uzunluğu 24'ten **96 belirtece** çıkarılır, yoksa
  durdurma koşulu sonucu keser. Bu genişletme de bedelin parçasıdır.
- **AY7.** **Koşum bandı**: aynı istem üç tohumda koşulur ve en yüksek ile en düşük isabet
  arasındaki fark banttır. Farkı bandın içinde kalan değişiklik **ölçülmemiş sayılır**.

#### Aynı İstemin İki Hâli

Üç sayı sabittir: **önceki istem**, **değiştirilmiş istem**, **bedel**. Önceki istem, istem tasarımı
konusunun bıraktığı hâldir: görev tanımlı, tarife verilmiş, biçim dayatılmış. Değiştirilmiş istem
ona tek bir cümle ekler — önce her basamağı ayrı ayrı adım adım yaz.

```python
# BENZETICI. Bu kod gercek bir model uc noktasi cagirmaz; standart kitaplikla yazilmis
# bir dil modeli benzeticisidir. Destek talepleri ve tarife de KURGU'dur.
import math

TOHUM, M32 = 20260218, 0xFFFFFFFF
PENCERE, EN_UZUN, EN_UZUN_ADIM = 240, 24, 96     # baglam penceresi ve cikti sinirlari


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):                  # KURGU belirtecleyici: parca en cok bes damga
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


def izno(m):                        # istemin icerigine bagli, kosumdan bagimsiz iz
    h = 2166136261
    for c in m:
        h = ((h ^ ord(c)) * 16777619) & M32
    return h


KONU = ["fatura", "ariza", "sayac", "tarife", "kesinti"]
KALIP = {
    "fatura": ["bu ayki fatura tutari gecen aya gore cok yuksek geldi",
               "faturami odedim ama sistemde borc gorunuyor",
               "fatura ayrintisini nereden gorebilirim"],
    "ariza": ["evde su akmiyor bir ariza var galiba",
              "baglanti bozuk oldu ve hic calismiyor",
              "ariza kaydi actim ama ekip gelmedi"],
    "sayac": ["sayac okumasi yanlis girilmis endeks tutmuyor",
              "sayac degisimi icin randevu istiyorum",
              "sayac uzerindeki endeks ile fatura ayni degil"],
    "tarife": ["hangi tarife basamagindayim ogrenmek istiyorum",
               "tarife degisikligi icin ne yapmam gerekiyor",
               "birim ucret abone tipine gore degisiyor mu"],
    "kesinti": ["mahallede kesinti var ne zaman gelecek",
                "planli kesinti duyurusu nereden takip edilir",
                "aksamdan beri kesinti yasiyoruz"],
}
EK = ["ayrica gecen ay da ayni sorun olmustu", "bu konuda memnun degilim",
      "acil bilgi almam gerekiyor", "kayit numaram elimde yok"]
TALEP = []
for i in range(120):
    r = uretec(TOHUM + i)
    k = KONU[ayrik(r(), [0.24, 0.22, 0.18, 0.20, 0.16])]
    m = KALIP[k][int(r() * 3)]
    if r() < 0.34:
        m += " " + EK[int(r() * 4)]
    TALEP.append({"no": 4001 + i, "metin": m, "konu": k})

IZ = {"fatur": "fatura", "tutar": "fatura", "ayrin": "fatura",
      "ariza": "ariza", "bozuk": "ariza", "calis": "ariza", "akmiy": "ariza",
      "sayac": "sayac", "endek": "sayac", "okuma": "sayac",
      "tarif": "tarife", "birim": "tarife", "abone": "tarife", "basam": "tarife",
      "kesin": "kesinti", "duyur": "kesinti", "mahal": "kesinti"}
TUZAK = {"degis": "tarife", "kayit": "ariza", "yukse": "tarife", "gorun": "fatura",
         "ekip": "kesinti", "takip": "tarife", "giril": "fatura"}   # yaniltici baglar
GEREKCE = ("birinci adim : talep metnindeki isaretler tarandi . ikinci adim : en guclu "
           "isaret {k} kavramini gosteriyor . ucuncu adim : etiket {k}")

# KURGU tarife: basamak ust siniri (m3) ve birim, sabit bedel, abone tipi indirimi
BASAMAK, SABIT = [(10, 3), (25, 5), (40, 8), (10 ** 6, 12)], 20
TIP = {"konut": 0, "tarim": 20, "resmi": 10}
HESAP = []
for i in range(60):
    r = uretec(TOHUM + 900 + i)
    m3 = 6 + int(r() * 52)
    tp = sorted(TIP)[ayrik(r(), [0.40, 0.34, 0.26])]
    HESAP.append({"no": 7001 + i, "m3": m3, "tip": tp,
                  "metin": f"tuketim {m3} m3 abone tipi {tp} tutar ne kadar"})


def kademe(m3):                     # basamaklara bolunmus tuketimin toplami
    alt, kalan, t = 0, m3, 0
    for ust, birim in BASAMAK:
        pay = min(kalan, ust - alt)
        t, kalan, alt = t + pay * birim, kalan - pay, ust
        if kalan <= 0:
            break
    return t


def kesin(m3, tip):                 # gorevin dogru cevabi, benzeticinin disinda
    return ((kademe(m3) + SABIT) * (100 - TIP[tip])) // 100


SAYAC = [0]


def _gorev(bel):                    # istemin sonundaki talepten tuketim ve abone tipi
    return (next((int(u) for u in reversed(bel) if u.isdigit()), 0),
            next((t for t in reversed(bel) if t in TIP), "konut"))


def _adim_adim(m3, tip, r, kayma=0.05):         # her basamak ayri, adim basina kayma
    alt, kalan, t, s = 0, m3, 0, []
    for i, (ust, birim) in enumerate(BASAMAK):
        pay = min(kalan, ust - alt)
        b = BASAMAK[i + 1][1] if r() < kayma and i + 1 < len(BASAMAK) else birim
        t, kalan, alt = t + pay * b, kalan - pay, ust
        s.append(f"basamak {i + 1} , {pay} m3 , birim {b} , ara toplam {t}")
        if kalan <= 0:
            break
    if r() < kayma:
        s.append(f"sabit bedel atlandi ara toplam {t}")
    else:
        t += SABIT
        s.append(f"sabit bedel {SABIT} ara toplam {t}")
    ind = 0 if r() < kayma else TIP[tip]
    t = (t * (100 - ind)) // 100
    return " . ".join(s + [f"indirim {ind} sonuc {t}"])


def _tek_hamle(m3, tip, r):                     # basamaklari atlayan kisayol kaliplari
    d, ind = next(b for u, b in BASAMAK if m3 <= u), TIP[tip]
    aday = [kesin(m3, tip), ((m3 * d + SABIT) * (100 - ind)) // 100, kademe(m3) + SABIT,
            (kademe(m3) * (100 - ind)) // 100, m3 * BASAMAK[0][1] + SABIT]
    return aday[ayrik(r(), [0.16, 0.30, 0.22, 0.20, 0.12])]


def cagir(istem, tohum=TOHUM, sicaklik=0.6, en_uzun=EN_UZUN):
    SAYAC[0] += 1
    bel = belirtecle(istem)
    if len(bel) > PENCERE:
        return {"durum": "baglam_asimi", "giris": len(bel), "cikis": 0, "yanit": ""}
    if SAYAC[0] % 37 == 0:
        return {"durum": "hiz_siniri", "giris": len(bel), "cikis": 0, "yanit": ""}
    r = uretec(tohum ^ izno(istem))
    adimli = "adim" in bel                      # istem adim adim cozum istiyor mu
    if "hesap" in bel:                          # cok adimli hesap gorevi
        m3, tip = _gorev(bel)
        y = _adim_adim(m3, tip, r) if adimli else f"sonuc {_tek_hamle(m3, tip, r)}"
    else:                                       # tek adimli siniflandirma gorevi
        p = {k: 0.15 for k in KONU}             # etiket kumesi zaten istemde yazili
        for t in bel:
            for tablo, w in ((IZ, 1.0), (TUZAK, 1.3)):
                if tablo.get(t) in p:
                    p[tablo[t]] += w
        e = [math.exp(p[a] / sicaklik) for a in sorted(p)]
        k = sorted(p)[ayrik(r(), [v / sum(e) for v in e])]
        y = GEREKCE.format(k=k) if adimli else k
    cb = belirtecle(y)
    if len(cb) > en_uzun:                       # durdurma kosulu
        cb = cb[:en_uzun]
        y = " ".join(cb)
    return {"durum": "tamam", "giris": len(bel), "cikis": len(cb), "yanit": y}


def oku(y):                                     # yanittaki ilk etiket
    return next((s for s in y.split() if s in KONU), None)


def oku_sayi(y):                                # yanittaki son sayi
    return next((int(x) for x in reversed(y.split()) if x.isdigit()), None)


TARIFE = ("Tarife: ilk 10 m3 birim 3 , sonraki 15 m3 birim 5 , sonraki 15 m3 birim 8 , "
          "40 ustu birim 12 . Sabit bedel 20 . Abone tipi indirimi yuzde konut 0 , "
          "tarim 20 , resmi 10 . Tutari hesapla . ")
H_ONCE = TARIFE + "Son satira sadece sonucu yaz . Talep: "
H_ADIM = TARIFE + "Once her basamagi ayri ayri adim adim yaz , sonra sonucu yaz . Talep: "
S_ONCE = ("Talebi su etiketlerden birine ata: fatura , ariza , sayac , tarife , kesinti . "
          "Yanit olarak tek etiket yaz . Talep: ")
S_ADIM = ("Talebi su etiketlerden birine ata: fatura , ariza , sayac , tarife , kesinti . "
          "Once adim adim incele , sonra yalniz etiketi yaz . Talep: ")
x = HESAP[0]
print(f"KURGU hesap kumesi {len(HESAP)} kayit, KURGU talep kumesi {len(TALEP)} kayit")
print(f"ornek {x['no']}: {x['metin']} , dogru cevap {kesin(x['m3'], x['tip'])}")
for ad, i, u in (("onceki", H_ONCE, EN_UZUN), ("adimli", H_ADIM, EN_UZUN_ADIM)):
    s = cagir(i + x["metin"], en_uzun=u)
    ik = cagir(i + x["metin"], tohum=TOHUM + 1, en_uzun=u)
    print(f"\n{ad} istem, giris {s['giris']} cikis {s['cikis']} belirtec: {s['yanit']}")
    print(f"  ayni istem tohum {TOHUM + 1}: {oku_sayi(ik['yanit'])}")
t = TALEP[2]
print(f"\nsiniflandirma ornegi {t['no']} , dogru etiket {t['konu']}:")
for ad, i, u in (("onceki", S_ONCE, EN_UZUN), ("adimli", S_ADIM, EN_UZUN_ADIM)):
    s = cagir(i + t["metin"], en_uzun=u)
    print(f"  {ad} istem , {s['giris']}+{s['cikis']} belirtec: {s['yanit']}")
```

```
KURGU hesap kumesi 60 kayit, KURGU talep kumesi 120 kayit
ornek 7001: tuketim 14 m3 abone tipi resmi tutar ne kadar , dogru cevap 63

onceki istem, giris 71 cikis 2 belirtec: sonuc 62
  ayni istem tohum 20260219: 70

adimli istem, giris 77 cikis 43 belirtec: basamak 1 , 10 m3 , birim 3 , ara toplam 30 . basamak 2 , 4 m3 , birim 5 , ara toplam 50 . sabit bedel 20 ara toplam 70 . indirim 10 sonuc 63
  ayni istem tohum 20260219: 63

siniflandirma ornegi 4003 , dogru etiket ariza:
  onceki istem , 50+1 belirtec: ariza
  adimli istem , 55+33 belirtec: birinci adim : talep metnindeki isaretler tarandi . ikinci adim : en guclu isaret ariza kavramini gosteriyor . ucuncu adim : etiket ariza
```

Tek hamlelik yanıt **62** dedi, doğru cevap **63**; ikinci tohumda **70** dedi. İkisi de yanlış ve
arada hiçbir ara adım yok. Adımlı yanıt basamakları tek tek yazdı: ilk 10 m³ birim 3'ten 30, kalan
4 m³ birim 5'ten 20, sabit bedelle 70, indirim düşülünce **63** — iki tohumda da aynı. Bedel aynı
satırda: çıkış belirteci **2'den 43'e** çıktı.

Son iki satır aynı değişikliğin öbür görevdeki karşılığıdır. Sınıflandırmada adım adım istemek
etiketi değiştirmedi, ama çıkış belirteci **1'den 33'e** çıktı. Otuz üç belirteçlik gerekçe, bir
belirteçlik yanıtın taşımadığı hiçbir bilgi taşımıyor.

#### İki Görevde Aynı Değişiklik

Ölçüm bütün kümede yinelenir. Her istem üç tohumda koşulur ve çağrı sayısı iki yolda da eşittir.

```python
def olc(kume, istem, tohum, u, dogru, oku_yanit):
    SAYAC[0] = 0
    g = c = d = 0
    for x in kume:
        s = cagir(istem + x["metin"], tohum=tohum, en_uzun=u)
        g, c, d = g + s["giris"], c + s["cikis"], d + (oku_yanit(s["yanit"]) == dogru(x))
    return {"isabet": d / len(kume), "giris": g, "cikis": c, "toplam": g + c}


def yaz(baslik, kume, i1, i2, dogru, oku_yanit):
    A = [olc(kume, i1, TOHUM + j, EN_UZUN, dogru, oku_yanit) for j in range(3)]
    B = [olc(kume, i2, TOHUM + j, EN_UZUN_ADIM, dogru, oku_yanit) for j in range(3)]
    print(f"{baslik:<24} {'onceki':>9} {'adimli':>9} {'fark':>9}")
    for j in range(3):
        print(f"{'isabet tohum ' + str(TOHUM + j):<24} {A[j]['isabet']:>9.4f} "
              f"{B[j]['isabet']:>9.4f} {B[j]['isabet'] - A[j]['isabet']:>+9.4f}")
    bant = [max(x['isabet'] for x in v) - min(x['isabet'] for x in v) for v in (A, B)]
    print(f"{'uc kosumun bandi':<24} {bant[0]:>9.4f} {bant[1]:>9.4f}")
    for ad, k in (("giris belirteci", "giris"), ("cikis belirteci", "cikis"),
                  ("toplam belirtec", "toplam")):
        print(f"{ad:<24} {A[0][k]:>9d} {B[0][k]:>9d} {B[0][k] - A[0][k]:>+9d}")
    print(f"belirtec {B[0]['toplam'] / A[0]['toplam']:.2f} kat, dogru yanit basina "
          f"{A[0]['toplam'] / A[0]['isabet'] / len(kume):.1f} -> "
          f"{B[0]['toplam'] / B[0]['isabet'] / len(kume):.1f} belirtec\n")


yaz("cok adimli hesap", HESAP, H_ONCE, H_ADIM, lambda x: kesin(x["m3"], x["tip"]), oku_sayi)
yaz("tek adimli siniflandirma", TALEP, S_ONCE, S_ADIM, lambda x: x["konu"], oku)
```

```
cok adimli hesap            onceki    adimli      fark
isabet tohum 20260218       0.3000    0.8833   +0.5833
isabet tohum 20260219       0.3500    0.8833   +0.5333
isabet tohum 20260220       0.3000    0.9000   +0.6000
uc kosumun bandi            0.0500    0.0167
giris belirteci               4260      4620      +360
cikis belirteci                118      3334     +3216
toplam belirtec               4378      7954     +3576
belirtec 1.82 kat, dogru yanit basina 243.2 -> 150.1 belirtec

tek adimli siniflandirma    onceki    adimli      fark
isabet tohum 20260218       0.7750    0.7250   -0.0500
isabet tohum 20260219       0.7000    0.6583   -0.0417
isabet tohum 20260220       0.7333    0.8083   +0.0750
uc kosumun bandi            0.0750    0.1500
giris belirteci               5300      5900      +600
cikis belirteci                192      4023     +3831
toplam belirtec               5492      9923     +4431
belirtec 1.81 kat, dogru yanit basina 59.1 -> 114.1 belirtec
```

Üst tablo tekniğin çalıştığı yerdir. İsabet **0,3000'den 0,8833'e** çıkıyor ve fark üç koşumda da
aynı işaretle büyük: +0,5833, +0,5333, +0,6000. Koşum bantları **0,0500** ve **0,0167**; fark
bandın on katından fazla, yani **ölçülmüş** sayılır. Toplam belirteç **1,82 kat** artıyor, artışın
neredeyse tamamı çıkıştan geliyor; buna karşılık doğru yanıt başına bedel **243,2'den 150,1
belirtece** iniyor.

Alt tablo aynı tekniğin ödemediği görevdir. Fark **-0,0500**, **-0,0417** ve **+0,0750**; **işaret
bile sabit değil** ve üçü de 0,0750 ile 0,1500'lük bantların içinde kalıyor. Kursun kuralına göre
bu fark **ölçülmemiştir**: aynı istemin koşumları arasındaki oynama, değişikliğin kattığı oynamadan
büyük. Bedel tarafında ise belirsizlik yok: toplam belirteç **1,81 kat**, doğru yanıt başına bedel
**59,1'den 114,1 belirtece** çıkıyor.

#### Kazancın Nereden Geldiği

Farkı yaratan şey görevin yapısıdır. Tarife hesabı zincirlemedir; ara adımları yazmak zinciri
parçalara ayırır ve her parçanın hatası küçük kalır. Sınıflandırma tek adımlıdır: işaretler okunur,
etiket seçilir. Yazılacak ara adım yoktur; gerekçe metni kararı üretmez, **anlatır**. Bedel ise iki
görevde de aynı ödenir, çünkü belirteç ara adımın işe yarayıp yaramadığını bilmez.

Kursun kuralı buradan okunur: **ölçülmeden değiştirilen istem bir iyileştirme değil bir
tahmindir.**

#### Özet

- Düşünce zinciri, modelden sonuca giden **ara adımları** istemektir: tek cümlelik bir istem
  değişikliği, sabit model ve küme.
- Çok adımlı kurgu tarife hesabında isabet **0,3000'den 0,8833'e** çıkıyor; fark üç koşumda da aynı
  işaretle büyük ve koşum bandının (0,0500 / 0,0167) çok dışında.
- Tek adımlı sınıflandırmada fark **-0,0500**, **-0,0417** ve **+0,0750**; işareti değişiyor ve
  koşum bandının (0,0750 / 0,1500) içinde kalıyor. **Bu fark ölçülmemiş sayılır.**
- Bedel iki görevde de kesindir: toplam belirteç **1,82** ve **1,81 kat** artıyor. Doğru yanıt
  başına bedel hesapta **243,2'den 150,1'e** iniyor, sınıflandırmada **59,1'den 114,1'e** çıkıyor —
  aynı teknik bir görevde ucuzlatıyor, öbüründe pahalılaştırıyor.

#### Sonraki Adım

Adım adım çözüm hesapta kazandırdı, ama tek bir koşumda **tek bir zincir** üretti. Zincirin kendisi
de belirsizdir: adımlı yolun isabeti 0,8833 ile 0,9000 arasında oynuyor ve elde tek zincir varken
hangisinin doğru olduğu bilinemez. Sonraki ders bunu bir düzeneğe çevirir: aynı istem birden çok
kez koşulur ve yanıtlar oylanır. Ölçülecek olan, örnek sayısıyla kazancın nasıl değiştiği, **çağrı
sayısının kaç katına çıktığı** ve uzlaşmanın **yanlış bir cevapta** kurulduğu durumların sayısıdır.

### Öz Tutarlılık

Source: https://academia.sh/tr/kurslar/istem-muhendisligi/oz-tutarlilik

Aynı istemin birden çok kez koşulup yanıtların oylanmasının kazancı ve bedeli: örnek sayısı birden dokuza çıkarken isabet 0,7667'den 0,8833'e yükseliyor ve yediden sonra duruyor, çağrı sayısı 60'tan 540'a, doğru yanıt başına belirteç 172,9'dan 1343,6'ya çıkıyor. Dokuz örnekte 58 kayıtta uzlaşma kuruluyor ama beşinde uzlaşma yanlış bir cevapta; bu beş kaydın tüketimi 41 ile 45 m³ arasında, yani hatanın dağınık değil sistematik olduğu yerde.

Önceki ders adım adım çözüm istemenin çok adımlı hesapta işe yaradığını gösterdi: isabet 0,3000'den
0,8833'e çıktı. Ama o sayı **tek bir koşumdan** geldi. Model belirsiz bir bileşendir; aynı istem
ikinci bir koşumda başka bir zincir üretir ve zincirin bir yerinde kayarsa sonuç değişir. Elde tek
bir zincir varken onun doğru olup olmadığını söyleyecek hiçbir şey yoktur.

Öz tutarlılık bu belirsizliği bir kaldıraca çevirir: aynı istem birden çok kez koşulur ve çıkan
yanıtlar **oylanır**. Bu derste **istemin metni hiç değişmez**; değişen tek şey aynı istemin kaç
kez koşulduğudur. Bu yüzden bedel belirtecin yanında **çağrı sayısıyla** da yazılır. Çoğunluk oyunun
kendisi önceki müfredatın topluluk yöntemleri dersinde ölçüldü ve burada tekrarlanmaz; eklenen şey
bedel ve **uzlaşmanın kırıldığı yerdir**.

- **AY11.** Kod gerçek bir uç nokta çağırmaz; standart kitaplıkla yazılmış bir dil modeli
  **benzeticisini** çağırır. Tohum **20260218**. Bu ders yalnız hesap yolunu kullanır.
- **AY12.** Görev önceki dersinkidir: 60 kayıtlık **kurgu** tarife hesabı, basamaklar 10, 25 ve
  40 m³, üstüne sabit bedel ve abone tipi indirimi. Ölçüt **kesin eşitliktir**.
- **AY13.** İstem önceki dersin adımlı istemidir ve harfi harfine aynı kalır.
- **AY14.** Gerçek bir uç noktada örnek çeşitliliği sıfırdan büyük **dağılım sıcaklığından** gelir;
  benzeticide tohum örnek başına bir artırılarak alınır.
- **AY15.** Örnek sayısı 1, 3, 5, 7 ve 9'dur; **dokuzu aşmaz**.
- **AY16.** Oylamada en çok oyu alan cevap seçilir, eşitlikte ilk ulaşan cevap kazanır. **Hız
  sınırına takılan çağrı oy veremez** ama çağrı sayısına ve belirteç bedeline girer.
- **AY17.** **Uzlaşma**: geçerli oyların yarısından fazlası aynı cevapta ise uzlaşma vardır. Tek
  örnekte uzlaşma her zaman kurulur ve hiçbir şey söylemez.
- **AY18.** Benzeticinin adım kayması iki türlüdür: her adımda **0,05 dağınık kayma** ve son
  basamağa düşen artık 5 m³ ve altındaysa **0,85 sistematik kayma**. İkincisi bir modelleme
  varsayımıdır ve bu dersin ölçtüğü şeyin kaynağıdır.
- **AY19.** Bütün ölçüm iki tohum tabanıyla yinelenir: **20260218** ve **20260258**.
- **AY20.** Bedel üç sayıdır: toplam belirteç, **çağrı sayısı** ve doğru yanıt başına düşen
  belirteç.

#### Aynı İstemin Dokuz Örneği

Önce tek bir kayıt üzerinde ne olduğuna bakılır. Aynı istem dokuz kez koşulur, her koşumda tohum
bir artar ve yanıttaki son sayı bir oy sayılır. İki kayıt seçildi: biri sıradan, öbürü 40 m³
sınırının hemen üstünde.

```python
# BENZETICI. Bu kod gercek bir model uc noktasi cagirmaz; standart kitaplikla yazilmis
# bir dil modeli benzeticisidir. Destek talepleri ve tarife de KURGU'dur.
TOHUM, M32 = 20260218, 0xFFFFFFFF
PENCERE, EN_UZUN = 240, 96          # baglam penceresi ve adimli yanit icin cikti siniri


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):                  # KURGU belirtecleyici: parca en cok bes damga
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


def izno(m):                        # istemin icerigine bagli, kosumdan bagimsiz iz
    h = 2166136261
    for c in m:
        h = ((h ^ ord(c)) * 16777619) & M32
    return h


# KURGU tarife: basamak ust siniri (m3) ve birim, sabit bedel, abone tipi indirimi
BASAMAK, SABIT = [(10, 3), (25, 5), (40, 8), (10 ** 6, 12)], 20
TIP = {"konut": 0, "tarim": 20, "resmi": 10}
HESAP = []
for i in range(60):
    r = uretec(TOHUM + 900 + i)
    m3 = 6 + int(r() * 52)
    tp = sorted(TIP)[ayrik(r(), [0.40, 0.34, 0.26])]
    HESAP.append({"no": 7001 + i, "m3": m3, "tip": tp,
                  "metin": f"tuketim {m3} m3 abone tipi {tp} tutar ne kadar"})


def kademe(m3):                     # basamaklara bolunmus tuketimin toplami
    alt, kalan, t = 0, m3, 0
    for ust, birim in BASAMAK:
        pay = min(kalan, ust - alt)
        t, kalan, alt = t + pay * birim, kalan - pay, ust
        if kalan <= 0:
            break
    return t


def kesin(m3, tip):                 # gorevin dogru cevabi, benzeticinin disinda
    return ((kademe(m3) + SABIT) * (100 - TIP[tip])) // 100


SAYAC = [0]


def _gorev(bel):                    # istemin sonundaki talepten tuketim ve abone tipi
    return (next((int(u) for u in reversed(bel) if u.isdigit()), 0),
            next((t for t in reversed(bel) if t in TIP), "konut"))


def _adim_adim(m3, tip, r):         # her basamak ayri yazilir, adim basina kayma payi
    alt, kalan, t, s = 0, m3, 0, []
    for i, (ust, birim) in enumerate(BASAMAK):
        pay = min(kalan, ust - alt)
        # son basamakta kalan kucukse kayma sistematiktir: hep ayni yanlisa gider
        b = birim
        if r() < (0.85 if i == 3 and pay <= 5 else 0.05):
            b = BASAMAK[i - 1][1] if i + 1 == len(BASAMAK) else BASAMAK[i + 1][1]
        t, kalan, alt = t + pay * b, kalan - pay, ust
        s.append(f"basamak {i + 1} , {pay} m3 , birim {b} , ara toplam {t}")
        if kalan <= 0:
            break
    if r() < 0.05:
        s.append(f"sabit bedel atlandi ara toplam {t}")
    else:
        t += SABIT
        s.append(f"sabit bedel {SABIT} ara toplam {t}")
    ind = 0 if r() < 0.05 else TIP[tip]
    t = (t * (100 - ind)) // 100
    return " . ".join(s + [f"indirim {ind} sonuc {t}"])


def cagir(istem, tohum=TOHUM, en_uzun=EN_UZUN):
    SAYAC[0] += 1
    bel = belirtecle(istem)
    if len(bel) > PENCERE:
        return {"durum": "baglam_asimi", "giris": len(bel), "cikis": 0, "yanit": ""}
    if SAYAC[0] % 37 == 0:                      # hiz siniri cagri sayisina baglidir
        return {"durum": "hiz_siniri", "giris": len(bel), "cikis": 0, "yanit": ""}
    m3, tip = _gorev(bel)
    y = _adim_adim(m3, tip, uretec(tohum ^ izno(istem)))
    cb = belirtecle(y)
    if len(cb) > en_uzun:                       # durdurma kosulu
        cb = cb[:en_uzun]
        y = " ".join(cb)
    return {"durum": "tamam", "giris": len(bel), "cikis": len(cb), "yanit": y}


def oku_sayi(y):                                # yanittaki son sayi
    return next((int(x) for x in reversed(y.split()) if x.isdigit()), None)


ISTEM = ("Tarife: ilk 10 m3 birim 3 , sonraki 15 m3 birim 5 , sonraki 15 m3 birim 8 , "
         "40 ustu birim 12 . Sabit bedel 20 . Abone tipi indirimi yuzde konut 0 , "
         "tarim 20 , resmi 10 . Tutari hesapla . Once her basamagi ayri ayri adim adim "
         "yaz , sonra sonucu yaz . Talep: ")


def ornekle(x, n, taban):           # ayni istem n kez kosulur, yanitlar oylanir
    oy = {}
    for j in range(n):
        v = oku_sayi(cagir(ISTEM + x["metin"], tohum=taban + j)["yanit"])
        if v is not None:                       # hiz sinirina takilan cagri oy vermez
            oy[v] = oy.get(v, 0) + 1
    if not oy:
        return None, 0
    en = max(oy.values())
    return next(k for k in oy if oy[k] == en), en
SAYAC[0] = 0
for x in (HESAP[3], next(h for h in HESAP if 40 < h["m3"] <= 45)):
    oy, d = {}, kesin(x["m3"], x["tip"])
    for j in range(9):
        v = oku_sayi(cagir(ISTEM + x["metin"], tohum=TOHUM + j)["yanit"])
        oy[v] = oy.get(v, 0) + 1
    sec, en = ornekle(x, 9, TOHUM)
    print(f"kayit {x['no']}: {x['m3']} m3 , {x['tip']} , dogru cevap {d}")
    print(f"  dokuz ornek: {sorted(oy.items(), key=lambda p: -p[1])}")
    print(f"  uzlasma {sec} ({en}/9) -> {'dogru' if sec == d else 'YANLIS'}")
```

```
kayit 7004: 12 m3 , resmi , dogru cevap 54
  dokuz ornek: [(54, 6), (36, 2), (59, 1)]
  uzlasma 54 (6/9) -> dogru
kayit 7008: 45 m3 , tarim , dogru cevap 244
  dokuz ornek: [(228, 5), (276, 2), (264, 1), (244, 1)]
  uzlasma 228 (5/9) -> YANLIS
```

Birinci kayıtta oylama işe yarıyor. Dokuz örneğin altısı **54** diyor ve doğru cevap bu. Kalan üç
oy iki ayrı yanlışa dağılmış: **36**, sabit bedelin atlandığı yanıt; **59**, ikinci basamağın
biriminin kaydığı yanıt. Hatalar birbirinden farklı, doğru cevap ise hepsinde aynı. Dağınık hatanın
oylamayla düzelmesinin nedeni budur — yanlış gitmenin birçok yolu vardır, doğru gitmenin bir tane.

İkinci kayıtta aynı düzenek ters çalışıyor. Doğru cevap **244** ve dokuz örnekten yalnız **biri**
onu söylüyor. Çoğunluk **228** üzerinde toplanıyor: 45 m³'ün son 5 m³'ü en üst basamağın birimiyle
değil bir alt basamağınkiyle hesaplanmış. Oylama bu kaydı düzeltmiyor, **yanlışı pekiştiriyor**.
Aradaki fark hatanın türündedir: birincisi dağınık, ikincisi sistematik.

#### Örnek Sayısı, Kazanç ve Çağrı

Aynı ölçüm bütün kümede ve beş ayrı örnek sayısında yinelenir. Her satır iki tohum tabanıyla
koşulur; ikinci sütun aynı düzeneğin ikinci koşumudur.

```python
def olc(n, taban):
    SAYAC[0] = 0
    g = c = d = uz = bos = 0
    kirik = []
    for x in HESAP:
        oy, dogru = {}, kesin(x["m3"], x["tip"])
        for j in range(n):
            s = cagir(ISTEM + x["metin"], tohum=taban + j)
            g, c = g + s["giris"], c + s["cikis"]
            v = oku_sayi(s["yanit"])
            if v is None:
                bos += 1                        # hiz sinirina takilan cagri oy vermez
            else:
                oy[v] = oy.get(v, 0) + 1
        if not oy:
            continue                            # tek ornek hiz sinirina takildi
        en = max(oy.values())
        sec = next(k for k in oy if oy[k] == en)
        d += sec == dogru
        if en * 2 > sum(oy.values()):           # yarisindan fazlasi ayni cevapta
            uz += 1
            if sec != dogru:
                kirik.append(x["m3"])
    return {"isabet": d / len(HESAP), "cagri": SAYAC[0], "belirtec": g + c,
            "uzlasan": uz, "kirik": kirik, "bos": bos}


print(f"{'ornek':>5} {'isabet':>8} {'ikinci':>8} {'cagri':>6} {'belirtec':>9} "
      f"{'birim':>7} {'uzlasan':>8} {'yanlista':>9}")
for n in (1, 3, 5, 7, 9):
    A, B = olc(n, TOHUM), olc(n, TOHUM + 40)
    print(f"{n:>5} {A['isabet']:>8.4f} {B['isabet']:>8.4f} {A['cagri']:>6} "
          f"{A['belirtec']:>9} {A['belirtec'] / A['isabet'] / len(HESAP):>7.1f} "
          f"{A['uzlasan']:>8} {len(A['kirik']):>9}")
    if n == 9:
        print(f"\ndokuz ornekte yanlista uzlasan kayitlarin tuketimi: "
              f"{sorted(A['kirik'], reverse=True)} m3")
        print(f"hiz sinirina takilip oy veremeyen cagri: {A['bos']}")
```

```
ornek   isabet   ikinci  cagri  belirtec   birim  uzlasan  yanlista
    1   0.7667   0.6667     60      7954   172.9       59        13
    3   0.8500   0.8667    180     23785   466.4       56         6
    5   0.8667   0.8833    300     39552   760.6       55         4
    7   0.8833   0.9000    420     55389  1045.1       57         5
    9   0.8833   0.8833    540     71211  1343.6       58         5

dokuz ornekte yanlista uzlasan kayitlarin tuketimi: [45, 45, 44, 43, 41] m3
hiz sinirina takilip oy veremeyen cagri: 14
```

İlk sütun kazancı veriyor. Tek örnekte isabet **0,7667**, dokuz örnekte **0,8833**; kazanç
**+0,1167**. Kazancın dağılımı düzgün değil: ilk üç örnek **+0,0833** getiriyor, sonraki dört
örnek yalnız **+0,0333** ve yediden dokuza geçiş **hiçbir şey** getirmiyor. Kazanç yedinci örnekte
doyuyor.

İkinci sütun bu dersin en önemli sayısıdır. Tek örnekte iki koşum **0,7667** ve **0,6667** veriyor;
aradaki fark **0,1000**. Dokuz örnekte iki koşum da **0,8833** veriyor; fark **0,0000**. Tek
örnekli kazanç (+0,1167) tek örneğin koşum farkının (0,1000) ancak biraz üstünde kalıyor, yani ilk
koşuma bakarak ölçülmüş saymak zor olurdu. İkinci koşumda aynı kazanç **+0,2166**. Tekniğin en
sağlam ölçülen etkisi isabeti yükseltmesi değil, **koşumdan koşuma oynamayı sıfıra indirmesidir**.

Üçüncü ve dördüncü sütunlar bedeldir ve tartışmasızdır. Çağrı sayısı **60'tan 540'a**, toplam
belirteç **7954'ten 71211'e** çıkıyor — belirteç neredeyse tam dokuz kat. Doğru yanıt başına bedel
**172,9'dan 1343,6 belirtece** yükseliyor, yani **7,8 kat**. Kazanç 0,1167'de kalırken bedelin
dokuz katına çıkması, bu tekniğin niçin her görevde açılamayacağını tek satırda söylüyor. Üç
örneğin sayısı (0,8500, 466,4 belirteç) çoğu durumda dokuz örnekten daha savunulabilir bir noktadır.

#### Uzlaşmanın Kırıldığı Yer

Son iki sütun oylamanın kendisine bakıyor. Tek örnekte **59 kayıtta uzlaşma var** ve bunların
**13'ü yanlış**; çünkü tek oy her zaman çoğunluktur. Uzlaşmanın tek başına hiçbir şey söylemediği
buradan görünür. Dokuz örnekte uzlaşan kayıt **58**, yanlışta uzlaşan **5**. Yanlışta uzlaşan kayıt
sayısı örnek sayısı üçten dokuza çıkarken **6, 4, 5 ve 5'te takılıp kalıyor**.

Bu beş kaydın tüketimi basılıyor: **45, 45, 44, 43 ve 41 m³**. Hepsi 40 m³ sınırının hemen üstünde.
Bu kayıtlarda son basamağa düşen artık küçüktür ve benzetici onu sistematik olarak bir alt basamağın
biriminden hesaplar. Hata rastgele değil, bu yüzden dokuz örnek de aynı yanlışa gidiyor. **Öz
tutarlılık dağınık hatayı düzeltir, sistematik hatayı pekiştirir.** Uzlaşma bir doğruluk kanıtı
değildir; yalnız hatanın dağınık olmadığının işaretidir.

Bedelin kazanca dönüşmediği bir yer daha var: 540 çağrının **14'ü** hız sınırına takıldı, oy
veremedi ve yine de çağrı sayısına girdi. Çağrı sayısını dokuza katlayan her düzenek, yüzeyin
başarısızlık payını da dokuza katlar.

#### Özet

- Öz tutarlılık, **aynı istemi** birden çok kez koşup yanıtları oylamaktır; istemin metni değişmez,
  değişen şey koşum sayısıdır.
- Örnek sayısı birden dokuza çıkarken isabet **0,7667'den 0,8833'e** yükseliyor; kazancın
  **+0,0833'ü ilk üç örnekten** geliyor ve yedinci örnekten sonra kazanç duruyor.
- Bedel iki birimle yazılır: çağrı **60'tan 540'a**, toplam belirteç **7954'ten 71211'e**, doğru
  yanıt başına belirteç **172,9'dan 1343,6'ya**. Belirteç dokuz kat, kazanç 0,1167.
- Tekniğin en sağlam ölçülen etkisi koşum farkını **0,1000'den 0,0000'a** indirmesidir; tek örneğin
  kazancı, tek örneğin koşum farkının ancak biraz üstündedir.
- Dokuz örnekte 58 kayıtta uzlaşma kuruluyor, **5'inde uzlaşma yanlış bir cevapta**. Bu beş kaydın
  tüketimi 41 ile 45 m³ arasındadır: hata sistematik olduğunda oylama onu düzeltmez, pekiştirir.

#### Sonraki Adım

Birden çok çözüm üretip oylamak işe yaradı, ama üretilen çözümlerin ortak bir yanı vardı: her biri
**baştan sona birbirinden bağımsız** kuruldu. Dokuz örnek dokuz kez sıfırdan başladı, hiçbiri
ötekinin nerede kaydığını görmedi ve hiçbiri bir başkasının iyi giden ilk yarısını devralmadı. Bir
çözümün **ortasından dallanmak** hiç denenmedi. Sonraki ders bunu dener: çözüm tek parça bir zincir
olmaktan çıkıp adım adım büyüyen ve her adımda birkaç yöne ayrılan bir yapıya dönüşür. Ölçülecek
olan dallanma çarpanı ve derinlik arttıkça **çağrı sayısının nasıl büyüdüğü** ve kazancın nerede
durduğudur.

### Düşünce Ağacı

Source: https://academia.sh/tr/kurslar/istem-muhendisligi/dusunce-agaci

Çözümün ortasından dallanmanın ölçülmesi: aynı 48 kurgu destek talebinde otuz iki arıza kodunu tek istemde soran düzen 0,4792 isabet ve 48 çağrı veriyor, çözümü adımlara bölüp her adımda birkaç uzatma isteyen düşünce ağacı dal 1'de 0,0833'e düşüyor, dal 3'te 0,6250'ye çıkıyor ve dal 4'te duruyor. Dallanma 3'ten 4'e çıkarken isabet 0,0208 geriliyor ama çağrı sayısı 795'ten 1086'ya, belirteç 43182'den 59835'e yükseliyor; bu fark aynı düzenin iki koşumu arasındaki 0,0417 farktan küçük olduğu için ölçülmemiş sayılıyor.

Bir önceki ders aynı istemi birden çok kez koşturup yanıtları oyladı. Öz tutarlılık işe yaradı:
tek yanıtın yakaladığı sayı, dokuz örneğin uzlaşmasıyla yukarı çıktı. Ama üretilen çözümlerin
ortak bir yanı vardı. Her biri **baştan sona birbirinden bağımsız** üretildi; hiçbiri ötekinin
neresinde yanıldığını görmedi. Bir çözümün ilk adımı sabit tutulup ikinci adımı birkaç ayrı
yönde denenmedi, kötü giden bir yol yarıda bırakılmadı.

Bu ders o boşluğu doldurur. Değiştirilen şey yine metindir, ama bu kez tek bir istem değil
**istemlerin düzenidir**: uzun tek bir istem yerine, her biri çözümü bir adım ilerleten kısa
istemler ve tutulacak dalları seçen bir kural. Ölçülecek olan bunun ne kazandırdığı ve **kaç
çağrıya** mal olduğudur.

- **AY21.** Görev **kurgudur**: kısa Türkçe destek taleplerine üç bileşenli bir arıza kodu
  atanır — alan, belirti ve derece. Dört alan, alan başına dört belirti, iki derece; toplam
  otuz iki kod.
- **AY22.** Çağrılan şey bir **benzeticidir**; gerçek bir model uç noktasına hiçbir istek gitmez.
  Benzetici bu müfredatın giriş kursunda kurulan biçimini sürdürür, tek farkla: seçenek kümesi
  dışarıdan verilir ve her seçenek bir **yoldur**, puanı bileşenlerinin izlerinden toplanır.
- **AY23.** Tohum **20260218**; aynı istem aynı tohumda aynı yanıtı verir. Belirsizlik **tohum
  değiştirilerek** ölçülür ve her düzenin ikinci koşumu 20260219 ile alınır.
- **AY24.** Talep metninde alan izi **zayıf**, belirti izi **güçlüdür**; ayrıca her talepte
  **yanıltıcı bir alan** adı geçer ve izi doğru alanınkinden ağırdır. Kurgu bu yapı ağacın
  ölçüleceği yeri açar: ilk adım en zayıf kanıtla atılır.
- **AY25.** Ağaç iki tür çağrı yapar. **Uzatma** çağrısı bir yolu bir adım uzatır ve dal sayısı
  kadar tekrarlanır; **seçim** çağrısı biriken adaylardan tutulacakları ayıklar. İkisi de sayılır.
- **AY26.** Dallanma çarpanı ile tutulan dal sayısı **eşit** tutulur. Ölçek küçüktür: dal en çok
  dört, derinlik en çok üç. Ölçüt **üç bileşenin birden doğru olmasıdır**.
- **AY27.** Bedel üç birimle yazılır: **çağrı sayısı**, **belirteç** ve **başarısız çağrı**. Hız
  sınırı çağrı sayısına bağlı olduğu için dallanma başarısızlığı da çoğaltır.

#### Yolun Ortasından Dallanmak

Önceki istem tektir ve her şeyi bir kerede ister: otuz iki kodun tamamı isteme yazılır, talep
eklenir, tek yanıt beklenir. Değiştirilmiş düzen aynı işi üç adıma böler — önce **alan**, sonra
o alanın **belirtisi**, sonra **derece** — ve her adımda birkaç ayrı uzatma ister; biriken
adaylardan bir bölümü tutulur, kalanı atılır. İlk blok benzeticiyi, kurgu kod ağacını ve bir
talebin ilk iki düzeyini kurar.

```python
# BENZETICI. Bu kod gercek bir model uc noktasi cagirmaz; standart kitaplikla yazilmis
# bir dil modeli benzeticisidir. Destek talepleri ve ariza kodlari da KURGU'dur.
import math

TOHUM, M32 = 20260218, 0xFFFFFFFF
PENCERE = 240                       # baglam penceresi, belirtec


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):                  # KURGU belirtecleyici: parca en cok bes damga
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


def izno(m):                        # istemin icerigine bagli, kosumdan bagimsiz iz
    h = 2166136261
    for c in m:
        h = ((h ^ ord(c)) * 16777619) & M32
    return h


ALAN = ["dagitim", "sayac", "abonelik", "saha"]
BELIRTI = {"dagitim": ["kesinti", "basinc", "sizinti", "tikanma"],
           "sayac": ["endeks", "bozukluk", "degisim", "okuma"],
           "abonelik": ["tarife", "fatura", "odeme", "kayit"],
           "saha": ["randevu", "erisim", "malzeme", "gecikme"]}
DERECE = ["birinci", "ikinci"]
A_SOZ = {"dagitim": "sebeke", "sayac": "olcum", "abonelik": "sozlesme", "saha": "ekip"}
T_SOZ = {"dagitim": "hatti", "sayac": "cihaz", "abonelik": "hesap", "saha": "servis"}
B_SOZ = {"kesinti": "akmiyor", "basinc": "zayif", "sizinti": "islak", "tikanma": "dolmus",
         "endeks": "rakam", "bozukluk": "calismiyor", "degisim": "yenisi", "okuma": "girilmemis",
         "tarife": "basamak", "fatura": "tutar", "odeme": "borcum", "kayit": "musteri",
         "randevu": "saatte", "erisim": "kapali", "malzeme": "parca", "gecikme": "bekliyor"}
D_SOZ = {"birinci": "acil", "ikinci": "normal"}
A_IZ = {A_SOZ[a][:5]: a for a in ALAN}                 # alan izi, zayif
T_IZ = {T_SOZ[a][:5]: a for a in ALAN}                 # yaniltici alan izi, daha agir
B_IZ = {B_SOZ[b][:5]: b for a in ALAN for b in BELIRTI[a]}
D_IZ = {D_SOZ[d][:5]: d for d in DERECE}

TALEP = []
for i in range(48):
    r = uretec(TOHUM + i)
    a = ALAN[int(r() * 4)]
    b = BELIRTI[a][int(r() * 4)]
    d = DERECE[int(r() * 2)]
    y = ALAN[(ALAN.index(a) + 1 + int(r() * 3)) % 4]    # talepte gecen yaniltici alan
    if r() < 0.5:
        m = (f"{T_SOZ[y]} icin kayit acilmisti ama sorun {A_SOZ[a]} tarafinda , "
             f"{B_SOZ[b]} durumu var , {D_SOZ[d]} bakilmasi gerekiyor")
    else:
        m = (f"{T_SOZ[y]} uzerinden bildirdim , {A_SOZ[a]} ile ilgili "
             f"{B_SOZ[b]} diye yaziyor , {D_SOZ[d]} olarak degerlendirin")
    TALEP.append({"no": 5001 + i, "metin": m, "kod": (a, b, d)})

TUM = [(a, b, d) for a in ALAN for b in BELIRTI[a] for d in DERECE]
SAYAC = [0, 0, 0]                   # cagri sayisi, belirtec, basarisiz cagri


def yaz(y):
    return " ".join(y)


def uzat(p, k):                     # yolu k bilesen uzatan butun secenekler
    y = [p]
    for _ in range(k):
        z = []
        for q in y:
            z += [q + (s,) for s in (ALAN if not q else
                                     BELIRTI[q[0]] if len(q) == 1 else DERECE)]
        y = z
    return y


def cagir(istem, secenek, tohum=TOHUM, sicaklik=0.6):
    SAYAC[0] += 1
    bel = belirtecle(istem)
    SAYAC[1] += len(bel)
    if len(bel) > PENCERE or SAYAC[0] % 37 == 0:
        SAYAC[2] += 1
        return {"giris": len(bel), "yanit": None}
    r = uretec(tohum ^ izno(istem))
    p = {k: 0.15 for k in secenek}
    for t in bel:
        for tablo, w in ((A_IZ, 1.0), (T_IZ, 1.3), (B_IZ, 1.6), (D_IZ, 0.9)):
            h = tablo.get(t)
            if h is not None:
                for k in p:
                    if h in k:      # secenek bir yoldur; puan bilesenlerden toplanir
                        p[k] += w
    d = sorted(p, key=yaz)
    if sicaklik <= 0.0:
        k = max(d, key=lambda a: p[a])
    else:
        e = [math.exp(p[a] / sicaklik) for a in d]
        k = d[ayrik(r(), [v / sum(e) for v in e])]
    SAYAC[1] += len(belirtecle(yaz(k)))
    return {"giris": len(bel), "yanit": k}


def istemle(basmak, secenek, metin):
    return (basmak + " secenekler : " + " , ".join(yaz(k) for k in secenek)
            + " . Talep : " + metin)


x = TALEP[2]
print(f"KURGU: {len(TALEP)} talep, {len(TUM)} ariza kodu (4 alan x 4 belirti x 2 derece)")
print(f"talep {x['no']}: {x['metin']}")
print(f"dogru kod: {yaz(x['kod'])}")
s = cagir(istemle("Talebe bir ariza kodu ata .", TUM, x["metin"]), TUM)
print(f"tek cagri: giris {s['giris']} belirtec, yanit '{yaz(s['yanit'])}'")
ilk, aday = uzat((), 1), []
print("\nilk duzeyde uc ayri uzatma cagrisi:")
for j in range(3):
    u = cagir(istemle("Cozum yolunu bir adim uzat .", ilk, x["metin"]), ilk, TOHUM + j)
    print(f"  aday {j + 1}: {yaz(u['yanit'])} (giris {u['giris']} belirtec)")
    if u["yanit"] not in aday:
        aday.append(u["yanit"])
print("ikinci duzeyde her dalin uzantisi:")
for p in aday:
    se = uzat(p, 1)
    u = cagir(istemle("Cozum yolunu bir adim uzat .", se, x["metin"]), se)
    print(f"  {yaz(p)} -> {yaz(u['yanit'])}")
```

```
KURGU: 48 talep, 32 ariza kodu (4 alan x 4 belirti x 2 derece)
talep 5003: hesap uzerinden bildirdim , olcum ile ilgili rakam diye yaziyor , acil olarak degerlendirin
dogru kod: sayac endeks birinci
tek cagri: giris 235 belirtec, yanit 'sayac endeks birinci'

ilk duzeyde uc ayri uzatma cagrisi:
  aday 1: abonelik (giris 43 belirtec)
  aday 2: abonelik (giris 43 belirtec)
  aday 3: sayac (giris 43 belirtec)
ikinci duzeyde her dalin uzantisi:
  abonelik -> abonelik kayit
  sayac -> sayac endeks
```

İki sayı hemen görünüyor. Otuz iki kodu isteme yazmak istemi **235 belirtece** çıkarıyor; bağlam
penceresi 240, yani tek istemli düzen sınırın beş belirteç altında duruyor. Ağacın istemi yalnız
o düzeyin seçeneklerini taşıdığı için **43 belirteç**. Bölmenin ilk kazancı budur.

Alt dört satır dallanmanın niçin gerekli olduğunu gösteriyor. Talepte geçen "hesap" yanıltıcı
alanın izidir ve doğru alanın izi olan "olcum" sözcüğünden ağırdır; bu yüzden ilk iki uzatma
çağrısı `abonelik` diyor, doğru alan `sayac` ancak üçüncüde çıkıyor. Tek dallı bir arama burada
biterdi ve ikinci düzeyde `abonelik kayit` üretip talepte karşılığı olmayan bir yolda
derinleşirdi. Doğru dal tutulduğunda ikinci düzey `sayac endeks` veriyor, çünkü belirti izi
güçlüdür. **Ağacın vaat ettiği şey budur: zayıf kanıtla atılmış yanlış bir ilk adım, tek adım
olmadığı sürece geri alınabilir.**

#### Dal, Derinlik ve Çağrı Sayısı

İkinci blok ağacı kurar ve altı düzeni yan yana koyar: dallanma bire, ikiye, üçe ve dörde
çıkarılır, sonra dal üçte tutulup derinlik bire ve ikiye indirilir. Tek çağrı ile bir önceki
dersin beş örnekli öz tutarlılığı da tabloya girer; her satırın ikinci koşumu tohum
değiştirilerek alınır.

```python
BOLUM = {1: (3,), 2: (2, 1), 3: (1, 1, 1)}      # yol kac adima bolunuyor


def agac(x, dal, tut, derinlik, tohum):
    yol = [()]
    for k in BOLUM[derinlik]:
        aday = []
        for p in yol:                            # uretim: her dali dal kez uzat
            se = uzat(p, k)
            for j in range(min(dal, len(se))):
                s = cagir(istemle("Cozum yolunu bir adim uzat .", se, x), se, tohum + j)
                if s["yanit"] is not None and s["yanit"] not in aday:
                    aday.append(s["yanit"])
        if not aday:
            aday = uzat(yol[0], k)[:1]
        if len(aday) <= tut:
            yol = aday                           # secilecek bir sey yok, cagri harcanmaz
        else:
            yol = []
            for j in range(tut):                 # secim: tutulacak dallari ayikla
                s = cagir(istemle("En umut verici yollari sec .", aday, x), aday, tohum + j)
                if s["yanit"] is not None and s["yanit"] not in yol:
                    yol.append(s["yanit"])
            yol = yol or aday[:tut]
    s = cagir(istemle("Kalan yollardan birini kod olarak yaz .", yol, x), yol, tohum)
    return s["yanit"] or yol[0]


def tekli(x, k, tohum):                          # k = 1 tek cagri, k > 1 oz tutarlilik
    sayim = {}
    for j in range(k):
        s = cagir(istemle("Talebe bir ariza kodu ata .", TUM, x), TUM, tohum + j)
        if s["yanit"] is not None:
            sayim[s["yanit"]] = sayim.get(s["yanit"], 0) + 1
    return max(sorted(sayim, key=yaz), key=lambda a: sayim[a]) if sayim else None


def olc(f, tohum):
    SAYAC[:] = [0, 0, 0]
    d = 0
    for x in TALEP:
        d += f(x["metin"], tohum) == x["kod"]
    return {"isabet": d / len(TALEP), "cagri": SAYAC[0], "bel": SAYAC[1], "hata": SAYAC[2]}


SIRA = [("tek cagri", lambda x, t: tekli(x, 1, t)),
        ("oz tutarlilik 5 ornek", lambda x, t: tekli(x, 5, t)),
        ("agac dal 1 derinlik 3", lambda x, t: agac(x, 1, 1, 3, t)),
        ("agac dal 2 derinlik 3", lambda x, t: agac(x, 2, 2, 3, t)),
        ("agac dal 3 derinlik 3", lambda x, t: agac(x, 3, 3, 3, t)),
        ("agac dal 4 derinlik 3", lambda x, t: agac(x, 4, 4, 3, t)),
        ("agac dal 3 derinlik 1", lambda x, t: agac(x, 3, 3, 1, t)),
        ("agac dal 3 derinlik 2", lambda x, t: agac(x, 3, 3, 2, t))]

print(f"{'istem duzeni':<22}{'isabet':>8}{'kosum2':>8}{'fark':>8}{'cagri':>7}"
      f"{'belirtec':>10}{'basarisiz':>10}")
for ad, f in SIRA:
    A, B = olc(f, TOHUM), olc(f, TOHUM + 1)
    print(f"{ad:<22}{A['isabet']:>8.4f}{B['isabet']:>8.4f}"
          f"{B['isabet'] - A['isabet']:>+8.4f}{A['cagri']:>7d}{A['bel']:>10d}"
          f"{A['hata']:>10d}")
```

```
istem duzeni            isabet  kosum2    fark  cagri  belirtec basarisiz
tek cagri               0.4792  0.5208 +0.0417     48     11617         1
oz tutarlilik 5 ornek   0.7292  0.7708 +0.0417    240     58074         6
agac dal 1 derinlik 3   0.0833  0.2708 +0.1875    192      9776         5
agac dal 2 derinlik 3   0.4167  0.5417 +0.1250    506     26651        13
agac dal 3 derinlik 3   0.6250  0.5833 -0.0417    795     43182        21
agac dal 4 derinlik 3   0.6042  0.5833 -0.0208   1086     59835        29
agac dal 3 derinlik 1   0.6250  0.6250 +0.0000    192     37617         5
agac dal 3 derinlik 2   0.7292  0.7500 +0.0208    421     30650        11
```

Üçüncü satır bu dersin en sert sayısıdır. Çözümü üç adıma bölmek ama **hiç dallanmamak** isabeti
0,4792'den **0,0833'e** düşürüyor ve bunu dört kat çağrıyla yapıyor. Sebep birinci blokta
görüldü: dallanmayan bir arama ilk adımı en zayıf kanıtla atar ve bir daha dönemez. Tek istemli
düzende üç bileşen **aynı puanda birlikte** değerlendirildiği için güçlü belirti izi zayıf alan
izini taşıyabiliyordu; bölme bu taşımayı kesti. **Adıma bölmek tek başına bir iyileştirme
değildir; bedeli kesin, kazancı eksidir.**

Dallanma bunu geri alıyor. Dal ikide 0,4167, dal üçte **0,6250**. Kazancın nerede durduğu dördüncü
adımda görünür: dal dörde çıkarıldığında isabet **0,0208 geriliyor**, buna karşılık çağrı sayısı
795'ten **1086'ya**, belirteç 43182'den **59835'e**, başarısız çağrı 21'den **29'a** çıkıyor. Aynı
düzenin iki koşumu arasındaki fark dal üçte 0,0417'dir. Dal üçten dörde geçişin kattığı fark bu
sayıdan küçük olduğu için **ölçülmemiş sayılır**: iki yüz doksan bir çağrı ve on altı binden
fazla belirteç, gösterilemeyen bir değişiklik için harcandı.

Son iki satır derinlik eksenidir ve tersine bir sonuç verir. Aynı dal sayısıyla derinlik üçten
ikiye indirildiğinde isabet 0,6250'den **0,7292'ye** çıkıyor ve çağrı 795'ten 421'e iniyor: alanla
belirti birlikte seçildiğinde güçlü belirti izi zayıf alan izini yeniden taşıyabiliyor. Derinlik
bire indiğinde isabet 0,6250'de kalıyor ve çağrı **192'ye** düşüyor, ama istemler otuz iki
seçeneği birden taşıdığı için belirteç 30650'den 37617'ye çıkıyor. **Çağrı sıralaması ile
belirteç sıralaması aynı değildir.**

Tablonun ikinci satırı dersi kapatır. Bir önceki dersin beş örnekli öz tutarlılığı **0,7292**
veriyor — en iyi ağaç düzeniyle aynı sayı — ve bunu 421 yerine **240 çağrıyla** yapıyor.
Belirteçte durum tersine dönüyor: 58074'e karşı 30650. İki teknik arasındaki seçim bir üstünlük
sıralaması değil **bir birim seçimidir**; ağacın bu görevde kattığı ölçülebilir tek şey, aynı
isabete daha az belirteçle ulaşmasıdır. **Ölçülmeden değiştirilen istem bir iyileştirme değil
bir tahmindir** ve bu tabloda değiştirilen istemlerin yarısı bir iyileştirme değildi.

#### Özet

- Düşünce ağacı tek bir istem değil bir **istem düzenidir**: çözüm adımlara bölünür, her adımda
  birden çok uzatma istenir, adayların bir bölümü tutulur. Uzatma ve seçim çağrıları birlikte
  sayılır.
- Adıma bölmek dallanmadan yapıldığında zarar verir: isabet 0,4792'den **0,0833'e** düşüyor,
  çağrı 48'den 192'ye çıkıyor. Yanlış atılan ilk adım tek adımsa geri alınamıyor.
- Dallanma kazandırıyor ama doyuyor: dal 1'den 3'e isabet **0,0833'ten 0,6250'ye** çıkıyor,
  dal 4'te **0,0208 geriliyor**. Çağrı 192'den 1086'ya, belirteç 9776'dan 59835'e yükseliyor.
- Dal üçten dörde geçişin farkı, aynı düzenin iki koşumu arasındaki **0,0417 farktan küçüktür**;
  ölçülmemiş sayılır ve kazanç olarak yazılamaz.
- Derinlik ters yönde çalışıyor: 3 yerine 2 kullanmak isabeti **0,7292'ye** çıkarıp çağrıyı
  421'e indiriyor. Öz tutarlılık aynı isabeti **240 çağrı** ve **58074 belirteçle** veriyor;
  ağacın 30650 belirteci ucuz, 421 çağrısı pahalıdır.

#### Sonraki Adım

Bu üç teknik de aynı yönde çalıştı: modelden **daha çok adım** istendi. Düşünce zinciri adımları
tek yanıtın içine yazdırdı, öz tutarlılık aynı adımları birden çok kez ürettirip oyladı, düşünce
ağacı adımların arasına bir seçim kuralı koydu. Üçünde de adımlar **aynı düzeydedir**: hepsi
çözümün ayrıntısına doğru ilerler. Yanlış giden şey ise bu derste ayrıntının kendisiydi;
yanıltıcı bir sözcük ilk adımı bozdu ve sonraki bütün adımlar o bozuk adımın üzerine kuruldu.

Ayrıntıya inmeden önce **yukarı çıkmak** hiç denenmedi. Bir talebe kod atamadan önce o talebin
hangi genel kurala girdiğini sormak elde bulunan bir seçenekti. Sonraki ders bunu ölçer: istem
iki aşamaya bölünür, önce ilke sorulur sonra çözüm istenir ve iki aşamalının tek aşamalıya göre
isabeti ne kadar oynattığı ile kaç belirteç eklediği yan yana basılır.

### Geri Adım İstemi

Source: https://academia.sh/tr/kurslar/istem-muhendisligi/geri-adim-istemi

Çözmeden önce ilke sormanın ölçülmesi: aynı 48 kurgu destek talebinde tek aşamalı istem 0,5417 kod isabeti ve 48 çağrı veriyor, önce genel kuralı sorup sonra çözüm isteyen iki aşamalı istem 0,7500 veriyor ve bunu 96 çağrı ile 1,66 kat belirteçle yapıyor. Kazancın tamamı birinci aşamaya bağlı: doğru ilkede kod isabeti 0,8000, yanlış ilke dayatıldığında 0,0000 ile 0,1458 arasına düşüyor, yani tek aşamalının altına iniyor. Aynı düzen yalnız derece soran görevde isabeti hiç oynatmıyor ama belirteci 2,69 katına çıkarıyor.

Önceki üç ders modelden hep aynı şeyi istedi: **daha çok adım**. Adımlar tek yanıtın içine
yazdırıldı, çoğaltılıp oylandı, dallandırılıp ayıklandı — ve üçünde de aynı yöne, talebin
ayrıntısına doğru baktılar. Ağaç dersinde hata tam oradan geldi: yanıltıcı bir sözcük ilk adımı
bozdu ve hiçbir adım "bu talepte neye bakmam gerekiyordu" diye sormadı.

Geri adım istemi ters yöne gider. Çözümü istemeden önce **soyutlama düzeyini yükseltir**: bu tür
talepler hangi genel kurala göre çözülür. İstem yine metindir, ama bu kez **iki aşamalıdır** ve
birincinin çıktısı ikincinin girdisine yazılır. Bedeli peşin bellidir — çağrı sayısı ikiye
katlanır. Ölçülecek olan bunun karşılığında ne alındığıdır.

- **AY28.** Görev ve kurgu bir önceki derstekiyle aynıdır: 48 kurgu destek talebi, üç bileşenli
  arıza kodu, toplam otuz iki kod. Çağrılan şey bir **benzeticidir**; gerçek bir model uç
  noktasına hiçbir istek gitmez. Tohum **20260218**, ikinci koşum 20260219.
- **AY29.** Kurgu **ilke dağarcığı** dört genel kuraldır. Bir ilke istemin başına yazıldığında
  benzeticinin hangi ize ne kadar ağırlık verdiği değişir; bu kurgu düzenek, gerçek bir yönergenin
  yaptığı şeyin ölçülebilir karşılığıdır — yönerge kanıt seçer.
- **AY30.** Bu kurguda **doğru ilke `gozlem`dir**: kod, talebin bildirdiği belirtiye ve yere göre
  seçilir, kaydın açıldığı kanala göre değil. Öbür üç ilke yanlıştır.
- **AY31.** İki aşama **iki çağrıdır**. Birinci aşamanın yanıtı ikinci istemin başına **aynen**
  yazılır; arada düzeltme, doğrulama ya da geri dönüş yoktur.
- **AY32.** Seçenekler isteme **bileşen listeleri** olarak yazılır; otuz iki kodun tek tek
  yazılması ilkeye yer bırakmaz.
- **AY33.** Bedel dört birimle yazılır: **çağrı sayısı**, **giriş belirteci**, **çıkış belirteci**
  ve **başarısız çağrı**. Ölçüt kod görevinde üç bileşenin birden, derece görevinde derecenin
  doğru olmasıdır.

#### Önce İlke, Sonra Çözüm

Önceki istem tektir: yönerge, seçenekler ve talep bir arada gider. Değiştirilmiş istem ikiye
ayrılır. Birinci çağrı yalnız **hangi genel kuralın geçerli olduğunu** sorar; talebi görür ama
kod seçeneklerini görmez. İkinci çağrı dönen kuralın metnini başına alıp asıl işi ister. İlk blok
benzeticiyi, ilke dağarcığını ve bir talep üzerinde iki aşamayı kurar.

```python
# BENZETICI. Bu kod gercek bir model uc noktasi cagirmaz; standart kitaplikla yazilmis
# bir dil modeli benzeticisidir. Destek talepleri ve ariza kodlari da KURGU'dur.
import math

TOHUM, M32 = 20260218, 0xFFFFFFFF
PENCERE = 240                       # baglam penceresi, belirtec


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):                  # KURGU belirtecleyici: parca en cok bes damga
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


def izno(m):                        # istemin icerigine bagli, kosumdan bagimsiz iz
    h = 2166136261
    for c in m:
        h = ((h ^ ord(c)) * 16777619) & M32
    return h


ALAN = ["dagitim", "sayac", "abonelik", "saha"]
BELIRTI = {"dagitim": ["kesinti", "basinc", "sizinti", "tikanma"],
           "sayac": ["endeks", "bozukluk", "degisim", "okuma"],
           "abonelik": ["tarife", "fatura", "odeme", "kayit"],
           "saha": ["randevu", "erisim", "malzeme", "gecikme"]}
DERECE = ["birinci", "ikinci"]
A_SOZ = {"dagitim": "sebeke", "sayac": "olcum", "abonelik": "sozlesme", "saha": "ekip"}
T_SOZ = {"dagitim": "hatti", "sayac": "cihaz", "abonelik": "hesap", "saha": "servis"}
B_SOZ = {"kesinti": "akmiyor", "basinc": "zayif", "sizinti": "islak", "tikanma": "dolmus",
         "endeks": "rakam", "bozukluk": "calismiyor", "degisim": "yenisi", "okuma": "girilmemis",
         "tarife": "basamak", "fatura": "tutar", "odeme": "borcum", "kayit": "musteri",
         "randevu": "saatte", "erisim": "kapali", "malzeme": "parca", "gecikme": "bekliyor"}
D_SOZ = {"birinci": "acil", "ikinci": "normal"}
A_IZ = {A_SOZ[a][:5]: a for a in ALAN}                 # yer izi, zayif
T_IZ = {T_SOZ[a][:5]: a for a in ALAN}                 # kanal izi, daha agir
B_IZ = {B_SOZ[b][:5]: b for a in ALAN for b in BELIRTI[a]}
D_IZ = {D_SOZ[d][:5]: d for d in DERECE}
I_IZ = {"sorun": "gozlem", "ilgil": "gozlem", "durum": "gozlem", "diye": "gozlem",
        "taraf": "gozlem", "yaziy": "gozlem", "kayit": "kanal", "uzeri": "kanal",
        "acilm": "sira", "bildi": "sira", "gerek": "sure", "deger": "sure"}
ILKE = {"gozlem": "ilke gozlem : kod , talebin bildirdigi belirtiye ve yere gore secilir .",
        "kanal": "ilke kanal : kod , kaydin acildigi kanala gore secilir .",
        "sure": "ilke sure : kod , bildirimin aciliyet duzeyine gore secilir .",
        "sira": "ilke sira : kod , talebin geldigi siraya gore secilir ."}
KURAL = {"gozle": {"A": 2.4, "T": 0.2, "B": 2.8},      # anahtar : ilke adinin ilk parcasi
         "kanal": {"A": 0.3, "T": 2.6}, "sure": {"B": 0.6}, "sira": {"A": 0.4, "B": 0.5}}

TALEP = []
for i in range(48):
    r = uretec(TOHUM + i)
    a = ALAN[int(r() * 4)]
    b = BELIRTI[a][int(r() * 4)]
    d = DERECE[int(r() * 2)]
    y = ALAN[(ALAN.index(a) + 1 + int(r() * 3)) % 4]    # talepte gecen kanal, yaniltici
    if r() < 0.5:
        m = (f"{T_SOZ[y]} icin kayit acilmisti ama sorun {A_SOZ[a]} tarafinda , "
             f"{B_SOZ[b]} durumu var , {D_SOZ[d]} bakilmasi gerekiyor")
    else:
        m = (f"{T_SOZ[y]} uzerinden bildirdim , {A_SOZ[a]} ile ilgili "
             f"{B_SOZ[b]} diye yaziyor , {D_SOZ[d]} olarak degerlendirin")
    TALEP.append({"no": 5001 + i, "metin": m, "kod": (a, b, d)})

TUM = [(a, b, d) for a in ALAN for b in BELIRTI[a] for d in DERECE]
SAYAC = [0, 0, 0, 0]                # cagri, giris belirteci, cikis belirteci, basarisiz


def yaz(y):
    return " ".join(y)


def cagir(istem, secenek, tohum=TOHUM, sicaklik=0.6):
    SAYAC[0] += 1
    bel = belirtecle(istem)
    SAYAC[1] += len(bel)
    if len(bel) > PENCERE or SAYAC[0] % 37 == 0:
        SAYAC[3] += 1
        return {"giris": len(bel), "yanit": None}
    ag = {"A": 1.0, "T": 1.3, "B": 1.6, "D": 0.9}
    for t in bel:
        ag.update(KURAL.get(t, {}))            # istemdeki ilke, iz agirliklarini degistirir
    r = uretec(tohum ^ izno(istem))
    p = {k: 0.15 for k in secenek}
    for t in bel:
        for tablo, w in ((A_IZ, ag["A"]), (T_IZ, ag["T"]), (B_IZ, ag["B"]),
                         (D_IZ, ag["D"]), (I_IZ, 1.0)):
            h = tablo.get(t)
            if h is not None:
                for k in p:
                    if h in k:
                        p[k] += w
    d = sorted(p, key=yaz)
    if sicaklik <= 0.0:
        k = max(d, key=lambda a: p[a])
    else:
        e = [math.exp(p[a] / sicaklik) for a in d]
        k = d[ayrik(r(), [v / sum(e) for v in e])]
    SAYAC[2] += len(belirtecle(yaz(k)))
    return {"giris": len(bel), "yanit": k}


KOD_ISTEM = ("Talebe bir ariza kodu ata . alanlar : " + " , ".join(ALAN)
             + " . belirtiler : " + " , ".join(b for a in ALAN for b in BELIRTI[a])
             + " . dereceler : " + " , ".join(DERECE) + " . Talep : ")
ILKE_ISTEM = ("Cozmeden once bu talebin hangi genel kurala girdigini yaz . kurallar : "
              + " , ".join(sorted(ILKE)) + " . Talep : ")

x = TALEP[2]
print(f"KURGU: {len(TALEP)} talep, {len(TUM)} ariza kodu, {len(ILKE)} genel kural")
print(f"talep {x['no']}: {x['metin']}")
print(f"dogru kod: {yaz(x['kod'])}")
t1 = cagir(KOD_ISTEM + x["metin"], TUM)
print(f"tek asamali: giris {t1['giris']} belirtec, yanit '{yaz(t1['yanit'])}'")
i1 = cagir(ILKE_ISTEM + x["metin"], [(k,) for k in sorted(ILKE)])
print(f"\nbirinci asama: giris {i1['giris']} belirtec, ilke '{yaz(i1['yanit'])}'")
for ad in ("gozlem", "kanal"):
    t2 = cagir(ILKE[ad] + " " + KOD_ISTEM + x["metin"], TUM)
    print(f"ikinci asama ilke {ad}: giris {t2['giris']} belirtec, yanit '{yaz(t2['yanit'])}'")
u = cagir(ILKE["gozlem"] + " Talebe bir ariza kodu ata . secenekler : "
          + " , ".join(yaz(k) for k in TUM) + " . Talep : " + x["metin"], TUM)
print(f"\notuz iki kod tek tek yazilsaydi: giris {u['giris']} belirtec (sinir {PENCERE}) , "
      f"yanit {u['yanit']}")
```

```
KURGU: 48 talep, 32 ariza kodu, 4 genel kural
talep 5003: hesap uzerinden bildirdim , olcum ile ilgili rakam diye yaziyor , acil olarak degerlendirin
dogru kod: sayac endeks birinci
tek asamali: giris 100 belirtec, yanit 'abonelik fatura birinci'

birinci asama: giris 49 belirtec, ilke 'gozlem'
ikinci asama ilke gozlem: giris 118 belirtec, yanit 'sayac endeks ikinci'
ikinci asama ilke kanal: giris 115 belirtec, yanit 'abonelik odeme birinci'

otuz iki kod tek tek yazilsaydi: giris 253 belirtec (sinir 240) , yanit None
```

Tek aşamalı istem `abonelik fatura birinci` diyor: talepte geçen "hesap" kaydın açıldığı kanaldır
ve izi ağırdır, asıl kanıt olan "olcum" onun altında kaldı. Birinci aşama 49 belirteç harcayıp
`gozlem` kuralını buluyor; kural ikinci istemin başına yazıldığında yanıt `sayac endeks ikinci`
oluyor — alan ve belirti düzeldi, derece hâlâ yanlış. Kural derece hakkında bir şey söylemiyor,
kalan hata da tam orada.

Üçüncü satır bedelin öbür yüzüdür. Yanlış ilke — `kanal` — ikinci istemin başına yazıldığında
yanıt `abonelik odeme birinci` oluyor; tek aşamalıdan daha kötü. İkinci aşama kendi başına bir
düzeltme yapmıyor, **önüne konan kurala uyuyor**. Son satır bir tasarım kısıtıdır: bir önceki
dersin istemi otuz iki kodu tek tek yazıyordu ve başına ilke eklendiğinde giriş 253 belirtece
çıkıp 240 sınırını aşıyor, çağrı hiç yanıt üretmeden dönüyor. **Geri adım istemi için pencerede
yer açılmış olması gerekir**; seçenekler bu yüzden bileşen listesi olarak yazıldı.

#### İki Aşamanın Kattığı ve Aldığı

İkinci blok iki görevi ölçer: üç bileşenli kod ve yalnız **derece** — talepte harfi harfine
yazılı olan tek bileşen. Her görev tek aşamalı ve geri adımlı, her düzen iki koşumda koşturulur.
Sonda kazancın kaynağı ayrılır: birinci aşama kaç talepte doğru ilkeyi buldu ve her ilke tek tek
dayatıldığında ikinci aşama ne veriyor.

```python
DER_ISTEM = "Talebin derecesini yaz . dereceler : " + " , ".join(DERECE) + " . Talep : "
ILKE_SEC = [(k,) for k in sorted(ILKE)]
KOD, DER = lambda x: x["kod"], lambda x: (x["kod"][2],)


def tek(istem, secenek):
    return lambda x, t: (cagir(istem + x["metin"], secenek, t)["yanit"], None)


def geri(istem, secenek):                        # once ilke , sonra cozum
    def f(x, t):
        i = cagir(ILKE_ISTEM + x["metin"], ILKE_SEC, t)
        ad = i["yanit"][0] if i["yanit"] else "sira"
        return cagir(ILKE[ad] + " " + istem + x["metin"], secenek, t)["yanit"], ad
    return f


def olc(f, hedef, tohum=TOHUM):
    SAYAC[:] = [0, 0, 0, 0]
    d = ni = di = yi = 0
    for x in TALEP:
        y, ad = f(x, tohum)
        v = y == hedef(x)
        d += v
        if ad is not None:
            ni += ad == "gozlem"
            di += v and ad == "gozlem"
            yi += v and ad != "gozlem"
    n = len(TALEP)
    return {"isabet": d / n, "nd": ni, "di": di / ni if ni else 0.0,
            "yi": yi / (n - ni) if ni < n else 0.0, "cagri": SAYAC[0],
            "giris": SAYAC[1], "cikis": SAYAC[2], "hata": SAYAC[3]}


SIRA = [("kod tek asamali", tek(KOD_ISTEM, TUM), KOD),
        ("kod geri adim", geri(KOD_ISTEM, TUM), KOD),
        ("derece tek asamali", tek(DER_ISTEM, [(d,) for d in DERECE]), DER),
        ("derece geri adim", geri(DER_ISTEM, [(d,) for d in DERECE]), DER)]

print(f"{'istem duzeni':<20}{'isabet':>8}{'kosum2':>8}{'fark':>8}{'cagri':>7}"
      f"{'giris':>8}{'cikis':>7}{'basarisiz':>10}")
S = {}
for ad, f, h in SIRA:
    A, B = olc(f, h), olc(f, h, TOHUM + 1)
    S[ad] = A
    print(f"{ad:<20}{A['isabet']:>8.4f}{B['isabet']:>8.4f}"
          f"{B['isabet'] - A['isabet']:>+8.4f}{A['cagri']:>7d}{A['giris']:>8d}"
          f"{A['cikis']:>7d}{A['hata']:>10d}")
for ad in ("kod", "derece"):
    a, b = S[ad + " tek asamali"], S[ad + " geri adim"]
    ta, tb = a["giris"] + a["cikis"], b["giris"] + b["cikis"]
    print(f"\n{ad} gorevinin bedeli: cagri {a['cagri']} -> {b['cagri']} , "
          f"belirtec {ta} -> {tb} ({tb / ta:.2f} kat)")
K = S["kod geri adim"]
print(f"ilke asamasi: dogru ilke {K['nd']}/{len(TALEP)} , dogru ilkede kod isabeti "
      f"{K['di']:.4f} , yanlis ilkede {K['yi']:.4f} ({len(TALEP) - K['nd']} talep)")
print("ilke dayatildiginda kod isabeti:", end="")
for ad in sorted(ILKE):
    A = olc(lambda x, t, a=ad: (cagir(ILKE[a] + " " + KOD_ISTEM + x["metin"],
                                      TUM, t)["yanit"], None), KOD)
    print(f" {ad} {A['isabet']:.4f}", end="")
print()
```

```
istem duzeni          isabet  kosum2    fark  cagri   giris  cikis basarisiz
kod tek asamali       0.5417  0.4792 -0.0625     48    4889    249         1
kod geri adim         0.7500  0.6458 -0.1042     96    8185    339         2
derece tek asamali    0.7708  0.7500 -0.0208     48    1913     94         1
derece geri adim      0.7708  0.7917 +0.0208     96    5209    186         2

kod gorevinin bedeli: cagri 48 -> 96 , belirtec 5138 -> 8524 (1.66 kat)

derece gorevinin bedeli: cagri 48 -> 96 , belirtec 2007 -> 5395 (2.69 kat)
ilke asamasi: dogru ilke 45/48 , dogru ilkede kod isabeti 0.8000 , yanlis ilkede 0.0000 (3 talep)
ilke dayatildiginda kod isabeti: gozlem 0.7708 kanal 0.0000 sira 0.0625 sure 0.1458
```

Kod görevinde iki aşamalı istem **0,5417'den 0,7500'e** çıkıyor, ikinci koşumda 0,4792'den
0,6458'e. Kazanç iki koşumda **+0,2083** ve **+0,1667**; düzenlerin kendi iki koşum farkları
0,0625 ve 0,1042. Kazanç ikisinden de büyük olduğu için bu fark **ölçülmüş sayılır** — bu konudaki
tekniklerin hepsi bu sınavı geçmiyor. Bedel de kesindir: çağrı 48'den **96'ya**, giriş belirteci
4889'dan 8185'e, toplam belirteç **1,66 kat**, doğru kod başına bedel 198'den 237 belirtece.
Teknik hem işe yaradı hem pahalılaştı.

Son iki satır kazancın kaynağını ve tekniğin asıl riskini söylüyor. Birinci aşama 48 talebin
**45'inde** doğru kuralı buldu ve o 45 talepte kod isabeti **0,8000**. Yanlış kural seçilen üç
talebin üçünde de kod yanlış çıktı — küçük bir sayı, ama son satır bunu tek başına kanıtlıyor.
Dört kural sırayla dayatıldığında ikinci aşama `gozlem` ile **0,7708**, `sure` ile 0,1458, `sira`
ile 0,0625 ve `kanal` ile **0,0000** veriyor; üçü de tek aşamalının **0,5417'sinin altında**.
Geri adım istemi modele akıl yürütme eklemiyor, isteme **yanlış olabilecek yeni bir yer** ekliyor.

Alt iki satır tekniğin sınırıdır. Derece görevinde tek aşamalı istem 0,7708 ve 0,7500, geri adımlı
istem 0,7708 ve 0,7917 veriyor; fark bir koşumda **0,0000**, öbüründe +0,0417 ve ikisi de
düzenlerin kendi koşum farkları mertebesinde. **Ölçülmemiş sayılır.** Buna karşılık çağrı yine
ikiye katlanıyor, belirteç **2,69 kata** çıkıyor — kod görevindekinden kötü bir oran, çünkü asıl
istem kısaldıkça ilke metninin payı büyüyor. Derece talepte harfi harfine yazılıdır; çözüm yanlış
soyutlama düzeyinde takılmıyor. **Geri adım istemi, hatanın kaynağı kanıt seçimi olduğunda
kazandırır; kanıt zaten doğru seçiliyorsa yalnız iki kat çağrıdır.**

#### Özet

- Geri adım istemi çağrıyı ikiye böler: birinci çağrı talebin girdiği **genel kuralı** sorar,
  ikinci çağrı o kuralı başına yazıp çözümü ister. Arada düzeltme yoktur.
- Kod görevinde isabet **0,5417'den 0,7500'e** çıkıyor (ikinci koşumda 0,4792'den 0,6458'e) ve
  kazanç düzenlerin iki koşum farklarından büyük olduğu için ölçülmüş sayılır.
- Bedel kesindir: çağrı **48'den 96'ya**, toplam belirteç **1,66 kat**, doğru kod başına bedel
  198'den 237 belirtece.
- Kazanç birinci aşamaya bağlıdır: doğru kural 45 talepte bulundu ve orada isabet **0,8000**.
  Kurallar tek tek dayatıldığında ikinci aşama **0,7708 ile 0,0000** arasında değişiyor; üç
  yanlış kural da tek aşamalının altında.
- Yalnız derece soran görevde fark **0,0000 ile +0,0417** arasında kalıp ölçülemiyor, belirteç ise
  **2,69 kata** çıkıyor. Harfi harfine yazılı bir bileşen için soyutlama düzeyini yükseltmenin
  karşılığı yoktur.

#### Sonraki Adım

Dört ders dört ayrı istem düzeni kurdu ve dördü de aynı yerden kazanmaya çalıştı: **modelin
kendi içinde daha çok adım atması**. Hepsinde adımların tamamı benzeticinin içinde geçti;
dışarıdan gelen tek şey talebin metniydi ve o metin ilk çağrıda zaten elde vardı.

Bu derste bunun sınırı göründü. Doğru kuralın ne olduğu talebin içinde yazılı değildi; birinci
aşama onu benzeticinin kendi eğiliminden çıkardı ve üç talepte yanıldı. Kuralın **dışarıdan
okunabildiği** bir durum — kurgu belge dağarcığına bakmak, bir kaydı sorgulamak — hiç ele
alınmadı. Adımlardan birinin **dışarıya bakmak** olduğu istem düzeni sonraki dersin konusudur:
düşünce ile eylemin aynı istemde istenmesi ve bunun kaç yanıtta geçerli bir eylem ürettiği.

### Akıl Yürüt ve Davran

Source: https://academia.sh/tr/kurslar/istem-muhendisligi/akil-yurut-ve-davran

Aynı istemde düşünce alanı ile eylem alanının birlikte istenmesinin ölçüsü: 120 kurgu destek talebinde eylem alanı istendiğinde yanıtların yalnız 0,1000 payı geçerli bir eylem alanı üretiyor, eylem kümesi isteme yazıldığında 0,5250, düşünce tek cümleye indirildiğinde 0,8000. Bedel giriş belirtecinde 5300'den 8060'a çıkıyor ve geçerli eylem alanı başına 645,8 belirteçten 102,1 belirtece iniyor. İki koşum karşılaştırması eylem kümesini yazmanın farkını ölçülemez bırakıyor.

Bu konunun ilk dört dersi aynı şeyi dört ayrı biçimde istedi: model, yanıtı vermeden önce
**kendi içinde** daha çok adım atsın. Adımlar zincir oldu, çoğaltıldı, dallandırıldı ve
soyutlandı; dördünde de hepsi modelin içinde geçti. Oysa bir talebi çözen adımlardan biri
düşünmek değil, **dışarıya bakmaktır** — bir belgeyi aramak, geçmiş bir kaydı getirmek, yeni
bir kayıt açmak. Bu ders o adımın **istemde nasıl istendiğini** ölçer: aynı istemde bir
**düşünce alanı** ve bir **eylem alanı** birlikte istendiğinde kaç yanıt geçerli bir eylem
alanı üretiyor ve bunun bedeli ne.

Ölçülen şey eylemin kendisi değildir. Bu derste hiçbir eylem çalıştırılmaz; araç düzeneği,
bellek ve döngü bu müfredatın yapay zekâ ajanları kursuna bırakılır.

- **AY41.** Kod gerçek bir model uç noktası çağırmaz; standart kitaplıkla yazılmış bir **dil
  modeli benzeticisini** çağırır. Destek talepleri de **kurgudur**: 120 kayıt, beş konu.
- **AY42.** Tohum **20260218**. Aynı istem aynı tohumda aynı yanıtı verir; belirsizlik **tohum
  değiştirilerek** ölçülür, ikinci koşum 20260219'dur.
- **AY43.** Eylem adları kurgudur ve üç tanedir; hiçbiri çalıştırılmaz, yanıt metni okunur ve
  orada bırakılır.
- **AY44.** Üç sayı ayrı ayrı sayılır: **etiket isabeti**, **eylem alanı taşıyan yanıt payı**
  ve **geçerli eylem alanı payı**. Geçerli sayılması için adın kapalı kümeden gelmesi ve
  argümanın parantezle kapanmış olması gerekir.
- **AY45.** Benzeticinin biçim dalı isteme bağlıdır: eylem alanı istendiğinde alan kalıpları,
  yalnız düşünce istendiğinde düşünce kalıpları üretilir; düşünce kalıplarının hepsi etiket
  taşır.
- **AY46.** Eylem adlarının isteme yazılması kalıp ağırlıklarını değiştirir. Etiket kümesini
  isteme yazmanın eylem kümesindeki karşılığıdır.
- **AY47.** En büyük çıktı **24 belirteçtir**. Uzun bir düşünce ile eylem alanı aynı yanıta
  sığmadığında durdurma koşulu alanı **ortadan keser** ve kesilen yanıtta eylem adı bozulur.
- **AY48.** Dört istem yalnız **metinde** ayrılır. Model, görev, küme ve tohum sabittir.

#### Aynı İstemde İki Alan

Görev değişmedi: 120 kurgu talebin her biri beş konudan birine atanacak. Değişen tek şey
istemin metnidir. **P1** bu konunun bıraktığı yerdir: önce düşün, sonra etiketi yaz. **P2**
aynı isteme bir eylem alanı ekler. **P3** eylem kümesini açıkça sayar. **P4** buna tek bir
cümle daha ekler: düşünceyi kısa tut.

```python
# BENZETICI. Gercek bir model uc noktasi cagrilmaz; standart kitaplikla yazilmis bir dil
# modeli benzeticisidir. Destek talepleri ve eylem kumesi KURGU'dur; hicbir eylem calismaz.
import math

TOHUM, M32 = 20260218, 0xFFFFFFFF
PENCERE, EN_UZUN = 240, 24


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


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


KONU = ["fatura", "ariza", "sayac", "tarife", "kesinti"]
KALIP = {
    "fatura": ["bu ayki fatura tutari gecen aya gore cok yuksek geldi",
               "faturami odedim ama sistemde borc gorunuyor",
               "fatura ayrintisini nereden gorebilirim"],
    "ariza": ["evde su akmiyor bir ariza var galiba",
              "baglanti bozuk oldu ve hic calismiyor",
              "ariza kaydi actim ama ekip gelmedi"],
    "sayac": ["sayac okumasi yanlis girilmis endeks tutmuyor",
              "sayac degisimi icin randevu istiyorum",
              "sayac uzerindeki endeks ile fatura ayni degil"],
    "tarife": ["hangi tarife basamagindayim ogrenmek istiyorum",
               "tarife degisikligi icin ne yapmam gerekiyor",
               "birim ucret abone tipine gore degisiyor mu"],
    "kesinti": ["mahallede kesinti var ne zaman gelecek",
                "planli kesinti duyurusu nereden takip edilir",
                "aksamdan beri kesinti yasiyoruz"],
}
EK = ["ayrica gecen ay da ayni sorun olmustu", "bu konuda memnun degilim",
      "acil bilgi almam gerekiyor", "kayit numaram elimde yok"]

TALEP = []
for i in range(120):
    r = uretec(TOHUM + i)
    k = KONU[ayrik(r(), [0.24, 0.22, 0.18, 0.20, 0.16])]
    m = KALIP[k][int(r() * 3)]
    if r() < 0.34:
        m += " " + EK[int(r() * 4)]
    TALEP.append({"no": 4001 + i, "metin": m, "konu": k})

KAVRAM = KONU + ["odeme", "sikayet", "bilgi", "genel"]
IZ = {"fatur": "fatura", "tutar": "fatura", "ayrin": "fatura",
      "ariza": "ariza", "bozuk": "ariza", "calis": "ariza", "akmiy": "ariza",
      "sayac": "sayac", "endek": "sayac", "okuma": "sayac",
      "tarif": "tarife", "birim": "tarife", "abone": "tarife", "basam": "tarife",
      "kesin": "kesinti", "duyur": "kesinti", "mahal": "kesinti",
      "borc": "odeme", "odedi": "odeme", "ucret": "odeme",
      "memnu": "sikayet", "sorun": "sikayet", "acil": "sikayet",
      "bilgi": "bilgi", "ogren": "bilgi", "nered": "bilgi"}
TUZAK = {"degis": "tarife", "kayit": "ariza", "yukse": "tarife", "gorun": "fatura",
         "ekip": "kesinti", "takip": "tarife", "giril": "fatura"}
SERBEST = ["talebiniz {k} konusuyla ilgili gorunuyor",
           "bu kayit {k} basligina girer , ilgili ekibe yonlendirildi",
           "kaydiniz alindi , konuyu inceleyip donus yapacagiz"]
SAYAC = [0]

EYLEM = ["belge_ara", "gecmis_getir", "kayit_ac"]        # KURGU eylem adlari
DUSUNCE = ["dusunce : metinde {k} isaretleri var | etiket : {k}",
           "dusunce : once konu belirlendi sonra etiket yazildi | etiket : {k}",
           "dusunce : kaydiniz alindi , {k} basligina girer"]
ALAN = ["dusunce : metinde {k} isaretleri var ve gecmis kayit kontrol edilmeli "
        "| eylem : belge_ara ( {k} )",
        "dusunce : {k} konusunda once gecmis kayit gerekli | eylem : gecmis_getir ( {k} )",
        "dusunce : bu kayit {k} basligina girer , dogrudan yanit yazilabilir"]
ALAN_KISA = ["dusunce : {k} isareti var | eylem : belge_ara ( {k} )",
             "dusunce : gecmis gerekli | eylem : gecmis_getir ( {k} )",
             "dusunce : {k} basligina girer"]


def cagir(istem, tohum=TOHUM, sicaklik=0.6, en_uzun=EN_UZUN):
    SAYAC[0] += 1
    bel = belirtecle(istem)
    if len(bel) > PENCERE:
        return {"durum": "baglam_asimi", "giris": len(bel), "cikis": 0,
                "yanit": "", "kesik": 0}
    if SAYAC[0] % 37 == 0:
        return {"durum": "hiz_siniri", "giris": len(bel), "cikis": 0,
                "yanit": "", "kesik": 0}
    r = uretec(tohum ^ izno(istem))
    if len(bel) > 90 and r() < 0.04:
        return {"durum": "zaman_asimi", "giris": len(bel), "cikis": 0,
                "yanit": "", "kesik": 0}
    aday = [k for k in KAVRAM if k[:5] in bel]
    if len(aday) < 3:
        aday = KAVRAM
    p = {k: 0.15 for k in aday}
    for t in bel:
        for tablo, w in ((IZ, 1.0), (TUZAK, 1.3)):
            if tablo.get(t) in p:
                p[tablo[t]] += w
    if sicaklik <= 0.0:
        k = max(sorted(p), key=lambda a: p[a])
    else:
        e = [math.exp(p[a] / sicaklik) for a in sorted(p)]
        k = sorted(p)[ayrik(r(), [v / sum(e) for v in e])]
    if "eylem" in bel:                                   # dusunce + eylem alani
        acik = all(a[:5] in bel for a in EYLEM)          # eylem kumesi yazilmis mi
        w = [0.46, 0.38, 0.16] if acik else [0.30, 0.22, 0.48]
        y = (ALAN_KISA if "kisa" in bel else ALAN)[ayrik(r(), w)].format(k=k)
    elif "dusun" in bel:                                 # yalniz dusunce alani
        y = DUSUNCE[ayrik(r(), [0.42, 0.26, 0.32])].format(k=k)
    elif "tek" in bel:
        y = k
    else:
        y = SERBEST[ayrik(r(), [0.42, 0.26, 0.32])].format(k=k)
    cb, kesik = belirtecle(y), 0
    if len(cb) > en_uzun:                                # durdurma kosulu
        cb, kesik = cb[:en_uzun], 1
        y = " ".join(cb)
    return {"durum": "tamam", "giris": len(bel), "cikis": len(cb),
            "yanit": y, "kesik": kesik}


def oku(y):
    for s in y.lower().split():
        if s in KONU:
            return s
    return None


def oku_eylem(y):                     # eylem alani okunuyor, hicbir eylem calistirilmiyor
    if "eylem :" not in y:
        return None
    p = y.split("eylem :", 1)[1].split()
    if len(p) < 3 or p[0] not in EYLEM or p[1] != "(" or ")" not in p[2:]:
        return None
    return p[0]


ETIKET = "Talebi su etiketlerden birine ata: fatura , ariza , sayac , tarife , kesinti . "
EY = "Once dusun , sonra yapilacak eylemi yaz . "
KUME = "Eylem su kumeden secilir: belge_ara , gecmis_getir , kayit_ac . "
P1 = ETIKET + "Once dusun , sonra etiketi yaz . Talep: "
P2 = ETIKET + EY + "Talep: "
P3 = ETIKET + EY + KUME + "Talep: "
P4 = ETIKET + EY + KUME + "Dusunceyi kisa tut . Talep: "

t = TALEP[6]
print(f"KURGU talep {t['no']} ({t['konu']}): {t['metin']}")
for ad, o in (("P1 yalniz dusunce", P1), ("P2 eylem alani", P2),
              ("P3 kume yazili", P3), ("P4 dusunce kisa", P4)):
    s = cagir(o + t["metin"])
    print(f"\n{ad}: giris {s['giris']} bel, cikis {s['cikis']} bel, kesik {s['kesik']}, "
          f"etiket {oku(s['yanit'])}, gecerli eylem {oku_eylem(s['yanit'])}")
    print(f"  {s['yanit']}")
```

```
KURGU talep 4007 (sayac): sayac uzerindeki endeks ile fatura ayni degil

P1 yalniz dusunce: giris 42 bel, cikis 14 bel, kesik 0, etiket sayac, gecerli eylem None
  dusunce : metinde sayac isaretleri var | etiket : sayac

P2 eylem alani: giris 44 bel, cikis 16 bel, kesik 0, etiket sayac, gecerli eylem None
  dusunce : bu kayit sayac basligina girer , dogrudan yanit yazilabilir

P3 kume yazili: giris 60 bel, cikis 16 bel, kesik 0, etiket ariza, gecerli eylem None
  dusunce : bu kayit ariza basligina girer , dogrudan yanit yazilabilir

P4 dusunce kisa: giris 65 bel, cikis 16 bel, kesik 0, etiket sayac, gecerli eylem gecmis_getir
  dusunce : gecmis gerekli | eylem : gecmis_getir ( sayac )
```

Tek kayıtta dört istem, dört ayrı sonuç verdi. P2 ve P3 eylem alanı istedi, yanıt bunun
yerine bir gerekçe cümlesi döndürdü; üstelik P3'te etiket de kaydı. Yalnız P4 hem doğru
etiketi hem okunabilir bir eylem alanı üretti. Tek kayıt bir ölçü değildir, ama ölçünün
nereye bakacağını söylüyor: **eylem alanının varlığı ile geçerliliği ayrı iki sayıdır.**

#### Geçerli Eylem Alanı Kaç Yanıtta Çıkıyor

İkinci blok dört istemi 120 kaydın tamamında koşturur ve her istemi iki tohumla ölçer.

```python
def olc(onek, tohum=TOHUM):
    SAYAC[0] = 0
    g = c = d = alanli = gecerli = kesik = 0
    for x in TALEP:
        s = cagir(onek + x["metin"], tohum=tohum)
        g, c, kesik = g + s["giris"], c + s["cikis"], kesik + s["kesik"]
        d += oku(s["yanit"]) == x["konu"]
        alanli += "eylem :" in s["yanit"]
        gecerli += oku_eylem(s["yanit"]) is not None
    n = len(TALEP)
    return {"isabet": d / n, "alanli": alanli / n, "gecerli": gecerli / n,
            "kesik": kesik / n, "giris": g, "cikis": c, "cagri": SAYAC[0],
            "gecerli_n": gecerli}


AD = ["P1 dusunce", "P2 +eylem", "P3 +kume", "P4 +kisa"]
ON = [P1, P2, P3, P4]
S1 = [olc(o) for o in ON]
S2 = [olc(o, tohum=TOHUM + 1) for o in ON]
print(f"{'olcu (tohum 20260218)':<24}" + "".join(f"{a:>12}" for a in AD))
for ad, k, b in (("etiket isabeti", "isabet", "{:.4f}"),
                 ("eylem alani tasiyan", "alanli", "{:.4f}"),
                 ("gecerli eylem alani", "gecerli", "{:.4f}"),
                 ("kesilen yanit payi", "kesik", "{:.4f}"),
                 ("giris belirteci", "giris", "{:d}"),
                 ("cikis belirteci", "cikis", "{:d}")):
    print(f"{ad:<24}" + "".join(b.format(x[k]).rjust(12) for x in S1))
print(f"{'toplam belirtec':<24}" + "".join(
    str(x["giris"] + x["cikis"]).rjust(12) for x in S1))
print(f"{'gecerli eylem basina':<24}" + "".join(
    ("-" if x["gecerli_n"] == 0 else
     f"{(x['giris'] + x['cikis']) / x['gecerli_n']:.1f}").rjust(12) for x in S1))
print(f"\n{'ikinci kosum (20260219)':<24}" + "".join(f"{a:>12}" for a in AD))
for ad, k in (("etiket isabeti", "isabet"), ("gecerli eylem alani", "gecerli")):
    print(f"{ad:<24}" + "".join(f"{x[k]:.4f}".rjust(12) for x in S2))
en_buyuk = max(abs(a["gecerli"] - b["gecerli"]) for a, b in zip(S1, S2))
print(f"\nen buyuk iki kosum farki (gecerli eylem alani): {en_buyuk:.4f}")
for i in range(3):
    f1 = S1[i + 1]["gecerli"] - S1[i]["gecerli"]
    f2 = S2[i + 1]["gecerli"] - S2[i]["gecerli"]
    o = "olculdu" if min(abs(f1), abs(f2)) > en_buyuk else "olculmedi"
    print(f"  {AD[i]} -> {AD[i + 1]}: fark {f1:+.4f} / {f2:+.4f}  {o}")
```

```
olcu (tohum 20260218)     P1 dusunce   P2 +eylem    P3 +kume    P4 +kisa
etiket isabeti                0.6750      0.5917      0.4833      0.6750
eylem alani tasiyan           0.0000      0.3167      0.8833      0.8000
gecerli eylem alani           0.0000      0.1000      0.5250      0.8000
kesilen yanit payi            0.0000      0.2167      0.3583      0.0000
giris belirteci                 5300        5540        7460        8060
cikis belirteci                 1729        2210        2584        1745
toplam belirtec                 7029        7750       10044        9805
gecerli eylem basina               -       645.8       159.4       102.1

ikinci kosum (20260219)   P1 dusunce   P2 +eylem    P3 +kume    P4 +kisa
etiket isabeti                0.8083      0.4500      0.5917      0.7333
gecerli eylem alani           0.0000      0.3250      0.3417      0.9333

en buyuk iki kosum farki (gecerli eylem alani): 0.2250
  P1 dusunce -> P2 +eylem: fark +0.1000 / +0.3250  olculmedi
  P2 +eylem -> P3 +kume: fark +0.4250 / +0.0167  olculmedi
  P3 +kume -> P4 +kisa: fark +0.2750 / +0.5917  olculdu
```

İkinci ve üçüncü satır bu dersin asıl ayrımıdır. P3'te yanıtların **0,8833 payı** bir eylem
alanı taşıyor, ama yalnız **0,5250 payı** geçerli. Aradaki **0,3583**, hemen altındaki
satırda birebir duruyor: **kesilen yanıt payı 0,3583.** Kaybın kaynağı istemin metni değil,
çıktı uzunluğu sınırıdır. Düşünce ile eylem alanı aynı yanıtın 24 belirteçlik bütçesini
paylaşıyor; düşünce uzadığında durdurma koşulu tam eylem alanının üzerine düşüyor ve geriye
`eylem : belge _ara (` gibi, biçimi doğru görünen ama argümanı kapanmamış bir kalıntı
kalıyor. Bir alanın **var görünmesi** ile **okunabilir olması** aynı şey değildir.

P4 bu kaybı kapatıyor: düşünceyi tek cümleye indiren tek bir cümle, kesilen yanıt payını
**0,3583'ten 0,0000'a**, geçerli eylem alanını **0,5250'den 0,8000'e** taşıyor. Metinde
değişen şey eylemle ilgili bile değil, düşüncenin uzunluğuyla ilgili.

#### Bedel ve Ölçülemeyen Fark

Giriş belirteci **5300'den 8060'a** çıktı; eylem kümesini ve kısa tutma cümlesini her
talebin başına yazmak istemi **1,52 kata** getirdi. Çıkış belirteci P3'te **2584'e** çıkıp
P4'te **1745'e** indi: kısa düşünce hem üretilen metni hem kesilmeyi azalttı. Çağrı sayısı
dört istemde de 120'dir, bedelin tamamı belirteçtir. Asıl karşılaştırma son satırdadır:
**geçerli eylem alanı başına 645,8 belirteçten 102,1 belirtece**.

Son blok kursun ölçü kuralını uygular. Geçerli eylem alanında iki koşum arasındaki en büyük
fark **0,2250**. Eylem kümesini isteme yazmak birinci koşumda **+0,4250**, ikinci koşumda
**+0,0167** kattı; iki koşum birbirini tutmadığı için bu fark **ölçülmemiş sayılır**. Etiket
kümesini isteme yazmanın işe yaradığı biliniyordu, ama aynı hamlenin eylem kümesinde de işe
yaradığı **bu ölçümle gösterilemedi**. Düşünceyi kısaltmak ise iki koşumda da bandın
üzerinde kaldı: **+0,2750 ve +0,5917**. Etiket isabetinde hiçbir değişiklik tutarlı bir fark
üretmedi; iki koşum farkı en fazla **0,1417**, en güçlü aday olan P3'ten P4'e geçiş
**+0,1917 ve +0,1416** ile tam bandın sınırında kalıyor. **Eylem alanı istemek isabeti
oynatmadı; makinece okunabilir bir eylem alanı kazandırdı ve bedeli belirteçle ödendi.**

#### Özet

- Düşünce ile eylemin aynı istemde istenmesi tek bir sayıyla ölçülemez: **eylem alanı
  taşıyan yanıt payı** ile **geçerli eylem alanı payı** ayrı sayılır.
- Eylem alanı ilk kez istendiğinde yanıtların yalnız **0,1000 payı** geçerli bir alan
  üretti; eylem kümesi yazıldığında 0,5250'ye, düşünce kısaltıldığında **0,8000'e** çıktı.
- P3'teki **0,3583**'lük varlık ile geçerlilik farkı tam olarak **kesilen yanıt payıdır**:
  iki alan aynı 24 belirteçlik çıktı bütçesini paylaşır ve sınır alanın üzerine düşer.
- Bedel: giriş belirteci **5300 → 8060**, geçerli eylem alanı başına **645,8 → 102,1
  belirteç**. Çağrı sayısı değişmedi.
- İki koşum kuralı uygulandığında eylem kümesini yazmanın farkı **ölçülemez** kaldı
  (+0,4250 ve +0,0167); yalnız düşünceyi kısaltmanın farkı ölçüldü.

#### Sonraki Adım

Bu derste de, önceki dördünde de modelin attığı her ek adım **görünürdü**: düşünce alanı
yanıtın içindeydi, belirteci sayıldı ve kesildiğinde ne olduğu okundu. Adımı kısaltma kararı
ancak adım görüldüğü için verilebildi. Bir model sınıfı bu adımları yanıt metnine hiç
koymadan, çağrının içinde üretirse elde ne kalır: adımlar okunamaz, uzunlukları
kısıtlanamaz, ama **belirteçleri yine ödenir**. Sonraki ders bu sınıfı yapısal farkıyla
ölçer — aynı görevde iki sınıf, isabet ve toplam belirteç olarak yan yana — ve **görünmeyen
belirtecin** hangi görevde bir şey kazandırdığını, hangisinde farkın ölçülemez kaldığını
yazar.

### Akıl Yürüten Modeller

Source: https://academia.sh/tr/kurslar/istem-muhendisligi/akil-yuruten-modeller

Yanıt yazmadan önce görünmeyen ara adımlar üreten model sınıfının ölçüsü: aynı 120 kurgu destek talebinde tek alanlı görevde iki sınıfın isabet farkı −0,0333 ve +0,1167 kalıyor, iki koşum farkı 0,1167 olduğu için ölçülmemiş sayılıyor ve belirteç 1,75 kata çıkıyor. İki alanlı görevde fark +0,1000 ve +0,1667 ile bandın üzerine çıkıyor; tek geçişli sınıf kendi yazdığı etiketle kod alanını yanıtların 0,2333 payında çelişiyor. Doğru yanıt başına bedel 52,0'den 95,1'e ve 83,9'dan 110,1 belirtece yükseliyor.

Önceki derste modelin attığı her ek adım görünürdü: düşünce alanı yanıtın içindeydi,
belirteci sayıldı, kesildiğinde ne olduğu okundu ve düşünceyi kısaltma kararı ancak bu
yüzden verilebildi. Bu derste ölçülen sınıfın ayırt edici özelliği tam da bunun yokluğudur.
Sınıf, yanıtı yazmadan önce **ara adımlar üretir**; bu adımların metni çağırana hiç dönmez,
uzunluğu istemle kısıtlanamaz ve durdurma koşulu onlara değmez — ama **çıkış belirteci
olarak ödenir**. Ölçülecek şey budur: **görünmeyen belirtecin bedeli.**

Bu bir ürün karşılaştırması değildir. Hiçbir model, sürüm ya da sağlayıcı anılmaz; iki sınıf
yalnız **yapısal farkla** tanımlanır. Tek geçişli sınıf istemi okur ve yanıtı yazar; akıl
yürüten sınıf araya kendi görmediğimiz adımları koyar. Öz tutarlılıkta olduğu gibi çağrı
sayısı artmaz — iki sınıf da kayıt başına **bir çağrı** yapar ve orada ödenen şey görünen
örnekler değil, görünmeyen belirteçlerdir.

- **AY49.** Kod gerçek bir model uç noktası çağırmaz; standart kitaplıkla yazılmış bir **dil
  modeli benzeticisini** çağırır. Destek talepleri ve belge kodları **kurgudur**.
- **AY50.** Tohum **20260218**, ikinci koşum **20260219**. Aynı istem aynı tohumda aynı
  yanıtı verir.
- **AY51.** Akıl yürüten sınıf **alan başına bir ara adım** üretir. Tek alanlı görevde ikinci
  adım bir **denetim geçişidir**: aynı aday kümesi ikinci kez puanlanır ve yanıt son adımın
  sonucundan yazılır.
- **AY52.** Ara adımların belirteci **çıkış belirtecine** eklenir ama yanıt metnine girmez.
  **Durdurma koşulu yalnız görünen yanıtı keser**; görünmeyen adımlar kısıtlanamaz.
- **AY53.** Tek geçişli sınıf iki alanı **iki ayrı çekilişle** doldurur: ikinci alan birinci
  alanın sonucuna bağlanmaz. Akıl yürüten sınıfta ikinci ara adım birinci adımın sonucundan
  **eşleştirme** yapar.
- **AY54.** İki görev de aynı 120 kurgu talebi kullanır. **A görevi** tek alan ister
  (etiket), **B görevi** iki alan ister (etiket ve belge kodu).
- **AY55.** Belge kodları kurgu belge dağarcığından gelir ve her konunun tek bir kodu vardır;
  doğru yanıt için **iki alanın da** doğru olması gerekir.
- **AY56.** Yanıt biçimi iki sınıfta da aynıdır ve dayatılmıştır. Ölçülen tek fark sınıfın
  kendisidir.

#### İki Sınıfın Yapısal Farkı

İlk blok benzeticiyi kurar ve iki sınıfı iki işlevle ayırır. `cagir` istemi okur ve yanıtı
yazar. `cagir_akil` araya ara adımlar koyar, adımların belirtecini `gizli` alanında biriktirir
ve yanıt metnine yalnız sonucu yazar.

```python
# BENZETICI. Gercek bir model uc noktasi cagrilmaz; standart kitaplikla yazilmis bir dil
# modeli benzeticisidir. Destek talepleri ve belge kodlari KURGU'dur.
import math

TOHUM, M32 = 20260218, 0xFFFFFFFF
PENCERE, EN_UZUN = 240, 24


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


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


KONU = ["fatura", "ariza", "sayac", "tarife", "kesinti"]
KOD = {"fatura": "FT", "ariza": "AR", "sayac": "SY", "tarife": "TR", "kesinti": "KS"}
KALIP = {
    "fatura": ["bu ayki fatura tutari gecen aya gore cok yuksek geldi",
               "faturami odedim ama sistemde borc gorunuyor",
               "fatura ayrintisini nereden gorebilirim"],
    "ariza": ["evde su akmiyor bir ariza var galiba",
              "baglanti bozuk oldu ve hic calismiyor",
              "ariza kaydi actim ama ekip gelmedi"],
    "sayac": ["sayac okumasi yanlis girilmis endeks tutmuyor",
              "sayac degisimi icin randevu istiyorum",
              "sayac uzerindeki endeks ile fatura ayni degil"],
    "tarife": ["hangi tarife basamagindayim ogrenmek istiyorum",
               "tarife degisikligi icin ne yapmam gerekiyor",
               "birim ucret abone tipine gore degisiyor mu"],
    "kesinti": ["mahallede kesinti var ne zaman gelecek",
                "planli kesinti duyurusu nereden takip edilir",
                "aksamdan beri kesinti yasiyoruz"],
}
EK = ["ayrica gecen ay da ayni sorun olmustu", "bu konuda memnun degilim",
      "acil bilgi almam gerekiyor", "kayit numaram elimde yok"]

TALEP = []
for i in range(120):
    r = uretec(TOHUM + i)
    k = KONU[ayrik(r(), [0.24, 0.22, 0.18, 0.20, 0.16])]
    m = KALIP[k][int(r() * 3)]
    if r() < 0.34:
        m += " " + EK[int(r() * 4)]
    TALEP.append({"no": 4001 + i, "metin": m, "konu": k, "kod": KOD[k]})

KAVRAM = KONU + ["odeme", "sikayet", "bilgi", "genel"]
IZ = {"fatur": "fatura", "tutar": "fatura", "ayrin": "fatura",
      "ariza": "ariza", "bozuk": "ariza", "calis": "ariza", "akmiy": "ariza",
      "sayac": "sayac", "endek": "sayac", "okuma": "sayac",
      "tarif": "tarife", "birim": "tarife", "abone": "tarife", "basam": "tarife",
      "kesin": "kesinti", "duyur": "kesinti", "mahal": "kesinti",
      "borc": "odeme", "odedi": "odeme", "ucret": "odeme",
      "memnu": "sikayet", "sorun": "sikayet", "acil": "sikayet",
      "bilgi": "bilgi", "ogren": "bilgi", "nered": "bilgi"}
TUZAK = {"degis": "tarife", "kayit": "ariza", "yukse": "tarife", "gorun": "fatura",
         "ekip": "kesinti", "takip": "tarife", "giril": "fatura"}
ARA = ["ara adim : metinde {k} izleri var , konu buna gore belirlendi",
       "ara adim : {k} konusunun belge kodu {d} olarak eslendi"]
SAYAC = [0]


def puanla(bel, kume):
    aday = [k for k in kume if k[:5] in bel]
    if len(aday) < 3:
        aday = list(kume)
    p = {k: 0.15 for k in aday}
    for t in bel:
        for tablo, w in ((IZ, 1.0), (TUZAK, 1.3)):
            if tablo.get(t) in p:
                p[tablo[t]] += w
    return p


def sec(p, r, sicaklik):
    if sicaklik <= 0.0:
        return max(sorted(p), key=lambda a: p[a])
    e = [math.exp(p[a] / sicaklik) for a in sorted(p)]
    return sorted(p)[ayrik(r(), [v / sum(e) for v in e])]


def sinir(bel, r):
    if len(bel) > PENCERE:
        return "baglam_asimi"
    if SAYAC[0] % 37 == 0:
        return "hiz_siniri"
    if len(bel) > 90 and r() < 0.04:
        return "zaman_asimi"
    return "tamam"


def don(durum, bel, y, gizli=0):
    if durum != "tamam":
        return {"durum": durum, "giris": len(bel), "cikis": 0, "gizli": 0, "yanit": ""}
    cb = belirtecle(y)
    if len(cb) > EN_UZUN:                    # durdurma kosulu yalniz goruneni keser
        cb, y = cb[:EN_UZUN], " ".join(cb[:EN_UZUN])
    return {"durum": durum, "giris": len(bel), "cikis": len(cb) + gizli,
            "gizli": gizli, "yanit": y}


def govde(istem):                       # istemin yonergeden sonraki kismi
    return istem.split("Talep: ")[-1]


def cagir(istem, tohum=TOHUM, sicaklik=0.6):
    """STANDART SINIF: tek gecis, ara adim yok."""
    SAYAC[0] += 1
    bel = belirtecle(istem)
    r = uretec(tohum ^ izno(istem))
    d = sinir(bel, r)
    if d != "tamam":
        return don(d, bel, "")
    k = sec(puanla(bel, KAVRAM), r, sicaklik)
    if "kod" not in bel:
        return don(d, bel, f"etiket : {k}")
    k2 = sec(puanla(bel, KAVRAM), r, sicaklik)      # ikinci alan icin ayri cekilis
    return don(d, bel, f"etiket : {k} | kod : {KOD.get(k2, 'XX')}")


def cagir_akil(istem, tohum=TOHUM, sicaklik=0.6):
    """AKIL YURUTEN SINIF: yaniti yazmadan once gorunmeyen ara adimlar uretir.
    Ara adimlarin metni cagirana donmez ama cikis belirteci olarak sayilir."""
    SAYAC[0] += 1
    bel = belirtecle(istem)
    r = uretec(tohum ^ izno(istem))
    d = sinir(bel, r)
    if d != "tamam":
        return don(d, bel, "")
    g = belirtecle(govde(istem))
    k = sec(puanla(g, KONU), r, sicaklik)                       # 1. ara adim
    gizli = len(belirtecle(ARA[0].format(k=k)))
    if "kod" not in bel:
        k = sec(puanla(g, KONU), r, sicaklik)                   # 2. ara adim: denetim
        gizli += len(belirtecle(ARA[0].format(k=k)))
        return don(d, bel, f"etiket : {k}", gizli)
    kod = KOD[k]                                                # 2. ara adim: eslestirme
    gizli += len(belirtecle(ARA[1].format(k=k, d=kod)))
    return don(d, bel, f"etiket : {k} | kod : {kod}", gizli)


def oku(y):
    e = kd = None
    p = y.split()
    for i, s in enumerate(p):
        if s == "etiket" and i + 2 < len(p) and p[i + 2] in KONU:
            e = p[i + 2]
        if s == "kod" and i + 2 < len(p):
            kd = p[i + 2]
    return e, kd


A = "Talebi su etiketlerden birine ata: fatura , ariza , sayac , tarife , kesinti . Talep: "
B = ("Talebi su etiketlerden birine ata: fatura , ariza , sayac , tarife , kesinti . "
     "Ayrica etiketin belge kodunu kod alanina yaz . Talep: ")

t = TALEP[9]
print(f"KURGU talep {t['no']}: {t['metin']}  (konu {t['konu']}, kod {t['kod']})")
for ad, f in (("standart sinif", cagir), ("akil yuruten sinif", cagir_akil)):
    for gad, o in (("A tek alan", A), ("B iki alan", B)):
        s = f(o + t["metin"])
        print(f"{ad:<19}{gad:<12} cikis {s['cikis']:>3} bel "
              f"(gorunmeyen {s['gizli']:>2}) | {s['yanit']}")
```

```
KURGU talep 4010: hangi tarife basamagindayim ogrenmek istiyorum kayit numaram elimde yok  (konu tarife, kod TR)
standart sinif     A tek alan   cikis   4 bel (gorunmeyen  0) | etiket : sayac
standart sinif     B iki alan   cikis   9 bel (gorunmeyen  0) | etiket : tarife | kod : TR
akil yuruten sinif A tek alan   cikis  36 bel (gorunmeyen 31) | etiket : tarife
akil yuruten sinif B iki alan   cikis  39 bel (gorunmeyen 30) | etiket : tarife | kod : TR
```

Tek kayıtta dört satır ve tek bir gözlem: **yanıtlar aynı biçimde, çıkışlar aynı büyüklükte
değil.** Akıl yürüten sınıfın görünen yanıtı beş belirteç, çıkış belirteci otuz altı.
Aradaki otuz bir belirteç okunamıyor, kısaltılamıyor, denetlenemiyor. Bir önceki dersin
kaldıracı burada elde yok, çünkü kısaltılacak metin yanıtın içinde değil.

#### Aynı Görevde İki Sınıf

Ölçüm iki görevde yapılır. **A görevi** tek alan ister ve istem beş etiketi zaten sayar.
**B görevi** ikinci bir alan daha ister: etiketin belge kodu. İkisi de aynı 120 kurgu talebi
kullanır ve her kayıt için tek çağrı yapılır.

```python
def olc(sinif, onek, iki_alan, tohum=TOHUM):
    SAYAC[0] = 0
    g = c = gz = d = uyum = 0
    for x in TALEP:
        s = sinif(onek + x["metin"], tohum=tohum)
        g, c, gz = g + s["giris"], c + s["cikis"], gz + s["gizli"]
        e, kd = oku(s["yanit"])
        if iki_alan:
            d += e == x["konu"] and kd == x["kod"]
            uyum += kd is not None and e is not None and kd == KOD[e]
        else:
            d += e == x["konu"]
    n = len(TALEP)
    return {"isabet": d / n, "uyum": uyum / n if iki_alan else None, "giris": g,
            "gorunen": c - gz, "gizli": gz, "toplam": g + c, "dogru": d}


IS = [("A standart", cagir, A, False), ("A akil", cagir_akil, A, False),
      ("B standart", cagir, B, True), ("B akil", cagir_akil, B, True)]
S1 = [olc(f, o, i) for _, f, o, i in IS]
S2 = [olc(f, o, i, tohum=TOHUM + 1) for _, f, o, i in IS]
print(f"{'olcu (tohum 20260218)':<24}" + "".join(f"{a[0]:>12}" for a in IS))
for ad, k, b in (("isabet", "isabet", "{:.4f}"), ("iki alan uyumu", "uyum", "{:.4f}"),
                 ("giris belirteci", "giris", "{:d}"),
                 ("gorunen cikis belirteci", "gorunen", "{:d}"),
                 ("gorunmeyen cikis bel.", "gizli", "{:d}"),
                 ("toplam belirtec", "toplam", "{:d}")):
    print(f"{ad:<24}" + "".join(("-" if x[k] is None else b.format(x[k])).rjust(12)
                                for x in S1))
print(f"{'dogru yanit basina':<24}" + "".join(
    f"{x['toplam'] / x['dogru']:.1f}".rjust(12) for x in S1))
print(f"\n{'ikinci kosum isabeti':<24}" + "".join(f"{x['isabet']:.4f}".rjust(12)
                                                  for x in S2))
for ad, i in (("A gorevi", 0), ("B gorevi", 2)):
    f1 = S1[i + 1]["isabet"] - S1[i]["isabet"]
    f2 = S2[i + 1]["isabet"] - S2[i]["isabet"]
    kf = max(abs(S1[i]["isabet"] - S2[i]["isabet"]),
             abs(S1[i + 1]["isabet"] - S2[i + 1]["isabet"]))
    o = "olculdu" if min(abs(f1), abs(f2)) > kf else "olculmedi"
    kat = (S1[i + 1]["toplam"] / S1[i]["toplam"])
    print(f"{ad}: sinif farki {f1:+.4f} / {f2:+.4f}, iki kosum farki {kf:.4f} -> {o}"
          f"   belirtec {kat:.2f} kat")
```

```
olcu (tohum 20260218)     A standart      A akil  B standart      B akil
isabet                        0.7833      0.7500      0.6750      0.7750
iki alan uyumu                     -           -      0.7667      0.9750
giris belirteci                 4340        4340        5780        5780
gorunen cikis belirteci          550         547        1017        1017
gorunmeyen cikis bel.              0        3671           0        3438
toplam belirtec                 4890        8558        6797       10235
dogru yanit basina              52.0        95.1        83.9       110.1

ikinci kosum isabeti          0.6667      0.7833      0.6333      0.8000
A gorevi: sinif farki -0.0333 / +0.1167, iki kosum farki 0.1167 -> olculmedi   belirtec 1.75 kat
B gorevi: sinif farki +0.1000 / +0.1667, iki kosum farki 0.0417 -> olculdu   belirtec 1.51 kat
```

**A görevinde fark ölçülemedi.** Sınıf farkı birinci koşumda **−0,0333**, ikincisinde
**+0,1167**; işareti bile sabit değil ve büyüklüğü iki koşum farkının (**0,1167**) üzerine
çıkmıyor. Nedeni tablodan okunur: istem beş etiketi zaten sayıyor, yani aday kümesini
daraltma işi **istem metninde** yapılmış. Ara adım aynı daraltmayı bir kez daha yapıyor ve
yeni bilgi eklemiyor. Buna karşılık görünmeyen çıkış belirteci **0'dan 3671'e** çıkıyor ve
toplam **1,75 kata** geliyor. Bu, kursun ikinci iddiasının en yalın hâlidir: teknik
belirteci katladı, sayıyı oynatmadı.

**B görevinde durum tersine döner.** Sınıf farkı iki koşumda da olumlu ve büyük — **+0,1000**
ve **+0,1667** — iki koşum farkı ise **0,0417**. Nedeni `iki alan uyumu` satırında duruyor:
tek geçişli sınıfın yanıtlarının yalnız **0,7667 payında** kod alanı **kendi yazdığı
etiketle** uyumlu. Yani model çoğu zaman etiketi doğru bulup kodu başka bir konudan yazıyor;
iki alan birbirine bağlanmıyor. Akıl yürüten sınıfta bu oran **0,9750** — kalan pay, hız
sınırına takılıp hiç yanıt üretmeyen üç çağrıdır. İkinci alanı birinci alanın **sonucundan**
üretmek, kaybın tamamını kapatıyor.

#### Görünmeyen Belirtecin Bedeli

Son satır bu dersin faturasıdır. **Doğru yanıt başına 52,0 belirteçten 95,1'e** (A) ve
**83,9'dan 110,1'e** (B). B görevinde akıl yürüten sınıf isabeti gerçekten yükseltti ve
**yine de doğru yanıt başına daha pahalı** kaldı, çünkü isabet 1,15 kat artarken toplam
belirteç 1,51 kat arttı. Çağrı sayısı iki sınıfta da 120'dir; artışın tamamı **çıkış
belirtecindedir** ve o belirtecin büyük bölümü hiç okunmadı.

Bedelin biçimi de önemlidir. Görünen çıkış belirteci iki sınıfta neredeyse aynı — A görevinde
550 ve 547. Fark tamamen görünmeyen kısımdadır: **3671 ve 3438 belirteç.** Bu, istem
tasarımcısının elini kısıtlar: uzunluk kısıtı yazılabilir ama görünmeyen adıma işlemez, biçim
dayatılabilir ama görünmeyen adım biçimsizdir, kesilen yanıt sayılabilir ama görünmeyen adım
kesilmez. Elde kalan tek kaldıraç **görevin kendisidir**: ara adımın daraltacağı bir karar
var mı, yoksa istem o daraltmayı zaten yapmış mı. **Görünmeyen ara adım, ancak istemin
yapamadığı bir işi yaptığında kazandırır; yaptığı işi istem zaten yapmışsa geriye yalnız
belirteç kalır.**

#### Özet

- Akıl yürüten model sınıfı bir ürünle değil **yapısal farkla** tanımlanır: yanıttan önce
  ara adımlar üretir, adımlar çağırana dönmez ve **çıkış belirteci olarak ödenir**.
- Çağrı sayısı artmaz. Öz tutarlılıkta bedel çağrıdaydı ve örnekler görülebiliyordu; burada
  bedel tek çağrının içindedir ve **görülemez**.
- Tek alanlı görevde iki sınıfın farkı **−0,0333 ve +0,1167**, iki koşum farkı **0,1167**:
  fark **ölçülmemiş sayılır**, ama belirteç **1,75 kat** arttı.
- İki alanlı görevde fark **+0,1000 ve +0,1667** ile bandın (**0,0417**) üzerinde. Kaynağı
  `iki alan uyumudur`: tek geçişli sınıf kod alanını kendi etiketiyle yalnız **0,7667**
  payında tutturuyor, akıl yürüten sınıf **0,9750**.
- Doğru yanıt başına bedel **52,0 → 95,1** ve **83,9 → 110,1 belirteç**. Kazandığı görevde
  bile birim maliyet arttı.

#### Sonraki Adım

Altı derste tek bir istem elden geçirildi: adımları zincirlendi, çoğaltıldı, dallandırıldı,
soyutlandı, içine bir eylem alanı kondu ve sonunda adımların görünmediği bir sınıfa
devredildi. Hepsinde ortak bir varsayım vardı — soruya bakan **tek bir metin** var ve iyi
sonuç o metnin daha da uzatılmasından çıkacak. Aynı soruya **birbirinden bağımsız birkaç
ayrı istemin** bakması, her birinin kendi yanıtını üretmesi ve bunların birleştirilmesi hiç
denenmedi. Sonraki ders bunu ölçer ve asıl soruyu sorar: farklı istemler **aynı örneklerde
mi yanılıyor**. Hatalar örtüşüyorsa birleştirmenin kazancı yoktur ve bu, birleştirmeden önce
sayılabilir.

### İstem Topluluğu

Source: https://academia.sh/tr/kurslar/istem-muhendisligi/istem-toplulugu

Aynı 120 kurgu destek talebine üç ayrı yönergeyle bakılıyor ve topluluğun dayandığı varsayım sınanıyor: farklı istemler farklı hatalar yapar mı. Üç istem tek başına 0,7750, 0,6583 ve 0,7833 veriyor, dokuz kayıtta üçü birden yanılıyor ve tavan 0,9250 çıkıyor. Çoğunluk oyu 0,8000'de kalıyor: tavanın 0,1250 altında, en iyi tek istemin yalnız 0,0167 üstünde ve bu kazanç aynı istemlerin iki koşum arasındaki 0,0333 ile 0,1333 farkının altında. Bedel çağrı sayısıyla yazılıyor: 120 çağrı 360 çağrıya, doğru etiket başına 61,1 belirteç 180,7 belirtece çıkıyor.

Önceki ders tek bir istemin ne kadar uzatılabileceğini ölçtü: yanıt öncesinde görünmeyen ara
adımlar üreten bir model sınıfı aynı görevde daha çok belirteç harcıyordu ve farkın bir görevde
ölçülemez kaldığı yazıldı. Altı dersin ortak yanı şudur — ortada hep **tek bir istem** vardı. O
istem uzatıldı, adım adım çözüme zorlandı, dallandırıldı, ikiye bölündü. Aynı soruya **birden çok
ayrı istemin** bakması hiç denenmedi.

Bu dersin düzeneği budur: aynı görev, aynı benzetici, aynı küme; üç ayrı yazılmış yönerge ve
sonunda bir oy. Adı **istem topluluğudur**. Çoğunluk oyunun yordamı Denetimli Öğrenme kursunun
topluluk yöntemleri dersinde ölçüldü ve tekrarlanmaz. Eklenen iki şey var: bedelin **çağrı
sayısıyla**
yazılması ve topluluğun dayandığı varsayımın sınanması. O varsayım şudur — farklı
istemler **farklı hatalar** yapar. Dersin sayısı, varsayımın ne kadar tuttuğudur: kaç kayıtta üç
istem **birden** yanılıyor.

- **AY61.** Görev, küme ve benzetici sabittir. Değişen tek şey **yönerge metnidir**; üç yönerge de
  aynı beş etiketi ve aynı biçim kısıtını taşır.
- **AY62.** Kod gerçek bir model uç noktası çağırmaz; standart kitaplıkla yazılmış bir
  **benzetici** çağırır. Destek talepleri ve konular **kurgudur**.
- **AY63.** Üç yönerge üç ayrı tasarım kararını taşır: yalın etiket kümesi, rol belirtme ve önce
  işlem alanını sorma.
- **AY64.** Ölçüt **etiket isabetidir**. Yanıttan etiket okunamazsa kayıt yanlış sayılır.
- **AY65.** Topluluğun kararı **çoğunluk oyudur**. Üç etiket de ayrıysa ilk istemin etiketi
  geçerlidir; bu durumların sayısı ayrıca basılır.
- **AY66.** **Örtüşme** şudur: üç istem bir kayıtta birden yanılıyorsa o kayıt topluluğun
  erişemeyeceği kayıttır. Kalan kayıtların payı topluluğun **tavanıdır**.
- **AY67.** Bedel **çağrı sayısıyla** yazılır: üç üyeli topluluk her kayıt için üç çağrı harcar.
  Belirteç ve doğru etiket başına birim bedel yanına konur.
- **AY68.** Her ölçü **iki koşumda** basılır (tohum 20260218 ve 20260219). Topluluğun kazancı iki
  koşum farkından küçükse **ölçülmemiş** sayılır.

#### Aynı Göreve Bakan Üç İstem

```python
# BENZETICI -- KURGUDUR. Bu kod gercek bir model uc noktasi cagirmaz; standart
# kitaplikla yazilmis bir dil modeli benzeticisini cagirir. Talepler de kurgudur.
import math

TOHUM, M32 = 20260218, 0xFFFFFFFF
PENCERE, EN_UZUN = 240, 24          # baglam penceresi ve en buyuk cikti, belirtec


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):                  # KURGU belirtecleyici: parca en cok bes damga
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


def izno(m):                        # istemin icerigine bagli, kosumdan bagimsiz iz
    h = 2166136261
    for c in m:
        h = ((h ^ ord(c)) * 16777619) & M32
    return h


KONU = ["fatura", "ariza", "sayac", "tarife", "kesinti"]
KALIP = {
    "fatura": ["bu ayki fatura tutari gecen aya gore cok yuksek geldi",
               "faturami odedim ama sistemde borc gorunuyor",
               "fatura ayrintisini nereden gorebilirim"],
    "ariza": ["evde su akmiyor bir ariza var galiba",
              "baglanti bozuk oldu ve hic calismiyor",
              "ariza kaydi actim ama ekip gelmedi"],
    "sayac": ["sayac okumasi yanlis girilmis endeks tutmuyor",
              "sayac degisimi icin randevu istiyorum",
              "sayac uzerindeki endeks ile fatura ayni degil"],
    "tarife": ["hangi tarife basamagindayim ogrenmek istiyorum",
               "tarife degisikligi icin ne yapmam gerekiyor",
               "birim ucret abone tipine gore degisiyor mu"],
    "kesinti": ["mahallede kesinti var ne zaman gelecek",
                "planli kesinti duyurusu nereden takip edilir",
                "aksamdan beri kesinti yasiyoruz"],
}
EK = ["ayrica gecen ay da ayni sorun olmustu", "bu konuda memnun degilim",
      "acil bilgi almam gerekiyor", "kayit numaram elimde yok"]

TALEP = []
for i in range(120):
    r = uretec(TOHUM + i)
    k = KONU[ayrik(r(), [0.24, 0.22, 0.18, 0.20, 0.16])]
    m = KALIP[k][int(r() * 3)]
    if r() < 0.34:
        m += " " + EK[int(r() * 4)]
    TALEP.append({"no": 4001 + i, "metin": m, "konu": k})

KAVRAM = KONU + ["odeme", "sikayet", "bilgi", "genel"]
IZ = {"fatur": "fatura", "tutar": "fatura", "ayrin": "fatura",
      "ariza": "ariza", "bozuk": "ariza", "calis": "ariza", "akmiy": "ariza",
      "sayac": "sayac", "endek": "sayac", "okuma": "sayac",
      "tarif": "tarife", "birim": "tarife", "abone": "tarife", "basam": "tarife",
      "kesin": "kesinti", "duyur": "kesinti", "mahal": "kesinti",
      "borc": "odeme", "odedi": "odeme", "ucret": "odeme",
      "memnu": "sikayet", "sorun": "sikayet", "acil": "sikayet",
      "bilgi": "bilgi", "ogren": "bilgi", "nered": "bilgi"}
TUZAK = {"degis": "tarife", "kayit": "ariza", "yukse": "tarife", "gorun": "fatura",
         "ekip": "kesinti", "takip": "tarife", "giril": "fatura"}   # yaniltici baglar
SERBEST = ["talebiniz {k} konusuyla ilgili gorunuyor",
           "bu kayit {k} basligina girer , ilgili ekibe yonlendirildi",
           "kaydiniz alindi , konuyu inceleyip donus yapacagiz"]
SAYAC = [0]


def cagir(istem, tohum=TOHUM, sicaklik=0.6, en_uzun=EN_UZUN):
    SAYAC[0] += 1
    bel = belirtecle(istem)
    if len(bel) > PENCERE:
        return {"durum": "baglam_asimi", "giris": len(bel), "cikis": 0, "yanit": ""}
    if SAYAC[0] % 37 == 0:
        return {"durum": "hiz_siniri", "giris": len(bel), "cikis": 0, "yanit": ""}
    r = uretec(tohum ^ izno(istem))
    if len(bel) > 90 and r() < 0.04:
        return {"durum": "zaman_asimi", "giris": len(bel), "cikis": 0, "yanit": ""}
    aday = [k for k in KAVRAM if k[:5] in bel]      # istemde adi gecen kavramlar
    if len(aday) < 3:
        aday = KAVRAM
    p = {k: 0.15 for k in aday}
    for t in bel:
        for tablo, w in ((IZ, 1.0), (TUZAK, 1.3)):
            if tablo.get(t) in p:
                p[tablo[t]] += w
    if sicaklik <= 0.0:
        k = max(sorted(p), key=lambda a: p[a])       # en olasi secim
    else:
        e = [math.exp(p[a] / sicaklik) for a in sorted(p)]
        k = sorted(p)[ayrik(r(), [v / sum(e) for v in e])]
    y = k if "tek" in bel else SERBEST[ayrik(r(), [0.42, 0.26, 0.32])].format(k=k)
    cb = belirtecle(y)
    if len(cb) > en_uzun:                            # durdurma kosulu
        cb = cb[:en_uzun]
        y = " ".join(cb)
    return {"durum": "tamam", "giris": len(bel), "cikis": len(cb), "yanit": y}


def oku(y):                                          # yanittan etiket cikarma
    for s in y.lower().split():
        if s in KONU:
            return s
    return None


UC = {
    "yalin": ("Talebi su etiketlerden birine ata: fatura , ariza , sayac , tarife , "
              "kesinti . Yanit olarak tek etiket yaz . Talep: "),
    "rol": ("Sen destek masasi gorevlisisin . Talebi fatura , ariza , sayac , tarife , "
            "kesinti etiketlerinden birine ata , tek etiket yaz . Talep: "),
    "alan": ("Once talebin hangi islem alanina girdigini belirle , sonra fatura , "
             "ariza , sayac , tarife , kesinti icinden tek etiket yaz . Talep: "),
}


def kosum(yonerge, tohum=TOHUM):
    SAYAC[0] = 0
    et, g, c, h = [], 0, 0, 0
    for x in TALEP:
        s = cagir(yonerge + x["metin"], tohum=tohum)
        g, c, h = g + s["giris"], c + s["cikis"], h + (s["durum"] != "tamam")
        et.append(oku(s["yanit"]))
    return {"et": et, "giris": g, "cikis": c, "cagri": SAYAC[0], "hata": h}


def isabet(et):
    return sum(e == x["konu"] for e, x in zip(et, TALEP)) / len(TALEP)


K1 = {ad: kosum(y) for ad, y in UC.items()}
K2 = {ad: kosum(y, TOHUM + 1) for ad, y in UC.items()}
print(f"{'istem':<7} {'belirtec':>8} {'kosum 1':>8} {'kosum 2':>8} {'fark':>8} "
      f"{'giris':>7} {'cikis':>6}")
for ad in UC:
    a, b = isabet(K1[ad]["et"]), isabet(K2[ad]["et"])
    print(f"{ad:<7} {len(belirtecle(UC[ad])):>8d} {a:>8.4f} {b:>8.4f} {b - a:>+8.4f} "
          f"{K1[ad]['giris']:>7d} {K1[ad]['cikis']:>6d}")
i = next(i for i in range(len(TALEP)) if len({K1[ad]["et"][i] for ad in UC}) == 3)
print(f"\ntalep {TALEP[i]['no']} ({TALEP[i]['konu']}): {TALEP[i]['metin']}")
print("uc istemin etiketi: " + " , ".join(f"{ad} -> {K1[ad]['et'][i]}" for ad in UC))
```

```
istem   belirtec  kosum 1  kosum 2     fark   giris  cikis
yalin         32   0.7750   0.6917  -0.0833    5300    192
rol           37   0.6583   0.7917  +0.1333    5900    210
alan          34   0.7833   0.7500  -0.0333    5540    201

talep 4023 (fatura): bu ayki fatura tutari gecen aya gore cok yuksek geldi bu konuda memnun degilim
uc istemin etiketi: yalin -> fatura , rol -> tarife , alan -> sayac
```

Üç istem üç ayrı sayı verdi; aralarındaki en büyük fark **0,1250**. Asıl bilgi ikinci koşum
sütunundadır. Birinci koşumda en iyi istem `alan` (0,7833), en kötüsü `rol` (0,6583); ikinci
koşumda sıralama tersine dönüyor ve `rol` **0,7917** ile başa geçiyor. Aynı istemin iki koşum
arasındaki farkı **0,0833**, **0,1333** ve **0,0333**: istemler arası fark ile aynı istemin kendi
içindeki oynaması **aynı büyüklükte**. Bu ölçekte "en iyi istem" kararlı bir kavram değildir.

Son iki satır topluluğun umududur. 4023 numaralı talep fatura konusundadır ve üç istem üç ayrı
etiket veriyor; biri doğru bildi. Topluluğun bütün iddiası bu gözlemdir — hatalar farklı yerlere
düşüyorsa oy birleştirme onları eler.

#### Hataların Örtüşmesi ve Tavan

```python
from collections import Counter


def oyla(satir):                       # cogunluk; uc etiket de ayriysa ilk istem karar verir
    s = Counter(e for e in satir if e is not None)
    if not s:
        return None
    en = max(s.values())
    return next((e for e in satir if e is not None and s[e] == en), None)


def cozumle(K):
    sat = [[K[ad]["et"][i] for ad in UC] for i in range(len(TALEP))]
    d = [[s[j] == TALEP[i]["konu"] for j in range(3)] for i, s in enumerate(sat)]
    top = [oyla(s) for s in sat]
    return {"top": top, "hepsi_yanlis": sum(not any(x) for x in d),
            "tavan": sum(any(x) for x in d) / len(TALEP),
            "uzlasma_yok": sum(len(set(s)) == 3 for s in sat),
            "yanlista_uzlasma": sum(1 for i, s in enumerate(sat)
                                    if Counter(s).most_common(1)[0][1] >= 2
                                    and top[i] != TALEP[i]["konu"]),
            "isabet": isabet(top), "cagri": sum(K[a]["cagri"] for a in UC),
            "belirtec": sum(K[a]["giris"] + K[a]["cikis"] for a in UC)}


C1, C2 = cozumle(K1), cozumle(K2)
en_iyi = max(isabet(K1[a]["et"]) for a in UC)
print(f"{'olcu':<26} {'kosum 1':>9} {'kosum 2':>9}")
for ad, k, b in (("ucu birden yanlis", "hepsi_yanlis", "{:d}"),
                 ("en az biri dogru (tavan)", "tavan", "{:.4f}"),
                 ("uc ayri etiket", "uzlasma_yok", "{:d}"),
                 ("yanlista uzlasma", "yanlista_uzlasma", "{:d}"),
                 ("topluluk isabeti", "isabet", "{:.4f}")):
    print(f"{ad:<26} {b.format(C1[k]):>9} {b.format(C2[k]):>9}")
print(f"\nen iyi tek istem {en_iyi:.4f} -> topluluk {C1['isabet']:.4f} "
      f"({C1['isabet'] - en_iyi:+.4f}); tavana uzaklik "
      f"{C1['isabet'] - C1['tavan']:+.4f}")
tek = K1["alan"]["giris"] + K1["alan"]["cikis"]
print(f"bedel: cagri {K1['alan']['cagri']} -> {C1['cagri']} "
      f"({C1['cagri'] / K1['alan']['cagri']:.1f} kat), belirtec {tek} -> "
      f"{C1['belirtec']} ({C1['belirtec'] / tek:.2f} kat)")
print(f"dogru etiket basina {tek / (en_iyi * 120):.1f} -> "
      f"{C1['belirtec'] / (C1['isabet'] * 120):.1f} belirtec")
print("\nkosumlar arasi etiket degisimi (120 kayitta):")
for ad in UC:
    print(f"  {ad:<9} {sum(a != b for a, b in zip(K1[ad]['et'], K2[ad]['et'])):>3d}")
print(f"  {'topluluk':<9} {sum(a != b for a, b in zip(C1['top'], C2['top'])):>3d}")
```

```
olcu                         kosum 1   kosum 2
ucu birden yanlis                  9        16
en az biri dogru (tavan)      0.9250    0.8667
uc ayri etiket                     1         8
yanlista uzlasma                  24        18
topluluk isabeti              0.8000    0.8000

en iyi tek istem 0.7833 -> topluluk 0.8000 (+0.0167); tavana uzaklik -0.1250
bedel: cagri 120 -> 360 (3.0 kat), belirtec 5741 -> 17343 (3.02 kat)
dogru etiket basina 61.1 -> 180.7 belirtec

kosumlar arasi etiket degisimi (120 kayitta):
  yalin      39
  rol        43
  alan       40
  topluluk   24
```

İlk satır bu dersin sorusuna doğrudan cevap veriyor. 120 kaydın **9'unda** üç istem birden
yanılıyor; örtüşme **0,0750**. Yani topluluğun ulaşabileceği en yüksek sayı **0,9250** ve en iyi
tek istemin **0,1417** üstünde bir boşluk duruyor. Örtüşme düşük, tavan yüksek: buraya kadar
topluluğun gerekçesi ayakta.

Gerçekleşen sayı **0,8000**, tavanın **0,1250** altında. Aradaki fark sayılabilir bir yerdedir:
**yanlışta uzlaşma** satırı çoğunluğun 24 kayıtta yanlış bir etikette buluştuğunu söylüyor.
Bunların 9'u zaten kimsenin bilemediği kayıtlar; kalan **15 kayıtta bir
istem doğruyu biliyordu ve oylamada yenildi**. Üç üyeli bir toplulukta doğru bilen tek üye her
zaman azınlıktadır. Örtüşme tavanı belirler, oylama da o tavanın ne kadarına erişileceğini; ikisi
ayrı sayılardır ve yalnız birincisini yazan bir rapor topluluğun kazancını iki kat abartır.

İkinci koşum sütunu ölçünün kendisinin ne kadar oynadığını gösteriyor: yalnız tohum değişti,
örtüşme 9'dan **16'ya** çıktı, tavan **0,8667'ye** indi. Örtüşme tek bir koşumdan okunamayan bir
büyüklüktür.

#### Üç Kat Çağrının Aldığı Şey

Kazanç, en iyi tek isteme göre **+0,0167**. Aynı istemlerin iki koşum arasındaki farkı ise
0,0333 ile 0,1333 arasındaydı. **Kazanç, koşum farkının en küçüğünün bile ancak yarısı
kadardır; bu kursun kuralına göre ölçülmemiş sayılır.** İkinci koşumda kazanç **+0,0083**; bir
sonraki koşumda işaretinin ne olacağı bilinmiyor.

Bedel ise ölçülmüş ve kesindir. Çağrı sayısı 120'den **360'a** çıktı — tam **üç kat**, çünkü üye
sayısı doğrudan çarpandır. Toplam belirteç **3,02 kat** arttı ve isabetteki kırıntı bu çarpanı
kapatmıyor: doğru etiket başına bedel **61,1 belirteçten 180,7 belirtece** çıkıyor. Üç kat pahalı
bir düzeneğin ölçülemez bir kazanç vermesi bu kursun ikinci iddiasının tam karşılığıdır —
**akıl yürütme teknikleri pahalıdır ve her görevde kazandırmaz.**

Son tablo, üç çağrının karşılığında gerçekten alınan tek şeyi gösteriyor. Tek istemler iki koşum
arasında 39, 43 ve 40 kaydın etiketini değiştiriyor; topluluk **24 kayıtta** değiştiriyor.
Oylamanın yaptığı iş isabeti yükseltmek değil **çıktıyı sabitlemektir** ve bunu da yarı yolda
bırakıyor. İki koşumun isabeti **0,8000** ve **0,8000** çıktı; bu iki eşit sayının altında değişen
24 etiket var. Toplam eşit diye kararlı sanmak, bu kursun uyardığı hatanın kendisidir.

Bir istem topluluğu, üyelerin hataları gerçekten ayrı yerlere düştüğünde kazandırır. Burada üç
yönerge de aynı beş etiketi ve aynı biçim kısıtını taşıyordu; farkları yazımda kaldı, kararda
değil. Aynı bilgiyi üç ayrı cümleyle söylemek üç bakış açısı üretmez, üç fatura üretir.

#### Özet

- Üç ayrı yönerge aynı görevde **0,7750**, **0,6583** ve **0,7833** veriyor; ikinci koşumda
  sıralama tersine dönüyor. İstemler arası fark ile koşum farkı aynı büyüklükte.
- Örtüşme sayılır: 120 kaydın **9'unda** üçü birden yanılıyor, tavan **0,9250**. İkinci koşumda
  bu sayılar **16** ve **0,8667**.
- Çoğunluk oyu **0,8000**'de kalıyor — tavanın **0,1250** altında. **15 kayıtta** bir istem
  doğruyu biliyordu ve oylamada yenildi; çoğunluk 24 kayıtta yanlışta uzlaştı.
- Kazanç en iyi tek isteme göre **+0,0167**, iki koşum farkı ise 0,0333 ile 0,1333 arasında.
  Kazanç ölçülmemiş sayılır.
- Bedel çağrı sayısıyla yazılır: 120 çağrı **360 çağrı**, doğru etiket başına 61,1 belirteç
  **180,7 belirteç**. Alınan tek şey koşumlar arası değişimin 40'tan **24'e** inmesi.

#### Sonraki Adım

Bu derste üç istem elle yazıldı ve hangisinin daha iyi olduğu koşuma göre değişti. Elde bir ölçüt,
bir küme ve aday istemler vardı; yalnız seçim gözle ve tek koşuma bakılarak yapıldı. Aynı işi bir
döngüye çevirmek mümkündür: adaylar üretilir, hepsi aynı ölçütle
puanlanır ve en yükseği seçilir. Sonraki ders bu döngüyü kurar ve tek bir soruyu sorar — arama
bütçesi büyüdükçe doğrulama kümesinde yükselen sayı, hiç görülmemiş bir sınama kümesine ne kadar
taşınıyor.

### Otomatik İstem Eniyileme

Source: https://academia.sh/tr/kurslar/istem-muhendisligi/otomatik-istem-eniyileme

İstem elle yazılmak yerine bir ölçütle aranıyor: dört parçadan mekanik olarak on aday üretiliyor, kurgu destek talepleri 40 kayıtlık doğrulama ve 80 kayıtlık sınama kümesine ayrılıyor. Arama bütçesi bir adaydan on adaya çıkarken doğrulamadaki en iyi puan 0,7750'den 0,9000'e yükseliyor, aynı adayın sınama puanı 0,6750'den 0,6500'e iniyor: doğrulama kazancı +0,1250, sınama kazancı -0,0250 ve seçilen adayın iyimserlik payı 0,2500. Arama 40 çağrıdan 400 çağrıya çıkıyor, sınamada gerçekten en iyi olan aday (0,8000) hiç seçilmiyor ve ikinci koşumda arama başka bir adayı seçiyor.

Önceki derste üç istem elle yazıldı, üçü de aynı kümede ölçüldü ve en iyisi gözle seçildi. O
seçimin dayanağı tek bir koşumdu ve ikinci koşumda sıralama tersine döndü. Bu işin elle yapılan
kısmı aslında dardır: adayları üretmek bir birleştirme işi, puanlamak bir döngü, seçmek bir
karşılaştırma. Üçü de yazılabilir. Yazıldığında ortaya **otomatik istem eniyileme** çıkar —
istemin bir ölçütle aranması.

Aramanın kendisi bu dersin konusu değildir. Bir aday kümesi üzerinde en iyiyi seçmenin yordamı
ve **ayar bütçesi büyüdükçe doğrulama kümesindeki en iyi puanın iyimserleşmesi**, Denetimli
Öğrenme kursunun hiperparametre arama dersinde ölçüldü ve tekrarlanmaz. Burada aranan şey bir ayar
değeri değil bir **metindir** ve puanı veren şey belirsiz bir bileşendir. Dersin tek sorusu
şudur: arama bütçesi büyüdükçe doğrulamada kazanılan sayı, hiç görülmemiş bir sınama kümesine
taşınıyor mu.

- **AY69.** Kod gerçek bir model uç noktası çağırmaz; standart kitaplıkla yazılmış bir
  **benzetici** çağırır. Destek talepleri ve konular **kurgudur**.
- **AY70.** **Aday sayısı 10'u aşmaz.** Adaylar dört parçadan mekanik olarak üretilir: rol
  cümlesi, önek cümlesi, etiket listesinin sırası ve biçim cümlesi.
- **AY71.** Küme ikiye ayrılır: **doğrulama 40 kayıt**, **sınama 80 kayıt**. Sınama kümesi arama
  boyunca hiç görülmez ve hiçbir seçim ona bakılarak yapılmaz.
- **AY72.** Ölçüt **etiket isabetidir**; yanıttan etiket okunamazsa kayıt yanlış sayılır.
- **AY73.** Arama kuralı: bütçe $b$ iken **ilk $b$ aday** içinde doğrulaması en yüksek olan
  seçilir. Beraberlikte listede önce gelen kazanır.
- **AY74.** Arama bedeli **çağrı sayısıyla** yazılır. Her aday doğrulama kümesinin tamamında
  koşturulur; bütçe $b$ için bedel $b \times 40$ çağrıdır.
- **AY75.** **İyimserlik payı**, seçilen adayın doğrulama puanı ile sınama puanı arasındaki
  farktır.
- **AY76.** İki koşum basılır. Tohum 20260219 ile arama baştan tekrarlanır; seçilen adayın
  değişip değişmediği ve aynı adayın sınama puanının ne kadar oynadığı yazılır.

#### On Aday, İki Küme

```python
# BENZETICI -- KURGUDUR. Bu kod gercek bir model uc noktasi cagirmaz; standart
# kitaplikla yazilmis bir dil modeli benzeticisini cagirir. Talepler de kurgudur.
import math

TOHUM, M32 = 20260218, 0xFFFFFFFF
PENCERE, EN_UZUN = 240, 24          # baglam penceresi ve en buyuk cikti, belirtec


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):                  # KURGU belirtecleyici: parca en cok bes damga
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


def izno(m):                        # istemin icerigine bagli, kosumdan bagimsiz iz
    h = 2166136261
    for c in m:
        h = ((h ^ ord(c)) * 16777619) & M32
    return h


KONU = ["fatura", "ariza", "sayac", "tarife", "kesinti"]
KALIP = {
    "fatura": ["bu ayki fatura tutari gecen aya gore cok yuksek geldi",
               "faturami odedim ama sistemde borc gorunuyor",
               "fatura ayrintisini nereden gorebilirim"],
    "ariza": ["evde su akmiyor bir ariza var galiba",
              "baglanti bozuk oldu ve hic calismiyor",
              "ariza kaydi actim ama ekip gelmedi"],
    "sayac": ["sayac okumasi yanlis girilmis endeks tutmuyor",
              "sayac degisimi icin randevu istiyorum",
              "sayac uzerindeki endeks ile fatura ayni degil"],
    "tarife": ["hangi tarife basamagindayim ogrenmek istiyorum",
               "tarife degisikligi icin ne yapmam gerekiyor",
               "birim ucret abone tipine gore degisiyor mu"],
    "kesinti": ["mahallede kesinti var ne zaman gelecek",
                "planli kesinti duyurusu nereden takip edilir",
                "aksamdan beri kesinti yasiyoruz"],
}
EK = ["ayrica gecen ay da ayni sorun olmustu", "bu konuda memnun degilim",
      "acil bilgi almam gerekiyor", "kayit numaram elimde yok"]

TALEP = []
for i in range(120):
    r = uretec(TOHUM + i)
    k = KONU[ayrik(r(), [0.24, 0.22, 0.18, 0.20, 0.16])]
    m = KALIP[k][int(r() * 3)]
    if r() < 0.34:
        m += " " + EK[int(r() * 4)]
    TALEP.append({"no": 4001 + i, "metin": m, "konu": k})

KAVRAM = KONU + ["odeme", "sikayet", "bilgi", "genel"]
IZ = {"fatur": "fatura", "tutar": "fatura", "ayrin": "fatura",
      "ariza": "ariza", "bozuk": "ariza", "calis": "ariza", "akmiy": "ariza",
      "sayac": "sayac", "endek": "sayac", "okuma": "sayac",
      "tarif": "tarife", "birim": "tarife", "abone": "tarife", "basam": "tarife",
      "kesin": "kesinti", "duyur": "kesinti", "mahal": "kesinti",
      "borc": "odeme", "odedi": "odeme", "ucret": "odeme",
      "memnu": "sikayet", "sorun": "sikayet", "acil": "sikayet",
      "bilgi": "bilgi", "ogren": "bilgi", "nered": "bilgi"}
TUZAK = {"degis": "tarife", "kayit": "ariza", "yukse": "tarife", "gorun": "fatura",
         "ekip": "kesinti", "takip": "tarife", "giril": "fatura"}   # yaniltici baglar
SERBEST = ["talebiniz {k} konusuyla ilgili gorunuyor",
           "bu kayit {k} basligina girer , ilgili ekibe yonlendirildi",
           "kaydiniz alindi , konuyu inceleyip donus yapacagiz"]
SAYAC = [0]


def cagir(istem, tohum=TOHUM, sicaklik=0.6, en_uzun=EN_UZUN):
    SAYAC[0] += 1
    bel = belirtecle(istem)
    if len(bel) > PENCERE:
        return {"durum": "baglam_asimi", "giris": len(bel), "cikis": 0, "yanit": ""}
    if SAYAC[0] % 37 == 0:
        return {"durum": "hiz_siniri", "giris": len(bel), "cikis": 0, "yanit": ""}
    r = uretec(tohum ^ izno(istem))
    if len(bel) > 90 and r() < 0.04:
        return {"durum": "zaman_asimi", "giris": len(bel), "cikis": 0, "yanit": ""}
    aday = [k for k in KAVRAM if k[:5] in bel]      # istemde adi gecen kavramlar
    if len(aday) < 3:
        aday = KAVRAM
    p = {k: 0.15 for k in aday}
    for t in bel:
        for tablo, w in ((IZ, 1.0), (TUZAK, 1.3)):
            if tablo.get(t) in p:
                p[tablo[t]] += w
    if sicaklik <= 0.0:
        k = max(sorted(p), key=lambda a: p[a])       # en olasi secim
    else:
        e = [math.exp(p[a] / sicaklik) for a in sorted(p)]
        k = sorted(p)[ayrik(r(), [v / sum(e) for v in e])]
    y = k if "tek" in bel else SERBEST[ayrik(r(), [0.42, 0.26, 0.32])].format(k=k)
    cb = belirtecle(y)
    if len(cb) > en_uzun:                            # durdurma kosulu
        cb = cb[:en_uzun]
        y = " ".join(cb)
    return {"durum": "tamam", "giris": len(bel), "cikis": len(cb), "yanit": y}


def oku(y):                                          # yanittan etiket cikarma
    for s in y.lower().split():
        if s in KONU:
            return s
    return None


ROL = ["", "Sen destek masasi gorevlisisin . ", "Kayit gorevlisi olarak yanitla . "]
ONEK = ["", "Once talebin hangi islem alanina girdigini belirle , sonra ",
        "Ornek: endeks tutmuyor -> sayac . "]
LISTE = ["fatura , ariza , sayac , tarife , kesinti",
         "kesinti , tarife , sayac , ariza , fatura",
         "ariza , kesinti , fatura , sayac , tarife"]
BICIM = ["Yanit olarak tek etiket yaz .", "Tek etiket yaz , aciklama ekleme .",
         "Cevabin tek sozcuk olsun , listedeki etiketlerden biri ."]

ADAY, PARCA = [], []
r = uretec(TOHUM + 777)
while len(ADAY) < 10:                # adaylar mekanik uretilir, tohum sabittir
    d = [int(r() * 3) for _ in range(4)]
    y = (ROL[d[0]] + ONEK[d[1]] + "Talebi su etiketlerden birine ata: " + LISTE[d[2]]
         + " . " + BICIM[d[3]] + " Talep: ")
    if y not in ADAY:
        ADAY.append(y)
        PARCA.append("".join(str(x) for x in d))

DOG, SIN = TALEP[:40], TALEP[40:]


def puan(yonerge, kume, tohum=TOHUM):
    d = 0
    for x in kume:
        d += oku(cagir(yonerge + x["metin"], tohum=tohum)["yanit"]) == x["konu"]
    return d / len(kume)


SAYAC[0] = 0
PD = [puan(y, DOG) for y in ADAY]
CAGRI_ARAMA = SAYAC[0]
PS = [puan(y, SIN) for y in ADAY]
print(f"{'aday':>4} {'parca':>6} {'belirtec':>8} {'dogrulama':>10} {'sinama':>8} "
      f"{'fark':>8}")
for i, y in enumerate(ADAY):
    print(f"{i + 1:>4d} {PARCA[i]:>6} {len(belirtecle(y)):>8d} {PD[i]:>10.4f} "
          f"{PS[i]:>8.4f} {PS[i] - PD[i]:>+8.4f}")
print(f"\ndogrulama kumesi {len(DOG)} kayit, sinama kumesi {len(SIN)} kayit")
print(f"arama cagrisi {CAGRI_ARAMA}, dogrulama ortalamasi {sum(PD) / 10:.4f}, "
      f"sinama ortalamasi {sum(PS) / 10:.4f}")
```

```
aday  parca belirtec  dogrulama   sinama     fark
   1   2110       53     0.7750   0.6750  -0.1000
   2   2201       51     0.7250   0.7250  +0.0000
   3   1210       50     0.7500   0.6500  -0.1000
   4   1000       41     0.6500   0.8000  +0.1500
   5   0212       47     0.4250   0.4625  +0.0375
   6   1101       56     0.9000   0.6500  -0.2500
   7   0121       47     0.6000   0.6750  +0.0750
   8   0202       47     0.5250   0.6000  +0.0750
   9   1020       41     0.7750   0.7375  -0.0375
  10   0100       45     0.7750   0.6875  -0.0875

dogrulama kumesi 40 kayit, sinama kumesi 80 kayit
arama cagrisi 400, dogrulama ortalamasi 0.6900, sinama ortalamasi 0.6663
```

Son satır bir yanlış açıklamayı baştan kapatıyor. İki kümenin ortalamaları **0,6900** ve
**0,6663**; aralarında sistematik bir uçurum yok. Yani sınama kümesi daha zor değil, dağılımı
farklı değil. Buna rağmen `fark` sütunu iki yöne birden gidiyor ve **0,2500** büyüklüğüne ulaşıyor.
Ayrışma kümelerin arasında değil, **aday başınadır**.

Altıncı aday doğrulamada **0,9000** ile açık ara birinci, sınamada **0,6500** ile sondan üçüncü.
Dördüncü aday tam tersi: doğrulamada 0,6500 ile alt sıralarda, sınamada **0,8000** ile birinci.
Kırk kayıtlık bir kümede tek kayıt 0,0250 eder; altıncı adayı birinciden ayıran **0,1250** farkı
beş kaydın nereye düştüğünden ibarettir.

`parca` sütunu adayın dört hanesini verir: rol cümlesi, önek cümlesi, etiket listesinin sırası,
biçim cümlesi. Dördüncü aday `1000`, dokuzuncu aday `1020`; yalnız üçüncü hanede ayrılıyorlar.
Aynı rol cümlesi, aynı önek yokluğu, aynı biçim cümlesi, aynı beş etiket — tek fark etiketlerin
**yazılma sırasıdır** ve sınama puanları **0,8000** ile **0,7375**. İstemin taşıdığı bilgi
değişmeden puanın 0,0625 oynaması, bu aramanın neyi ölçtüğü sorusunu şimdiden açıyor.

#### Arama Bütçesi Büyüdükçe

```python
def secim(pd):                       # butce b: ilk b aday icinde dogrulamasi en yuksek olan
    return [max(range(b), key=lambda i: pd[i]) for b in range(1, len(pd) + 1)]


S = secim(PD)
print(f"{'butce':>5} {'secilen':>7} {'dogrulama':>10} {'sinama':>8} {'arama cagrisi':>14}")
for b, i in enumerate(S, 1):
    print(f"{b:>5d} {i + 1:>7d} {PD[i]:>10.4f} {PS[i]:>8.4f} {b * len(DOG):>14d}")
ilk, son = S[0], S[-1]
print(f"\nbutce 1 -> 10: dogrulama {PD[son] - PD[ilk]:+.4f}, sinama {PS[son] - PS[ilk]:+.4f}")
print(f"secilen adayin iyimserlik payi {PD[son] - PS[son]:+.4f}")
en = max(range(10), key=lambda i: PS[i])
print(f"sinamada en iyi aday {en + 1} ({PS[en]:.4f}); dogrulamasi {PD[en]:.4f}, "
      f"arama onu hic secmedi")

SAYAC[0] = 0
PD2 = [puan(y, DOG, TOHUM + 1) for y in ADAY]
PS2 = [puan(y, SIN, TOHUM + 1) for y in ADAY]
son2 = secim(PD2)[-1]
print(f"\nikinci kosum (tohum {TOHUM + 1}): secilen aday {son2 + 1}, dogrulama "
      f"{PD2[son2]:.4f}, sinama {PS2[son2]:.4f}")
print(f"aday {son + 1} sinamasi iki kosumda {PS[son]:.4f} -> {PS2[son]:.4f} "
      f"({PS2[son] - PS[son]:+.4f})")
print(f"on adayin sinama sirasi iki kosumda ayni mi: "
      f"{sorted(range(10), key=lambda i: -PS[i]) == sorted(range(10), key=lambda i: -PS2[i])}")
```

```
butce secilen  dogrulama   sinama  arama cagrisi
    1       1     0.7750   0.6750             40
    2       1     0.7750   0.6750             80
    3       1     0.7750   0.6750            120
    4       1     0.7750   0.6750            160
    5       1     0.7750   0.6750            200
    6       6     0.9000   0.6500            240
    7       6     0.9000   0.6500            280
    8       6     0.9000   0.6500            320
    9       6     0.9000   0.6500            360
   10       6     0.9000   0.6500            400

butce 1 -> 10: dogrulama +0.1250, sinama -0.0250
secilen adayin iyimserlik payi +0.2500
sinamada en iyi aday 4 (0.8000); dogrulamasi 0.6500, arama onu hic secmedi

ikinci kosum (tohum 20260219): secilen aday 9, dogrulama 0.7500, sinama 0.7875
aday 6 sinamasi iki kosumda 0.6500 -> 0.8500 (+0.2000)
on adayin sinama sirasi iki kosumda ayni mi: False
```

Tablonun iki sütunu ters yönde ilerliyor. Bütçe birden ona çıkarken doğrulama sütunu
**0,7750'den 0,9000'e** yükseliyor — arama çalışıyor, işini yapıyor, her yeni adayla daha yüksek
bir sayı buluyor. Aynı satırlarda sınama sütunu **0,6750'den 0,6500'e** iniyor. Doğrulama kazancı
**+0,1250**, sınama kazancı **−0,0250**. Arama bütçesinin on katına çıkması, hiç görülmemiş
veride hiçbir şey kazandırmadı; küçük bir kayıp getirdi.

Bedel aynı tabloda ve tartışmasız: **40 çağrıdan 400 çağrıya**. Fazladan 360 çağrı harcandı ve
karşılığında elde edilen tek şey **rapor edilecek sayının 0,1250 yükselmesi** oldu. Seçilen adayın
**iyimserlik payı 0,2500**: doğrulamada 0,9000 yazan istem, hiç görülmemiş kayıtlarda 0,6500
veriyor. Bu istemi "0,9000'lik istem" diye teslim etmek, ölçünün dörtte birini uydurmak demektir.

Üçüncü satır aramanın körlüğünü gösteriyor. Sınamada gerçekten en iyi olan aday dördüncüdür
(**0,8000**) ve arama onu hiçbir bütçede seçmedi; doğrulamada 0,6500 aldığı için daha ilk
karşılaştırmada elendi. Arama iyi istemi bulamadı, **doğrulama kümesine en iyi uyan** istemi buldu.

#### İki Koşum ve Aramanın Ölçtüğü Şey

Son üç satır bütün alıştırmanın zeminini yokluyor. Tohum değiştirilip arama baştan koşturulunca
seçilen aday **altıncıdan dokuzuncuya** kayıyor: aynı adaylar, aynı kümeler, aynı kural, başka
bir kazanan. Dokuzuncu aday, sınamada birinci olan dördüncüden yalnız etiket sırasıyla ayrılıyordu.
Dahası, altıncı adayın sınama puanı **0,6500'den 0,8500'e**, yani **+0,2000**
oynuyor. Aramanın on aday üzerinde kazandığı doğrulama farkı 0,1250 idi; **tek bir adayın
koşumdan koşuma oynaması bunun üstünde**. Son satır bunu tamamlıyor: on adayın sınama sıralaması
iki koşumda aynı değil.

Buradan çıkan sonuç aramayı yasaklamaz, ölçüsünü düzeltir. Doğrulama kümesindeki en iyi puan bir
istemin niteliği değil, **bir arama bütçesinin artığıdır**; bütçe büyüdükçe iyimserleşir ve bu
iyimserlik ayrı bir sayıyla, hiç dokunulmamış bir kümede ölçülmedikçe görünmez. Aynı şey belirsiz
bir bileşenin ikinci koşumu için de geçerlidir. Bu kursun kuralı burada son biçimini alıyor:
**ölçülmeden değiştirilen istem bir iyileştirme değil bir tahmindir** — ve tek bir kümede, tek bir
koşumda ölçülen istem de öyledir.

#### Özet

- On aday dört parçadan mekanik olarak üretiliyor; doğrulama kümesi 40, sınama kümesi 80 kayıt.
  İki kümenin ortalamaları **0,6900** ve **0,6663**, yani ayrışma kümeler arasında değil aday
  başınadır.
- Arama bütçesi birden ona çıkarken doğrulama **0,7750'den 0,9000'e** yükseliyor, aynı adayın
  sınaması **0,6750'den 0,6500'e** iniyor: **+0,1250** karşılığında **−0,0250**.
- Bedel çağrı sayısıyla yazılır: arama **40 çağrıdan 400 çağrıya** çıkıyor.
- Seçilen adayın **iyimserlik payı 0,2500**. Sınamada gerçekten en iyi olan aday (0,8000)
  doğrulamada 0,6500 aldığı için hiçbir bütçede seçilmiyor.
- İkinci koşumda arama başka bir adayı seçiyor ve altıncı adayın sınaması **+0,2000** oynuyor —
  tek bir adayın koşum farkı, aramanın on adayda kazandığı farktan büyük.

#### Sonraki Adım

On altı derste isteme ne söyleneceği düzenlendi ve modelden nasıl düşüneceği istendi: yönerge,
rol, biçim, örnek, yasak bildirimi, adım adım çözüm, çoklu örnek, dallanma, geri adım, eylem
alanı, topluluk ve şimdi arama. Hepsinin altında sessiz duran bir şey vardı — modelden gelen yanıt
**serbest metindi**. Etiket her derste yanıtın içinden bir okuma yordamıyla çıkarıldı; okunamayan
yanıt yanlış sayıldı ve o pay ayrıca sayıldı. İstem tarafında yapılan her iyileştirme, çıktının
biçimini **rica etmekten** ibaretti. Sonraki konu bu tarafa geçer: yanıtın üretilme ayarları,
yanıtın nerede durduğu, biçimin dayatılması, gelen çıktının şemaya ve iş kuralına karşı
doğrulanması ve doğrulamaya takılan yanıtın ne kadarının yeniden denemeyle kurtarıldığı.

## Çıktı Denetimi

Belirsiz bir üreticiden gelen çıktının biçimce ve içerikçe sınırlanmasının ölçülmesi: sıcaklık, çekirdek örnekleme ve en olası k seçiminin birlikte davranışı ile iki koşum farkını hangisinin daralttığı, yineleme cezası ve durdurma dizisi eklendiğinde yineleme oranıyla erken kesilen yanıt sayısı, serbest metin, biçim tarifi ve şema dayatmasının şemaya uyan yanıt oranı ile belirteç bedeli, doğrulamanın yakaladığı şema ve iş kuralı ihlali ile yeniden denemenin kurtardığı yanıt ve mal olduğu ek çağrı, bir yanlış yanıtın bazen daha iyi yönergeyle bazen yalnız eksik bilgiyle düzelmesi, istemle dengelemenin alt grup açıklığını ne kadar daralttığı ve veri yanlılığını çözmediği.

### Örnekleme Parametreleri

Source: https://academia.sh/tr/kurslar/istem-muhendisligi/ornekleme-parametreleri

Sıcaklık, çekirdek örnekleme ve en olası k seçiminin aynı istem üzerinde birlikte ölçülmesi: taban ayarda etiket isabeti 0,6417 ve iki koşum farkı 0,5667, sıcaklık 0,2'de 0,8750 ve 0,0417, çekirdek 0,50'de 0,8417 ve 0,1333, en olası k üçte 0,7833 ve 0,3583, üçü birlikte daraltıldığında 0,8667 ve 0,0083. Sabit kesim ortalama üç aday bırakırken çekirdek kesimi 1,20 aday bırakıyor. Giriş belirteci 5300'de sabit kalıyor ve çağrı sayısı 120'de durduğu için değişikliğin bedeli on üç çıkış belirtecidir.

Önceki on altı derste istemin metni bir tasarım nesnesi olarak ele alındı: yönerge düzenlendi,
örnek kondu, kısıt yazıldı, modelden adım adım akıl yürütmesi istendi. Bütün bu derslerde ölçülen
şey **isteme ne yazıldığıydı**. Yanıtın kendisi ise hep serbest metin olarak geri geldi ve nasıl
üretildiği hiç sorulmadı.

Bu konu oradan açılır. Yanıt bir dağılımdan çekilir ve o çekilişin üç ayarı vardır: dağılım
sıcaklığı, çekirdek örnekleme ve en olası k seçimi. Bu üç ayar M28/K01'in Yapay Zekâ
Mühendisliğine Giriş kursunda tanımlandı; burada tanımları tekrarlanmaz. Bu dersin sorusu
başkadır: **üçü aynı anda kullanıldığında ne oluyor**, hangisi hangi görevde işe yarıyor ve
**iki koşum arasındaki farkı** hangisi daraltıyor.

- **CD1.** Kod bir **benzeticidir** ve gerçek bir model uç noktası çağırmaz. Destek talepleri,
  konular ve belge dağarcığı **kurgudur**; tohum **20260218**.
- **CD2.** Önceki istem sabittir: etiket kümesini sayan ve tek etiket isteyen yönerge. Bu istem
  bütün derste **hiç değişmez**; değişen tek şey çağrının örnekleme ayarıdır.
- **CD3.** Ölçüt ikilidir. Etiketleme görevinde **etiket isabeti** (büyük iyi), serbest yanıt
  görevinde **ayrı yanıt sayısı** (çeşitlilik) ölçülür.
- **CD4.** **İki koşum farkı**, aynı 120 talepte tohum 20260218 ile 20260219 arasında **kararı
  değişen kayıt payıdır**. Bir değişikliğin kattığı fark bu sayıdan küçükse ölçülmemiş sayılır.
- **CD5.** Sıcaklık dağılımı yeniden biçimler; **aday listesini kısaltmaz**. Çekirdek örnekleme ve
  en olası k seçimi ise **listeyi keser**.
- **CD6.** Aday sayısı ayrıca basılır: sabit kesimin bıraktığı aday sayısı ile uyarlanan kesimin
  bıraktığı aday sayısı aynı tabloda görünür.
- **CD7.** Benzeticinin iç işaret tablosunda **yanıltıcı bağlar** vardır; hiçbir örnekleme ayarı
  bunları düzeltmez.
- **CD8.** Bedel **belirteçle** yazılır: giriş belirteci, çıkış belirteci ve çağrı sayısı.

#### Üç Ayarın Ayrı İşleri

Üç ayar aynı yerde iş görür: puanlar bir olasılık dağılımına çevrildikten sonra, çekiliş
yapılmadan hemen önce. Sıcaklık bölendir ve dağılımı sivrileştirir ya da düzleştirir. En olası k
seçimi listeyi **baştan sabit sayıda** keser. Çekirdek örnekleme ise sayıya değil **olasılık
toplamına** bakar ve eşiğe ulaşana kadar aday alır.

```python
# BENZETICI -- KURGUDUR. Gercek bir model uc noktasi cagrilmaz; asagidaki kod
# standart kitaplikla yazilmis bir dil modeli benzeticisidir. Talepler de KURGU'dur.
import math

TOHUM, M32 = 20260218, 0xFFFFFFFF
PENCERE, EN_UZUN = 240, 24


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):                      # KURGU belirtecleyici, parca en cok bes damga
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


def izno(m):                            # isteme bagli, kosumdan bagimsiz iz
    h = 2166136261
    for c in m:
        h = ((h ^ ord(c)) * 16777619) & M32
    return h


KONU = ["fatura", "ariza", "sayac", "tarife", "kesinti"]
KALIP = [("bu ayki fatura tutari gecen aya gore cok yuksek geldi", "fatura"),
         ("faturami odedim ama sistemde borc gorunuyor", "fatura"),
         ("fatura ayrintisini nereden gorebilirim", "fatura"),
         ("evde su akmiyor bir ariza var galiba", "ariza"),
         ("baglanti bozuk oldu ve hic calismiyor", "ariza"),
         ("ariza kaydi actim ama ekip gelmedi", "ariza"),
         ("sayac okumasi yanlis girilmis endeks tutmuyor", "sayac"),
         ("sayac degisimi icin randevu istiyorum", "sayac"),
         ("sayac uzerindeki endeks ile fatura ayni degil", "sayac"),
         ("hangi tarife basamagindayim ogrenmek istiyorum", "tarife"),
         ("tarife degisikligi icin ne yapmam gerekiyor", "tarife"),
         ("birim ucret abone tipine gore degisiyor mu", "tarife"),
         ("mahallede kesinti var ne zaman gelecek", "kesinti"),
         ("planli kesinti duyurusu nereden takip edilir", "kesinti"),
         ("aksamdan beri kesinti yasiyoruz", "kesinti")]
EK = ["ayrica gecen ay da ayni sorun olmustu", "bu konuda memnun degilim",
      "acil bilgi almam gerekiyor", "kayit numaram elimde yok"]
TALEP = []
for i in range(120):                    # 120 KURGU destek talebi
    r = uretec(TOHUM + i)
    k = KONU[ayrik(r(), [0.24, 0.22, 0.18, 0.20, 0.16])]
    m, _ = [x for x in KALIP if x[1] == k][int(r() * 3)]
    TALEP.append({"no": 4001 + i, "konu": k,
                  "metin": m + (" " + EK[int(r() * 4)] if r() < 0.34 else "")})

KAVRAM = KONU + ["odeme", "sikayet", "bilgi", "genel"]
IZ = {"fatur": "fatura", "tutar": "fatura", "ayrin": "fatura", "ariza": "ariza",
      "bozuk": "ariza", "calis": "ariza", "akmiy": "ariza", "sayac": "sayac",
      "endek": "sayac", "okuma": "sayac", "tarif": "tarife", "birim": "tarife",
      "abone": "tarife", "basam": "tarife", "kesin": "kesinti", "duyur": "kesinti",
      "mahal": "kesinti", "borc": "odeme", "odedi": "odeme", "ucret": "odeme",
      "memnu": "sikayet", "sorun": "sikayet", "acil": "sikayet", "bilgi": "bilgi",
      "ogren": "bilgi", "nered": "bilgi"}
TUZAK = {"degis": "tarife", "kayit": "ariza", "yukse": "tarife", "gorun": "fatura",
         "ekip": "kesinti", "takip": "tarife", "giril": "fatura"}   # yaniltici baglar
SERBEST = ["talebiniz {k} konusuyla ilgili gorunuyor",
           "bu kayit {k} basligina girer , ilgili ekibe yonlendirildi",
           "kaydiniz alindi , konuyu inceleyip donus yapacagiz"]
SAYAC = [0]


def dagilim(bel, sicaklik, cekirdek, en_olasi_k):
    """Uc ayar burada ve yalniz burada is gorur: sicaklik dagilimi yeniden bicimler,
    en olasi k sabit sayida aday birakir, cekirdek ornekleme olasilik toplamina bakar."""
    aday = [k for k in KAVRAM if k[:5] in bel]
    p = {k: 0.15 for k in (aday if len(aday) >= 3 else KAVRAM)}
    for t in bel:
        for tablo, w in ((IZ, 1.0), (TUZAK, 1.3)):
            if tablo.get(t) in p:
                p[tablo[t]] += w
    ad = sorted(p, key=lambda a: (-p[a], a))
    if sicaklik <= 0.0:
        return [ad[0]], [1.0]                       # en olasi secim
    e = [math.exp(p[a] / sicaklik) for a in ad]
    o = [v / sum(e) for v in e]
    ad, o = ad[:en_olasi_k], o[:en_olasi_k]         # en olasi k secimi
    n, t = 0, 0.0
    while t < cekirdek and n < len(o):              # cekirdek ornekleme
        t += o[n]
        n += 1
    ad, o = ad[:n], o[:n]
    return ad, [v / sum(o) for v in o]


def cagir(istem, tohum=TOHUM, sicaklik=1.0, cekirdek=1.0, en_olasi_k=9,
          en_uzun=EN_UZUN):
    SAYAC[0] += 1
    bel = belirtecle(istem)
    if len(bel) > PENCERE:
        return {"durum": "baglam_asimi", "giris": len(bel), "cikis": 0, "yanit": ""}
    if SAYAC[0] % 37 == 0:
        return {"durum": "hiz_siniri", "giris": len(bel), "cikis": 0, "yanit": ""}
    r = uretec(tohum ^ izno(istem))
    ad, o = dagilim(bel, sicaklik, cekirdek, en_olasi_k)
    k = ad[ayrik(r(), o)]
    y = k if "tek" in bel else SERBEST[ayrik(r(), [0.42, 0.26, 0.32])].format(k=k)
    cb = belirtecle(y)
    if len(cb) > en_uzun:                           # durdurma kosulu
        cb, y = cb[:en_uzun], " ".join(cb[:en_uzun])
    return {"durum": "tamam", "giris": len(bel), "cikis": len(cb), "yanit": y}


def oku(y):
    for s in y.lower().split():
        if s in KONU:
            return s
    return None


ETIKET = ("Talebi su etiketlerden birine ata: fatura , ariza , sayac , tarife , "
          "kesinti . Yanit olarak tek etiket yaz . Talep: ")
b = belirtecle(ETIKET + TALEP[6]["metin"])
print(f"KURGU talep kumesi {len(TALEP)} kayit; ornek talep {TALEP[6]['no']}")
print(f"istem {len(b)} belirtec, gercek konu {TALEP[6]['konu']}")
print("ayar                       aday  ilk uc olasilik")
for ad, s, c, k in (("taban 1,0 / 1,00 / 9", 1.0, 1.0, 9),
                    ("sicaklik 0,2", 0.2, 1.0, 9),
                    ("cekirdek 0,50", 1.0, 0.5, 9),
                    ("en olasi k 3", 1.0, 1.0, 3)):
    a, o = dagilim(b, s, c, k)
    print(f"{ad:<24} {len(a):>5}  {' '.join(f'{v:.3f}' for v in o[:3])}")
```

```
KURGU talep kumesi 120 kayit; ornek talep 4007
istem 42 belirtec, gercek konu sayac
ayar                       aday  ilk uc olasilik
taban 1,0 / 1,00 / 9         5  0.564 0.207 0.076
sicaklik 0,2                 5  0.993 0.007 0.000
cekirdek 0,50                1  1.000
en olasi k 3                 3  0.665 0.245 0.090
```

Dört satır üç ayrı işi gösteriyor. Sıcaklık 0,2'de aday sayısı **beşte kalıyor** ama en yüksek
olasılık 0,564'ten 0,993'e çıkıyor: liste kısalmadı, dağılım sivrildi. Çekirdek 0,50 tek adayla
dönüyor, çünkü ilk adayın olasılığı zaten 0,564 ve eşiği tek başına aşıyor. En olası k üç seçimi
listeyi üçe indiriyor ama kalan üç adayın olasılıkları yeniden ölçeklenince ikinci aday 0,207'den
0,245'e **yükseliyor**. Kesmek, kalanları güçlendirir.

Buradan çıkan ayrım dersin geri kalanını taşır: sıcaklık bir **biçimleme**, çekirdek örnekleme
uyarlanan bir **kesim**, en olası k seçimi sabit bir **kesimdir**.

#### Üç Ayarın Birlikte Davranışı

Aynı istem, aynı 120 talep ve aynı benzetici üzerinde dokuz ayar bileşimi ölçülür. Etiketleme
görevinde isabet, serbest yanıt görevinde ayrı yanıt sayısı basılır. İki koşum farkı, tohum
değiştirilerek alınan ikinci koşumda kararı değişen kayıt payıdır.

```python
SERBESTI = "Su destek talebine kisa bir yanit yaz . Talep: "
AYAR = [("taban 1,0 / 1,00 / 9", 1.0, 1.0, 9), ("sicaklik 0,6", 0.6, 1.0, 9),
        ("sicaklik 0,2", 0.2, 1.0, 9), ("en olasi secim", 0.0, 1.0, 9),
        ("cekirdek 0,50", 1.0, 0.5, 9), ("cekirdek 0,20", 1.0, 0.2, 9),
        ("en olasi k 3", 1.0, 1.0, 3), ("en olasi k 1", 1.0, 1.0, 1),
        ("ucu birlikte", 0.6, 0.5, 3)]


def kosum(yonerge, s, c, k, tohum):
    SAYAC[0] = 0
    return [oku(cagir(yonerge + x["metin"], tohum=tohum, sicaklik=s,
                      cekirdek=c, en_olasi_k=k)["yanit"]) for x in TALEP]


print("ayar                   isabet A  isabet B  iki kosum farki  ayri yanit  aday")
for ad, s, c, k in AYAR:
    a, b = kosum(ETIKET, s, c, k, TOHUM), kosum(ETIKET, s, c, k, TOHUM + 1)
    d = sum(1 for x, y in zip(a, b) if x != y) / len(a)
    ia = sum(x == t["konu"] for x, t in zip(a, TALEP)) / len(a)
    ib = sum(x == t["konu"] for x, t in zip(b, TALEP)) / len(b)
    SAYAC[0] = 0
    n = len({cagir(SERBESTI + x["metin"], sicaklik=s, cekirdek=c,
                   en_olasi_k=k)["yanit"] for x in TALEP})
    m = sum(len(dagilim(belirtecle(ETIKET + t["metin"]), s, c, k)[0])
            for t in TALEP) / len(TALEP)
    print(f"{ad:<22} {ia:>8.4f}  {ib:>8.4f}  {d:>15.4f}  {n:>10}  {m:>4.2f}")
for ad, s, c, k in (AYAR[0], AYAR[-1]):
    SAYAC[0] = 0
    y = [cagir(ETIKET + x["metin"], sicaklik=s, cekirdek=c, en_olasi_k=k) for x in TALEP]
    print(f"bedel {ad:<22} giris {sum(z['giris'] for z in y)} "
          f"cikis {sum(z['cikis'] for z in y)} cagri {SAYAC[0]}")
```

```
ayar                   isabet A  isabet B  iki kosum farki  ayri yanit  aday
taban 1,0 / 1,00 / 9     0.6417    0.6000           0.5667          15  5.03
sicaklik 0,6             0.8167    0.8250           0.2833          17  5.03
sicaklik 0,2             0.8750    0.8917           0.0417          10  5.03
en olasi secim           0.8667    0.8667           0.0000          10  1.00
cekirdek 0,50            0.8417    0.9667           0.1333          15  1.20
cekirdek 0,20            0.8667    0.8667           0.0000          10  1.00
en olasi k 3             0.7833    0.7833           0.3583          15  3.00
en olasi k 1             0.8667    0.8667           0.0000          10  1.00
ucu birlikte             0.8667    0.8667           0.0083          10  1.01
bedel taban 1,0 / 1,00 / 9   giris 5300 cikis 191 cagri 120
bedel ucu birlikte           giris 5300 cikis 204 cagri 120
```

Taban satırı ölçülemez bir satırdır. İsabet **0,6417** görünüyor, ama iki koşum farkı **0,5667**:
kayıtların yarıdan fazlasında karar tohum değişince değişiyor. Bu tabanda ölçülen hiçbir istem
iyileştirmesi savunulamaz, çünkü aranan fark gürültünün altında kalır.

Üç ayarın hepsi bu farkı daraltıyor, ama aynı ölçüde değil. Sıcaklık 0,2 farkı **0,0417**'ye
indiriyor ve isabeti **0,8750** ile tablonun en yükseğine çıkarıyor. Dikkat çekici olan, bunun
en olası seçimden (**0,8667**) de yüksek olması: dağılımı sivriltmek, tamamen kesmekten iyi sonuç
verdi. Çekirdek 0,50 farkı **0,1333**'e indirirken ortalama aday sayısını **1,20**'de tutuyor;
yani talebin çoğunda tek adaya iniyor, kanıtın zayıf olduğu birkaç talepte ikinci adayı da açık
bırakıyor. Bu **uyarlanan** kesimdir.

En olası k üç satırı tablodaki en öğretici satırdır. Aday sayısı **3,00**'te sabittir ve iki koşum
farkı **0,3583** ile taban dışındaki en büyük değerdir. Sabit bir kesim, kanıtın güçlü olduğu
taleplerde gereksiz yere iki rakip aday bırakır ve sıcaklık 1,0 onları yarıştırmaya devam eder.
Kesmek tek başına belirsizliği kapatmaz; **neye göre kesildiği** belirler.

Serbest yanıt sütunu ters yönü gösteriyor. Daraltma etiketlemede kazandırırken burada kaybettirir:
ayrı yanıt sayısı sıcaklık 0,6'da **17** iken en çok daraltılmış ayarlarda **10**'a iniyor;
çekirdek 0,50 ile en olası k üç ise **15**'te kalıyor.
Aynı üç ayar, iki görevde iki ayrı yöne çalışıyor. Tek doğru cevabı olan bir görevde belirsizlik
bir kusurdur; her aboneye ayrı cümle yazması beklenen bir görevde belirsizlik **ürünün kendisidir**.
On ayrı yanıtın kalması, ayarların yanıtın **biçimini** seçen çekilişi hiç etkilememesindendir:
bir ayar her belirsizlik kaynağını kapatmaz.

#### Bedeli Sıfır Belirteç Olan Değişiklik

Bu dersin bedel satırı kursun geri kalanından ayrılır. Önceki istem ile değiştirilmiş istem
**birebir aynı metindir**: giriş belirteci iki ayarda da **5300**, çağrı sayısı iki ayarda da
**120**. Çıkış belirteci 191'den 204'e çıkıyor, çünkü daraltılmış ayar daha uzun yazılan etiketleri
biraz daha sık seçiyor. Toplam bedel **13 belirteçtir**, yani istek başına 0,11 belirteç.

Karşılığında alınan şey ölçülebilirliğin kendisidir. Taban ayarda iki koşum farkı 0,5667 iken üç
ayar birlikte daraltıldığında **0,0083**'e iniyor. Bundan sonraki derslerde bir istem değişikliğinin
kattığı 0,05'lik bir kazanç anlamlı bir sayıdır; taban ayarda aynı kazanç ölçülemezdi.
**Kursun kuralı burada bir ön koşula dönüşür: ölçülmeden değiştirilen istem bir iyileştirme değil
bir tahmindir ve ölçüm ancak iki koşum farkı yeterince küçükken mümkündür.**

Bunun bir sınırı da yazılmalıdır. Üçü birlikte daraltılmış ayarda isabet **0,8667**'de duruyor ve
kalan 16 yanlış kaydın çoğu benzeticinin yanıltıcı bağlarından geliyor. Örnekleme ayarları
belirsizliği kapatır, **sistematik hatayı kapatmaz**. Kararlı biçimde yanlış bir yanıt da
kararlıdır.

#### Özet

- Sıcaklık dağılımı biçimler ve aday listesini kısaltmaz; çekirdek örnekleme olasılık toplamına
  bakarak **uyarlanan** bir kesim yapar; en olası k seçimi **sabit** sayıda aday bırakır.
- Taban ayarda etiket isabeti 0,6417 ama iki koşum farkı 0,5667'dir; bu tabanda hiçbir istem
  değişikliği ölçülemez.
- Sıcaklık 0,2 farkı 0,0417'ye indirirken isabeti 0,8750 ile en yükseğe çıkarıyor ve en olası
  seçimin 0,8667'sini geçiyor; dağılımı sivriltmek, tamamen kesmekten iyi sonuç verdi.
- En olası k üç, aday sayısını 3,00'te sabitleyip iki koşum farkını 0,3583'te bırakıyor; çekirdek
  0,50 ise 1,20 aday ile farkı 0,1333'e indiriyor.
- Aynı ayarlar serbest yanıt görevinde çeşitliliği 17'den 10'a düşürüyor: daraltma bir görevde
  kazanç, öbüründe kayıptır.
- Değişikliğin bedeli 13 çıkış belirteci ve sıfır ek çağrıdır; giriş belirteci 5300'de sabittir.

#### Sonraki Adım

Örnekleme ayarları hangi kavramın seçileceğini denetledi, ama yanıtın **nerede biteceğini** hiç
denetlemedi. Bu derste çıktı uzunluğu tek bir sert sınırla kesildi ve kesilen yanıtların kaç tane
olduğu sayılmadı. Aynı biçimde, bir yanıtın kendi içinde aynı cümleyi tekrar etmesi de hiç
ölçülmedi: dağılımı sivriltmek en olası ifadeyi daha da olası kılar ve uzun yanıtlarda bu
kendini tekrara dönüşür. Sonraki ders iki yeni denetimi ekler ve ikisini de sayıyla ölçer:
yineleme cezası yineleme oranını ne kadar düşürüyor, durdurma dizisi kaç yanıtı kesiyor ve
bunların kaçını **erken** kesiyor.

### Cezalar ve Durdurma Dizileri

Source: https://academia.sh/tr/kurslar/istem-muhendisligi/cezalar-ve-durdurma-dizileri

Yineleme cezası ve durdurma dizisinin aynı yanıt üretiminde ölçülmesi: taban düzenekte yineleme oranı 0,3431 ve 120 yanıtın 107'si uzunluk sınırında kesiliyor, isteme yazılan yasak bildirimi oranı 0,2167'ye indirirken giriş belirtecini 2734'ten 3574'e çıkarıyor, aynı işi 0,45 yineleme cezası sıfır ek belirteçle 0,1972'ye indiriyor. Durdurma dizisi kesilen yanıt sayısını 55'e, ceza ile birlikte 24'e düşürüyor ve çıkış belirtecini 4073'ten 2653'e indiriyor, ama yirmi beş yanıtı etiket cümlesi yazılmadan erken kesip kullanılabilirliği 0,8833'ten 0,7417'ye düşürüyor. Durdurma dizisi satırında iki koşum farkı 0,0543'tür ve tabana göre kazancın 0,0746 olması bu satırı sınırda ölçülebilir kılar.

Önceki derste örnekleme ayarları hangi kavramın seçileceğini denetledi. Yanıtın **nerede
biteceği** ise tek bir sert uzunluk sınırına bırakıldı ve o sınırda kaç yanıtın kesildiği hiç
sayılmadı. Aynı biçimde, uzun bir yanıtın kendi içinde aynı cümleyi tekrar etmesi de ölçülmedi.

Bu ders iki denetimi ekler ve ikisini de sayıyla karşılaştırır. **Yineleme cezası**, daha önce
üretilmiş bir parçanın puanını düşürür. **Durdurma dizisi**, belirlenen bir metin parçası
üretildiğinde üretimi bitirir. İkisi de çağrı ayarıdır ve isteme tek bir belirteç eklemez; bu
yüzden ders bir üçüncü yolu da yan yana ölçer: aynı işi **isteme yazarak** istemek.

- **CD9.** Kod bir **benzeticidir**; gerçek bir uç nokta çağrılmaz. Talepler ve yanıt cümleleri
  **kurgudur**, tohum **20260218**.
- **CD10.** Benzetici yanıtı **cümle cümle** üretir. Her adımda altı kurgu cümleden biri puanına
  göre çekilir; çekiliş kısıtsızsa aynı cümle birden çok kez gelebilir.
- **CD11. Yineleme oranı**, bir yanıtta tekrar eden cümlelerin payıdır: bir eksi ayrı cümle
  sayısının toplam cümle sayısına oranı, 120 yanıt üzerinde ortalanır.
- **CD12. Kesilen yanıt**, çıktı belirteci sınırına (34 belirteç) çarpıp son cümlesi yarıda kalan
  yanıttır. **Erken kesilen yanıt**, durdurma dizisi yüzünden **etiket cümlesi yazılmadan** biten
  yanıttır; ikisi ayrı sayılır.
- **CD13.** Etiket cümlesi, konunun kaydedildiğini bildiren cümledir. Yarıda kalmış bir son cümle
  **tam sayılmaz**; yanıtın kullanılabilirliği bu cümleye bakılarak ölçülür.
- **CD14.** İstemdeki yasak bildirimi benzeticide **ılımlı bir cezaya** karşılık gelir. Bu, bir
  yönergenin bir ayara doğrudan çevrilmediğini gösteren bir kurgu kabuldür.
- **CD15.** İki koşum tohum 20260218 ve 20260219 ile alınır; yineleme oranı iki koşumda ayrı ayrı
  basılır ve aradaki fark ölçülebilirlik eşiğidir.
- **CD16.** Bedel giriş belirteci, çıkış belirteci ve çağrı sayısı olarak yazılır; çağrı sayısı bu
  derste hiç değişmez.

#### Yanıtın Kendini Tekrar Etmesi

Bir yanıt tek bir seçim değildir; art arda gelen birçok seçimdir. Her adımda en yüksek puanlı
parça biraz daha olasıdır ve bir kez seçilmesi onu daha az olası kılmaz. Sonuç, uzun yanıtlarda
kendini gösteren bir döngüdür: aynı cümle döner durur ve yanıt sınırda kesilir.

```python
# BENZETICI -- KURGUDUR. Gercek bir model uc noktasi cagrilmaz. Bu blok yaniti
# cumle cumle ureten bir dil modeli benzeticisidir; talepler de KURGU'dur.
import math

TOHUM, M32 = 20260218, 0xFFFFFFFF
EN_UZUN, EN_COK_CUMLE = 34, 6           # cikti belirteci siniri ve cumle siniri


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):                      # KURGU belirtecleyici, parca en cok bes damga
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


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


KONU = ["fatura", "ariza", "sayac", "tarife", "kesinti"]
KALIP = [("bu ayki fatura tutari gecen aya gore cok yuksek geldi", "fatura"),
         ("faturami odedim ama sistemde borc gorunuyor", "fatura"),
         ("fatura ayrintisini nereden gorebilirim", "fatura"),
         ("evde su akmiyor bir ariza var galiba", "ariza"),
         ("baglanti bozuk oldu ve hic calismiyor", "ariza"),
         ("ariza kaydi actim ama ekip gelmedi", "ariza"),
         ("sayac okumasi yanlis girilmis endeks tutmuyor", "sayac"),
         ("sayac degisimi icin randevu istiyorum", "sayac"),
         ("sayac uzerindeki endeks ile fatura ayni degil", "sayac"),
         ("hangi tarife basamagindayim ogrenmek istiyorum", "tarife"),
         ("tarife degisikligi icin ne yapmam gerekiyor", "tarife"),
         ("birim ucret abone tipine gore degisiyor mu", "tarife"),
         ("mahallede kesinti var ne zaman gelecek", "kesinti"),
         ("planli kesinti duyurusu nereden takip edilir", "kesinti"),
         ("aksamdan beri kesinti yasiyoruz", "kesinti")]
TALEP = []
for i in range(120):                    # 120 KURGU destek talebi
    r = uretec(TOHUM + i)
    k = KONU[ayrik(r(), [0.24, 0.22, 0.18, 0.20, 0.16])]
    TALEP.append({"no": 4001 + i, "konu": k,
                  "metin": [x for x in KALIP if x[1] == k][int(r() * 3)][0]})

IZ = {"fatur": "fatura", "tutar": "fatura", "ayrin": "fatura", "ariza": "ariza",
      "bozuk": "ariza", "calis": "ariza", "akmiy": "ariza", "sayac": "sayac",
      "endek": "sayac", "okuma": "sayac", "tarif": "tarife", "birim": "tarife",
      "abone": "tarife", "basam": "tarife", "kesin": "kesinti", "duyur": "kesinti",
      "mahal": "kesinti"}
CUMLE = [("talebiniz alindi", 1.00), ("konu {k} olarak kaydedildi", 1.25),
         ("ilgili ekibe yonlendirildi", 1.05), ("en kisa surede donus yapilacak", 0.95),
         ("ek bilgi icin kayit numaranizi hazir bulundurun", 0.80),
         ("anlayisiniz icin tesekkur ederiz", 0.85)]
SAYAC = [0]


def yanitla(istem, tohum=TOHUM, ceza=0.0, durdurma=None, en_uzun=EN_UZUN):
    """Yanit cumle cumle uretilir. ceza kullanilan cumlenin puanini dusurur;
    durdurma dizisi uretilen cumlede gorunurse uretim o cumleyi yazmadan biter."""
    SAYAC[0] += 1
    bel = belirtecle(istem)
    p = {k: 0.15 for k in KONU}
    for t in bel:
        if IZ.get(t) in p:
            p[IZ[t]] += 1.0
    k = max(sorted(p), key=lambda a: p[a])
    if "tekra" in bel:                                  # istemdeki yasak bildirimi
        ceza = max(ceza, 0.45)
    r = uretec(tohum ^ izno(istem))
    kullanim, cumleler, belir, kesildi, erken = {}, [], [], False, False
    while len(cumleler) < EN_COK_CUMLE:
        s = [b - ceza * kullanim.get(c, 0) for c, b in CUMLE]
        e = [math.exp(v / 0.35) for v in s]
        c = CUMLE[ayrik(r(), [v / sum(e) for v in e])][0].format(k=k)
        if durdurma and durdurma in c:                  # durdurma dizisi
            erken = not any("konu" in x for x in cumleler)
            break
        kullanim[c.replace(k, "{k}")] = kullanim.get(c.replace(k, "{k}"), 0) + 1
        yeni = belirtecle(c)
        if len(belir) + len(yeni) > en_uzun:            # uzunluk siniri: kesilme
            belir, kesildi = (belir + yeni)[:en_uzun], True
            cumleler.append(c)
            break
        belir += yeni
        cumleler.append(c)
    tam = cumleler[:-1] if kesildi else cumleler
    return {"cumle": cumleler, "belirtec": len(belir), "kesildi": kesildi,
            "erken": erken, "etiket": any(c.startswith("konu") for c in tam)}


YONERGE = "Su destek talebine kisa bir yanit yaz . Talep "
ORNEK = TALEP[4]
o = yanitla(YONERGE + f"{ORNEK['no']} : {ORNEK['metin']}")
print(f"KURGU talep kumesi {len(TALEP)} kayit; ornek talep {ORNEK['no']}")
print(f"cikti siniri {EN_UZUN} belirtec, cumle siniri {EN_COK_CUMLE}")
for c in o["cumle"]:
    print(f"  - {c}")
print(f"cumle {len(o['cumle'])}, ayri cumle {len(set(o['cumle']))}, "
      f"belirtec {o['belirtec']}, kesildi {o['kesildi']}, etiket {o['etiket']}")
d = yanitla(YONERGE + f"{ORNEK['no']} : {ORNEK['metin']}", ceza=0.90,
            durdurma="ek bilgi")
print("ceza 0,90 ve durdurma dizisi 'ek bilgi' ile ayni talep:")
for c in d["cumle"]:
    print(f"  - {c}")
print(f"cumle {len(d['cumle'])}, ayri cumle {len(set(d['cumle']))}, "
      f"belirtec {d['belirtec']}, kesildi {d['kesildi']}, erken {d['erken']}")
```

```
KURGU talep kumesi 120 kayit; ornek talep 4005
cikti siniri 34 belirtec, cumle siniri 6
  - anlayisiniz icin tesekkur ederiz
  - ilgili ekibe yonlendirildi
  - en kisa surede donus yapilacak
  - talebiniz alindi
  - ilgili ekibe yonlendirildi
  - en kisa surede donus yapilacak
cumle 6, ayri cumle 4, belirtec 34, kesildi True, etiket False
ceza 0,90 ve durdurma dizisi 'ek bilgi' ile ayni talep:
  - anlayisiniz icin tesekkur ederiz
  - ilgili ekibe yonlendirildi
  - en kisa surede donus yapilacak
  - talebiniz alindi
  - konu sayac olarak kaydedildi
cumle 5, ayri cumle 5, belirtec 31, kesildi False, erken False
```

Aynı talep iki ayarda iki ayrı yanıt verdi ve ikisinin farkı bir üslup meselesi değil. Üstteki
yanıt altı cümlenin dördü ayrı olacak biçimde iki tekrar taşıyor, otuz dört belirtecin tamamını
harcıyor, sınırda kesiliyor ve **etiket cümlesini hiç yazamıyor**. Yanıt kullanılamaz: talebin
hangi konuya atandığı içinde yok. Alttaki yanıt beş ayrı cümleyle otuz bir belirteçte bitiyor ve
etiket cümlesi sona yetişiyor. Kesilme yok, tekrar yok.

Buradaki nedensellik önemlidir. Tekrar, yanıtı yalnız çirkinleştirmiyor; **sınırlı bütçeyi
tüketip asıl içeriği dışarıda bırakıyor**. Yineleme, uzunluk sınırıyla birleştiğinde bir
biçim sorunu olmaktan çıkıp bir **içerik kaybına** dönüşür.

#### Üç Yolun Aynı Tabloda Sayılması

Aynı 120 talep altı düzenekte koşturulur. İkinci satır **isteme yazılan** bir yasak bildirimidir;
üçüncü ve dördüncü satır **çağrı ayarı** olan yineleme cezasıdır; beşinci satır durdurma dizisi,
altıncısı ikisinin birleşimidir.

```python
YASAK = "Ayni cumleyi tekrar etme . "
DUZENEK = [("taban", YONERGE, 0.0, None),
           ("istemde yasak bildirimi", YASAK + YONERGE, 0.0, None),
           ("yineleme cezasi 0,45", YONERGE, 0.45, None),
           ("yineleme cezasi 0,90", YONERGE, 0.90, None),
           ("durdurma dizisi", YONERGE, 0.0, "ek bilgi"),
           ("ceza + durdurma", YONERGE, 0.90, "ek bilgi")]


def olc(yonerge, ceza, durdurma, tohum=TOHUM):
    SAYAC[0] = 0
    yin = kes = erk = kul = g = c = 0
    for x in TALEP:
        istem = yonerge + f"{x['no']} : {x['metin']}"
        o = yanitla(istem, tohum=tohum, ceza=ceza, durdurma=durdurma)
        n = len(o["cumle"])
        yin += 0.0 if n == 0 else 1 - len(set(o["cumle"])) / n
        kes += o["kesildi"]
        erk += o["erken"]
        kul += o["etiket"]
        g += len(belirtecle(istem))
        c += o["belirtec"]
    return (yin / len(TALEP), kes, erk, kul / len(TALEP), g, c)


print("duzenek                 yineleme A  yineleme B  kesilen  erken  etiketli  giris  cikis")
for ad, y, ce, d in DUZENEK:
    a = olc(y, ce, d)
    b = olc(y, ce, d, TOHUM + 1)
    print(f"{ad:<23} {a[0]:>10.4f}  {b[0]:>10.4f}  {a[1]:>4}/{b[1]:<3}{a[2]:>6}"
          f"  {a[3]:>8.4f}  {a[4]:>5}  {a[5]:>5}")
```

```
duzenek                 yineleme A  yineleme B  kesilen  erken  etiketli  giris  cikis
taban                       0.3431      0.3750   107/106     0    0.8833   2734   4073
istemde yasak bildirimi     0.2167      0.1939   112/117     0    0.9083   3574   4072
yineleme cezasi 0,45        0.1972      0.1944   117/117     0    0.9667   2734   4078
yineleme cezasi 0,90        0.0892      0.0925   120/120     0    0.9833   2734   4080
durdurma dizisi             0.2685      0.3228    55/59     25    0.7417   2734   2942
ceza + durdurma             0.0578      0.0715    24/25     20    0.8333   2734   2653
```

İkinci ve üçüncü satır bu dersin asıl karşılaştırmasıdır. İkisi de aynı şeyi ister: kendini
tekrar etme. Yasak bildirimi yineleme oranını **0,3431'den 0,2167'ye** indiriyor ve giriş
belirtecini **2734'ten 3574'e** çıkarıyor — talep başına yedi belirteç, toplamda **840**. Yineleme
cezası aynı oranı **0,1972'ye** indiriyor ve giriş belirteci **2734'te sabit kalıyor**. Daha az
etkili olan yol pahalı, daha etkili olan yol bedelsiz. Bir hedefin isteme yazılabiliyor olması,
oraya yazılmasının doğru olduğu anlamına gelmez.

Ceza 0,45'ten 0,90'a çıkarıldığında yineleme **0,0892**'ye iniyor ve kazanç **0,1080**'dir. Bu
satırda iki koşum farkı yalnız **0,0033**, yani kazanç farkın otuz katından büyük: rahatça
ölçülebilir bir iyileştirme. Aynı okuma beşinci satırda ters sonuç verir. Durdurma dizisi
yinelemeyi 0,3431'den **0,2685**'e indiriyor, kazanç **0,0746**; ama o satırın iki koşum farkı
**0,0543**'tür. Kazanç farkın ancak biraz üstünde kalıyor ve tek koşuma bakan biri bu satırı
olduğundan güçlü gösterir. **Ölçülmeden değiştirilen istem bir iyileştirme değil bir tahmindir**
ve ölçüm iki koşumu birlikte okumayı gerektirir.

İki koşum farkının satırdan satıra değişmesi de bir bilgidir. Ceza satırlarında fark 0,0033 ile
0,0028 arasında kalıyor, çünkü ceza aynı cümlenin ikinci kez seçilmesini her koşumda aynı ölçüde
engelliyor. Durdurma dizisi satırında fark 0,0543'e çıkıyor, çünkü yanıtın nerede biteceği
tek bir çekilişe bağlı ve o çekiliş tohumla birlikte kayıyor. Bir düzenek ölçtüğü sayıyı
iyileştirirken **o sayının güvenilirliğini düşürebilir**; iki koşumu basmayan bir tablo bunu
göstermez.

Yineleme oranı düşerken **kesilen yanıt sayısının arttığı** da tabloda görünüyor: taban 107,
ceza 0,90 ile 120. Ceza tekrarı azaltır ama yanıtı kısaltmaz; tersine, tekrar yerine gelen ayrı
cümleler daha uzundur ve bütçeyi daha hızlı tüketir. Uzunluk sorununu çözen tek düzenek durdurma
dizisidir: kesilen yanıt **55'e**, ceza ile birlikte **24'e** iniyor ve çıkış belirteci
**4073'ten 2653'e** düşüyor. Toplam kazanç **1420 belirteç**, yanıt başına 11,8 belirteçtir.

#### Durdurma Dizisinin Erken Kestiği

Durdurma dizisinin bedeli çıkışta değil **içerikte** ödenir. Beşinci satırda yirmi beş yanıt,
etiket cümlesi hiç yazılmadan bitiyor: durdurma dizisini taşıyan cümle sıraya erken düştü ve
üretim orada durdu. Kullanılabilir yanıt payı tabanın **0,8833**'ünden **0,7417**'ye iniyor.
Yani çıkış belirtecinden kazanılan 1131 belirteç, on yedi kullanılabilir yanıtla ödendi.

Son satır iki düzeneğin birbirini nasıl düzelttiğini gösteriyor. Yineleme cezası eklenince erken
kesme 25'ten **20'ye**, kullanılabilirlik **0,8333**'e çıkıyor. Sebep sıradadır: ceza, daha önce
kullanılmış cümlelerin puanını düşürdüğü için etiket cümlesi yanıtın başlarına doğru kayıyor ve
durdurma dizisi geldiğinde çoğu yanıtta zaten yazılmış oluyor. Buna karşın son satır **hâlâ
tabanın altındadır**: 0,8333 karşısında 0,8833. İki düzenek birlikte çıkışı üçte bir oranında
ucuzlattı ve kullanılabilirliği düşürdü.

Bu, durdurma dizisi seçiminin bir tasarım kararı olduğunu gösterir. Dizinin kendisi keyfi
değildir: yanıtta **zorunlu içerikten sonra** görünmesi beklenen bir metin parçası seçilmelidir.
Burada seçilen parça yanıtın sonlarında beklenen bir ek bilgi cümlesinin başıydı ve beklentinin
tutmadığı yirmi beş yanıtta içerik kaybı oluştu. Ölçülmesi gereken şey dizinin kendisi değil,
**onun hangi sıklıkla zorunlu içerikten önce çıktığıdır**; bu sayı basılmadan durdurma dizisi
ölçülmüş sayılmaz.

Üç sayıyla toparlanır. Önceki istem, yalın yanıt yönergesidir: 2734 giriş belirteci, yineleme
0,3431, kesilen 107, çıkış 4073, kullanılabilirlik 0,8833. Değiştirilmiş istem iki ayrı biçimde
kurulabilir. İsteme yasak bildirimi yazmak yinelemeyi 0,2167'ye indirir ve **840 belirteç** ekler.
Çağrı ayarını değiştirmek yinelemeyi 0,0578'e, kesileni 24'e, çıkışı 2653'e indirir; **giriş
belirteci ve çağrı sayısı hiç değişmez**, karşılığında yirmi yanıt erken kesilir ve
kullanılabilirlik tabanın altına iner. Bir düzeneğin bedeli her zaman belirteçle ödenmez; bazen
doğrudan **kullanılabilirlikle** ödenir.

#### Özet

- Yanıt cümle cümle üretildiği için tekrar kendiliğinden oluşur: taban düzenekte yineleme oranı
  0,3431 ve 120 yanıtın 107'si uzunluk sınırında kesiliyor.
- Tekrar bir üslup sorunu değildir; sınırlı çıkış bütçesini tüketip etiket cümlesini dışarıda
  bırakır ve yanıtı kullanılamaz kılar.
- İsteme yazılan yasak bildirimi yinelemeyi 0,2167'ye indirir ve 840 giriş belirteci ekler; çağrı
  ayarı olan 0,45 yineleme cezası aynı oranı 0,1972'ye indirir ve sıfır belirteç ekler.
- Ceza 0,45'ten 0,90'a çıkınca kazanç 0,1080 ve iki koşum farkı 0,0033'tür; durdurma dizisinin
  tabana göre kazancı 0,0746 ve iki koşum farkı 0,0543'tür, yani ikinci satır sınırdadır.
- Durdurma dizisi kesilen yanıtı 107'den 55'e, ceza ile birlikte 24'e indirir ve çıkış belirtecini
  4073'ten 2653'e düşürür; bedeli yirmi beş erken kesilen yanıt ve kullanılabilirliğin 0,8833'ten
  0,7417'ye inmesidir.

#### Sonraki Adım

Bu iki denetim yanıtın **ne kadar sürdüğünü** düzenledi, **neye benzediğini** değil. Kesilme
azaldı, tekrar azaldı, ama çıktı hâlâ serbest metin: etiketin yanıtın kaçıncı cümlesinde
geçtiği, hangi sözcükle yazıldığı ve yanında başka ne bulunduğu her seferinde başka. Bir kayıt
sistemine yazılacak bir çıktı bu biçimde okunamaz. Sonraki ders çıktının biçimini üç düzeyde
karşılaştırır — serbest metin, isteme yazılmış biçim tarifi ve şema dayatması — ve her düzeyde
**şemaya uyan yanıt oranını** belirteç bedeliyle birlikte basar.

### Yapılandırılmış Çıktı

Source: https://academia.sh/tr/kurslar/istem-muhendisligi/yapilandirilmis-cikti

Serbest metin, isteme yazılmış biçim tarifi ve şema dayatmasının aynı 120 kurgu talepte yan yana ölçülmesi: serbest metinde şemaya uyan yanıt oranı 0,0000, biçim tarifiyle 0,8000, örnek eklendiğinde 0,8833, şema dayatmasıyla 1,0000. Biçim tarifi satırının iki koşum farkı 0,0833'tür ve örnek eklemenin kattığı fark da 0,0833 olduğu için o kazanç ölçülmemiş sayılır, üstelik 2040 belirteç ekler. Konu isabeti dört düzeyde de 0,8833'te sabit kalıyor. Giriş belirteci 2254'ten biçim tarifiyle 5614'e, örnekle 7654'e çıkarken şema dayatması 2974'te kalıyor, yani en yüksek uyumu en ucuz istem veriyor.

Önceki iki ders yanıtın **hangi kavramı** seçtiğini ve **nerede bittiğini** düzenledi. Yanıtın
kendisi hâlâ bir cümleydi: etiketin kaçıncı sözcükte geçtiği, yanında hangi ifadenin bulunduğu
ve bir kayıt alanının nereden okunacağı her seferinde başkaydı.

Bir destek yardımcısının çıktısı bir insana değil bir **kayıt sistemine** gidiyorsa, cümle
kullanılamaz. Gereken şey belirli alanların belirli değerlerle dolu olduğu bir kayıttır. Bu ders
o kaydı üç düzeyde ister — serbest metin, isteme yazılmış **biçim tarifi** ve üretimi kısıtlayan
**şema dayatması** — ve üçünün **şemaya uyan yanıt oranını** belirteç bedeliyle yan yana basar.

- **CD17.** Kod bir **benzeticidir**; gerçek bir uç nokta çağrılmaz. Talepler, alanlar ve değer
  kümeleri **kurgudur**, tohum **20260218**.
- **CD18. Şema dört alandır:** sayı olması gereken bir talep numarası ve üçü kapalı değer
  kümesinden gelen konu, öncelik ve aksiyon. Talep numarası isteme yazılır, yani model onu
  uydurmak zorunda değildir.
- **CD19.** Şema doğrulayıcısı **ders içinde yazılır**; dışarıdan hiçbir şema kitaplığı
  kullanılmaz. Dört hata sınıfı sayılır: ayrıştırılamadı, eksik anahtar, fazladan anahtar,
  geçersiz değer.
- **CD20. Biçim tarifi bir eğilimdir, bir garanti değildir.** Benzetici, istemde biçim tarifi
  görürse yanıtın bir payını tarife uygun üretir; kalan pay beş bozuk biçimden birine düşer.
  Beşincisi **şemadan geçer**: alanlar yerindedir ama talep numarası kayıtlı olmayan bir sayıdır.
- **CD21. Şema dayatması bir kısıttır.** Bu kipte üretim şemanın dışına **çıkamaz**; alanlar
  eksiksiz ve değerler kapalı kümedendir.
- **CD22.** Benzeticideki her karar **ayrı tuzlanmış tek bir çekilişten** gelir; kararlar
  birbirine bağlanmaz. Konu seçimi yalnız **talep metninden** okunur, böylece biçim düzeyleri
  arasında yalnız biçim değişir.
- **CD23. Kaydedilebilir doğru kayıt**, hem şemaya uyan hem konusu doğru olan yanıttır; bu dersin
  ürün ölçütü budur.
- **CD24.** Bedel giriş ve çıkış belirteci olarak yazılır; çağrı sayısı üç düzeyde de talep
  başına birdir.

#### Şema, Ayrıştırıcı ve Doğrulayıcı

Şema doğrulaması M16'nın API sözleşmesi kursunda ve M24'te ölçüldü; yordamı burada
tekrarlanmaz. Eklenen tek şey üreticinin kimliğidir: doğrulanan kayıt bir istemciden değil,
**belirsiz bir bileşenden** geliyor. Bu yüzden doğrulayıcı bir güvenlik kapısı değil, bir
**ölçüm aracıdır**: kaç yanıtın hangi sınıfta düştüğünü sayar.

```python
# BENZETICI -- KURGUDUR. Gercek bir model uc noktasi cagrilmaz. Sema dogrulamasi
# da ders icinde yazilir; disaridan hicbir sema kitapligi kullanilmaz.
TOHUM, M32 = 20260218, 0xFFFFFFFF


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):                      # KURGU belirtecleyici, parca en cok bes damga
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


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


KONU = ["fatura", "ariza", "sayac", "tarife", "kesinti"]
ONCELIK, AKSIYON = ["dusuk", "orta", "yuksek"], ["kayit", "yonlendirme", "bilgi"]
SEMA = {"talep_no": "sayi", "konu": KONU, "oncelik": ONCELIK, "aksiyon": AKSIYON}
KALIP = [("bu ayki fatura tutari gecen aya gore cok yuksek geldi", "fatura"),
         ("faturami odedim ama sistemde borc gorunuyor", "fatura"),
         ("fatura ayrintisini nereden gorebilirim", "fatura"),
         ("evde su akmiyor bir ariza var galiba", "ariza"),
         ("baglanti bozuk oldu ve hic calismiyor", "ariza"),
         ("ariza kaydi actim ama ekip gelmedi", "ariza"),
         ("sayac okumasi yanlis girilmis endeks tutmuyor", "sayac"),
         ("sayac degisimi icin randevu istiyorum", "sayac"),
         ("sayac uzerindeki endeks ile fatura ayni degil", "sayac"),
         ("hangi tarife basamagindayim ogrenmek istiyorum", "tarife"),
         ("tarife degisikligi icin ne yapmam gerekiyor", "tarife"),
         ("birim ucret abone tipine gore degisiyor mu", "tarife"),
         ("mahallede kesinti var ne zaman gelecek", "kesinti"),
         ("planli kesinti duyurusu nereden takip edilir", "kesinti"),
         ("aksamdan beri kesinti yasiyoruz", "kesinti")]
TALEP = []
for i in range(120):                    # 120 KURGU destek talebi
    r = uretec(TOHUM + i)
    k = KONU[ayrik(r(), [0.24, 0.22, 0.18, 0.20, 0.16])]
    TALEP.append({"no": 4001 + i, "konu": k,
                  "metin": [x for x in KALIP if x[1] == k][int(r() * 3)][0]})

IZ = {"fatur": "fatura", "tutar": "fatura", "ayrin": "fatura", "ariza": "ariza",
      "bozuk": "ariza", "calis": "ariza", "akmiy": "ariza", "sayac": "sayac",
      "endek": "sayac", "okuma": "sayac", "tarif": "tarife", "birim": "tarife",
      "abone": "tarife", "basam": "tarife", "kesin": "kesinti", "duyur": "kesinti",
      "mahal": "kesinti"}
TUZAK = {"degis": "tarife", "kayit": "ariza", "yukse": "tarife", "gorun": "fatura",
         "ekip": "kesinti", "takip": "tarife", "giril": "fatura"}   # yaniltici baglar
SAYAC = [0]


def ayristir(metin):
    """Anahtar=deger cifti ayristirici. Ayrilamayan yanit icin None doner."""
    if "=" not in metin:
        return None
    kayit = {}
    for parca in metin.split(";"):
        if "=" not in parca:
            return None
        a, _, d = parca.partition("=")
        kayit[a.strip()] = d.strip()
    return kayit


def dogrula(kayit):
    """Sema dogrulama: eksik anahtar, fazladan anahtar, gecersiz deger."""
    if kayit is None:
        return ["ayristirilamadi"]
    hata = [f"eksik:{a}" for a in SEMA if a not in kayit]
    hata += [f"fazla:{a}" for a in kayit if a not in SEMA]
    for a, kural in SEMA.items():
        if a not in kayit:
            continue
        d = kayit[a]
        if kural == "sayi" and not d.isdigit():
            hata.append(f"sayi_degil:{a}")
        elif kural != "sayi" and d not in kural:
            hata.append(f"gecersiz:{a}")
    return hata


def cekilis(istem, tohum, tuz):
    """Her karar icin ayri tuzlanmis tek cekilis; kararlar birbirine baglanmaz."""
    return uretec((tohum + tuz) ^ izno(istem))()


def cagir(istem, talep, kip, tohum=TOHUM):
    """kip: serbest | tarif | sema. Sema kipinde uretim sema disina cikamaz."""
    SAYAC[0] += 1
    bel = belirtecle(istem)
    p = {k: 0.15 for k in KONU}
    for t in belirtecle(talep["metin"]):    # konu yalniz talep metninden okunur
        for tablo, w in ((IZ, 1.0), (TUZAK, 1.3)):
            if tablo.get(t) in p:
                p[tablo[t]] += w
    k = max(sorted(p), key=lambda a: p[a])
    o = ONCELIK[ayrik(cekilis(istem, tohum, 11), [0.31, 0.44, 0.25])]
    a = AKSIYON[ayrik(cekilis(istem, tohum, 29), [0.46, 0.32, 0.22])]
    duz = f"talep_no={talep['no']} ; konu={k} ; oncelik={o} ; aksiyon={a}"
    if kip == "sema":                                   # sema dayatmasi
        return duz, k
    if kip == "serbest":
        return f"talebiniz {k} konusunda kaydedildi ve {a} adimi baslatildi", k
    egilim = 0.62 if "bicim" in bel else 0.0            # istemdeki bicim tarifi
    if "ornek" in bel:
        egilim += 0.22
    if cekilis(istem, tohum, 53) < egilim:
        return duz, k
    bozuk = ayrik(cekilis(istem, tohum, 71),            # tarife uymayan yanit
                  [0.22, 0.20, 0.18, 0.16, 0.24])
    if bozuk == 0:
        return f"talebiniz {k} konusunda kaydedildi ve {a} adimi baslatildi", k
    if bozuk == 1:
        return f"talep_no={talep['no']} ; konu={k} ; aksiyon={a}", k
    if bozuk == 2:
        return f"talep_no={talep['no']} ; konu={k} ; oncelik=acil ; aksiyon={a}", k
    if bozuk == 3:
        return f"talep_no=TL{talep['no']} ; konu={k} ; oncelik={o} ; aksiyon={a}", k
    return f"talep_no={talep['no'] + 500} ; konu={k} ; oncelik={o} ; aksiyon={a}", k


TARIF = ("Yaniti su bicimde yaz: talep_no=<sayi> ; konu=<fatura|ariza|sayac|"
         "tarife|kesinti> ; oncelik=<dusuk|orta|yuksek> ; aksiyon=<kayit|"
         "yonlendirme|bilgi> . ")


def istemi(onek, x):
    return onek + f"Talep {x['no']} : {x['metin']}"


print("sema anahtarlari:", " , ".join(SEMA))
for kip, onek in (("serbest", "Su talebi yanitla . "), ("tarif", TARIF),
                  ("sema", "Sema: talep_no ; konu ; oncelik ; aksiyon . ")):
    y, _ = cagir(istemi(onek, TALEP[0]), TALEP[0], kip)
    h = dogrula(ayristir(y))
    print(f"kip {kip:<8} {y}")
    print(f"           hata {h if h else 'yok'}")
print("\nbicim tarifi kipinde ilk dort dogrulama hatasi:")
n = 0
for x in TALEP:
    y, _ = cagir(istemi(TARIF, x), x, "tarif")
    h = dogrula(ayristir(y))
    if h and n < 4:
        n += 1
        print(f"  {h[0]:<22} {y[:52]}")
```

```
sema anahtarlari: talep_no , konu , oncelik , aksiyon
kip serbest  talebiniz kesinti konusunda kaydedildi ve yonlendirme adimi baslatildi
           hata ['ayristirilamadi']
kip tarif    talep_no=TL4001 ; konu=kesinti ; oncelik=orta ; aksiyon=kayit
           hata ['sayi_degil:talep_no']
kip sema     talep_no=4001 ; konu=kesinti ; oncelik=orta ; aksiyon=bilgi
           hata yok

bicim tarifi kipinde ilk dort dogrulama hatasi:
  sayi_degil:talep_no    talep_no=TL4001 ; konu=kesinti ; oncelik=orta ; aksi
  gecersiz:oncelik       talep_no=4009 ; konu=sayac ; oncelik=acil ; aksiyon=
  ayristirilamadi        talebiniz kesinti konusunda kaydedildi ve yonlendirm
  sayi_degil:talep_no    talep_no=TL4032 ; konu=tarife ; oncelik=orta ; aksiy
```

Üç kipin aynı talepte ürettiği çıktı, aradaki farkın nerede olduğunu gösteriyor. Serbest metnin
içinde doğru konu var (`kesinti`) ama kayıt alanı yok; ayrıştırıcı hiçbir şey bulamıyor. Biçim
tarifi kipinde yanıt neredeyse doğru: dört alan da yerinde, ama talep numarasının başına iki harf
gelmiş ve alan artık sayı değil. Kayıt sistemi bu satırı **reddeder**, üstelik yanıtın içeriği
tamamen doğrudur.

Dört hata örneği bozulmanın nerede olduğunu da söylüyor: bir alan sayı olmadığı için, biri kapalı
kümenin dışında bir değer taşıdığı için, biri hiç ayrıştırılamadığı için düşüyor. Hepsi biçim
hatasıdır ve hiçbiri konu hatası değildir.

#### Üç Düzeyin Uyum ve Bedel Tablosu

Aynı 120 talep dört istemle koşturulur. İlk üçü **isteme yazarak** ister, sonuncusu üretimi
kısıtlar. İkinci koşum tohum 20260219 ile alınır ve şemaya uyan oran onun için ayrıca basılır.

```python
ORNEK = "Ornek: talep_no=4000 ; konu=ariza ; oncelik=orta ; aksiyon=kayit . "
DUZEY = [("serbest metin", "serbest", "Su talebi yanitla . "),
         ("bicim tarifi", "tarif", TARIF),
         ("bicim tarifi + ornek", "tarif", TARIF + ORNEK),
         ("sema dayatmasi", "sema", "Sema: talep_no ; konu ; oncelik ; aksiyon . ")]


def konuyu_oku(y, kayit):
    if kayit and "konu" in kayit:
        return kayit["konu"]
    return next((s for s in y.split() if s in KONU), None)


def olc(kip, onek, tohum=TOHUM):
    SAYAC[0] = 0
    ayr = uy = isb = kay = g = c = 0
    sayim = {}
    for x in TALEP:
        istem = istemi(onek, x)
        y, _ = cagir(istem, x, kip, tohum)
        kayit = ayristir(y)
        h = dogrula(kayit)
        ayr += kayit is not None
        uy += not h
        d = konuyu_oku(y, kayit) == x["konu"]
        isb += d
        kay += d and not h
        for e in h:
            sayim[e.split(":")[0]] = sayim.get(e.split(":")[0], 0) + 1
        g += len(belirtecle(istem))
        c += len(belirtecle(y))
    return (ayr / 120, uy / 120, isb / 120, kay / 120, g, c, sayim)


print("duzey                 ayristirilabilir  uyan A  uyan B  konu isabeti"
      "  kaydedilebilir  giris  cikis")
for ad, kip, onek in DUZEY:
    a, b = olc(kip, onek), olc(kip, onek, TOHUM + 1)
    print(f"{ad:<21} {a[0]:>16.4f}  {a[1]:>6.4f}  {b[1]:>6.4f}  {a[2]:>12.4f}"
          f"  {a[3]:>14.4f}  {a[4]:>5}  {a[5]:>5}")
for ad, kip, onek in DUZEY[1:3]:
    print(f"{ad:<21} hata dagilimi {dict(sorted(olc(kip, onek)[6].items()))}")
```

```
duzey                 ayristirilabilir  uyan A  uyan B  konu isabeti  kaydedilebilir  giris  cikis
serbest metin                   0.0000  0.0000  0.0000        0.8833          0.0000   2254   1614
bicim tarifi                    0.9333  0.8000  0.7167        0.8833          0.7000   5614   1789
bicim tarifi + ornek            0.9667  0.8833  0.8667        0.8833          0.7750   7654   1789
sema dayatmasi                  1.0000  1.0000  1.0000        0.8833          0.8833   2974   1810
bicim tarifi          hata dagilimi {'ayristirilamadi': 8, 'eksik': 1, 'gecersiz': 9, 'sayi_degil': 6}
bicim tarifi + ornek  hata dagilimi {'ayristirilamadi': 4, 'eksik': 5, 'gecersiz': 2, 'sayi_degil': 3}
```

İlk satır kayıt sistemi açısından tam bir kayıptır. Serbest metnin konu isabeti **0,8833**, yani
yanıtların yaklaşık dokuzda sekizi doğru konuyu söylüyor. Kaydedilebilir doğru kayıt oranı ise
**0,0000**. Doğru bilgi üretildi ve **okunamadığı için yok sayıldı**. Bu, biçim denetiminin
niçin bir süsleme değil bir ölçüt olduğunu gösteren en açık satırdır.

İkinci satır isteme yazmanın kısmi kazancıdır: ayrıştırılabilir yanıt **0,9333**, ama şemaya
uyan **0,8000**. Aradaki 0,1333 tamamen ayrıştırılabilen fakat doğrulamayı geçemeyen yanıtlardır:
dokuzunda öncelik kapalı kümenin dışında, altısında talep numarası sayı değil, birinde bir alan
eksik. Ayrıştırılabilirlik ile geçerlilik aynı şey değildir ve tek sayıyla ölçülemez.

#### Ölçülemeyen Kazanç ve Bedelin Ters Yönü

Üçüncü satır sezgiye en uygun olan ve tabloda en zayıf duran satırdır. Örnek eklemek uyumu
**0,8000'den 0,8833'e** çıkarıyor; kazanç **0,0833**. Karşılaştırmanın tabanı olan biçim tarifi satırının iki koşum
sütununa bakmak gerekiyor: o satır ikinci tohumda **0,7167** veriyor, yani iki koşum farkı da
**0,0833**. Kazanç, farktan **büyük değil**. Kursun kuralı burada doğrudan uygulanır: bir istem
değişikliğinin kattığı fark iki koşum farkını aşmıyorsa **ölçülmemiş sayılır**. Örnek eklemek
işe yaramış olabilir, ama bu tablo onu göstermiyor.

Aynı değişikliğin bedeli ise kesindir. Giriş belirteci **5614'ten 7654'e** çıkıyor: talep başına
on yedi, toplamda **2040 belirteç**. Ölçülemeyen bir kazanç için ödenen ölçülebilir bir bedel,
bu kursun ikinci iddiasının tam karşılığıdır.

Dördüncü satır bunun tersidir. Şema dayatması uyumu **1,0000**'a çıkarıyor; tabana göre kazanç
**0,2000**, yani iki koşum farkının iki buçuk katı. Bedel sütunu daha da şaşırtıcıdır: giriş
belirteci **2974**'te kalıyor. Biçim tarifinin yarısından biraz fazla, örnekli tarifin beşte ikisi kadar.
Çünkü şema isteme uzun uzun **anlatılmıyor**, alan adlarıyla kısaca bildiriliyor ve asıl iş
üretimin kısıtlanmasında yapılıyor. En yüksek uyumu en ucuz istem veriyor. Çıkış belirteci ise
dört düzeyde birbirine yakındır (1614 ile 1810 arası), çünkü çıktının uzunluğu değil **biçimi**
değişiyor.

Son olarak konu isabeti sütunu dört satırda da **0,8833**'te sabittir ve bu tesadüf değildir.
Şema dayatması yanıtın **biçimini** garanti eder, **içeriğini** değil. On dört talep hâlâ yanlış
konuya atanıyor ve bu yanlış konu artık kusursuz biçimli bir kayıt içinde, geçerli bir değer
olarak duruyor. Geçerlilik doğruluk değildir; şemadan geçen bir kayıt yanlış olabilir. Nitekim
biçim tarifi satırında şemadan geçen kayıtların on üçü, isteme yazılan numaranın yerine kayıtlı
olmayan bir talep numarası taşıyor ve doğrulayıcı bunların hiçbirini görmüyor.

#### Özet

- Şema dört alandır ve doğrulayıcısı ders içinde standart kitaplıkla yazılır; hata sınıfları ayrı
  ayrı sayılır.
- Serbest metinde konu isabeti 0,8833 iken kaydedilebilir doğru kayıt oranı 0,0000'dır: doğru
  bilgi okunamadığı için yok sayılır.
- Biçim tarifi uyumu 0,8000'e çıkarır; ayrıştırılabilirlik (0,9333) ile şemaya uygunluk aynı şey
  değildir.
- Örnek eklemek uyumu 0,8833'e çıkarır ama kazanç 0,0833, biçim tarifi satırının iki koşum farkı
  da 0,0833'tür: kazanç ölçülmemiş sayılır ve karşılığında 2040 belirteç ödenir.
- Şema dayatması uyumu 1,0000'a çıkarır ve bunu 2974 giriş belirteciyle yapar; en yüksek uyumu
  en ucuz istem veriyor.
- Konu isabeti dört düzeyde de 0,8833'te sabittir ve şemadan geçen on üç kayıt kayıtlı olmayan
  bir talep numarası taşır: şema biçimi garanti eder, içeriği değil.

#### Sonraki Adım

Bu derste doğrulayıcı yalnız bir sayaç olarak kullanıldı: kaç yanıtın düştüğünü saydı ve düşen
yanıtlar atıldı. Bir üretim hattında atmak bir seçenek değildir; düşen kayıt ya kurtarılır ya da
elle işlenir. Üstelik son paragrafta görülen sorun hiç ele alınmadı: şemadan geçen bir kayıt
**iş kurallarına** aykırı olabilir ve kayıtlı olmayan bir talep numarası bunun en açık örneğidir.
Sonraki ders iki denetimi ayrı ayrı sayar ve üzerine bir yeniden deneme döngüsü kurar: kaç yanıt
şemaya uymuyor, kaçı iş kuralına takılıyor, yeniden deneme bunların kaçını kurtarıyor ve bu
kurtarma kaç ek çağrıya mal oluyor.

### Çıktı Doğrulama

Source: https://academia.sh/tr/kurslar/istem-muhendisligi/cikti-dogrulama

Şema doğrulaması ve iş kuralı denetiminin ayrı ayrı sayılması ve üzerine bir yeniden deneme döngüsü kurulması: 120 kurgu yanıtın 24'ü şemaya uymuyor, şemadan geçen 96 kaydın 24'ü iş kuralına takılıyor ve doğrulama yokken hatalı kayıt oranı 0,4000. İki denetim birlikte kabul oranını 0,6000'a indiriyor, bir yeniden deneme 26 kaydı kurtarıp 0,8167'ye çıkarıyor ve 48 ek çağrıya mal oluyor. İkinci deneme sekiz kayıt daha kurtarıyor ama kazancı 0,0666 ile iki koşum farkı 0,0667'nin altında kalıyor. Hatayı isteme yazan deneme 23 kayıt kurtarıyor ve 514 belirteç ekliyor.

Önceki ders çıktının biçimini üç düzeyde ölçtü ve doğrulayıcıyı yalnız bir sayaç olarak
kullandı: kaç yanıtın düştüğünü saydı, düşenleri attı. Kapanışında iki eksik yazılıydı. Birincisi,
bir üretim hattında düşen kaydı atmak bir seçenek değildir. İkincisi, şemadan geçen bir kayıt da
yanlış olabilir: önceki dersin biçim tarifi satırında şemadan geçen kayıtların on üçü, isteme
yazılan numaranın yerine kayıtlı olmayan bir talep numarası taşıyordu ve doğrulayıcı bunu hiç
görmedi.

Bu ders iki denetimi ayırır ve üzerine bir yeniden deneme döngüsü kurar. Girdi doğrulama, şema ve
iş kuralı yordamı M16'nın API sözleşmesi kursunda ve M24'te ölçüldü; burada tekrarlanmaz. Eklenen
tek şey **üreticinin belirsiz olmasıdır**: reddedilen bir kayıt yeniden istenebilir ve ikinci
istek başka bir yanıt verebilir. Ölçülecek olan da budur — doğrulamanın yakaladığı, yeniden
denemenin kurtardığı ve bunun kaç çağrıya mal olduğu.

- **CD25.** Kod bir **benzeticidir**; gerçek bir uç nokta çağrılmaz. Talepler, alanlar ve kurallar
  **kurgudur**, tohum **20260218**.
- **CD26.** Başlangıç istemi önceki dersin **biçim tarifi** istemidir; şema dayatması bilerek
  kullanılmaz, çünkü bu ders **hatalı çıktının** ne yapıldığını ölçer.
- **CD27. İki denetim ayrıdır.** Şema doğrulaması alanların varlığına ve değer kümelerine bakar.
  **İş kuralı denetimi** yalnız şemadan geçmiş kayıtlara uygulanır ve kurumun kurallarına bakar.
- **CD28. Üç iş kuralı kurgudur:** yüksek öncelikli bir kayıt bilgilendirmeyle kapatılamaz,
  kesinti konulu bir kayıt tek başına kayıtla kapatılamaz ve talep numarası kayıtlı talepler
  kümesinde olmalıdır. Üçünü de şema **göremez**.
- **CD29. Yeniden deneme aynı isteği yeni bir tohumla tekrar eder.** Model belirsiz olduğu için
  ikinci yanıt başka çıkabilir; bu, düzeltmenin tek dayanağıdır.
- **CD30.** Bir değişke, hatayı isteme **yazar**: reddedilen yanıtın hata adı isteme eklenir.
  Bu, giriş belirtecini artırır.
- **CD31. Sisteme giren hatalı kayıt** ayrıca sayılır: doğrulama olmadığında kabul oranı 1,0000
  görünür ama kaydın bir bölümü bozuktur.
- **CD32.** Bedel ek çağrı sayısı ve toplam belirteç olarak yazılır; iki koşum farkı için ikinci
  koşum tohum 20260219 ile alınır.

#### Şemanın Göremediği Hata

Şema bir kaydın **biçimini** tanımlar: hangi alanlar var, değerler hangi kümeden. Bir kurumun
kuralları ise kaydın **anlamına** bakar ve şemanın diliyle yazılamaz. Bu ders üç kurgu kural
tanımlar ve üçünün de kusursuz biçimli kayıtlarda tetiklendiğini gösterir.

```python
# BENZETICI -- KURGUDUR. Gercek bir model uc noktasi cagrilmaz. Sema dogrulamasi
# ve is kurali denetimi ders icinde yazilir; disaridan kitaplik kullanilmaz.
TOHUM, M32 = 20260218, 0xFFFFFFFF


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):                      # KURGU belirtecleyici, parca en cok bes damga
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


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


KONU = ["fatura", "ariza", "sayac", "tarife", "kesinti"]
ONCELIK, AKSIYON = ["dusuk", "orta", "yuksek"], ["kayit", "yonlendirme", "bilgi"]
SEMA = {"talep_no": "sayi", "konu": KONU, "oncelik": ONCELIK, "aksiyon": AKSIYON}
KALIP = [("bu ayki fatura tutari gecen aya gore cok yuksek geldi", "fatura"),
         ("faturami odedim ama sistemde borc gorunuyor", "fatura"),
         ("fatura ayrintisini nereden gorebilirim", "fatura"),
         ("evde su akmiyor bir ariza var galiba", "ariza"),
         ("baglanti bozuk oldu ve hic calismiyor", "ariza"),
         ("ariza kaydi actim ama ekip gelmedi", "ariza"),
         ("sayac okumasi yanlis girilmis endeks tutmuyor", "sayac"),
         ("sayac degisimi icin randevu istiyorum", "sayac"),
         ("sayac uzerindeki endeks ile fatura ayni degil", "sayac"),
         ("hangi tarife basamagindayim ogrenmek istiyorum", "tarife"),
         ("tarife degisikligi icin ne yapmam gerekiyor", "tarife"),
         ("birim ucret abone tipine gore degisiyor mu", "tarife"),
         ("mahallede kesinti var ne zaman gelecek", "kesinti"),
         ("planli kesinti duyurusu nereden takip edilir", "kesinti"),
         ("aksamdan beri kesinti yasiyoruz", "kesinti")]
TALEP = []
for i in range(120):                    # 120 KURGU destek talebi
    r = uretec(TOHUM + i)
    k = KONU[ayrik(r(), [0.24, 0.22, 0.18, 0.20, 0.16])]
    TALEP.append({"no": 4001 + i, "konu": k,
                  "metin": [x for x in KALIP if x[1] == k][int(r() * 3)][0]})

IZ = {"fatur": "fatura", "tutar": "fatura", "ayrin": "fatura", "ariza": "ariza",
      "bozuk": "ariza", "calis": "ariza", "akmiy": "ariza", "sayac": "sayac",
      "endek": "sayac", "okuma": "sayac", "tarif": "tarife", "birim": "tarife",
      "abone": "tarife", "basam": "tarife", "kesin": "kesinti", "duyur": "kesinti",
      "mahal": "kesinti"}
TUZAK = {"degis": "tarife", "kayit": "ariza", "yukse": "tarife", "gorun": "fatura",
         "ekip": "kesinti", "takip": "tarife", "giril": "fatura"}   # yaniltici baglar
SAYAC = [0]


def ayristir(metin):
    """Anahtar=deger cifti ayristirici. Ayrilamayan yanit icin None doner."""
    if "=" not in metin:
        return None
    kayit = {}
    for parca in metin.split(";"):
        if "=" not in parca:
            return None
        a, _, d = parca.partition("=")
        kayit[a.strip()] = d.strip()
    return kayit


def dogrula(kayit):
    """Sema dogrulama: eksik anahtar, fazladan anahtar, gecersiz deger."""
    if kayit is None:
        return ["ayristirilamadi"]
    hata = [f"eksik:{a}" for a in SEMA if a not in kayit]
    hata += [f"fazla:{a}" for a in kayit if a not in SEMA]
    for a, kural in SEMA.items():
        if a not in kayit:
            continue
        d = kayit[a]
        if kural == "sayi" and not d.isdigit():
            hata.append(f"sayi_degil:{a}")
        elif kural != "sayi" and d not in kural:
            hata.append(f"gecersiz:{a}")
    return hata


def cekilis(istem, tohum, tuz):
    """Her karar icin ayri tuzlanmis tek cekilis; kararlar birbirine baglanmaz."""
    return uretec((tohum + tuz) ^ izno(istem))()


def cagir(istem, talep, tohum=TOHUM):
    """Onceki dersin bicim tarifi istemi; yanitin bir payi tarife uymaz."""
    SAYAC[0] += 1
    bel = belirtecle(istem)
    p = {k: 0.15 for k in KONU}
    for t in belirtecle(talep["metin"]):    # konu yalniz talep metninden okunur
        for tablo, w in ((IZ, 1.0), (TUZAK, 1.3)):
            if tablo.get(t) in p:
                p[tablo[t]] += w
    k = max(sorted(p), key=lambda a: p[a])
    o = ONCELIK[ayrik(cekilis(istem, tohum, 11), [0.31, 0.44, 0.25])]
    a = AKSIYON[ayrik(cekilis(istem, tohum, 29), [0.46, 0.32, 0.22])]
    duz = f"talep_no={talep['no']} ; konu={k} ; oncelik={o} ; aksiyon={a}"
    egilim = 0.62 if "bicim" in bel else 0.0            # istemdeki bicim tarifi
    if "hatal" in bel:                                  # hatayi isteme yazan deneme
        egilim += 0.14
    if cekilis(istem, tohum, 53) < egilim:
        return duz
    bozuk = ayrik(cekilis(istem, tohum, 71),            # tarife uymayan yanit
                  [0.22, 0.20, 0.18, 0.16, 0.24])
    if bozuk == 0:
        return f"talebiniz {k} konusunda kaydedildi ve {a} adimi baslatildi"
    if bozuk == 1:
        return f"talep_no={talep['no']} ; konu={k} ; aksiyon={a}"
    if bozuk == 2:
        return f"talep_no={talep['no']} ; konu={k} ; oncelik=acil ; aksiyon={a}"
    if bozuk == 3:
        return f"talep_no=TL{talep['no']} ; konu={k} ; oncelik={o} ; aksiyon={a}"
    return f"talep_no={talep['no'] + 500} ; konu={k} ; oncelik={o} ; aksiyon={a}"


TARIF = ("Yaniti su bicimde yaz: talep_no=<sayi> ; konu=<fatura|ariza|sayac|"
         "tarife|kesinti> ; oncelik=<dusuk|orta|yuksek> ; aksiyon=<kayit|"
         "yonlendirme|bilgi> . ")


def istemi(onek, x):
    return onek + f"Talep {x['no']} : {x['metin']}"


KAYITLI = {t["no"] for t in TALEP}


def is_kurali(kayit):
    """Semadan gecen kaydin kurum kurallari. Sema bunlarin hicbirini goremez."""
    hata = []
    if kayit.get("oncelik") == "yuksek" and kayit.get("aksiyon") == "bilgi":
        hata.append("yuksek_oncelik_bilgi_ile_kapanamaz")
    if kayit.get("konu") == "kesinti" and kayit.get("aksiyon") == "kayit":
        hata.append("kesinti_kayitla_kapanamaz")
    if kayit.get("talep_no", "").isdigit() and int(kayit["talep_no"]) not in KAYITLI:
        hata.append("kayitli_olmayan_talep_no")
    return hata


sem, isk, gorulen = 0, 0, {}
for x in TALEP:
    y = cagir(istemi(TARIF, x), x)
    kayit = ayristir(y)
    h = dogrula(kayit)
    if h:
        sem += 1
        continue
    k = is_kurali(kayit)
    isk += bool(k)
    if k:
        gorulen.setdefault(k[0], y)
print(f"KURGU talep {len(TALEP)}: semaya takilan {sem}, is kuraline takilan {isk}")
for e, y in sorted(gorulen.items()):
    print(f"  {e}\n    {y}")
```

```
KURGU talep 120: semaya takilan 24, is kuraline takilan 24
  kayitli_olmayan_talep_no
    talep_no=4505 ; konu=sayac ; oncelik=orta ; aksiyon=kayit
  kesinti_kayitla_kapanamaz
    talep_no=4015 ; konu=kesinti ; oncelik=dusuk ; aksiyon=kayit
  yuksek_oncelik_bilgi_ile_kapanamaz
    talep_no=4022 ; konu=tarife ; oncelik=yuksek ; aksiyon=bilgi
```

İki sayı birbirine eşit ve bu eşitlik dersin çıkış noktasıdır: **24 yanıt şemaya uymuyor, şemadan
geçen 96 yanıtın 24'ü iş kuralına takılıyor.** Yani biçim denetimi hatanın ancak yarısını
görüyor. Üç örneğin üçü de kusursuz biçimlidir; ayrıştırıcı ve doğrulayıcı hiçbirinde bir şey
bulmaz. Birincisinde talep numarası istemde yazılı olmayan bir sayıdır, ikincisinde kesinti
kaydı yanlış aksiyonla kapatılmıştır, üçüncüsünde yüksek öncelikli bir kayıt bilgilendirmeye
bağlanmıştır.

Bu üç kural şemanın diline çevrilemez, çünkü hiçbiri tek bir alanın değeriyle ilgili değildir.
İlk ikisi **alanlar arası** bir tutarlılıktır, üçüncüsü ise kaydın **dış dünyayla** tutarlılığıdır.
Belirsiz bir üreticinin çıktısında bu iki sınıf ayrı ayrı sayılmadan doğrulama ölçülmüş sayılmaz.

#### Yeniden Denemenin Kurtardığı

Altı hat aynı 120 talepte koşturulur. İlk üçünde yeniden deneme yoktur ve yalnız denetimin
neyi elediği ölçülür; son üçü reddedilen kaydı yeniden ister.

```python
HAT = [("dogrulama yok", False, False, 0, False),
       ("yalniz sema", True, False, 0, False),
       ("sema + is kurali", True, True, 0, False),
       ("+ 1 yeniden deneme", True, True, 1, False),
       ("+ 2 yeniden deneme", True, True, 2, False),
       ("+ 1 deneme, hata istemde", True, True, 1, True)]


def denetle(kayit, semali, kurali):
    h = dogrula(kayit) if semali else []
    if not h and kurali and kayit is not None:
        h = is_kurali(kayit)
    return h


def hat(semali, kurali, deneme, hatayi_yaz, tohum=TOHUM):
    SAYAC[0] = 0
    ilk_sema = ilk_kural = kurtarilan = kabul = hatali = ek = bel = 0
    for x in TALEP:
        istem = istemi(TARIF, x)
        y = cagir(istem, x, tohum)
        bel += len(belirtecle(istem)) + len(belirtecle(y))
        kayit = ayristir(y)
        ilk_sema += bool(dogrula(kayit))
        ilk_kural += not dogrula(kayit) and bool(is_kurali(kayit))
        h = denetle(kayit, semali, kurali)
        for d in range(deneme):
            if not h:
                break
            ek += 1
            i2 = istem + f" Onceki yanit hatali: {h[0]} ." if hatayi_yaz else istem
            y = cagir(i2, x, tohum + 1 + d)
            bel += len(belirtecle(i2)) + len(belirtecle(y))
            kayit = ayristir(y)
            h = denetle(kayit, semali, kurali)
            kurtarilan += not h
        kabul += not h
        hatali += (not h) and bool(dogrula(kayit) or is_kurali(kayit))
    return (ilk_sema, ilk_kural, kurtarilan, kabul / 120, hatali / 120, ek, bel)


print("hat                       sema  kural  kurtarilan  kabul   hatali  ek cagri  belirtec")
for ad, s, k, d, w in HAT:
    a = hat(s, k, d, w)
    print(f"{ad:<25} {a[0]:>4}  {a[1]:>5}  {a[2]:>10}  {a[3]:>6.4f}  {a[4]:>6.4f}"
          f"  {a[5]:>8}  {a[6]:>8}")
b = hat(True, True, 1, False, TOHUM + 1)
print(f"ikinci kosum (+ 1 yeniden deneme): kabul {b[3]:.4f}, kurtarilan {b[2]}, "
      f"ek cagri {b[5]}")
```

```
hat                       sema  kural  kurtarilan  kabul   hatali  ek cagri  belirtec
dogrulama yok               24     24           0  1.0000  0.4000         0      7403
yalniz sema                 24     24           0  0.8000  0.2000         0      7403
sema + is kurali            24     24           0  0.6000  0.0000         0      7403
+ 1 yeniden deneme          24     24          26  0.8167  0.0000        48     10350
+ 2 yeniden deneme          24     24          34  0.8833  0.0000        70     11716
+ 1 deneme, hata istemde    24     24          23  0.7917  0.0000        48     10864
ikinci kosum (+ 1 yeniden deneme): kabul 0.7500, kurtarilan 26, ek cagri 56
```

İlk üç satır tek bir çağrıyla üretilmiştir ve belirteç sütunu üçünde de aynıdır: **7403**.
Değişen tek şey kabulden önce yapılan denetimdir. Doğrulama yokken kabul oranı **1,0000** görünür
ve kayıt sistemine giren yanlış kayıt oranı **0,4000**'dır. Yani hiçbir şey ölçülmediğinde
sistem kusursuz görünür ve her beş kayıttan ikisi bozuktur. Şema eklendiğinde hatalı kayıt
**0,2000**'a, iş kuralı da eklendiğinde **0,0000**'a iniyor.

Bunun bedeli kabul oranıdır: **1,0000'dan 0,6000'a**. Doğrulama hiçbir kaydı düzeltmez, yalnız
görünür kılar. Üçüncü satırdaki sistem birincisinden daha iyidir ama daha az iş yapar; 48 talep
elde kalır. Doğrulamanın ölçüsü kabul oranı değil, **kabul edilenlerin ne kadarının doğru
olduğudur**.

#### Kurtarmanın Bedeli

Dördüncü satır yeniden denemeyi ekliyor. **26 kayıt kurtarılıyor** ve kabul oranı 0,6000'dan
**0,8167**'ye çıkıyor; hatalı kayıt oranı **0,0000**'da kalıyor, çünkü kurtarma denetimin
önüne değil arkasına konmuştur. Bedel **48 ek çağrı** ve **2947 belirteçtir**: kurtarılan kayıt
başına 1,85 çağrı ve 113,3 belirteç. Kazanç 0,2167 ve iki koşum farkı 0,0667 olduğu için bu
satır rahatça ölçülebilir.

Beşinci satır kursun kuralının en keskin uygulandığı yerdir. İkinci deneme sekiz kayıt daha
kurtarıyor ve kabul oranını **0,8833**'e çıkarıyor. Kazanç **0,0666**. Bir önceki hattın iki koşum
farkı ise **0,0667**: birinci koşumda 0,8167, ikinci koşumda 0,7500. Kazanç farktan **büyük
değil**, dolayısıyla **ölçülmemiş sayılır**. Bu satır için ödenen bedel ise kesindir: 22 ek çağrı
ve 1366 belirteç, kurtarılan kayıt başına 2,75 çağrı. Ölçülemeyen bir kazanç, ölçülebilir bir
bedelle satın alınmıştır.

Altıncı satır sezgiye en uygun düzeltmeyi sınıyor: reddedilen yanıtın hatasını isteme yazmak.
Sonuç 26 yerine **23 kurtarma** ve kabul oranında **0,7917**. Aradaki 0,0250, iki koşum farkı
0,0667'nin çok altında kaldığı için bu satırla dördüncü satır arasında **ölçülebilir bir fark
yoktur**. Bedel ise ölçülebilir: aynı 48 çağrıyla belirteç 10350'den **10864'e** çıkıyor, yani
**514 belirteç** eklenmiştir. Hataları isteme yazmak burada bir iyileştirme değil, ölçülmemiş
bir tahmindir.

Üç sayıyla toparlanır. Önceki istem biçim tarifi istemidir: kabul 0,6000, hatalı kayıt 0,0000,
7403 belirteç, 120 çağrı. Değiştirilmiş hat bir yeniden deneme ekler: kabul 0,8167, aynı hatalı
kayıt oranı, 10350 belirteç, 168 çağrı. Bedel **48 çağrı ve 2947 belirteçtir**; bu kursta ilk
kez bir düzenek **çağrı sayısını** oynatıyor ve bedelin belirteçten büyük olan kısmı orada
duruyor.

#### Özet

- Şema doğrulaması 24 yanıtı eliyor, iş kuralı denetimi şemadan geçen 96 yanıtın 24'ünü daha
  eliyor: biçim denetimi hatanın yarısını görüyor.
- Üç iş kuralının üçü de kusursuz biçimli kayıtlarda tetikleniyor; ikisi alanlar arası
  tutarlılık, biri kaydın dış dünyayla tutarlılığıdır.
- Doğrulama yokken kabul oranı 1,0000 ve sisteme giren hatalı kayıt 0,4000'dır; iki denetim
  hatalıyı 0,0000'a indirirken kabulü 0,6000'a düşürür. Doğrulama düzeltmez, görünür kılar.
- Bir yeniden deneme 26 kaydı kurtarır ve kabulü 0,8167'ye çıkarır; bedeli 48 ek çağrı ve 2947
  belirteçtir, kurtarılan kayıt başına 1,85 çağrı.
- İkinci denemenin kazancı 0,0666, hattın iki koşum farkı 0,0667'dir: kazanç ölçülmemiş sayılır
  ve karşılığında 22 çağrı ile 1366 belirteç ödenir.
- Hatayı isteme yazmak 26 yerine 23 kayıt kurtarır ve 514 belirteç ekler; iki hat arasında
  ölçülebilir bir fark yoktur.

#### Sonraki Adım

Bu derste kurtarma tek bir kaldıraçla yapıldı: aynı isteği yeniden sormak. Kurtarılamayan 14
kayıt ise hiç incelenmedi. Onların bir kısmı ne kadar denenirse denensin düzelmez, çünkü sorun
yanıtın çekilişinde değil, modelin **bilmediği bir şeyde**dir. Bir talebin hangi tarife
basamağına girdiği isteme yazılmamışsa, daha iyi bir yönerge bunu üretemez. Sonraki ders bu
ayrımı sayar: aynı yanlış yanıt bazen daha iyi bir yönergeyle, bazen yalnız eksik bilginin
sağlanmasıyla düzelir. Hangi hatanın hangisiyle düzeldiği ayrı ayrı sayılır ve ikisinin bedeli
karşılaştırılır.

### İstem ve Bağlam Mühendisliği Farkı

Source: https://academia.sh/tr/kurslar/istem-muhendisligi/istem-ve-baglam-muhendisligi-farki

Aynı hata kümesinin iki ayrı çözümle karşılaştırılması: 120 kurgu talepte taban konu isabeti 0,8833 ve arıza kodu isabeti 0,4083, ikisi birden 0,4083. İsteme ayırt edici kural yazmak konu isabetini 0,9667'ye çıkarıyor ve kod isabetine hiç dokunmuyor, kurgu kod tablosunu isteme koymak kod isabetini 0,9167'ye çıkarıyor ve konu isabetine hiç dokunmuyor. On dört konu hatasının onu yalnız yönergeyle, yetmiş bir kod hatasının altmış altısı yalnız bilgiyle düzeliyor ve her sınıfta bir hata ikisiyle de düzelmiyor. Bedel ayrışıyor: yönerge 1680, bilgi 14520 belirteç ekliyor.

Önceki ders reddedilen kayıtları yeniden sorarak kurtardı ve on dört kayıt hiçbir denemeyle
düzelmedi. Bu ders o kalıntının nedenini sorar. Bir yanlış yanıt iki ayrı sebeple yanlış olabilir
ve ikisi birbirine benzemez. Model **ne yapacağını** yanlış anlamış olabilir: yönerge belirsizdir,
yanıltıcı bir sözcük kararı çekmiştir. Ya da model **bilmediği bir şeyi** söylemek zorunda
bırakılmıştır: istenen bilgi istemde hiç yoktur ve hiçbir yönerge onu üretemez.

Birinci sınıf istem tasarımının konusudur. İkincisi **bağlam mühendisliğinin** konusudur: modele
ne söylendiği değil, yanına ne konduğu. Bu ders yalnız ayrımı kurar ve ölçer. Hangi belgenin
nereden bulunacağı, nasıl getirileceği ve kaç parçanın seçileceği bir erişim hattı sorusudur ve
Gömme Vektörleri ve Erişim Artırılmış Üretim kursuna bırakılır; burada kurgu tablo **olduğu gibi**
isteme konur.

- **CD33.** Kod bir **benzeticidir**; gerçek bir uç nokta çağrılmaz. Talepler, arıza kodları ve
  kod tablosu **kurgudur**, tohum **20260218**.
- **CD34. Görev iki alanlıdır:** talebe bir konu ve bir **arıza kodu** atamak. İki alan iki ayrı
  hata kaynağı taşır.
- **CD35. Konu hatasının kaynağı yanıltıcı bağlardır.** Talebin yan cümlesindeki bir sözcük
  kararı başka bir konuya çeker. Bu bir yönerge sorunudur.
- **CD36. Kod hatasının kaynağı bilgi eksikliğidir.** Kod tablosu istemde yoksa benzetici
  konunun **en yaygın kodunu** yazar; on beş koddan yalnız beşi böyle bulunabilir.
- **CD37. Yönerge çözümü** isteme bir ayırt edici kural yazar. Kural her zaman izlenmez;
  benzetici kuralı yanıtların bir payında uygular.
- **CD38. Bilgi çözümü** kurgu kod tablosunun tamamını isteme koyar. **Erişim yapılmaz**: hangi
  satırın gerektiği aranmaz, tablo bütünüyle verilir. Model tabloyu kendi tanım metinleriyle
  eşleştirir ve bir payında yanlış satırı okur.
- **CD39.** Bir hata, o alandaki değerin yanlış olmasıdır; hatalar **alan bazında** sayılır. Aynı
  kayıt iki hata birden taşıyabilir.
- **CD40.** Bedel giriş belirteci olarak yazılır ve ayrıca **düzelen hata başına belirteç** olarak
  verilir; iki koşum için ikinci tohum 20260219'dur.

#### İki Hatanın İki Ayrı Kaynağı

İki örnek talep dört düzenekte yan yana konur. Birincisi her iki hatayı birden taşır, ikincisi
yalnız kod hatasını.

```python
# BENZETICI -- KURGUDUR. Gercek bir model uc noktasi cagrilmaz. Kod tablosu da
# KURGU'dur ve erisim yapilmadan, oldugu gibi isteme konur.
TOHUM, M32 = 20260218, 0xFFFFFFFF


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):                      # KURGU belirtecleyici, parca en cok bes damga
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


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


KONU = ["fatura", "ariza", "sayac", "tarife", "kesinti"]
KALIP = [("bu ayki fatura tutari gecen aya gore cok yuksek geldi", "fatura"),
         ("faturami odedim ama sistemde borc gorunuyor", "fatura"),
         ("fatura ayrintisini nereden gorebilirim", "fatura"),
         ("evde su akmiyor bir ariza var galiba", "ariza"),
         ("baglanti bozuk oldu ve hic calismiyor", "ariza"),
         ("ariza kaydi actim ama ekip gelmedi", "ariza"),
         ("sayac okumasi yanlis girilmis endeks tutmuyor", "sayac"),
         ("sayac degisimi icin randevu istiyorum", "sayac"),
         ("sayac uzerindeki endeks ile fatura ayni degil", "sayac"),
         ("hangi tarife basamagindayim ogrenmek istiyorum", "tarife"),
         ("tarife degisikligi icin ne yapmam gerekiyor", "tarife"),
         ("birim ucret abone tipine gore degisiyor mu", "tarife"),
         ("mahallede kesinti var ne zaman gelecek", "kesinti"),
         ("planli kesinti duyurusu nereden takip edilir", "kesinti"),
         ("aksamdan beri kesinti yasiyoruz", "kesinti")]
TALEP = []
for i in range(120):                    # 120 KURGU destek talebi
    r = uretec(TOHUM + i)
    k = KONU[ayrik(r(), [0.24, 0.22, 0.18, 0.20, 0.16])]
    TALEP.append({"no": 4001 + i, "konu": k,
                  "metin": [x for x in KALIP if x[1] == k][int(r() * 3)][0]})

IZ = {"fatur": "fatura", "tutar": "fatura", "ayrin": "fatura", "ariza": "ariza",
      "bozuk": "ariza", "calis": "ariza", "akmiy": "ariza", "sayac": "sayac",
      "endek": "sayac", "okuma": "sayac", "tarif": "tarife", "birim": "tarife",
      "abone": "tarife", "basam": "tarife", "kesin": "kesinti", "duyur": "kesinti",
      "mahal": "kesinti"}
TUZAK = {"degis": "tarife", "kayit": "ariza", "yukse": "tarife", "gorun": "fatura",
         "ekip": "kesinti", "takip": "tarife", "giril": "fatura"}   # yaniltici baglar
KODLAR = [("FT-21", "fatura tutari yuksek geldi"),
          ("FT-34", "odenen fatura borc gorunuyor"),
          ("FT-47", "fatura ayrinti talebi"), ("AR-12", "evde su akmiyor sikayeti"),
          ("AR-25", "baglanti bozuk calismiyor"), ("AR-38", "acik kayit ekip gelmedi"),
          ("SY-16", "endeks yanlis girilmis"), ("SY-29", "sayac degisim randevusu"),
          ("SY-42", "endeks ile fatura uyusmuyor"), ("TR-13", "tarife basamagi sorusu"),
          ("TR-26", "tarife degisiklik talebi"), ("TR-39", "birim ucret abone tipi"),
          ("KS-15", "mahalle kesintisi suresi"), ("KS-28", "planli duyuru takibi"),
          ("KS-41", "aksamdan beri kesinti")]
KOD = {t: KODLAR[i][0] for i, (t, _) in enumerate(KALIP)}
KONU_KODU = {}
for i, (t, k) in enumerate(KALIP):
    KONU_KODU.setdefault(k, KODLAR[i][0])   # belgesiz durumda konunun ilk kodu
BELGE = " ; ".join(f"{k} {a}" for k, a in KODLAR)
SAYAC = [0]


def cekilis(istem, tohum, tuz):
    """Her karar icin ayri tuzlanmis tek cekilis; kararlar birbirine baglanmaz."""
    return uretec((tohum + tuz) ^ izno(istem))()


def cagir(istem, talep, tohum=TOHUM):
    """Konu ve ariza kodu birlikte istenir. Kod tablosu istemde yoksa model
    konunun en yaygin kodunu yazar; varsa tanimlarla ortusmeye bakarak secer."""
    SAYAC[0] += 1
    bel = belirtecle(istem)
    uyar = "ayirt" in bel and cekilis(istem, tohum, 91) < 0.78
    tuzak_agirligi = 0.9 if uyar else 1.3               # istemdeki ayirt edici kural
    p = {k: 0.15 for k in KONU}
    for t in belirtecle(talep["metin"]):
        for tablo, w in ((IZ, 1.0), (TUZAK, tuzak_agirligi)):
            if tablo.get(t) in p:
                p[tablo[t]] += w
    k = max(sorted(p), key=lambda a: p[a])
    if "tablo" not in bel:                              # kod tablosu istemde yok
        return k, KONU_KODU[k]
    tb = set(belirtecle(talep["metin"]))
    puan = [(len(tb & set(belirtecle(a))), -i) for i, (_, a) in enumerate(KODLAR)]
    i = -max(puan)[1]
    if cekilis(istem, tohum, 17) < 0.08:                # belgeyi yanlis okuma payi
        i = (i + 1) % len(KODLAR)
    return k, KODLAR[i][0]


AYIRT = "Ayirt edici kural: yan cumledeki sozcukler etiketi belirlemez . "
TABLO = "Ariza kodu tablosu: " + BELGE + " . "
print(f"KURGU kod tablosu {len(KODLAR)} satir, {len(belirtecle(BELGE))} belirtec")
print("ornek satirlar:", " | ".join(f"{k} {a}" for k, a in KODLAR[3:6]))
for j in (3, 0):
    x = TALEP[j]
    print(f"\ntalep {x['no']} : {x['metin']}")
    print(f"  gercek        konu {x['konu']:<8} kod {KOD[x['metin']]}")
    for ad, onek in (("taban", ""), ("yonerge", AYIRT), ("bilgi", TABLO),
                     ("ikisi", AYIRT + TABLO)):
        k, kod = cagir(onek + f"Talep {x['no']} : {x['metin']}", x)
        d = "dogru" if (k == x["konu"] and kod == KOD[x["metin"]]) else ""
        print(f"  {ad:<13} konu {k:<8} kod {kod}  {d}")
```

```
KURGU kod tablosu 15 satir, 116 belirtec
ornek satirlar: AR-12 evde su akmiyor sikayeti | AR-25 baglanti bozuk calismiyor | AR-38 acik kayit ekip gelmedi

talep 4004 : ariza kaydi actim ama ekip gelmedi
  gercek        konu ariza    kod AR-38
  taban         konu kesinti  kod KS-15  
  yonerge       konu ariza    kod AR-12  
  bilgi         konu kesinti  kod AR-38  
  ikisi         konu ariza    kod AR-38  dogru

talep 4001 : planli kesinti duyurusu nereden takip edilir
  gercek        konu kesinti  kod KS-28
  taban         konu kesinti  kod KS-15  
  yonerge       konu kesinti  kod KS-15  
  bilgi         konu kesinti  kod KS-28  dogru
  ikisi         konu kesinti  kod KS-28  dogru
```

Üstteki talep iki hatayı birden taşıyor. Konu `kesinti` çıkıyor, çünkü talebin son iki sözcüğü
yanıltıcı bir bağ tetikliyor; ayırt edici kural yazıldığında konu `ariza`ya dönüyor. Ama aynı
satırda kod hâlâ yanlış: `AR-12`, doğrusu `AR-38`. Yönerge konuyu düzeltti ve kodu düzeltemedi,
çünkü doğru kod istemde hiçbir yerde yazmıyordu. Tablo konduğunda kod `AR-38` oluyor, bu kez konu
yanlış kalıyor. Kayıt ancak **ikisi birlikte** doğru oluyor.

Alttaki talebin konusu baştan doğrudur ve yalnız kodu yanlıştır. Yönerge satırı tabanla birebir
aynıdır: konu `kesinti` kalıyor, kod `KS-15` kalıyor. İsteme on dört belirteçlik bir kural
eklendi ve çıktının hiçbir alanı değişmedi. Tablo ise kodu tek adımda `KS-28`'e getiriyor. Aynı
hata biçimi, iki ayrı çözüm — ve yanlış olanı seçmenin bedeli yalnız belirteçtir, kazancı hiç
yoktur.

İki örneğin birlikte söylediği şey şudur: bir yanlış yanıta bakarak hangi düzeneğin gerektiği
anlaşılmaz. Yanlışın kendisi iki durumda da aynı görünür. Ayrım ancak **iki düzenek de ayrı ayrı
denenip sayıldığında** ortaya çıkar.

#### Hangi Hata Hangisiyle Düzeliyor

Aynı 120 talep dört düzenekte koşturulur ve hatalar **alan bazında** sayılır.

```python
HAT = [("taban", ""), ("+ yonerge", AYIRT), ("+ bilgi", TABLO),
       ("+ ikisi", AYIRT + TABLO)]


def olc(onek, tohum=TOHUM):
    SAYAC[0] = 0
    d, g = [], 0
    for x in TALEP:
        istem = onek + f"Talep {x['no']} : {x['metin']}"
        k, kod = cagir(istem, x, tohum)
        d.append((k == x["konu"], kod == KOD[x["metin"]]))
        g += len(belirtecle(istem))
    return d, g


S = {ad: olc(onek) for ad, onek in HAT}
print("hat        konu isabeti  kod isabeti  ikisi birden  giris belirteci")
for ad, _ in HAT:
    d, g = S[ad]
    print(f"{ad:<10} {sum(a for a, b in d) / 120:>12.4f}  {sum(b for a, b in d) / 120:>11.4f}"
          f"  {sum(a and b for a, b in d) / 120:>12.4f}  {g:>15}")
print("\nhata sinifi   taban hata  yonergeyle  bilgiyle  ikisiyle  hicbiriyle")
for ad, j in (("konu hatasi", 0), ("kod hatasi", 1)):
    n = [i for i in range(120) if not S["taban"][0][i][j]]
    y = sum(S["+ yonerge"][0][i][j] for i in n)
    b = sum(S["+ bilgi"][0][i][j] for i in n)
    ik = sum(S["+ ikisi"][0][i][j] for i in n)
    h = sum(not (S["+ yonerge"][0][i][j] or S["+ bilgi"][0][i][j]
                 or S["+ ikisi"][0][i][j]) for i in n)
    print(f"{ad:<13} {len(n):>10}  {y:>10}  {b:>8}  {ik:>8}  {h:>10}")
b1 = olc(AYIRT + TABLO, TOHUM + 1)[0]
print(f"\nikinci kosum (+ ikisi): konu {sum(a for a, _ in b1) / 120:.4f}, "
      f"kod {sum(b for _, b in b1) / 120:.4f}, ikisi birden "
      f"{sum(a and b for a, b in b1) / 120:.4f}")
```

```
hat        konu isabeti  kod isabeti  ikisi birden  giris belirteci
taban            0.8833       0.4083        0.4083             1534
+ yonerge        0.9667       0.4083        0.4083             3214
+ bilgi          0.8833       0.9167        0.8000            16054
+ ikisi          0.9583       0.9000        0.8667            17734

hata sinifi   taban hata  yonergeyle  bilgiyle  ikisiyle  hicbiriyle
konu hatasi           14          10         0         9           1
kod hatasi            71           0        66        63           1

ikinci kosum (+ ikisi): konu 0.9667, kod 0.8917, ikisi birden 0.8583
```

İlk tablonun ikinci ve üçüncü satırı ayrımı çıplak biçimde gösteriyor. Yönerge konu isabetini
**0,8833'ten 0,9667'ye** çıkarıyor ve kod isabetini **0,4083'te** olduğu gibi bırakıyor. Bilgi
kod isabetini **0,4083'ten 0,9167'ye** çıkarıyor ve konu isabetini **0,8833'te** olduğu gibi
bırakıyor. İki düzenek aynı görevde çalışıyor ama **hiç aynı hataya dokunmuyor**.

İkinci tablo bunu hata başına sayıyor. On dört konu hatasının **onu** yönergeyle düzeliyor,
**sıfırı** bilgiyle. Yetmiş bir kod hatasının **altmış altısı** bilgiyle düzeliyor, **sıfırı**
yönergeyle. İki sütunun biri diğerinin sıfırıdır; bu, iki çözümün birbirinin yerine
geçemeyeceğinin sayısal karşılığıdır. Bir sistemi iyileştirmenin ilk adımı, hangi hatanın hangi
sınıfta olduğunu saymaktır — çünkü yanlış sınıfa harcanan her belirteç boşa gider.

Her sınıfta **bir hata** hiçbir düzenekle düzelmiyor. Konu tarafında bu, ayırt edici kuralın
izlenmediği bir çağrıdır; kod tarafında tablonun yanlış satırının okunduğu bir çağrıdır. İkisi de
istem tasarımının değil, üreticinin belirsizliğinin kalıntısıdır ve daha fazla metin yazarak
kapanmaz.

#### İki Çözümün Bedeli

Bedel sütunu iki çözümü keskin biçimde ayırıyor. Yönerge giriş belirtecini **1534'ten 3214'e**
çıkarıyor: talep başına on dört, toplamda **1680 belirteç**. Bilgi ise **16054**'e çıkarıyor:
talep başına yüz yirmi bir, toplamda **14520 belirteç** ve tabanın **10,5 katı**. Bir kod
tablosunun tamamını her isteğe koymanın bedeli budur.

Düzelen hata başına okunduğunda tablo yumuşuyor ama tersine dönmüyor: yönerge on hatayı 1680
belirteçle düzeltiyor, hata başına **168 belirteç**; bilgi altmış altı hatayı 14520 belirteçle
düzeltiyor, hata başına **220 belirteç**. Bilgi daha pahalıdır ama **karşılığında ölçülemeyecek
kadar çok hata düzeltir**: taban 71 kod hatası taşıyordu ve yönergeye ne kadar metin eklenirse
eklensin bunların hiçbiri düzelmezdi.

Son satır iki düzeneğin birlikte çalışmasının bedelini de gösteriyor. İkisi birden doğru olan
kayıt oranı **0,4083'ten 0,8667**'ye çıkıyor; ikinci koşumda aynı sayı **0,8583**, yani iki koşum
farkı **0,0084**. Kazanç bu farkın elli katından büyük olduğu için rahatça ölçülebilir. Buna
karşın birleşik hat, tek tek hatlardan **her alanda biraz daha kötüdür**: konu 0,9667 yerine
0,9583, kod 0,9167 yerine 0,9000. İstem uzadıkça hem kuralın izlendiği hem tablonun doğru
okunduğu çağrıların payı azalıyor. **Ölçülmeden değiştirilen istem bir iyileştirme değil bir
tahmindir** ve iki iyileştirmenin toplamı ikisinin toplamı değildir.

#### Özet

- Bir yanlış yanıt ya modelin **ne yapacağını** yanlış anlamasından ya da **bilmediği bir şeyi**
  söylemek zorunda kalmasından gelir; ikisi ayrı düzeneklerle düzelir.
- Yönerge konu isabetini 0,8833'ten 0,9667'ye çıkarır ve kod isabetine hiç dokunmaz; bilgi kod
  isabetini 0,4083'ten 0,9167'ye çıkarır ve konu isabetine hiç dokunmaz.
- On dört konu hatasının onu yalnız yönergeyle, yetmiş bir kod hatasının altmış altısı yalnız
  bilgiyle düzelir; her iki sütunun karşılıklı değeri sıfırdır.
- Her sınıfta bir hata hiçbir düzenekle düzelmez: bunlar üreticinin belirsizliğinin kalıntısıdır.
- Yönerge 1680, bilgi 14520 belirteç ekler; düzelen hata başına 168 ve 220 belirteç. Bilgi
  pahalıdır ama yönergenin hiç ulaşamadığı hataları düzeltir.
- İkisi birden doğru kayıt oranı 0,4083'ten 0,8667'ye çıkar, ama birleşik hat her alanda tek tek
  hatlardan biraz daha kötüdür.

#### Sonraki Adım

Bu derste hatalar iki kaynağa ayrıldı ve her ikisi de tek tek kayıtlarda ölçüldü. Sorulmayan
şey, hataların **kimin üzerinde toplandığıdır**. Bir sistem 0,8667 oranında doğru olabilir ve
kalan yanlışların tamamı belirli bir abone kümesinde toplanabilir; bu durumda ortalama iyidir ve
o küme için sistem çalışmıyordur. Sonraki ders bunu ölçer: alt grup açıklığı istemle ne kadar
daraltılabiliyor, hangi kısmı kalıyor ve istemin **veri yanlılığını** niçin çözmediği sayıyla
gösterilir.

### Yanlılık Azaltıcı İstemler

Source: https://academia.sh/tr/kurslar/istem-muhendisligi/yanlilik-azaltici-istemler

İstemle dengelemenin alt grup açıklığını ne kadar kapattığının ve neyi kapatmadığının ölçülmesi: 200 kurgu talepte merkez isabeti 0,9016, kırsal isabeti 0,5513 ve açıklık 0,3504. İsteme yazılan yanlılık azaltıcı bildirim açıklığı 0,3586'ya taşıyor ve 3800 belirteç ekliyor; dengeli örnek açıklığı 0,2888'e indiriyor ve 14400 belirteç ekliyor. Örneklenen yerel yazımın isabeti 0,4848'den 0,8788'e çıkıyor, örneklenmeyen yerel yazım 0,3023'te sabit kalıyor. İstem açıklığın yalnız 0,1758 payını kapatıyor. Kurs kapanışı yirmi iki dersin önceki istem, değiştirilmiş istem ve bedel satırlarını tek tabloda topluyor.

Önceki ders hataları iki kaynağa ayırdı. Sorulmayan şey hataların **kimin üzerinde
toplandığıydı**: genel isabet kabul edilebilir olabilir ve kalan yanlışların tamamı belirli bir
abone kümesinde birikebilir; o küme için sistem çalışmıyordur ve ortalama bunu gizler.

Alt grup, açıklık ve adalet ölçütleri M27'nin makine öğrenmesi etiği kursunda kuruldu ve
tekrarlanmaz. Bu dersin sorusu dardır: **istem yazarak bir alt grup açıklığı ne kadar
kapatılabilir ve hangi kısmı kalır.**

- **CD41.** Kod bir **benzeticidir**; gerçek bir uç nokta çağrılmaz. Abone grupları, talep
  yazımları ve işaret tablosu **kurgudur**, tohum **20260218**.
- **CD42.** İki kurgu abone grubu vardır, **merkez** ve **kırsal**; grup adı karara hiç girmez,
  yalnız ölçüm için kullanılır. Her konunun bir **standart** ve iki **yerel** yazımı vardır ve
  merkez çoğunlukla standart, kırsal çoğunlukla yerel yazar.
- **CD43. Yanlılığın kaynağı veridedir:** işaret tablosu yalnız **standart yazımdan** kurulmuştur
  ve işaret bulunamayan talepte karar **en sık görülen sınıfa** düşer.
- **CD44. Birinci dengeleyici** isteme yazılan bir bildirimdir (yazım biçimi kararı etkilemez) ve
  benzeticide düşmeyi eşit bir çekilişe çevirir. **İkinci dengeleyici** dengeli örnektir: her
  konunun **yerel A** yazımı etiketiyle isteme konur ve benzetici örneklerden geçici bir işaret
  tablosu çıkarır. **Yerel B örneklenmez.**
- **CD45.** Ölçüt grup başına konu isabeti ve **açıklıktır** (merkez eksi kırsal, küçük iyi).
  Bedel giriş belirteci olarak yazılır; ikinci koşum tohum 20260219'dur.

#### Açıklığın Kaynağı

Açıklık modelin gruplar hakkında bir şey bilmesinden gelmiyor; grup adı isteme hiç yazılmıyor.
Kaynağı **işaret tablosunun hangi metinlerden kurulduğudur**.

```python
# BENZETICI -- KURGUDUR. Gercek bir model uc noktasi cagrilmaz. Abone gruplari,
# talep yazimlari ve isaret tablosu KURGU'dur.
TOHUM, M32 = 20260218, 0xFFFFFFFF


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):                      # KURGU belirtecleyici, parca en cok bes damga
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


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


# her konunun bir standart, iki yerel yazimi var; yerel yazimlar KURGU'dur
YAZIM = {
    "fatura": ["bu ayki fatura tutari gecen aya gore cok yuksek geldi",
               "bu ayki hesap pusulasi baya kabarik cikmis",
               "gecen ayki odemeye gore rakam iki misli olmus"],
    "ariza": ["evde su akmiyor bir ariza var galiba",
              "muslugu actim damla bile gelmiyor",
              "avludaki boru patlamis her yer golet"],
    "sayac": ["sayac okumasi yanlis girilmis endeks tutmuyor",
              "saatin rakamlari bizimkiyle uyusmuyor",
              "kutunun icindeki numara yerinde saymis"],
    "tarife": ["hangi tarife basamagindayim ogrenmek istiyorum",
               "bizden hangi ucretlendirmeyle para aliniyor",
               "kademeli hesaplama nasil yapiliyor anlamadim"],
    "kesinti": ["mahallede kesinti var ne zaman gelecek",
                "iki gundur su yok kimse haber vermedi",
                "koyun ustunde bir gundur akmiyor diyorlar"],
}
KONU = list(YAZIM)
# merkez aboneler cogunlukla standart, kirsal aboneler cogunlukla yerel yaziyor
YAZIM_PAYI = {"merkez": [0.86, 0.08, 0.06], "kirsal": [0.24, 0.40, 0.36]}
TALEP = []
for i in range(200):
    r = uretec(TOHUM + i)
    g = "merkez" if r() < 0.62 else "kirsal"
    k = KONU[ayrik(r(), [0.24, 0.22, 0.18, 0.20, 0.16])]
    j = ayrik(r(), YAZIM_PAYI[g])
    TALEP.append({"no": 4001 + i, "konu": k, "grup": g, "yazim": j,
                  "metin": YAZIM[k][j]})

# benzeticinin isaret tablosu YALNIZ standart yazimdan kuruldu: veri yanliligi budur
IZ = {}
for k in KONU:
    for t in belirtecle(YAZIM[k][0]):
        IZ.setdefault(t, k)
ONCELIK = "fatura"                      # kanit yoksa en sik gorulen sinifa duser
SAYAC = [0]


def ornek_tablosu(bel):
    """Istemdeki 'ornek: <metin> -> <konu>' parcalarindan gecici isaret tablosu."""
    tablo, agiz = {}, []
    for i, t in enumerate(bel):
        if t == "->" and i + 1 < len(bel) and bel[i + 1] in KONU:
            for s in agiz:
                tablo.setdefault(s, bel[i + 1])
            agiz = []
        elif t == "ornek":
            agiz = []
        else:
            agiz.append(t)
    return tablo


def cagir(istem, talep, tohum=TOHUM):
    """Konu atamasi. Kanit yoksa model en sik sinifa duser; istemdeki yanlilik
    azaltici bildirim bu dusmeyi esit bir cekilise cevirir."""
    SAYAC[0] += 1
    bel = belirtecle(istem)
    tablo = dict(IZ)
    tablo.update(ornek_tablosu(bel))            # istemdeki ornekler tabloyu genisletir
    p = {k: 0.0 for k in KONU}
    for t in belirtecle(talep["metin"]):
        if tablo.get(t) in p:
            p[tablo[t]] += 1.0
    if max(p.values()) == 0.0:                  # hicbir isaret yok
        if "esit" in bel:                       # yanlilik azaltici bildirim
            return KONU[ayrik(uretec((tohum + 5) ^ izno(istem))(), [0.2] * 5)]
        return ONCELIK
    return max(sorted(p), key=lambda a: p[a])


BILDIRIM = ("Talebin yazim bicimi karari etkilemez ; her yazim esit olcutle "
            "degerlendirilir . ")
ORNEK = " ".join(f"ornek: {YAZIM[k][1]} -> {k} ." for k in KONU) + " "
print(f"KURGU talep {len(TALEP)}: merkez {sum(x['grup'] == 'merkez' for x in TALEP)}, "
      f"kirsal {sum(x['grup'] == 'kirsal' for x in TALEP)}")
y = {g: sum(x["grup"] == g and x["yazim"] > 0 for x in TALEP)
     for g in ("merkez", "kirsal")}
print(f"yerel yazimli talep: merkez {y['merkez']}, kirsal {y['kirsal']}")
print(f"isaret tablosu {len(IZ)} girdi, tamami standart yazimdan")
for j, ad in enumerate(("standart", "yerel A", "yerel B")):
    x = next(t for t in TALEP if t["konu"] == "sayac" and t["yazim"] == j)
    print(f"  {ad:<9} {x['metin'][:42]:<43} -> {cagir('Talep: ' + x['metin'], x)}")
```

```
KURGU talep 200: merkez 122, kirsal 78
yerel yazimli talep: merkez 18, kirsal 58
isaret tablosu 49 girdi, tamami standart yazimdan
  standart  sayac okumasi yanlis girilmis endeks tutmu  -> sayac
  yerel A   saatin rakamlari bizimkiyle uyusmuyor       -> fatura
  yerel B   kutunun icindeki numara yerinde saymis      -> fatura
```

Aynı konunun üç yazımı üç ayrı sonuç veriyor. Standart yazım doğru okunuyor; iki yerel yazımın
ikisi de `fatura` çıkıyor, çünkü tabloda hiçbir işaret bulunamıyor ve karar en sık görülen sınıfa
düşüyor. Kırsal taleplerin 58'i yerel, merkez taleplerin yalnız 18'i; hata bu yüzden kırsal
abonelerin üzerinde birikiyor. Model onları **ayırt etmiyor** — yalnız kendi tablosunda karşılığı
olmayan metni tanıyamıyor ve o metni kimin yazdığı veriden gelen bir olgudur.

#### İstemin Kapattığı ve Kapatmadığı

```python
HAT = [("taban", ""), ("+ bildirim", BILDIRIM), ("+ dengeli ornek", ORNEK),
       ("+ ikisi", BILDIRIM + ORNEK)]


def olc(onek, tohum=TOHUM):
    SAYAC[0] = 0
    d = {"merkez": [0, 0], "kirsal": [0, 0]}
    y = [[0, 0], [0, 0], [0, 0]]
    g = 0
    for x in TALEP:
        istem = onek + f"Talep {x['no']} : {x['metin']}"
        k = cagir(istem, x, tohum)
        d[x["grup"]][0] += k == x["konu"]
        d[x["grup"]][1] += 1
        y[x["yazim"]][0] += k == x["konu"]
        y[x["yazim"]][1] += 1
        g += len(belirtecle(istem))
    m, ki = d["merkez"][0] / d["merkez"][1], d["kirsal"][0] / d["kirsal"][1]
    return m, ki, m - ki, [a / b for a, b in y], g


print("hat              merkez  kirsal  aciklik  aciklik B  yerelA  yerelB  giris")
for ad, onek in HAT:
    m, ki, a, y, g = olc(onek)
    ab = olc(onek, TOHUM + 1)[2]
    print(f"{ad:<15} {m:>7.4f} {ki:>7.4f} {a:>8.4f} {ab:>10.4f} {y[1]:>7.4f} "
          f"{y[2]:>7.4f} {g:>6}")
t, e = olc("")[2], olc(BILDIRIM + ORNEK)[2]
print(f"\ntaban acikligi {t:.4f}, istemle kapanan {t - e:.4f} "
      f"({(t - e) / t:.4f} payi), kalan {e:.4f}")
```

```
hat              merkez  kirsal  aciklik  aciklik B  yerelA  yerelB  giris
taban            0.9016  0.5513   0.3504     0.3504  0.4848  0.3023   2624
+ bildirim       0.9098  0.5513   0.3586     0.3457  0.4848  0.3256   6424
+ dengeli ornek  0.9426  0.6538   0.2888     0.2888  0.8788  0.3023  17024
+ ikisi          0.9426  0.6538   0.2888     0.2760  0.8788  0.3023  20824

taban acikligi 0.3504, istemle kapanan 0.0616 (0.1758 payi), kalan 0.2888
```

İkinci satır sezgiye en uygun ve tabloda en boş duran satırdır. İsteme "her yazım eşit ölçütle
değerlendirilir" yazmak kırsal isabeti **0,5513'te** bırakıyor ve açıklığı **0,3586**'ya
**çıkarıyor**; satırın iki koşum farkı 0,0129 olduğu için bu 0,0082'lik kötüleşme bile ölçülmemiş
sayılır. Ölçülen tek şey bedeldir: giriş belirteci **2624'ten 6424'e**. Bir niyet beyanının
modele hiçbir işaret eklemediği yer burasıdır.

Üçüncü satır gerçek bir kazanç taşıyor: dengeli örnek açıklığı **0,2888**'e indiriyor, kazanç
**0,0616** ve iki koşum farkı **0,0000**. Bedeli **14400 belirteçtir**, tabanın 6,5 katı.
Örneklerin merkez isabetini de yükseltmesi (0,9016'dan 0,9426'ya) açıklığın kırsal kazancından
daha az kapanmasının sebebidir.

Son iki sütun kalanı açıklıyor. Örneklenen **yerel A** yazımının isabeti **0,4848'den 0,8788'e**
çıkıyor; örneklenmeyen **yerel B** yazımı **0,3023'te** kımıldamıyor. **İstem veri yanlılığını
çözmez.** Taban açıklığının yalnız **0,1758 payı** kapandı; kalanı kapatmanın yolu daha iyi bir
cümle yazmak değil, işaret tablosunun yerel yazımlardan da kurulmasıdır.

#### Özet

- Alt grup açıklığı modelin grubu tanımasından değil, işaret tablosunun **hangi metinlerden
  kurulduğundan** gelir; tabanda merkez 0,9016, kırsal 0,5513, açıklık 0,3504'tür.
- Yanlılık azaltıcı bildirim açıklığı 0,3586'ya taşır ve 3800 belirteç ekler; iki koşum farkı
  0,0129 olduğu için bu değişim ölçülmemiş sayılır.
- Dengeli örnek açıklığı 0,2888'e indirir ve 14400 belirteç ekler; kazanç 0,0616 ölçülmüştür ama
  örnekler merkez isabetini de yükselttiği için açıklık kırsal kazancından az kapanır.
- Örneklenen yerel yazımın isabeti 0,4848'den 0,8788'e çıkar, örneklenmeyen yazım 0,3023'te sabit
  kalır: istem açıklığın 0,1758 payını kapatır, kalan 0,2888 veri yanlılığıdır.

#### Kurs Kapanışı

Yirmi iki dersin hesabı tek tabloda ve her sayı kendi dersinden okundu. Satırlar ortak birim
taşımaz; ikinci ve üçüncü sütun her satırın **hangi ölçütle** okunduğunu yazar. **Fark tek işaret
düzeniyle verilir: değiştirilmiş istemin sayısı eksi önceki istemin sayısı**, üçüncü sütunda
parantez içinde.

| Ders | Önceki istem | Değiştirilmiş istem | Bedel |
|---|---|---|---|
| Tasarım 01 istem nedir | bağlamsız istem 0,7083 | tam istem 0,7833 (+0,0750) | +1797 belirteç; iki koşum farkı 0,2000 → 0,0583 |
| Tasarım 02 sistem yönergesi | yönergesiz istem 0,4583 | orta yönerge 0,7500 (+0,2917) | +2871 belirteç; uzun yönerge +3487 belirteçle (−0,0083) |
| Tasarım 03 rol belirtme | taban istem 0,7500 | rol öneki 0,6833 (−0,0667) | +1080 ile +3240 belirteç; tohum bandı 0,1500, dört önek de ölçülemez |
| Tasarım 04 açık talep | belirsiz talep, 4,81 ayrı yanıt | kapalı küme 3,89 (−0,92) | istek başına +15 belirteç; etiketsiz pay 0,4333 → 0,2889 |
| Tasarım 05 biçim denetimi | serbest yanıt, ayrıştırılabilir 0,0000 | biçim bildirimi 0,9750 (+0,9750) | giriş 6140 → 8780, çıkış 1392 → 2026 |
| Tasarım 06 örnek kullanımı | sıfır örnek 0,8571 | üç örnek 0,9643 (+0,1071) | +4928 belirteç, istek başına +44 |
| Tasarım 07 yasak bildirimi | bildirimsiz istem, ihlal 0,2583 | olumlu bildirim 0,0167 (−0,2416) | +3360 belirteç, önlenen ihlal başına 115,9; yasak bildirimi ihlali 0,5333 yapar |
| Tasarım 08 istem yinelemesi | başlangıç istemi, sınama 0,3778 | beşinci yineleme 0,9333 (+0,5555) | 2640 çağrı; sekizincide 0,8111'e iner |
| Akıl 01 düşünce zinciri | doğrudan yanıt, hesapta 0,3000 | ara adım istemi 0,8833 (+0,5833) | belirteç 1,82 kat; birim bedel 243,2 → 150,1 |
| Akıl 02 öz tutarlılık | tek örnek 0,7667 | dokuz örnek 0,8833 (+0,1167) | çağrı 60 → 540, belirteç 7954 → 71211, doğru yanıt başına 172,9 → 1343,6 |
| Akıl 03 düşünce ağacı | tek istemde çözüm 0,4792 | dal 3 ağaç 0,6250 (+0,1458) | çağrı 48 → 795, belirteç 43182; dal 4 (−0,0208) |
| Akıl 04 geri adım istemi | tek aşamalı istem 0,5417 | iki aşamalı istem 0,7500 (+0,2083) | çağrı 48 → 96, belirteç 1,66 kat, doğru kod başına 198 → 237 |
| Akıl 05 akıl yürüt ve davran | eylem alanı istemi, geçerli alan 0,1000 | düşüncesi kısaltılmış istem 0,8000 (+0,7000) | giriş 5300 → 8060; geçerli alan başına 645,8 → 102,1 belirteç |
| Akıl 06 akıl yürüten model | tek geçişli sınıf, iki alanlı görev | akıl yürüten sınıf (+0,1000 ve +0,1667) | belirteç 1,51 kat, doğru yanıt başına 83,9 → 110,1 |
| Akıl 07 istem topluluğu | en iyi tek istem 0,7833 | üç istemin çoğunluk oyu 0,8000 (+0,0167) | çağrı 120 → 360, doğru etiket başına 61,1 → 180,7 belirteç |
| Akıl 08 otomatik eniyileme | tek aday, sınama 0,6750 | on adaydan seçilen 0,6500 (−0,0250) | çağrı 40 → 400; doğrulamada +0,1250, iyimserlik payı 0,2500 |
| Çıktı 01 örnekleme ayarları | taban ayar 0,6417 | üçü birlikte daraltılmış 0,8667 (+0,2250) | giriş 5300 sabit, çıkış 191 → 204, çağrı 120 → 120; koşum farkı 0,5667 → 0,0083 |
| Çıktı 02 ceza ve durdurma | yalın istem, yineleme 0,3431 | ceza ve durdurma dizisi 0,0578 (−0,2853) | çıkış 4073 → 2653, giriş sabit; kullanılabilirlik 0,8833 → 0,8333 |
| Çıktı 03 yapılandırılmış çıktı | biçim tarifi, uyum 0,8000 | şema dayatması 1,0000 (+0,2000) | giriş 5614 → 2974 (−2640 belirteç), çıkış 1789 → 1810 |
| Çıktı 04 çıktı doğrulama | şema ve iş kuralı, kabul 0,6000 | bir yeniden deneme 0,8167 (+0,2167) | +48 çağrı, +2947 belirteç, kurtarma başına 1,85 çağrı |
| Çıktı 05 istem ve bağlam ayrımı | yalın istem, ikisi doğru 0,4083 | kural ve kod tablosu 0,8667 (+0,4584) | giriş 1534 → 17734; yönerge 1680 belirteçle 10, bilgi 14520 ile 66 hata düzeltir |
| Çıktı 06 yanlılık azaltıcı istem | yalın istem, açıklık 0,3504 | bildirim ve dengeli örnek 0,2888 (−0,0616) | giriş 2624 → 20824; örneklenmeyen yazım 0,3023'te sabit |

**Kursun kuralı budur: istem bir tasarım nesnesidir; ölçülmeden değiştirilen istem bir iyileştirme
değil bir tahmindir.** Hiçbir satırda model değişmedi: aynı benzetici, aynı tohum, aynı kurgu
talep kümesi. Değişen tek şey metindi ve dördüncü sütun o metnin her değişiminin bir bedeli
olduğunu yirmi iki kez yazıyor.

Kursun ikinci iddiası da aynı tablodan adıyla okunur: **akıl yürütme teknikleri pahalıdır ve her
görevde kazandırmaz.** Akıl 01'de düşünce zinciri sınıflandırmada belirteci 1,81 kat artırıp farkı
bandın içinde bıraktı; Akıl 04'te geri adım istemi derece görevinde 2,69 kata çıkarıp isabeti
oynatmadı; Akıl 06'da akıl yürüten sınıf tek alanlı görevde 1,75 kat artırıp farkı 0,1167 bandının
içinde bıraktı; Akıl 07'de istem topluluğu çağrıyı üç katına çıkarıp +0,0167 kazandı; Akıl 08'de
arama bütçesi on kata çıktı ve sınama 0,0250 düştü. Aynı okuma akıl yürütme dışında da geçerlidir:
Tasarım 02'de uzun yönerge 3487 belirteç ekleyip 0,0083 götürdü, Tasarım 06'da üçüncüden
sekizinci örneğe 8736 belirteç 0,0089 kazandırdı, Çıktı 03'te örnekli tarif 2040 belirteçle iki
koşum farkına eşit bir fark üretti, Çıktı 04'te ikinci deneme 1366 belirteçle o farkın altında.

Üçüncü sayı tek başına verilir: **yirmi iki dersin üçünde**, tabloya yazılan fark aynı dersin iki
koşum farkının altında kaldı — **Tasarım 03** (rol belirtme), **Akıl 07** (istem topluluğu) ve
**Akıl 08** (otomatik istem eniyileme). Üçünde de bedel sütunu doludur ve kazanç sütunu boştur.

Yirmi iki derste istem bir tasarım nesnesine dönüştü ve her değişikliğin bedeli yazıldı. Ama bir
varsayım hiç sorgulanmadı: her çağrının **tek başına, hemen ve hatasız** gerçekleştiği. Çağrı
sayısı bir maliyet kalemi olarak sayıldı; o çağrıların bir ağ üzerinden gittiği, sıraya girdiği,
yarıda kesildiği, hız sınırına takıldığı ve **para yerine belirteç harcadığı** bir uygulamada bu
istemlerin ne olacağı sorulmadı. Üç yüz altmış çağrılık bir istem topluluğu ve iki bin altı yüz
kırk çağrılık bir istem araması, tek bir makinede sırayla koşan bir döngüde ölçüldü. Sonraki kurs,
Model API'leri ile Uygulama Geliştirme, bu varsayımı açar.

