---
title: 'İzleme ve Günlükleme'
source: 'https://academia.sh/tr/kurslar/yapay-zeka-ajanlari/izleme-ve-gunlukleme'
course: 'Yapay Zekâ Ajanları'
language: tr
updated: '2026-08-17T18:06:32+00:00'
license: 'CC BY-SA 4.0'
---

# İzleme ve Günlükleme

Üretimde koşan bir ajan döngüsünün adım izinin neyi geri okuttuğunun ölçülmesi: yirmi dört görevin on koşumundan oluşan iki yüz kırk koşumluk akışta on beş görev yanlış bitiyor ve nedenleri on iki yanlış seçim ile üç dolaşmadan oluşuyor. Yalnız sonucu saklayan iz bu nedenlerin 0,0000'ini, araç adlarını sayan iz 0,4000'ini, tam gözlemi saklayan iz 1,0000'ini veriyor; saklanan belirteç 2738'den 5954'e ve 13623'e çıkıyor, bulunan neden başına belirteç ise 992,3'ten 908,2'ye iniyor. Altmış bir araç hatasının 0,8689'u doğru biten koşumlarda oluşuyor, yani araç hatası sayacı bir neden değil bir belirtidir.

Bir önceki iki ders ajanı sınadı. Araç düzeyi sınama beş araca konan kusurları tek tek yokladı,
uçtan uca akış sınaması onun kaçırdıklarını yakaladı ve ikisinin de göremediği bir kalıntı kaldı.
Her ikisinin de ortak bir kısıtı var: **sınanan koşumu biz kurduk**. Hangi görevin çalıştığını,
hangi aracın bozulduğunu ve doğru yanıtın ne olduğunu önceden biliyorduk.

Üretimde koşan bir döngüde bunların hiçbiri elimizde değildir. Görev bir aboneden gelir, ajan
kendi adımlarını seçer, sonuç bir kayda yazılır ve geriye yalnız **sakladığımız kadarı** kalır. Bu
dersin ölçtüğü şey ajanın kendisi değil, **izin geri okuttuğudur**: bir görev yanlış bittiğinde,
sakladığımız kayıt onun **neden** yanlış bittiğini söyleyebiliyor mu. Gözlemlenebilirliğin genel
yordamı Gözlemlenebilirlik ve Güvenilirlik kursunda ve Gözlemlenebilirlik ve İşletim kursunda
kuruldu; burada tekrarlanmaz. Ölçülen tek şey **adım izinin taşıdığı
bilgi ile bedeli** arasındaki alışveriştir.

- **KL31.** Ortam, araçlar, görev kümesi ve ajan döngüsü **kurgudur** ve aşağıda ders içinde
  tanımlanır; gerçek bir model uç noktası, araç sunucusu ya da çalışma zamanı çağrılmaz. Tohum
  **20260218**, ikinci koşum **20260219**.
- **KL32. Üretim akışı**, aynı yirmi dört görevin **on kez** koşmasıdır. Model belirsiz bir
  bileşen olduğu için her koşumda ajanın çekilişi ayrıdır; toplam **240 koşum** olur. Adım bütçesi
  **6**, yani `ajan-mimarisi/04`'ün süpürmesinde en iyi çıkan değerdir.
- **KL33. Üç iz düzeyi** şunları saklar. **Yalnız sonuç**: görev adı, son yanıt ve döngünün durup
  durmadığı. **Araç adları**: bunlara ek olarak hangi aracın kaç kez çağrıldığı — **sıra
  saklanmaz**, çünkü bu düzey bir sayaçtır. **Tam gözlem**: bunlara ek olarak çağrıların **sırası
  ve her çağrının döndürdüğü gözlemin tamamı**.
- **KL34. Neden**, izdeki **ilk sapmadır** ve tam gözlemden okunur: plan bitmeden plan dışı bir
  araç çağrıldıysa **yanlış seçim**, plan bittikten sonra çağrı sürdüyse **dolaşma**, plandaki araç
  sırasında hata döndürdüyse **araç hatası**, hiç sapma yokken plan bitmediyse **bütçe**.
- **KL35.** Bir iz düzeyi bir nedeni ancak **sakladığı alanlar onu belirliyorsa** verir; belirsiz
  kaldığı yerde neden **bulunamadı** sayılır ve yanlış tahmin doğru sayılmaz.
- **KL36.** Saklanan belirteç, kaydın ortak belirteçleyiciden geçirilmesiyle sayılır. Bu kursta iz
  için kullanılan terim **adım izidir**.

## Üretim Akışı ve Ortak Tanım

Aşağıdaki blok kursun ortak tanımını kurar: ölçüm ağının kurgu abone kayıtları, kurgu belge
dağarcığı, beş araç, yirmi dört görev ve ajan döngüsü. Araç seçimi derinlikle bozulur, iş bitince
ajan 0,88 payla durur, şema dışı alanlar süzülür ve eksik alan aracın kendi hatasıdır.

```python
# KURGUDUR. Olcum aginin abone kayitlari, belge dagarcigi, bes arac ve yirmi dort
# gorev ders icinde tanimlanir; gercek bir uc nokta ya da arac sunucusu cagrilmaz.
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


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)


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"])


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)}
```

## İzin Geri Okuttuğu

Üç düzeyin her biri için aynı akış koşar, kayıtlar kurulur ve başarısız görevlerin nedeni o
düzeyin sakladığı alanlardan çıkarılmaya çalışılır. Tam gözlem düzeyini kurmak için araç çağrısı
sarmalanır: dönen sözlüğün tamamı günlüğe düşer.

```python
# Uretim akisi: ayni gorev kumesi on kez kosar, ajanin cekilisi her kosumda ayridir.
BUTCE, KOSUM = 6, 10
GUNLUK = []
_ham_cagir = cagir_arac


def cagir_arac(ad, durum):                 # tam gozlem duzeyi: donen alanlar da saklanir
    s = _ham_cagir(ad, durum)
    GUNLUK.append((ad, dict(s)))
    return s


def neden(g, iz):
    """Tam gozlemden okunan neden: izdeki ilk sapma."""
    k = 0
    for ad, gz in iz:
        if k >= len(g["dizi"]):
            return "dolasma"
        if ad != g["dizi"][k]:
            return "yanlis secim"
        if "hata" in gz:
            return "arac hatasi"
        k += 1
    return "butce" if k < len(g["dizi"]) else "bilinmiyor"


def tani_ad(g, say):
    """Ad duzeyi yalniz sayac tutar: sira da gozlem de yok."""
    if not [a for a in say if a not in g["dizi"]]:
        return None
    if [a for a in g["dizi"] if say.get(a, 0) == 0]:
        return "yanlis secim"
    if all(say[a] == g["dizi"].count(a) for a in set(g["dizi"])):
        return "dolasma"
    return None


ozet = {}
for taban in (20260218, 20260219):
    bulunan, saklanan, basarisiz, dagilim, hata, hata_dogru = [0, 0, 0], [0, 0, 0], 0, {}, 0, 0
    for d in range(KOSUM):
        for g in GOREV:
            GUNLUK.clear()
            s = ajan(g, en_cok_adim=BUTCE, tohum=taban + 7 * d)
            iz = list(GUNLUK)
            say = {}
            for a, _ in iz:
                say[a] = say.get(a, 0) + 1
            k1 = {"ad": g["ad"], "yanit": s["yanit"], "bitti": s["bitti"]}
            kayit = (k1, dict(k1, sayac=say), dict(k1, iz=iz))
            for i in range(3):
                saklanan[i] += len(belirtecle(kayit[i]))
            hata += s["hata"]
            if s["yanit"] == dogru_yanit(g):
                hata_dogru += s["hata"]
                continue
            basarisiz += 1
            gercek = neden(g, iz)
            dagilim[gercek] = dagilim.get(gercek, 0) + 1
            bulunan[1] += tani_ad(g, say) == gercek
            bulunan[2] += neden(g, iz) == gercek
    ozet[taban] = (bulunan, saklanan, basarisiz)
    n = " , ".join(f"{k} {v}" for k, v in sorted(dagilim.items()))
    print(f"tohum {taban} , {KOSUM * len(GOREV)} kosum , basarisiz {basarisiz} , neden: {n}")
    print(f"  arac hatasi {hata} , bunun dogru biten kosumdaki payi {hata_dogru / hata:.4f}")
print("\niz duzeyi     neden bulunan pay   saklanan belirtec   bulunan neden basina")
for i, ad in enumerate(("yalniz sonuc", "arac adlari", "tam gozlem")):
    a, b = ozet[20260218], ozet[20260219]
    ba = f"{a[0][i] / a[2]:.4f} {b[0][i] / b[2]:.4f}"
    bel = f"{a[1][i]:>6} {b[1][i]:>6}"
    bas = " ".join(f"{x[1][i] / x[0][i]:>7.1f}" if x[0][i] else "      -" for x in (a, b))
    print(f"{ad:<14} {ba}      {bel}      {bas}")
```

```
tohum 20260218 , 240 kosum , basarisiz 15 , neden: dolasma 3 , yanlis secim 12
  arac hatasi 61 , bunun dogru biten kosumdaki payi 0.8689
tohum 20260219 , 240 kosum , basarisiz 11 , neden: dolasma 3 , yanlis secim 8
  arac hatasi 66 , bunun dogru biten kosumdaki payi 0.9242

iz duzeyi     neden bulunan pay   saklanan belirtec   bulunan neden basina
yalniz sonuc   0.0000 0.0000        2738   2739            -       -
arac adlari    0.4000 0.2727        5954   6043        992.3  2014.3
tam gozlem     1.0000 1.0000       13623  14486        908.2  1316.9
```

Yalnız sonucu saklayan iz **hiçbir** nedeni vermiyor. Bu düzey başarısızlığı **sayabilir**: on beş
görevin yanlış bittiğini bilir. Neden sorulduğunda elinde yalnız yanıt ile durma bayrağı vardır ve
bu iki alan, aynı yanlış yanıtı üreten iki ayrı yolu birbirinden ayırmaz. Bir gösterge tablosu bu
düzeyle kurulabilir; bir arıza bu düzeyle kapatılamaz.

Araç adlarını sayan iz nedenlerin **0,4000'ini** veriyor. Bu düzeyin bildiği şey hangi aracın kaç
kez çağrıldığıdır; sıra yoktur. Sayaçta plan dışı bir araç görünüyorsa ve plandaki araçlardan biri
**hiç** çağrılmamışsa plan tamamlanmamıştır, yani sapma yanlış seçimdir. Plan dışı araç var ama
plandaki araçların hepsi tam birer kez çağrılmışsa plan bitmiş ve fazladan çağrı sonradan gelmiştir,
yani dolaşmadır. Bu iki durumun dışında sayaç iki senaryoyu **ayırt edemez**: aynı sayaç hem plan
ortasında yapılmış bir yanlış seçimden hem de plan bittikten sonraki bir dolaşmadan çıkabilir. O
koşumlarda neden bulunamadı sayılır.

Tam gözlem düzeyi nedenlerin **hepsini** veriyor, çünkü sıra ile birlikte her çağrının döndürdüğü
gözlem de saklanmıştır ve plan işaretçisi birebir yeniden yürütülebilir. Bedeli, saklanan
belirtecin 2738'den **13623'e** çıkmasıdır — beş katı.

Son sütun sıralamayı değiştiriyor. **Bulunan neden başına belirteç** okunduğunda araç adları düzeyi
992,3, tam gözlem düzeyi **908,2**'dir. Toplamda beş kat pahalı olan düzey, işe yarayan çıktı
birimi başına **daha ucuzdur**, çünkü ucuz düzeyin sakladığı belirtecin çoğu hiçbir soruyu
kapatmıyor. İkinci koşumda aynı okuma daha da keskindir: 2014,3'e karşı 1316,9.

## Araç Hatası Bir Neden Değil, Belirtidir

Akışta **61 araç hatası** var ve bunların **0,8689'u doğru biten koşumlarda** oluşuyor. Araç hatası
sayacına konan bir uyarı altmış bir kez çalar, elli üçü sorunsuz biten bir görev içindir. Ters
yönde de eksiktir: nedenler tablosunda **araç hatası sınıfı hiç görünmez**. Mekanizma bunu
açıklıyor. Plandaki araç sırası geldiğinde girdisi zaten durumda hazırdır ve hata döndürmez; hata
ancak **yanlış seçilmiş** bir araç şemasının istediği alanı bulamadığında çıkar. Yani araç hatası
her zaman bir yanlış seçimin **ardından** gelir ve o seçim düzeltilmeden hata sayısına bakmak
insanı aracı düzeltmeye götürür.

İki koşum bandı bu okumanın sınırını da çiziyor. Araç adları düzeyi bir koşumda 0,4000, öbüründe
0,2727 veriyor; aradaki **0,1273** ölçüm bandıdır. Bu düzeyin tam gözlemden **0,6000** geride
olması banda göre büyüktür ve bir bulgudur. Ama iki koşum arasında bu düzeyin kendi değerinin ne
kadar oynadığı, "araç adları nedenlerin şu kadarını verir" biçimindeki bir iddianın **tek başına
ölçülmemiş** olduğunu söyler; ölçülen şey düzeyler arasındaki sıradır.

## Özet

- Üretim akışı yirmi dört görevin on koşumudur; 240 koşumun 15'i yanlış biter ve nedenleri 12
  yanlış seçim ile 3 dolaşmadır.
- Yalnız sonuç düzeyi nedenlerin 0,0000'ini, araç adları düzeyi 0,4000'ini, tam gözlem düzeyi
  1,0000'ini verir.
- Bedel 2738, 5954 ve 13623 belirteçtir; bulunan neden başına okunduğunda sıralama tersine döner
  ve tam gözlem 908,2 ile araç adlarının 992,3'ünün altına iner.
- 61 araç hatasının 0,8689'u doğru biten koşumlardadır ve nedenler tablosunda araç hatası sınıfı
  hiç görünmez: hata sayacı bir belirtidir, neden değildir.
- Araç adları düzeyinin iki koşum arasındaki farkı 0,1273'tür; bu düzeyin tek başına değeri
  ölçülmemiş, düzeyler arasındaki sıra ölçülmüş sayılır.

## Sonraki Adım

İz, bir görevin neden yanlış bittiğini geri okutuyor ve bunun bir belirteç bedeli var. Ama bu
bedel, döngünün ödettiği bedelin yalnız bir kalemidir. Ajan her adımda bir çağrı yapar, her çağrı
belirteç harcar ve adım sayısı görevden göreve değişir. Sonraki ders bu harcamayı iki ayrı
paydayla okur: **adım başına** ve **doğru yanıt başına**. İki sıralamanın aynı olmadığı bir nokta
vardır ve o noktada hangi düzeneğin ucuz sayılacağı paydanın seçimine bağlıdır.
