---
title: 'Biçim ve Uzunluk Denetimi'
source: 'https://academia.sh/tr/kurslar/istem-muhendisligi/bicim-ve-uzunluk-denetimi'
course: 'İstem Mühendisliği'
language: tr
updated: '2026-08-17T18:06:39+00:00'
license: 'CC BY-SA 4.0'
---

# Biçim 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 üçte biri 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 on altı 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.
