İçeriğe geç
academia.sh

Ders 17 / 26

Ajanlı Kodlama

Çok adımlı bir işin devredilmesinde denetim noktası aralığının ölçülmesi: altmış kurgu işin 480 adımı altı ayrı aralıkta koşturulunca her adımda durmak 478/480 doğru adım veriyor ama 479 durma istiyor, sekiz adımda bir durmak 60 durmaya iniyor ve 355/480'e düşüyor. Yakalanan hata başına boşa giden adım 1,00'den 5,64'e çıkıyor; kaçan hata 1'den 21'e. Çağrı sayısı altı aralıkta neredeyse sabit (549 ile 598 arası), yani durmanın bedeli çağrı değil insan bakışıdır. Doğru adım başına belirteç iki koşumda da üç adımlık aralıkta en düşüktür (146,8 ve 144,9), yani en doğru aralık ile en ucuz aralık aynı değildir.

İçindekiler

Önceki iki derste her görev tek bir çağrıydı: bağlam gitti, öneri geldi, geliştirici kabul etti ya da etmedi. Karar noktası tekti ve öneriyle aynı yerdeydi. Bir dosyayı okumak, bir işlevi değiştirmek, çağıranları güncellemek ve raporu yeniden biçimlemek tek bir istekle devredildiğinde bu düzen bozulur: araç arka arkaya adım atar, her adım bir öncekinin üstüne kurulur ve geliştirici artık her adımda değil, durduğu yerde bakar.

Bu ders o durma yerini ölçer ve başka bir şey ölçmez. Aracın nasıl planladığı, neyi hatırladığı ve döngüsünü nasıl kapattığı burada ele alınmaz; bunlar bu müfredatın Yapay Zekâ Ajanları kursunun konusudur. Buradaki tek soru şudur: kaç adımda bir durulduğunda hata yayılmadan yakalanıyor ve bunun bedeli ne.

  • YG17. Kurulum önceki iki dersle aynıdır: kurgu kod tabanı (beş modül, 53 satır), yirmi dört kurgu görev ve yardımcı benzeticisi. Gerçek bir ajanlı kodlama aracı çalıştırılmaz.
  • YG18. Çok adımlı iş: 60 kurgu iş, her biri 8 adım, toplam 480 adım. Her adımın bağlamı seçilidir, yani yalnız o adımın gerektirdiği dosyalar gönderilir.
  • YG19. Yayılma kuralı: reddedilen bir adım fark edilmezse sonraki adımlar onun üstüne kurulur ve bulaşık sayılır. Bu dersin ölçtüğü tek yapısal olgu budur.
  • YG20. Denetim noktası her d adımda bir ve işin sonunda konur; durakta o pencere insana bakılır.
  • YG21. Görme payı pencere büyüdükçe düşer: 0,95 - 0,07 x (d - 1), alt sınır 0,40. Sekiz adımlık bir değişikliği tek seferde okumak, tek adımı okumaktan zordur.
  • YG22. Yakalanan hata yeniden koşulur: hatalı adımdan durağa kadarki adımlar yeniden çağrılır ve düzeldiği varsayılır. Bunlar boşa giden adımdır.
  • YG23. Yakalanmayan hata tabana girer: işin kalan adımları bulaşıktır ve sonraki duraklar onu göremez, çünkü bakılan şey kabul edilmiş taban değil yeni iştir.
  • YG24. Bedel üç ayrı kalemdir: durma sayısı (insanın baktığı kez), çağrı ve belirteç; her durak ayrıca 50 belirteç durum özeti ekler.
  • YG25. Teslim ölçüsü doğru adımdır: kaçan hatası olan bir işte doğru adım sayısı hatanın bulunduğu yere kadardır.
  • YG26. Adım sonuçları aralıktan bağımsız olarak aynı tohumla üretilir; aralıklar arasında değişen tek şey nerede durulduğudur. İkinci koşum tohum 20260219.

Bir İşin İzi

Önce tek bir iş iki ayrı aralıkla koşturulur. Aynı sekiz adım, aynı sonuçlar; değişen yalnız durakların yeri.

# AYNI KURGU KURULUM -- bes modullu kod tabani (53 satir), 24 kurgu gorev,
# yardimci benzeticisi. Gercek bir ajanli kodlama araci calistirilmaz.
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 izno(m):
    h = 2166136261
    for c in m:
        h = ((h ^ ord(c)) * 16777619) & M32
    return h


SINIF = ("tamamlama", "aciklama", "donusturme")
DOSYA = ("okuma.py", "tarife.py", "denetim.py", "ozet.py", "bicim.py")
GEREKEN = {
    0: ("okuma.py",), 1: ("tarife.py",), 2: ("denetim.py", "okuma.py"),
    3: ("ozet.py", "denetim.py"), 4: ("bicim.py", "ozet.py"),
    5: ("tarife.py", "okuma.py"), 6: ("ozet.py", "okuma.py", "tarife.py"),
    7: ("denetim.py", "bicim.py"),
}
GOREV = [
    {"ad": s + "-" + str(i + 1), "sinif": s, "gereken": GEREKEN[i], "zorluk": 0.05 * (i % 4)}
    for s in SINIF
    for i in range(8)
]
TABAN = {"tamamlama": 0.34, "aciklama": 0.72, "donusturme": 0.18}


def yardimci(gorev, baglam, tohum=TOHUM):   # BENZETICI -- KURGUDUR
    r = uretec(tohum ^ izno(gorev["ad"] + "|" + ",".join(sorted(baglam))))
    ortu = sum(1 for d in gorev["gereken"] if d in baglam) / len(gorev["gereken"])
    ilgisiz = sum(1 for d in baglam if d not in gorev["gereken"]) / len(DOSYA)
    puan = TABAN[gorev["sinif"]] + 0.55 * ortu - 0.30 * ilgisiz - gorev["zorluk"]
    puan = min(max(puan, 0.0), 1.0)
    kabul = r() < puan
    belirtec = 40 + 26 * len(baglam) + (18 if gorev["sinif"] == "donusturme" else 0)
    return {"kabul": kabul, "puan": puan, "belirtec": belirtec}


IS_SAYI, ADIM, DURUM_BEL = 60, 8, 50


def gorme(d):
    """Denetim penceresi buyudukce insanin hatayi gorme payi duser."""
    return max(0.95 - 0.07 * (d - 1), 0.40)


def devir(j, d, tohum=TOHUM, ayrinti=False):
    """Tek bir cok adimli isin d adimda bir durdurularak kosturulmasi."""
    say = {"cagri": 0, "belirtec": 0, "durma": 0, "yakalanan": 0,
           "kacan": 0, "bosa": 0, "dogru": 0}
    hatali, kacti = None, False
    for k in range(ADIM):
        g = GOREV[(j * ADIM + k) % len(GOREV)]
        s = yardimci(g, g["gereken"], tohum ^ izno("adim|" + str(j) + "|" + str(k)))
        say["cagri"] += 1
        say["belirtec"] += s["belirtec"]
        if kacti:
            if ayrinti:
                print(f"  adim {k}  {g['ad']:<14} bulasik (kacan hatanin ustune)")
            continue
        if hatali is None and not s["kabul"]:
            hatali = k
        if ayrinti:
            d_ad = "kabul" if s["kabul"] else "RET"
            if hatali is not None and hatali < k:
                d_ad = "bulasik"
            print(f"  adim {k}  {g['ad']:<14} {d_ad}")
        if (k + 1) % d == 0 or k == ADIM - 1:
            say["durma"] += 1
            say["belirtec"] += DURUM_BEL
            if hatali is None:
                if ayrinti:
                    print(f"  DURMA adim {k}: temiz")
                continue
            r = uretec(tohum ^ izno("denetim|" + str(j) + "|" + str(k)))
            if r() < gorme(d):
                yeniden = k - hatali + 1
                say["yakalanan"] += 1
                say["bosa"] += yeniden
                say["cagri"] += yeniden
                say["belirtec"] += yeniden * s["belirtec"]
                if ayrinti:
                    print(f"  DURMA adim {k}: hata adim {hatali} noktasinda"
                          f" gorundu, {yeniden} adim yeniden")
                hatali = None
            else:
                say["kacan"] += 1
                kacti = True
                if ayrinti:
                    print(f"  DURMA adim {k}: gorulmedi, hata tabana girdi")
    say["dogru"] = hatali if kacti else ADIM
    return say


print("is 0, adim araligi 4:")
a = devir(0, 4, ayrinti=True)
print("  ->", {x: a[x] for x in ("dogru", "bosa", "durma", "cagri", "belirtec")})
print("\nis 0, adim araligi 8:")
b = devir(0, 8, ayrinti=True)
print("  ->", {x: b[x] for x in ("dogru", "bosa", "durma", "cagri", "belirtec")})
is 0, adim araligi 4:
  adim 0  tamamlama-1    kabul
  adim 1  tamamlama-2    kabul
  adim 2  tamamlama-3    RET
  adim 3  tamamlama-4    bulasik
  DURMA adim 3: hata adim 2 noktasinda gorundu, 2 adim yeniden
  adim 4  tamamlama-5    kabul
  adim 5  tamamlama-6    kabul
  adim 6  tamamlama-7    RET
  adim 7  tamamlama-8    bulasik
  DURMA adim 7: hata adim 6 noktasinda gorundu, 2 adim yeniden
  -> {'dogru': 8, 'bosa': 4, 'durma': 2, 'cagri': 12, 'belirtec': 1178}

is 0, adim araligi 8:
  adim 0  tamamlama-1    kabul
  adim 1  tamamlama-2    kabul
  adim 2  tamamlama-3    RET
  adim 3  tamamlama-4    bulasik
  adim 4  tamamlama-5    bulasik
  adim 5  tamamlama-6    bulasik
  adim 6  tamamlama-7    bulasik
  adim 7  tamamlama-8    bulasik
  DURMA adim 7: hata adim 2 noktasinda gorundu, 6 adim yeniden
  -> {'dogru': 8, 'bosa': 6, 'durma': 1, 'cagri': 14, 'belirtec': 1312}

İki iz aynı sekiz adımı taşıyor ve altta yatan sonuçlar da aynı: 2 ve 6 numaralı adımlar reddediliyor. Değişen tek şey durakların yeridir, ama iz aynı değildir. Dört adımlık aralıkta ilk hata iki adım yayıldıktan sonra yakalanıyor, ikinci hata da öyle; toplam dört adım yeniden koşuluyor. Sekiz adımlık aralıkta ilk hata altı adım yayıyor ve ikinci hata hiç görünmüyor6 numaralı adım o noktada zaten bulaşık olduğu için ayrı bir hata olarak sayılmıyor. İkisi de sonunda sekiz doğru adım teslim ediyor, ama biri 12 çağrı ve 1178 belirteç, öbürü 14 çağrı ve 1312 belirteç harcıyor.

Bu tek iş iyi bir örnek ama bir sayı değildir: burada denetim ikisinde de gördü. Görmediğinde ne olacağı ancak yeterince iş üzerinde okunur.

Aralığın Süpürülmesi

Altmış iş, dört yüz seksen adım, altı ayrı denetim aralığı. Adım sonuçları aralıktan bağımsızdır; değişen tek şey durakların yeridir.

def kosum(d, tohum=TOHUM):
    top = {"cagri": 0, "belirtec": 0, "durma": 0, "yakalanan": 0,
           "kacan": 0, "bosa": 0, "dogru": 0}
    for j in range(IS_SAYI):
        for a, v in devir(j, d, tohum).items():
            top[a] += v
    return top


ADIMLAR = IS_SAYI * ADIM
BASLIK = ("aralik  gorme  durma  yakalanan  kacan  bosa  dogru adim"
          "  cagri  belirtec  bel/dogru")


def yaz(d, tohum):
    a = kosum(d, tohum)
    print(f"{d:>6}{gorme(d):>7.2f}{a['durma']:>7}{a['yakalanan']:>11}{a['kacan']:>7}"
          f"{a['bosa']:>6}{a['dogru']:>8}/{ADIMLAR}{a['cagri']:>7}{a['belirtec']:>10}"
          f"{a['belirtec'] / a['dogru']:>11.1f}")


print("kosum A (tohum 20260218)")
print(BASLIK)
for d in (1, 2, 3, 4, 6, 8):
    yaz(d, TOHUM)
print("\nkosum B (tohum 20260219)")
print(BASLIK)
for d in (1, 2, 3, 4, 6, 8):
    yaz(d, TOHUM + 1)
kosum A (tohum 20260218)
aralik  gorme  durma  yakalanan  kacan  bosa  dogru adim  cagri  belirtec  bel/dogru
     1   0.95    479         90      1    90     478/480    570     78648      164.5
     2   0.88    233         69      8   109     455/480    589     67790      149.0
     3   0.81    172         52     11   104     441/480    584     64746      146.8
     4   0.74    117         45     11   118     430/480    598     63320      147.3
     6   0.60    104         23     23    69     367/480    549     57784      157.4
     8   0.46     60         14     21    79     355/480    559     56414      158.9

kosum B (tohum 20260219)
aralik  gorme  durma  yakalanan  kacan  bosa  dogru adim  cagri  belirtec  bel/dogru
     1   0.95    467         71      4    71     463/480    551     76070      164.3
     2   0.88    224         52     11    79     430/480    559     64318      149.6
     3   0.81    168         44     12    78     428/480    558     62010      144.9
     4   0.74    107         29     14    85     392/480    565     59550      151.9
     6   0.60    105         24     17    79     393/480    559     58790      149.6
     8   0.46     60         18     16   101     393/480    581     59032      150.2

Yayılmanın Ölçüsü

Sorunun ilk yarısı — hata yayılmadan yakalanıyor mu — tabloda iki sütunun bölümüdür. Boşa giden adım, yakalanan hata sayısına bölündüğünde yakalandığı ana kadar kaç adım yayıldığını verir. Birinci koşumda bu sayı sırayla 1,00 / 1,58 / 2,00 / 2,62 / 3,00 / 5,64; ikinci koşumda 1,00 / 1,52 / 1,77 / 2,93 / 3,29 / 5,61. İki koşum ayrı ayrı aynı şeyi söylüyor: her adımda durulduğunda hata yayılmıyor, sekiz adımda bir durulduğunda ortalama beş buçuk adım yayıldıktan sonra yakalanıyor.

Kaçan hata sütunu ikinci yarıyı veriyor. Her adımda durmak birinci koşumda 1, ikinci koşumda 4 hatayı kaçırıyor; sekiz adımda bir durmak 21 ve 16. Bunun nedeni tabloda yazılı: görme payı 0,95’ten 0,46’ya iniyor, çünkü sekiz adımlık bir değişikliği tek seferde okumak zordur.

Bir sütun burada yanıltıcıdır ve okunmamalıdır: yakalanan hata sayısı. Aralık büyüdükçe 90’dan 14’e iniyor, sanki hata azalmış gibi. Azalan şey hata değil, hata sayabildiğimiz iştir; kaçan bir hata işin kalanını bulaştırdığı için o işte başka hata sayılmaz. Devredilen işin kalitesi “kaç hata bulundu” ile ölçülemez. Ölçülebilen tek şey teslim edilen doğru adımdır: 478/480’den 355/480’e, ikinci koşumda 463/480’den 393/480’e.

Aynı bağlılık durma sütununda da görünüyor. Her adımda durulan koşumda durak sayısı 480 değil 479; ikinci koşumda 467. Eksik duraklar, hatası kaçmış işlerin kalanıdır: taban artık bulaşık olduğu için o duraklarda bakılacak temiz bir iş kalmamıştır ve sayılmazlar. Tablodaki sütunlar birbirinden bağımsız değildir, çünkü devredilen iş de bağımsız adımlardan oluşmuyor.

Durmanın Bedeli

Bedel üç kalemdir ve üçü aynı yöne gitmiyor. Çağrı sayısı altı aralıkta 549 ile 598 arasında, ikinci koşumda 551 ile 581 arasında kalıyor — yani neredeyse sabit. Sık durmak yeniden koşum doğurur, seyrek durmak daha uzun yeniden koşum doğurur; ikisi birbirini götürür. Durmak bir çağrı meselesi değildir.

Belirteç düzenli düşüyor: 78648’den 56414’e, yani seyrek durmak toplam belirtecin yaklaşık yüzde yirmi sekizini kurtarıyor. Bunun büyük kısmı durak başına eklenen 50 belirteçlik durum özetinden gelir; 479 durak ile 60 durak arasındaki fark tek başına 20950 belirteçtir.

Asıl bedel üçüncü kalemdedir ve belirteçle ödenmez: durma sayısı. Her adımda durmak insanı 479 kez masaya çağırıyor, sekiz adımda bir durmak 60 kez. Aradaki fark sekiz kattır ve karşılığında kazanılan 123 doğru adımdır. Kurtarılan her doğru adım için insan yaklaşık 3,4 kez fazladan bakmıştır. Bu takas bir mühendislik kararıdır ve tabloda yazılıdır; hangi tarafın seçileceği adımın ne kadar geri alınabilir olduğuna bağlıdır.

Son sütun üçüncü bir eniyileme noktası gösteriyor. Doğru adım başına belirteç iki koşumda da üç adımlık aralıkta en düşüktür: 146,8 ve 144,9. Bu, en çok doğru adım veren aralık (bir) değildir; en az durma isteyen aralık (sekiz) de değildir. Üç ayrı ölçüt, üç ayrı kazanan. Bir denetim aralığı seçmek bu yüzden bir eniyileme değil bir beyandır: hangi maliyeti düşürdüğünü söylemeden seçilmiş bir aralık, ölçülmüş sayılmaz.

Özet

  • Çok adımlı bir devirde yakalanmayan bir hata sonraki adımlara bulaşır; denetim noktası bu bulaşmayı kestiği yerdir ve tek ölçtüğü şey nerede durulduğudur.
  • Yakalanana kadar yayılan adım sayısı her adımda durulduğunda 1,00, sekiz adımda bir durulduğunda 5,64’tür; ikinci koşumda 1,00 ve 5,61.
  • Kaçan hata 1’den 21’e çıkar (ikinci koşumda 4’ten 16’ya), çünkü pencere büyüdükçe görme payı 0,95’ten 0,46’ya iner.
  • Yakalanan hata sayısı bir kalite ölçüsü değildir: aralık büyüdükçe düşer, çünkü kaçan hata işin kalanını sayılamaz kılar. Ölçülebilen tek şey teslim edilen doğru adımdır (478/480’e karşı 355/480).
  • Bedelin üç kalemi ayrışır: çağrı sayısı neredeyse sabittir (549 ile 598 arası), belirteç yüzde yirmi sekiz düşer, durma sayısı sekiz kat düşer. Sık durmanın asıl fiyatı insan bakışıdır.
  • Doğru adım başına belirteç iki koşumda da üç adımlık aralıkta en düşüktür (146,8 ve 144,9); en doğru aralık, en ucuz aralık ve en az durduran aralık üç ayrı satırdır.

Sonraki Adım

Bu derste denetim noktası bir yer olarak ele alındı ve görme payı tek bir sayıya sıkıştırıldı: duran insan hatayı bir olasılıkla görüyor, görmüyorsa hata tabana giriyor. O sayının içinde ne olduğu hiç açılmadı. Durakta tam olarak neye bakılıyor — kod koşuyor mu, doğru sonucu mu veriyor, var olmayan bir bağımlılığı mı çağırıyor, bağlama giren metinde ne taşındı. Denetim noktası koyuldu, ama neyin denetleneceği söylenmedi. Sonraki ders bu boşluğu doldurur ve görme payını bir varsayım olmaktan çıkarıp ölçülen bir sayıya çevirir: birbirinden bağımsız denetimler aynı üretilmiş kod üzerinde koşturulur, her birinin yakaladığı kusur ayrı sayılır ve hiçbirinin yakalamadığı kalıntı adıyla yazılır.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat