Ders 01 / 26
Mesaj Tabanlı Arayüzler
Konuşma durumunun istemcide taşınmasının belirteç bedeli: sekiz turluk bir görüşmede toplam gönderilen giriş belirteci son turun 3,96 katıdır, çünkü her tur bütün dökümü yeniden gönderir. Kırk kurgu görüşmede beş gönderim kararı yan yana ölçülür: durum göndermeyen istemci 8346 giriş belirteciyle 0,2000 isabet, tam döküm 31160 ile 0,8250, son üç tur 23102 ile 0,4500, yalnız kullanıcı sıraları 19738 ile 0,6750, çıkarılmış durum kaydı 10474 ile 0,6500. Doğru etiket başına belirteç okuması sıralamayı değiştirir: son üç tur 1413,8 ile hiçbir şey yapmayan istemciden pahalıdır, çıkarılmış durum kaydı 494,9 ile en ucuzudur. İki koşum farkı 0,1250'dir, bu yüzden durum kaydı ile yalnız kullanıcı arasındaki 0,0250 fark ölçülmemiş sayılır.
İçindekiler
İstem Mühendisliği kursu yirmi iki derste istemi bir tasarım nesnesine dönüştürdü ve her değişikliğin bedelini belirteçle yazdı. Her satırında sessiz bir varsayım vardı: çağrı tek başına, hemen ve hatasız gerçekleşiyordu.
Bir uygulamanın içinde bu varsayımın hiçbiri durmaz. Çağrı bir ağ üzerinden gider, sıraya girer, reddedilir, yarıda kesilir ve her seferinde para yerine belirteç harcar. Bu kursun kuralı budur: bir model çağrısı bir işlev çağrısı değil bir ağ işlemidir; başarısızlığı yazılmayan çağrı ölçülmemiş sayılır. İlk ders arayüzün en temel özelliğinden başlar. Mesaj tabanlı bir arayüzde konuşma durumu sunucuda tutulmaz; döküm istemcidedir ve her istekte yeniden gönderilir. Bu ders o yeniden gönderimin ne tuttuğunu ve beş gönderim kararının onu kaça indirdiğini sayar.
- AK1. Kod bir benzeticidir; gerçek bir model uç noktası çağrılmaz. Görüşmeler, talep metinleri ve etiket kümesi kurgudur, tohum 20260218.
- AK2. Benzetici ağ davranışı da taşır: hız sınırı reddi (her otuz yedinci çağrı), bağlam penceresi aşımı, zaman aşımı ve yanıtın yarıda kesilmesi. Eşikler kurgudur; ölçülen şey eşiğin değeri değil, istemcinin karşılığıdır.
- AK3. Arayüz üç rol tanır: sistem, kullanıcı ve model. Rol adları da belirteç eder.
- AK4. Konuşma durumu sunucuda tutulmaz. Döküm istemcide durur; her istekte neyin gönderileceği bir istemci kararıdır ve bu derste beş karar ölçülür.
- AK5. Gecikme ham süre olarak değil adım olarak yazılır: ilk parça adımı girişe, toplam adım çıkışa bağlıdır. Bir görüşme sekiz ardışık çağrıdır; gecikme sınıfı zincirdir.
- AK6. Kurgu görüşme sekiz turdur. Konuyu belirleyen anahtar tur ikinci ile altıncı arasındadır; kalan turlar dolgudur ve dördü yanıltıcı sözcük taşır.
- AK7. Ölçüt son turda verilen etikettir. Reddedilen, zaman aşımına uğrayan ya da etiketi tamamlanmayan çağrı yanlış sayılır.
- AK8. Bedel giriş belirteci, çıkış belirteci, adım ve başarısızlık payı; çağrı sayısı beş kipte de 320’dir.
Mesaj Tabanlı Arayüz ve Ağ Davranışlı Benzetici
Kaynak düzeni, sürümleme, hata yanıtı biçimi ve sözleşme API Tasarımı ve Belgelendirme kursunda ölçüldü; o yordam tekrarlanmaz. Mesaj tabanlı arayüzün eklediği tek şey gövdenin şeklidir: istek bir alan kümesi değil, rol ve içerik çiftlerinden oluşan bir listedir.
# BENZETICI -- KURGUDUR. Gercek bir uc nokta cagrilmaz; ag katmani da benzeticide: # hiz siniri reddi, yarida kesilme, parca parca uretim. TOHUM, M32 = 20260218, 0xFFFFFFFF PENCERE, EN_UZUN, HIZ = 240, 24, 37 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 parcala(m): """KURGU belirtecleyici; parca en cok bes damga.""" b = [] for s in m.lower().replace(",", " , ").split(): yeni = True while len(s) > 5: b.append((s[:5], yeni)) s, yeni = s[5:], False b.append((s, yeni)) return b def belirtecle(m): return [p for p, _ in parcala(m)] def birlestir(pl): """Parcalari sozcuge geri baglar.""" s = "" for p, yeni in pl: s += (" " if yeni and s else "") + p return s def izno(m): h = 2166136261 for c in m: h = ((h ^ ord(c)) * 16777619) & M32 return h def cekilis(istem, tohum, tuz): return uretec((tohum + tuz) ^ izno(istem))() KONU = ["fatura", "ariza", "sayac", "tarife", "kesinti"] KAVRAM = KONU + ["odeme", "sikayet", "bilgi", "genel"] IZ = {"fatur": "fatura", "tutar": "fatura", "ayrin": "fatura", "borc": "fatura", "ariza": "ariza", "bozuk": "ariza", "calis": "ariza", "akmiy": "ariza", "sayac": "sayac", "endek": "sayac", "okuma": "sayac", "rande": "sayac", "tarif": "tarife", "birim": "tarife", "abone": "tarife", "basam": "tarife", "kesin": "kesinti", "duyur": "kesinti", "mahal": "kesinti", "odeme": "odeme", "sikay": "sikayet", "bilgi": "bilgi"} TUZAK = {"degis": "tarife", "kayit": "ariza", "ekip": "kesinti", "takip": "tarife"} KABUL = ["talebinizi aldim ve kaydi guncelledim", # etiket istenmediginde "ilgili ekibe ilettim donus yapilacak", "kaydinizi kontrol ediyorum lutfen bekleyin"] SAYAC = [0] def duzlestir(mesajlar): """Rol etiketleri de belirtec eder.""" return " ".join(f"{r} : {i}" for r, i in mesajlar) def cagir(mesajlar, tohum=TOHUM, sicaklik=0.6, en_uzun=EN_UZUN): """Mesaj tabanli arayuz. mesajlar: [(rol, icerik)], rol sistem|kullanici|model.""" SAYAC[0] += 1 istem = duzlestir(mesajlar) bel = belirtecle(istem) ilk = 1 + len(bel) // 40 # ilk parcaya kadar gecen adim bos = {"giris": len(bel), "cikis": 0, "yanit": "", "ilk": ilk, "adim": ilk} if len(bel) > PENCERE: return dict(bos, durum="baglam_asimi") if SAYAC[0] % HIZ == 0: # hiz siniri cagri sayisinda 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] if len(aday) < 3: # etiket kumesi adayi daraltir aday = list(KAVRAM) p = {k: 0.15 for k in aday} for t in bel: for tablo, w in ((IZ, 1.0), (TUZAK, 0.6)): if tablo.get(t) in p: p[tablo[t]] += w ad = sorted(p) if sicaklik <= 0.0: k = max(ad, key=lambda a: p[a]) else: from math import exp e = [exp(p[a] / sicaklik) for a in ad] k = ad[ayrik(r(), [x / sum(e) for x in e])] c = cekilis(istem, tohum, 17) if "tek" in bel: # yalniz etiket istendi metin = k else: metin = KABUL[ayrik(c, [0.40, 0.33, 0.27])] pl, durum = parcala(metin), "tamam" if len(pl) > en_uzun: # durdurma kosulu pl, durum = pl[:en_uzun], "durduruldu" u = cekilis(istem, tohum, 91) # ag yaniti yarida keser if len(pl) > 3 and u < 0.08: pl, durum = pl[:1 + int(u / 0.08 * (len(pl) - 1))], "kesildi" return {"durum": durum, "giris": len(bel), "cikis": len(pl), "yanit": birlestir(pl), "ilk": ilk, "adim": ilk + len(pl)} def oku(y): return next((s for s in y.split() if s in KONU), None) ACILIS = ["merhaba yardim gerekiyor", "iyi gunler destek istiyorum", "selam bir sorunum var", "merhaba destek almak istiyorum"] ANAHTAR = {"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"]} DOLGU = ["tesekkur ederim not aldim", "peki bunun icin ne kadar beklemem gerekir", "daha once de ayni durum olmustu", "yazili bir bildirim alabilir miyim", "bu konuda kayit acildi mi", "degisiklik yapilirsa haber verilir mi", "ekip ne zaman gelir", "hafta sonu da ulasabilir miyim"] SISTEM = ("sistem", "destek yardimcisisin . kisa yanit ver .") SORU = ("gorusme {n} konusunu su etiketlerden birine ata : fatura , ariza , " "sayac , tarife , kesinti . tek etiket yaz") GORUSME = [] for i in range(40): # 40 KURGU gorusme, sekizer tur r = uretec(TOHUM + 7 * i) k = KONU[ayrik(r(), [0.24, 0.22, 0.18, 0.20, 0.16])] anahtar = ANAHTAR[k][int(r() * 3)] yeri = 1 + int(r() * 5) # anahtar tur ikiden altiya tur = [ACILIS[int(r() * 4)]] for t in range(1, 7): tur.append(anahtar if t == yeri else DOLGU[int(r() * 8)]) tur.append(SORU.format(n=7301 + i)) GORUSME.append({"no": 7301 + i, "konu": k, "yeri": yeri + 1, "tur": tur}) g = GORUSME[0] print(f"gorusme {g['no']} -- konu {g['konu']} , anahtar tur {g['yeri']}") gecmis, satir = [SISTEM], [] for t, metin in enumerate(g["tur"], 1): gecmis.append(("kullanici", metin)) s = cagir(gecmis) satir.append(s["giris"]) if t in (1, g["yeri"], 8): print(f" tur {t} gonderilen {s['giris']:>3} cikis {s['cikis']:>2}" f" ilk parca {s['ilk']} {s['durum']:<6} -> {s['yanit'][:34]}") gecmis.append(("model", s["yanit"] or "-")) print(" tur basina gonderilen giris belirteci:", satir) print(f" toplam {sum(satir)} belirtec , son turun {sum(satir) / satir[-1]:.2f} kati") print(" ayni son tur tohum 20260219 ile ->", cagir(gecmis[:-1], TOHUM + 1)["yanit"])
gorusme 7301 -- konu kesinti , anahtar tur 5 tur 1 gonderilen 21 cikis 8 ilk parca 1 tamam -> talebinizi aldim ve kaydi guncelle tur 5 gonderilen 99 cikis 10 ilk parca 3 tamam -> kaydinizi kontrol ediyorum lutfen tur 8 gonderilen 187 cikis 2 ilk parca 5 tamam -> kesinti tur basina gonderilen giris belirteci: [21, 41, 53, 75, 99, 123, 142, 187] toplam 741 belirtec , son turun 3.96 kati ayni son tur tohum 20260219 ile -> kesinti
Kullanıcı sekiz kısa cümle yazdı, ama arayüze giden toplam 741 belirteçtir ve bu, son turun
tek başına ettiğinin 3,96 katıdır. Nedeni açıktır: her tur, kendinden önceki bütün turları
yeniden taşır. Tur uzunlukları yaklaşık eşitse turluk bir görüşmenin toplam gönderimi
ile büyür; tur sayısı ikiye katlandığında bedel dörde yaklaşır. İlk parça adımı da
1’den 5’e çıkıyor: uzayan durum yalnız pahalı değil, yavaştır. Son satırda aynı son tur ikinci
tohumla yine kesinti verdi; tek çağrıda çıktı sabit kaldı, ama aşağıdaki tablo bu sabitliğin
kırk görüşme ölçeğinde durmadığını gösterecek.
Beş Gönderim Kararı
Döküm istemcide olduğuna göre, her istekte hangi parçasının gönderileceği bir tasarım kararıdır. Beş karar aynı kırk görüşmede koşturulur: durum göndermemek, dökümün tamamı, son üç tur, yalnız kullanıcı sıraları, ve döküm yerine istemcide üretilmiş çıkarılmış bir durum kaydı. Sonuncunun çıkarıcısı yedi alan tanır ve tanımadığını sessizce düşürür.
ALAN = {"fatur": "fatura", "borc": "borc", "ariza": "ariza", "sayac": "sayac", "endek": "endeks", "tarif": "tarife", "kesin": "kesinti"} def durum_kaydi(gecmis): """Istemcide tutulan durum: dokum degil, alan listesi.""" a = [] for rol, icerik in gecmis: if rol == "kullanici": for t in belirtecle(icerik): if t in ALAN and ALAN[t] not in a: a.append(ALAN[t]) return " , ".join(a) if a else "yok" def gonder(kip, gecmis, simdi): """Dokumun hangi kisminin gonderilecegi karari.""" su = [("kullanici", simdi)] if kip == "durumsuz": return [SISTEM] + su if kip == "tam durum": return [SISTEM] + gecmis + su if kip == "son uc tur": return [SISTEM] + gecmis[-6:] + su if kip == "yalniz kullanici": return [SISTEM] + [m for m in gecmis if m[0] == "kullanici"] + su return [SISTEM, ("kullanici", "durum : " + durum_kaydi(gecmis))] + su def olc(kip, tohum=TOHUM): SAYAC[0] = 0 g = c = ad = dogru = basarisiz = 0 for gr in GORUSME: gecmis = [] for t, metin in enumerate(gr["tur"], 1): s = cagir(gonder(kip, gecmis, metin), tohum) g, c, ad = g + s["giris"], c + s["cikis"], ad + s["adim"] basarisiz += s["durum"] != "tamam" gecmis += [("kullanici", metin), ("model", s["yanit"] or "-")] if t == 8: dogru += oku(s["yanit"]) == gr["konu"] return g, c, ad, dogru, basarisiz / 320 KIP = ["durumsuz", "tam durum", "son uc tur", "yalniz kullanici", "durum kaydi"] print("kip giris cikis adim isabet A isabet B basarisiz" " dogru basina") for kip in KIP: a, b = olc(kip), olc(kip, TOHUM + 1) print(f"{kip:<17} {a[0]:>6} {a[1]:>6} {a[2]:>5} {a[3] / 40:>8.4f}" f" {b[3] / 40:>8.4f} {a[4]:>9.4f} {(a[0] + a[1]) / a[3]:>12.1f}") g0 = GORUSME[0] print("\ndurum kaydi , gorusme", g0["no"], ":", durum_kaydi([("kullanici", m) for m in g0["tur"][:7]])) bos = sum(durum_kaydi([("kullanici", m) for m in gr["tur"][:7]]) == "yok" for gr in GORUSME) print("cikarici hicbir alan bulamayan gorusme:", bos, "/ 40") gecmis, t = [], 0 while True: # tam durum penceresi nerede asiyor t += 1 metin = g0["tur"][t - 1] if t <= 7 else DOLGU[t % 8] s = cagir([SISTEM] + gecmis + [("kullanici", metin)]) if s["durum"] == "baglam_asimi": print(f"tam durum {t}. turda pencereyi asiyor: {s['giris']} > {PENCERE}") break gecmis += [("kullanici", metin), ("model", s["yanit"])]
kip giris cikis adim isabet A isabet B basarisiz dogru basina durumsuz 8346 2350 2710 0.2000 0.2500 0.0406 1337.0 tam durum 31160 2341 3294 0.8250 0.7000 0.0625 1015.2 son uc tur 23102 2347 3132 0.4500 0.4250 0.0844 1413.8 yalniz kullanici 19738 2297 2946 0.6750 0.7750 0.1000 816.1 durum kaydi 10474 2393 2753 0.6500 0.5500 0.0375 494.9 durum kaydi , gorusme 7301 : kesinti cikarici hicbir alan bulamayan gorusme: 5 / 40 tam durum 12. turda pencereyi asiyor: 246 > 240
İlk satır düzeneksiz istemcidir: durum taşınmadığında son tur yalnız etiket kümesini ve görüşme numarasını görür, isabet 0,2000 ile beş etiket arasından şans payıdır. İkinci satır aynı işi konuşma durumuyla yapar ve isabeti 0,8250‘ye çıkarır. Bedel giriş sütunundadır: **8346’dan 31160’a**, yani 3,73 kat. Adım 2710’dan 3294’e çıkıyor, çünkü uzayan istem ilk parçayı geciktiriyor; başarısızlık payı da 0,0406’dan 0,0625’e yükseliyor.
Ölçülen Kazanç, Ölçülmeyen Kazanç ve Sessiz Kayıp
Üç kısaltma kararı tabloyu ortadan böler. Son üç tur gönderimi girişi %26 azaltır ama isabeti 0,4500’e düşürür, çünkü anahtar tur çoğu görüşmede pencerenin dışında kalıyor. Yalnız kullanıcı sıraları girişi %37 azaltır ve isabeti 0,6750’de tutar; model kendi eski yanıtlarını görmediğinde bir şey kaybetmiyor. Çıkarılmış durum kaydı girişi %66 azaltır ve isabeti 0,6500’de tutar.
Son iki sayının farkı 0,0250’dir. İki koşum sütununa bakmak gerekiyor: tam durum satırı ikinci tohumda 0,8250 yerine 0,7000 veriyor, yani bu düzeneğin koşum farkı 0,1250’ye çıkabiliyor. 0,0250 bunun beşte biri kadardır ve ölçülmemiş sayılır; tam durum ile durum kaydı arasındaki 0,1750 ise koşum farkını aşar ve ölçülmüştür.
Son sütun sıralamayı değiştirir. Doğru etiket başına belirteç, son üç tur kipinde 1413,8’dir
ve bu, hiç durum göndermeyen istemcinin 1337,0’ından pahalıdır: bir kısaltma kararı hem
tam dökümün hem de düzeneksiz istemcinin altına düşebiliyor. Durum kaydı ise 494,9 ile en ucuz
doğru sonucu veriyor. Ucuzluğun bedeli çıkarıcının sessizliğidir: kırk görüşmenin beşinde
hiçbir alan bulunamıyor ve istemci bunu hata olarak değil yok diye bildiriyor. Son satır sınırı
söylüyor: görüşme sürdürülürse tam döküm on ikinci turda 246 belirteçle bağlam penceresini
aşıyor ve çağrı hiç kurulmuyor. Pencere aşımı Yapay Zekâ Mühendisliğine Giriş kursunda ölçüldü;
burada eklenen tek şey, o sınıra istemcinin kendi durum kararının sürüklediğidir.
Özet
- Konuşma durumu sunucuda tutulmaz; döküm her istekte yeniden gönderildiği için sekiz turluk bir görüşmenin toplam gönderimi son turun 3,96 katı olur.
- Durum taşınmadığında isabet 0,2000 ile şans düzeyinde kalır; döküm tümüyle gönderildiğinde 0,8250’ye çıkar ve giriş belirteci 3,73 kat artar.
- Son üç tur gönderimi girişi %26 azaltır ama isabeti 0,4500’e düşürür; anahtar tur çoğu görüşmede dışarıda kalır.
- Çıkarılmış durum kaydı girişi %66 azaltır ve isabeti 0,6500’de tutar; yalnız kullanıcı sıralarıyla arasındaki 0,0250 fark, iki koşum farkı 0,1250 olduğu için ölçülmemiş sayılır.
- Doğru etiket başına belirteç sıralamayı değiştirir: son üç tur 1413,8 ile düzeneksiz istemciden pahalı, durum kaydı 494,9 ile en ucuzdur.
- Ucuz kararın bedeli sessiz kayıptır: çıkarıcı kırk görüşmenin beşinde alan bulamıyor ve bunu hata olarak bildirmiyor.
Sonraki Adım
Bu derste her yanıt tek parça hâlinde geldi ve kullanıcı onun tamamlanmasını bekledi. Basılan ilk parça adımı hiçbir karara girmedi: uzayan istem ilk parçayı 1 adımdan 5 adıma iterken, beklenen süre yine son parçaya kadar uzadı. Yanıt bütün olarak değil de üretildiği sırayla elimize geçseydi hangi sayı değişir, hangisi aynı kalırdı. Bir de başarısızlık sütununda görünen kesilme var: yanıtın ortasında olduğunda geriye ne kalıyor. Sonraki ders bu üçünü ayrı ayrı sayar.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.