---
title: 'Durdurma Ölçütleri'
source: 'https://academia.sh/tr/kurslar/yapay-zeka-ajanlari/durdurma-olcutleri'
course: 'Yapay Zekâ Ajanları'
language: tr
updated: '2026-08-17T18:06:31+00:00'
license: 'CC BY-SA 4.0'
---

# Durdurma Ölçütleri

Döngünün nerede duracağının kursun kuralı olarak yazılması ve adım bütçesinin iki, dört, altı, sekiz ve on iki değerlerinde süpürülmesi: 24 kurgu görevde başarım 0,3750'den 1,0000'e çıkıyor, sonra 0,9583'te düzleşiyor; ikinci koşumda 0,4167, 0,8333, 0,9583, 0,9583, 0,9583. Altıncı adımdan sekizinciye düşüş 0,0417'dir ve altıncı adımdaki iki koşum farkı da 0,0417'dir, yani düşüş ölçüm bandının içindedir ve bir bulgu olarak ilan edilemez; mekanizması tek bir görevin izinde gösterilir ve etkisi ölçülmemiş sayılır. Bütçe altıdan on ikiye çıkarıldığında başarım değişmezken belirteç 10884'ten 12214'e çıkıyor. Bütçeyle durmak bir durdurma ölçütü değil emniyet sınırıdır: altıncı adımda üç görev bütçe tükendiği için duruyor.

Önceki üç dersin hepsi aynı sayıyı sabit tuttu: adım bütçesi sekizdi. Bu bir karardı, gerekçesi
yazılmadı ve sonuçların hepsi o karara asılı. Bölünmüş düzende G05 planı tükendikten sonra düzelmek
için üç adıma daha ihtiyaç duydu; bütçe altı olsaydı yanlış yanıt verecekti. Tersi de doğrudur: işi
biten bir ajan durmayı beceremezse elindeki doğru sonucu bozabilir.

Bu ders o kararı ölçer. Adım bütçesi beş değerde süpürülür ve her değerde başarımın yanına bedeli
yazılır. Ders aynı zamanda kursun kuralını kurar: **bir ajanın sayısı tek bir yanıtın değil bütün
döngünün sayısıdır ve durma koşulu yazılmayan ajan ölçülmemiş sayılır.** Taban çizgisi en dar
bütçedir — iki adımlık döngü.

- **AM31.** Ortam, araç kümesi, görev kümesi ve döngü önceki derslerdeki tanımın aynısıdır ve
  **kurgudur**. Tohum **20260218**, ikinci koşum **20260219**.
- **AM32. Durdurma ölçütü döngünün parçasıdır**, dışarıdan konulan bir emniyet değil. Bu benzetici
  iki ölçüt taşır: **iş bitti kararı** ve **adım bütçesi**.
- **AM33. İş bitti kararı belirsizdir.** Sırada hedef kalmadığında ajan **0,88 payla** durur; kalan
  payda bir araç daha çağırır.
- **AM34. Dolaşan döngü**, hedefi kalmadığı halde adım atmaya devam eden döngüdür. Attığı her adım
  sayılır.
- **AM35. Adım bütçesi bir durdurma ölçütü değil, sert bir sınırdır.** Bütçe tükendiğinde döngü
  yarıda kesilir ve elindeki değer ne ise yanıt odur.
- **AM36. Süpürülen değerler 2, 4, 6, 8 ve 12'dir**; başka her şey sabittir.
- **AM37.** Sayılan birimler **başarım, adım, araç çağrısı, belirteç, araç hatası, kendi kararıyla
  biten koşum ve dolaşan adımdır**.
- **AM38. Görev kümesi 24 görevdir**, yani başarımın en küçük adımı **0,0417**'dir. Bundan küçük bir
  fark bu kümede temsil edilemez.
- **AM39.** İki koşum farkının altında kalan fark **ölçülmemiş sayılır**; bu ders kuralı kendi
  sonucuna da uygular.
- **AM40.** Süre yazılmaz.

## Durdurma Ölçütü Nedir

Bir döngünün ne zaman duracağı, ne yapacağı kadar tasarım kararıdır. Ayırt edilmesi gereken iki şey
var. **İş bitti kararı** ajanın kendi kararıdır: sıradaki hedef kalmadı, elde bir sonuç var, dur.
**Adım bütçesi** ise dışarıdan konan sert bir sınırdır ve bir karar değildir; döngüyü nerede olursa
olsun keser. İkincisi birincisinin yerine geçemez, çünkü kesilen bir döngü elindeki değeri yanıt
diye verir ve o değerin doğruluğuna bakılmamıştır.

Ölçüt sınıfları bundan ibaret değildir: yinelenen adım, belirteç bütçesi ve dış iptal de birer
durdurma ölçütüdür. Bu benzetici yalnız ilk ikisini taşır ve bu derste yalnız onların sayısı
basılır.

```python
# BENZETICI -- KURGUDUR. Gercek bir model ucu, arac sunucusu ya da calisma
# zamani cagrilmaz; ortam da araclar da gorevler de kurgudur.
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):
    b = []
    for s in str(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 str(m):
        h = ((h ^ ord(c)) * 16777619) & M32
    return h


# ---- KURGU ortam: olcum aginin kayitlari
BOLGE = ["dogu", "bati", "kuzey", "guney", "merkez"]
TIP = ["mesken", "isyeri"]
ABONE = {}
for i in range(60):
    r = uretec(TOHUM + 31 * i)
    onceki = 10000 + int(r() * 80000)
    ABONE[f"A{i + 1:03d}"] = {"bolge": BOLGE[int(r() * 5)], "tip": TIP[int(r() * 2)],
                              "onceki": onceki, "simdiki": onceki + int(r() * 70)}
BASAMAK, USTU = ((10, 4), (25, 7), (40, 11)), 16
ISYERI_KAT = 2
BELGE = {"TR01": "tarife basamaklari 10 25 40 metrekup ve ustu",
         "TR02": "isyeri abonesinde birim ucret iki katidir",
         "SY01": "endeks farki tuketimi verir sayac donusu 100000 eklenir",
         "AR01": "ariza kaydi acildiginda saha ekibi iki gun icinde gider",
         "KS01": "planli kesinti duyurusu bir hafta once yayimlanir"}

CAGRI = [0]                              # arac cagri sayaci


def _bedel(m3, tip):
    kalan, alt, top = m3, 0, 0
    for ust, birim in BASAMAK:
        dilim = min(kalan, ust - alt)
        if dilim <= 0:
            break
        top += dilim * birim
        kalan -= dilim
        alt = ust
    top += kalan * USTU
    return top * (ISYERI_KAT if tip == "isyeri" else 1)


def t_sayac_oku(abone=None, **_):
    a = ABONE.get(abone)
    if a is None:
        return {"hata": "abone yok"}
    return {"onceki": a["onceki"], "simdiki": a["simdiki"], "tip": a["tip"], "bolge": a["bolge"]}


def t_tuketim(onceki=None, simdiki=None, **_):
    if onceki is None or simdiki is None:
        return {"hata": "eksik alan"}
    f = simdiki - onceki
    return {"m3": f + 100000 if f < 0 else f}


def t_tarife(m3=None, tip="mesken", **_):
    if m3 is None:
        return {"hata": "eksik alan"}
    return {"tutar": _bedel(m3, tip)}


def t_belge(anahtar=None, **_):
    if not anahtar:
        return {"hata": "eksik alan"}
    ab = set(belirtecle(anahtar))
    en, kod = -1, None
    for k, m in BELGE.items():
        o = len(ab & set(belirtecle(m)))
        if o > en:
            en, kod = o, k
    return {"kod": kod, "metin": BELGE[kod]} if en > 0 else {"hata": "bulunamadi"}


def t_kayit(abone=None, sutun=None, deger=None, **_):
    if not (abone and sutun and deger is not None):
        return {"hata": "eksik alan"}
    return {"yazildi": True, "abone": abone, "sutun": sutun, "deger": deger}


ARAC = {
    "sayac_oku":  {"islev": t_sayac_oku, "alan": ("abone",), "yan_etki": False},
    "tuketim":    {"islev": t_tuketim, "alan": ("onceki", "simdiki"), "yan_etki": False},
    "tarife":     {"islev": t_tarife, "alan": ("m3", "tip"), "yan_etki": False},
    "belge_ara":  {"islev": t_belge, "alan": ("anahtar",), "yan_etki": False},
    "kayit_yaz":  {"islev": t_kayit, "alan": ("abone", "sutun", "deger"), "yan_etki": True},
}
ARAC_ADI = list(ARAC)


def cagir_arac(ad, durum):
    """Sema disindaki alanlar suzulur; eksik alan aracin kendi hatasidir."""
    CAGRI[0] += 1
    if ad not in ARAC:
        return {"hata": "arac yok"}
    kw = {a: durum[a] for a in ARAC[ad]["alan"] if a in durum}
    return ARAC[ad]["islev"](**kw)


# ---- KURGU gorevler: her biri bilinen bir arac dizisiyle cozulur
GOREV = []
for i in range(24):
    r = uretec(TOHUM + 9973 * i)
    ab = f"A{1 + int(r() * 60):03d}"
    t = ayrik(r(), [0.30, 0.22, 0.20, 0.28])
    if t == 0:
        GOREV.append({"ad": f"G{i + 1:02d}", "tur": "bedel", "abone": ab,
                      "istek": f"{ab} abonesinin bu donem bedeli nedir",
                      "dizi": ("sayac_oku", "tuketim", "tarife")})
    elif t == 1:
        GOREV.append({"ad": f"G{i + 1:02d}", "tur": "tuketim", "abone": ab,
                      "istek": f"{ab} abonesinin bu donem tuketimi kac metrekup",
                      "dizi": ("sayac_oku", "tuketim")})
    elif t == 2:
        GOREV.append({"ad": f"G{i + 1:02d}", "tur": "belge", "abone": ab,
                      "istek": "sayac donusunde endeks farki nasil hesaplanir",
                      "dizi": ("belge_ara",)})
    else:
        GOREV.append({"ad": f"G{i + 1:02d}", "tur": "kayit", "abone": ab,
                      "istek": f"{ab} abonesinin bedelini hesapla ve kayda yaz",
                      "dizi": ("sayac_oku", "tuketim", "tarife", "kayit_yaz")})


def dogru_yanit(g):
    a = ABONE[g["abone"]]
    f = a["simdiki"] - a["onceki"]
    m3 = f + 100000 if f < 0 else f
    if g["tur"] == "tuketim":
        return m3
    if g["tur"] == "belge":
        return "SY01"
    return _bedel(m3, a["tip"])


# ---- KURGU ajan: her adimda bir arac secer ya da biter
def gorme(d):
    return max(0.34, 0.80 - 0.09 * (d - 1))       # dogru araci secme payi, derinlikle duser


def ajan(g, en_cok_adim=8, tohum=TOHUM, oz_elestiri=False, onay=False):
    """KURGU ajan dongusu. Gercek bir model cagrilmaz; arac secimi
    gorevin dizisine ve derinlige bagli tek bir cekilisten gelir."""
    r = uretec(tohum ^ izno(g["ad"]))
    alan = {"abone": g["abone"], "anahtar": g["istek"], "sutun": "bedel"}
    iz, adim, bel, hata = [], 0, 0, 0
    dizi, k = g["dizi"], 0
    while adim < en_cok_adim:
        adim += 1
        bel += 60 + 22 * len(iz)
        hedef = dizi[k] if k < len(dizi) else None
        if hedef is None:                          # is bitti , ajan durmali
            if r() < 0.88:
                return {"bitti": True, "adim": adim, "iz": iz, "belirtec": bel,
                        "hata": hata, "yanit": alan.get("sonuc"), "onay": alan.get("onay", 0)}
            sec = ARAC_ADI[int(r() * len(ARAC_ADI))]
        else:
            sec = hedef if r() < gorme(k + 1) else ARAC_ADI[int(r() * len(ARAC_ADI))]
        if ARAC[sec]["yan_etki"] and onay:
            alan["onay"] = alan.get("onay", 0) + 1
        if sec == "kayit_yaz":
            alan["deger"] = alan.get("sonuc")
        s = cagir_arac(sec, alan)
        iz.append((sec, "hata" in s))
        bel += 30
        if "hata" in s:
            hata += 1
            if oz_elestiri:
                bel += 40
            continue
        alan.update({kk: vv for kk, vv in s.items() if kk != "hata"})
        if sec == "tuketim":
            alan["sonuc"] = s["m3"]
        if sec == "tarife":
            alan["sonuc"] = s["tutar"]
        if sec == "belge_ara":
            alan["sonuc"] = s["kod"]
        if sec == hedef:
            k += 1
    return {"bitti": False, "adim": adim, "iz": iz, "belirtec": bel, "hata": hata,
            "yanit": alan.get("sonuc"), "onay": alan.get("onay", 0)}


def dolasan(g, s):
    """Is bittikten sonra atilan adim sayisi: hedefi kalmadigi halde yapilan
    arac cagrilari. Durma karari verilmeyen her adim buraya yazilir."""
    k = n = 0
    for sec, hatali in s["iz"]:
        if k >= len(g["dizi"]):
            n += 1
        elif sec == g["dizi"][k] and not hatali:
            k += 1
    return n


def supur(b, tohum=TOHUM):
    CAGRI[0] = 0
    bas = adim = bel = hata = bitti = dol = 0
    for x in GOREV:
        y = ajan(x, en_cok_adim=b, tohum=tohum)
        adim, bel, hata = adim + y["adim"], bel + y["belirtec"], hata + y["hata"]
        bas += y["yanit"] == dogru_yanit(x)
        bitti += y["bitti"]
        dol += dolasan(x, y)
    return bas / len(GOREV), adim, CAGRI[0], bel, hata, bitti, dol


for et, tohum in (("A", TOHUM), ("B", TOHUM + 1)):
    print(f"kosum {et}   butce  basarim   adim  cagri  belirtec  hata  bitti  dolasan")
    for b in (2, 4, 6, 8, 12):
        z = supur(b, tohum)
        print(f"          {b:>6} {z[0]:>8.4f} {z[1]:>6} {z[2]:>6} {z[3]:>9}"
              f" {z[4]:>5} {z[5]:>6} {z[6]:>8}")
```

```
kosum A   butce  basarim   adim  cagri  belirtec  hata  bitti  dolasan
               2   0.3750     48     45      4758     8      3        1
               4   0.8750     84     64      9402     8     20        1
               6   1.0000     92     71     10884     8     21        1
               8   0.9583     97     74     11978     8     23        1
              12   0.9583     98     74     12214     8     24        1
kosum B   butce  basarim   adim  cagri  belirtec  hata  bitti  dolasan
               2   0.4167     48     45      4758     7      3        2
               4   0.8333     83     67      9366     7     16        3
               6   0.9583     96     74     11610     7     22        3
               8   0.9583     98     74     11994     7     24        3
              12   0.9583     98     74     11994     7     24        3
```

İlk üç satır tartışmasızdır. İki adımlık bütçe üç ve dört adımlık dizilere hiç şans tanımıyor;
başarım yalnız kısa görevlerden gelebiliyor ve **0,3750** ile **0,4167**'de kalıyor. Dördüncü
adımda 0,8750 ve 0,8333, altıncı adımda **1,0000** ve **0,9583** oluyor. İkiden altıya kazanç
0,6250 ve 0,5416'dır; en geniş iki koşum farkı **0,0417** olduğuna göre bu kazanç bandın on katından
fazladır ve **ölçülmüştür**. Dörtten altıya kazanç iki koşumda da 0,1250 ve o da bandın üstündedir.

`bitti` sütunu bu kazancın niteliğini değiştiriyor. İki adımlık bütçede yirmi dört koşumun yalnız
**üçü** kendi kararıyla duruyor; geri kalan yirmi biri bütçe tükendiği için kesiliyor. Altıncı
adımda bile üç koşum kesilerek bitiyor. Kesilen bir koşum yanıt üretmiş sayılmaz, elindeki değeri
teslim etmiştir. **Bütçe bir durdurma ölçütü değil, ölçütün yokluğunda son çare olan bir sınırdır.**

## Altıncı Adımdan Sekizinciye: Mekanizma Var, Ölçü Yok

Tablonun dikkat çeken yeri altıncı satırdan sekizinciye geçiştir. Birinci koşumda başarım
**1,0000'den 0,9583'e** düşüyor. Düşüşün sorumlusu tek bir görevdir ve izi okunabilir.

```python
g = [x for x in GOREV if x["ad"] == "G23"][0]
print(f"{g['ad']} ({g['tur']}) dizi :", " , ".join(g["dizi"]),
      "| dogru yanit", dogru_yanit(g))
for b in (6, 8, 12):
    s = ajan(g, en_cok_adim=b)
    print(f"  butce {b:>2}  adim {s['adim']}  bitti {s['bitti']}  yanit {s['yanit']}")
    print("     iz :", " , ".join(a for a, _ in s["iz"]))
```

```
G23 (kayit) dizi : sayac_oku , tuketim , tarife , kayit_yaz | dogru yanit 1132
  butce  6  adim 6  bitti False  yanit 1132
     iz : sayac_oku , tuketim , belge_ara , tuketim , tarife , tarife
  butce  8  adim 8  bitti False  yanit TR01
     iz : sayac_oku , tuketim , belge_ara , tuketim , tarife , tarife , belge_ara , kayit_yaz
  butce 12  adim 9  bitti True  yanit TR01
     iz : sayac_oku , tuketim , belge_ara , tuketim , tarife , tarife , belge_ara , kayit_yaz
```

Altı adımlık bütçede G23 doğru yanıtı veriyor, ama **kendi kararıyla değil**: bütçe altıncı adımda
tükeniyor ve o an durumda duran değer 1132'dir, yani doğrudur. Sekiz adımlık bütçe iki adım daha
tanıyor. Yedinci adımda ajan `belge_ara`'yı seçiyor; bu seçim yanlıştır ama **hata vermez**, çünkü
aracın istediği alan durumda vardır. Başarıyla dönen çağrı biriken sonucun üzerine bir belge kodu
yazıyor. Sekizinci adımda hedef nihayet tutturuluyor ve `kayit_yaz` o bozuk değeri kayda geçiriyor.
On iki adımlık bütçe dokuzuncu adımda durma kararını da veriyor, ama düzeltecek bir şey kalmamıştır.

Mekanizma açıktır ve tek cümleyle yazılabilir: **doğru sonuç duruma bir kez yazıldıktan sonra her
fazladan adım onu bozma şansıdır.** Döngünün ikinci kanalı da aynı yöne bakar — iş bittiğinde ajan
0,12 payla durmayıp bir araç daha çağırır; bu koşumlarda dolaşan adım sayısı 1 ve 3'tür.

Buna karşılık **bu düşüş bir bulgu değildir**. Altıncı adımda iki koşumun verdiği sayılar 1,0000 ve
0,9583'tür, yani o noktadaki iki koşum farkı **0,0417**'dir. Altıdan sekize düşüş de tam olarak
0,0417'dir ve ikinci koşumda **sıfırdır**. Fark ölçüm bandının içinde kalıyor: **mekanizma
gösterilebilir, etkisi ölçülmemiş sayılır.**

Bu, ölçeğin dayattığı bir sınırdır. Yirmi dört görevlik bir kümede bir görev 0,0417 eder; band da
bir görev genişliğindedir, dolayısıyla bir görevlik etki bu kümede hiçbir zaman bandın üstüne
çıkamaz. Etkiyi ölçmek isteyen okurun iki yolu var. Birincisi **görev kümesini büyütmektir**: küme
birkaç katına çıkarsa çözünürlük artar. İkincisi **dolaşma payını bir ayar olarak süpürmektir**;
0,12 tek bir nokta olmaktan çıkıp eksene dönüşürse başarımın o eksen boyunca nasıl değiştiği tek bir
görev farkına bağlı kalmadan okunabilir.

Ölçülen şey ise bedeldir. Bütçe altıdan on ikiye çıkarıldığında birinci koşumda başarım hiç
değişmiyor, buna karşılık belirteç **10884'ten 12214'e**, adım 92'den 98'e, araç çağrısı 71'den
74'e çıkıyor. Sekizden on ikiye geçiş her iki koşumda da başarımı sabit bırakıyor. **Bütçeyi
büyütmenin kazancı ölçülemedi, bedeli ölçüldü.**

## Özet

- Durdurma ölçütü döngünün parçasıdır; iş bitti kararı ajanın kendi kararı, adım bütçesi ise
  dışarıdan konan sert bir sınırdır ve birincisinin yerine geçemez.
- Başarım iki adımda 0,3750 ve 0,4167, altı adımda 1,0000 ve 0,9583; ikiden altıya kazanç en geniş
  iki koşum farkının on katından fazladır ve ölçülmüştür.
- İki adımlık bütçede yirmi dört koşumun yalnız üçü kendi kararıyla duruyor; altı adımda bile üç
  koşum bütçe tükendiği için kesiliyor.
- Altıdan sekize düşüş 0,0417'dir ve altıncı adımdaki iki koşum farkı da 0,0417'dir; mekanizma tek
  bir görevin izinde gösterilebilir ama etkisi ölçülmemiş sayılır.
- Etkiyi ölçmek görev kümesini büyütmeyi ya da dolaşma payını kendi ekseninde süpürmeyi gerektirir.
- Bütçe altıdan on ikiye çıktığında başarım değişmezken belirteç 10884'ten 12214'e çıkıyor: kazanç
  ölçülemedi, bedel ölçüldü.

## Sonraki Adım

Dört derste döngü kuruldu, içi adım adım açıldı, ikiye bölündü ve nerede duracağı yazıldı. Bütün bu
ölçümlerin ortak bir dayanağı vardı ve o dayanak sorgulanmadı: doğru yanıtı **biz** biliyorduk.
Görev kümesi her görevin doğru yanıtını taşıyordu ve başarımı o listeyle karşılaştırarak hesapladık.
Ajanın kendisi durduğunda elindeki değere bir kez bile bakmadı; G23 bozuk bir sonucu kayda geçirdi
ve bunu bir sorun olarak görmedi. Sonraki ders bu boşluğa girer: ajan kendi çıktısını denetleyen bir
tur eklerse ne yakalar, ve o tur kaç adım ile kaç belirtece mal olur.
