Ders 08 / 22
Araç Tanımı
Aracın adının, açıklamasının ve şemasının döngüye ne kattığının ölçülmesi: 24 kurgu görevde tanım dört düzeyde verilir ve yalnız ad verildiğinde 157 çağrının 113'ü araç hatasıyla döner, geçerli çağrı oranı 0,2803'te kalır, görev başarımı 0,3333 olur. Açıklama eklendiğinde hata 56'ya iner ve başarım 0,6667'ye çıkar. Şema eklendiğinde çağrı sayısı 74'e, hata 8'e düşer ve geçerli oran 0,8919 olur, ama başarım 0,7917'de durur: şema alan adlarını verir, hangi alanın hangi değeri taşıdığını vermez ve yer değiştiren iki endeks şemadan geçen bir çağrıyla 52 yerine 99948 döndürür. Örnek çağrı bu payı sıfırlar, başarımı 0,9583'e çıkarır ve adım, çağrı ile araç hatasını hiç değiştirmez; bedeli katalogun 97'den 164 belirtece büyümesidir ve doğru yanıt başına belirteç 1126'dan 1212'ye çıkar.
İçindekiler
Önceki yedi derste ajan döngüsü kuruldu: algı, akıl yürütme, eylem ve gözlem sırası, planlayıcı ile yürütücünün ayrılması, adım bütçesi, durdurma ölçütü, öz eleştiri turu, çoklu ajan düzeni ve yan etkili araçta onay noktası. Hepsinde bir şey sessizce varsayıldı: araç hazır ve doğruydu.
Bu ders o varsayımı kaldırır: aracın tanımı döngüye ne katıyor? Model API’leri ile Uygulama Geliştirme kursu tek bir çağrının biçimini ölçmüştü — katalog verilmediğinde geçerli çağrı oranı 0,0500, adlar ve parametreler birlikte verildiğinde 0,6917. O ölçüm bir metnin ayrıştırılması üzerineydi ve tekrarlanmaz; sayılar girdi alınır. Buradaki çağrı bir işlev sınırından geçer ve ölçülen şey tanımın döngü boyunca kattığıdır.
- AB1. Ortam, araç kümesi, görev kümesi ve ajan döngüsü kurgudur; gerçek bir model uç noktası, araç sunucusu ya da çalışma zamanı çağrılmaz. 60 kurgu abone, 5 kurgu belge, 5 araç ve bilinen bir araç dizisiyle çözülen 24 görev. Tohum 20260218, ikinci koşum 20260219.
- AB2. Araç tanımı dört düzeyde verilir: yalnız ad; ad ve açıklama; ad, açıklama ve şema; şema ve örnek çağrı. Her düzey bir öncekini kapsar.
- AB3. Tanım iki şeyi belirler: doğru aracı seçme payının çarpanını ve bildirilen her alanın doldurulma payını. Ad zayıf bir imdir; açıklama aracın ne yaptığını, şema hangi alanları istediğini söyler.
- AB4. Şema alan adlarını verir, alanların hangi değeri taşıdığını vermez. Aynı türden iki
alan (
oncekivesimdiki) 0,30 payla yer değiştirir; örnek çağrı bu payı sıfırlar. - AB5. Araç hatası aracın kendi döndürdüğü hatadır: eksik alan ya da olmayan araç. Şema dışındaki alanlar çağrı sınırında süzülür; geçerli çağrı, hata döndürmeyendir.
- AB6. Katalog her adımda istemde durur; bedeli düzeyin belirteç sayısıdır.
- AB7. Taban çizgisi yalnız ad düzeyidir; düzeneksiz döngü budur. Adım bütçesi dört düzeyde de sekizdir.
- AB8. Görev başarımı, döngünün bıraktığı sonucun doğru yanıta eşit olmasıdır; ajanın kendi kendine durup durmadığından bağımsızdır.
Tanımın Dört Düzeyi
Aşağıdaki kod ortamı, araç kümesini, görev kümesini ve ajan döngüsünü kurar, sonra döngünün üzerine tanım katmanını ekler. Çağrı sınırı şema dışı alanları yine süzer, fakat bildirilen bir alanın doldurulup doldurulmadığı artık tanımın düzeyine bağlıdır.
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) # ---- 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 ACIKLAMA = { "sayac_oku": "abonenin onceki ve simdiki sayac endeksini dondurur", "tuketim": "iki endeks arasindaki farki metrekup olarak verir", "tarife": "metrekup ve abone tipinden donem bedelini hesaplar", "belge_ara": "anahtar metne en yakin kurgu belgeyi getirir", "kayit_yaz": "bir abonenin bir sutununa deger yazar ; yan etkilidir"} ORNEK = {"sayac_oku": "sayac_oku ( abone = A007 )", "tuketim": "tuketim ( onceki = 41200 , simdiki = 41255 )", "tarife": "tarife ( m3 = 55 , tip = mesken )", "belge_ara": "belge_ara ( anahtar = endeks farki )", "kayit_yaz": "kayit_yaz ( abone = A007 , sutun = bedel , deger = 470 )"} # duzey : ad , secim carpani , alan doldurma payi , yer degistirme payi TANIM = {1: ("yalniz ad", 0.62, 0.45, 0.30), 2: ("ad + aciklama", 0.86, 0.72, 0.30), 3: ("ad + aciklama + sema", 1.00, 1.00, 0.30), 4: ("sema + ornek cagri", 1.00, 1.00, 0.00)} def katalog(duzey, ad): s = ad if duzey >= 2: s += " : " + ACIKLAMA[ad] if duzey >= 3: s += " ( " + " , ".join(ARAC[ad]["alan"]) + " )" if duzey >= 4: s += " ornek : " + ORNEK[ad] return s TANIM_BEL = {d: sum(len(belirtecle(katalog(d, a))) for a in ARAC) for d in TANIM} def cagir_tanimli(ad, durum, duzey, rt): """Ortak cagri sinirinin tanim katmanli hali: bildirilen alanin doldurulup doldurulmadigi tanimin duzeyine baglidir.""" CAGRI[0] += 1 if ad not in ARAC: return {"hata": "arac yok"} _, _, pay, karis = TANIM[duzey] kw = {a: durum[a] for a in ARAC[ad]["alan"] if a in durum and rt() < pay} if {"onceki", "simdiki"} <= set(kw) and rt() < karis: kw["onceki"], kw["simdiki"] = kw["simdiki"], kw["onceki"] return ARAC[ad]["islev"](**kw) def ajan_tanim(g, duzey=4, en_cok_adim=8, tohum=TOHUM): """Ortak ajan dongusu; tek fark cagrinin tanim katmanindan gecmesi ve katalogun her adimda istemde durmasi.""" r = uretec(tohum ^ izno(g["ad"])) rt = uretec(tohum ^ izno(g["ad"] + "tanim")) carpan = TANIM[duzey][1] alan = {"abone": g["abone"], "anahtar": g["istek"], "sutun": "bedel"} iz, adim, bel, hata, yabanci = [], 0, 0, 0, 0 dizi, k = g["dizi"], 0 while adim < en_cok_adim: adim += 1 bel += 60 + 22 * len(iz) + TANIM_BEL[duzey] hedef = dizi[k] if k < len(dizi) else None if hedef is None: if r() < 0.88: break sec = ARAC_ADI[int(r() * len(ARAC_ADI))] else: sec = hedef if r() < gorme(k + 1) * carpan else ARAC_ADI[int(r() * len(ARAC_ADI))] if sec == "kayit_yaz": alan["deger"] = alan.get("sonuc") s = cagir_tanimli(sec, alan, duzey, rt) iz.append((sec, "hata" in s)) bel += 30 if "hata" in s: hata += 1 continue yabanci += sec not in dizi 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 {"adim": adim, "belirtec": bel, "hata": hata, "yabanci": yabanci, "yanit": alan.get("sonuc")} for d in TANIM: print(f"duzey {d} {TANIM[d][0]:<20} katalog {TANIM_BEL[d]:>3} belirtec") print(" duzey 3 satiri :", katalog(3, "tuketim")) print(" duzey 4 eki : ornek :", ORNEK["tuketim"]) g = GOREV[2] for d in (3, 4): s = ajan_tanim(g, d) print(f" {g['ad']} {g['tur']:<8} duzey {d} yanit {s['yanit']:>6} dogru" f" {dogru_yanit(g)} arac hatasi {s['hata']}")
duzey 1 yalniz ad katalog 10 belirtec duzey 2 ad + aciklama katalog 71 belirtec duzey 3 ad + aciklama + sema katalog 97 belirtec duzey 4 sema + ornek cagri katalog 164 belirtec duzey 3 satiri : tuketim : iki endeks arasindaki farki metrekup olarak verir ( onceki , simdiki ) duzey 4 eki : ornek : tuketim ( onceki = 41200 , simdiki = 41255 ) G03 tuketim duzey 3 yanit 99948 dogru 52 arac hatasi 1 G03 tuketim duzey 4 yanit 52 dogru 52 arac hatasi 1
Son iki satır bu dersin çekirdeğidir. Aynı görev, aynı tohum, aynı araç dizisi ve aynı sayıda
araç hatası. Üçüncü düzeyde ajan tuketim aracını şemanın bildirdiği iki alanla çağırdı, çağrı
şemadan geçti, araç hata döndürmedi — ve sonuç 52 yerine 99948 çıktı. Şema onceki ile simdiki
adlarını bildiriyor, hangisinin küçük olduğunu bildirmiyor. Alanlar yer değiştirdiğinde fark eksiye
düşüyor, sayaç dönüşü kuralı devreye giriyor ve araç yüz bine yakın bir tüketim döndürüyor. Bu çağrı
geçerlidir ve yanlıştır.
Dört Düzeyin Sayıları
Aynı 24 kurgu görev dört tanım düzeyinde koşturulur; başarım iki tohumla ayrı ayrı basılır.
def olc(duzey, tohum=TOHUM): CAGRI[0] = 0 ok = adim = bel = hata = yab = 0 for g in GOREV: s = ajan_tanim(g, duzey, tohum=tohum) ok += s["yanit"] == dogru_yanit(g) adim += s["adim"] bel += s["belirtec"] hata += s["hata"] yab += s["yabanci"] return ok / len(GOREV), CAGRI[0], hata, yab, adim, bel print("tanim duzeyi cagri hata gecerli basarim A basarim B adim" " belirtec yanit basina") for d in TANIM: a, b = olc(d), olc(d, TOHUM + 1) print(f"{TANIM[d][0]:<20} {a[1]:>6} {a[2]:>5} {(a[1] - a[2]) / a[1]:>7.4f}" f" {a[0]:>9.4f} {b[0]:>9.4f} {a[4]:>4} {a[5]:>8} {a[5] / (a[0] * 24):>12.0f}") a = olc(4) print(f"en yuksek duzey : gecerli {a[1] - a[2]} cagrinin {a[3]} tanesi gorevin" f" dizisinde olmayan bir araci cagiriyor")
tanim duzeyi cagri hata gecerli basarim A basarim B adim belirtec yanit basina yalniz ad 157 113 0.2803 0.3333 0.4167 167 27950 3494 ad + aciklama 111 56 0.4955 0.6667 0.5833 129 27489 1718 ad + aciklama + sema 74 8 0.8919 0.7917 0.7917 97 21387 1126 sema + ornek cagri 74 8 0.8919 0.9583 0.9583 97 27886 1212 en yuksek duzey : gecerli 66 cagrinin 8 tanesi gorevin dizisinde olmayan bir araci cagiriyor
Taban çizgisi ilk satırdır: yalnız ad bilindiğinde 157 çağrının 113’ü araç hatasıyla dönüyor, geçerli çağrı oranı 0,2803, başarım 0,3333. Hataların çoğu eksik alandır. Ad, aracın ne istediğini söylemez; ajan elindeki durumdan hangi anahtarı geçireceğini bilemez. Bedeli adım sütununda görünür: bütçe sekiz olduğu halde toplam adım 167, görev başına yedinin üstünde. Hatalı çağrı adımı harcar ve diziyi ilerletmez.
Açıklama eklendiğinde hata 56’ya, çağrı 111’e iniyor, başarım 0,6667 oluyor. Açıklama iki iş yapar: doğru aracı seçme payını yükseltir ve alanların hangi bilgiyi istediğini ima eder. Şema eklendiğinde çağrı 74’e, hata 8’e düşüyor, geçerli oran 0,8919 oluyor ve adım 97’ye iniyor. Kalan sekiz hata şemayla ilgili değildir: yanlış seçilen bir aracın kendi ön koşulu tutmaz.
Şemanın Söylemediği
Üçüncü ve dördüncü satır aynı çağrıyı, aynı hatayı ve aynı adımı taşıyor; başarımları 0,7917 ile 0,9583 olarak ayrışıyor. Aradaki 0,1666, örnek çağrının kattığıdır ve döngüye tek bir adım eklemeden gelir. İki koşum farkı ilk iki düzeyde 0,0834, son iki düzeyde sıfırdır; 0,1666 bu bandın iki katının üstündedir ve ölçülmüş sayılır. Örnek çağrı, şemanın veremediği tek bilgiyi verir: alanın hangi değeri taşıdığını.
Bedel belirteç sütunundadır. Katalog 97 belirteçten 164 belirtece büyür ve her adımda istemde durduğu için toplam belirteç 21387’den 27886’ya çıkar. Doğru yanıt başına belirteç ise 1126’dan 1212’ye yükselir: örnek çağrı başarımı yükseltirken bu ölçekte birim maliyeti de yükseltiyor. Bedeli yazılmayan düzenek ölçülmemiş sayılır; buradaki bedel altmış yedi belirteçtir.
Son satır şemanın en dıştaki sınırıdır. En yüksek düzeyde bile geçerli 66 çağrının sekizi görevin dizisinde olmayan bir aracı çağırıyor. Model API’leri kursunda aynı kalıntı ondört yanlış araç adıydı; orada çağrı bir metindi, burada bir işlev sınırından geçti ve araç düzgün çalıştı. Bir tanım neyin çağrılabileceğini söyler, neyin çağrılması gerektiğini söylemez.
Özet
- Araç tanımı dört düzeye ayrılır: yalnız ad, ad ve açıklama, şema, şema ve örnek çağrı.
- Yalnız ad verildiğinde 157 çağrının 113’ü araç hatasıyla döner, geçerli oran 0,2803, başarım 0,3333’tür; hatalı çağrı adım harcar ve toplam adımı 167’ye çıkarır.
- Açıklama hatayı 56’ya, şema 8’e indirir; şemayla çağrı 74’e, adım 97’ye iner, geçerli oran 0,8919 olur.
- Şema alan adlarını verir, alanın hangi değeri taşıdığını vermez: yer değiştiren iki endeks şemadan geçen bir çağrıyla 52 yerine 99948 döndürür.
- Örnek çağrı başarımı 0,7917’den 0,9583’e çıkarır ve adımı, çağrıyı, hatayı hiç değiştirmez; bedeli katalogun 164 belirtece büyümesi ve yanıt başına belirtecin 1126’dan 1212’ye çıkmasıdır.
- En yüksek düzeyde bile geçerli 66 çağrının sekizi görevin dizisinde olmayan aracı çağırır; geçerlilik doğruluk değildir.
Sonraki Adım
Bu derste araç çağrıldı ve döndürdüğü sözlük olduğu gibi duruma yazıldı; her alan bir sonraki adıma taşındı ve her adımda istemde yeniden durdu. Belirteç sütununun görev başına bin belirtecin üstüne çıkmasının bir nedeni budur. Sonucu olduğu gibi taşımak tek seçenek değildir: kırpılabilir, özetlenebilir, yalnız gereken alan bırakılabilir. Her biri belirteci düşürür ve bir şeyi düşürme riski taşır. Sonraki ders sonucun modele hangi biçimde geri verildiğini ölçer ve başarımı döngü boyunca biriken belirteçle yan yana basar.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.