Ders 01 / 11
Model Bağlam Protokolü Nedir
Araç tanımının çağıran tarafın kodundan çıkıp bir sunucuya taşınmasının sayılması: üç kurgu sunucu beş araç bildirir, istemcinin izin listesi dört araç taşır ve yetenek uzlaşması sonrası anlaşılan küme üç araçta kalır. Aynı üç araçlık zincir protokolsüz tabanda 844 sonucunu sıfır mesaj, sıfır zarf belirteci ve sıfır gidiş-dönüşle üretir; protokollü kurulumda aynı 844 için 6 istek, 6 yanıt, 179 zarf belirteci ve 9 gidiş-dönüş ödenir. Bağlantıyı kurmak işi yapmaktan pahalıdır: el sıkışması 99 belirteç, zincirin kendisi 80 belirteç tutar ve el sıkışmasının 2 mesajı ile 2 gidiş-dönüşü hiçbir araç kazandırmayan bir sunucuya gider. Karşılığında kazanılan taşınabilirlik de sayılır: dört istemcide protokolsüz kurulum 20 araç tanımı yazdırır ve arayüz değiştiğinde dört yeri kırar, protokollü kurulum 5 tanımı tek yerde tutar ve karşılığında istemci başına 6 mesaj ile 99 zarf belirteci ister.
İçindekiler
Yapay Zekâ Ajanları kursu yirmi iki derste bir ajanı kurdu, donattı ve ölçtü: algı ile eylemin sırası, planlayıcı ile yürütücünün ayrılması, adım bütçesi, durdurma ölçütü, araç tanımının dört düzeyi, bellek, yetki yüzeyi ve değerlendirme. Hepsinde bir şey sessizce varsayıldı: her araç ders içinde elle tanımlandı. Tanım da yürütme de aynı elin altındaydı; aracın adı, şeması ve örnek çağrısı ajanın kodunun yanı başında duruyordu.
Bu ders o varsayımı kaldırır ve üç soru sorar: aynı araç başka bir ajana, başka bir ekibe ya da başka bir uygulamaya nasıl verilir, tanım kimin elinde durur ve arayüz değiştiğinde kim kırılır. Model bağlam protokolü bu üç sorunun ortak yanıtıdır: araç tanımını çağıran tarafın kodundan çıkarır, karşı tarafa bir sunucuya taşır ve arayı sabit bir mesaj düzeniyle bağlar. Kazanç taşınabilirliktir. Bedeli ise sayılabilir: her mesajın bir zarfı, her uzak isteğin bir gidiş-dönüşü vardır. Bu ders ikisini yan yana koyar.
- PY1. Ortam, üç sunucu ve protokol benzeticisi kurgudur; gerçek bir sunucu, istemci kitaplığı ya da çalışma zamanı çağrılmaz. 60 kurgu abone, üç kurgu sunucu, beş bildirilen araç. Tohum 20260218.
- PY2. Benzetici protokolün kendisini uygulamaz; sözleşmenin gözlenebilir kalemlerini sayar: istek, yanıt, bildirim, zarf belirteci ve gidiş-dönüş.
- PY3. Zarfın sabit bedeli sekiz belirteçtir; gövdenin belirteçleri bunun üstüne eklenir.
- PY4. Taban çizgisi protokolsüz kurulumdur: araç çağıran tarafın içinde tanımlıdır, el sıkışması yoktur, zarf sayılmaz. Yapay Zekâ Ajanları kursunun bütün ölçümleri bu tabandaydı.
- PY5. Yerel aktarımda bir istek bir, uzak aktarımda iki gidiş-dönüş sayılır.
- PY6. Yetenek uzlaşması her sunucuya bir istek gönderip bir yanıt alır. Sürüm uyuşmazlığında sunucunun tamamı düşer; izin listesi dışındaki araç alınmaz.
- PY7. Küme küçüktür: sunucu üç, bildirilen araç beş, izin listesi dört. Bu kümede oran basan bir ölçünün en küçük adımı ’dir ve bundan küçük fark ölçülemez. Bu ders oran yerine sayım basar.
- PY8. Sayımlar koşumdan bağımsızdır; benzeticide belirsiz bir bileşen yoktur. İkinci koşum aynı zinciri başka bir abone için çalıştırır.
- PY9. Aracın kendi doğruluğu Yapay Zekâ Ajanları kursunda ölçüldü ve tekrarlanmaz; şema eklendiğinde geçerli çağrı oranının 0,2803’ten 0,8919’a çıktığı oradan girdi alınır. Burada ölçülen şey tanımın yerinin bedelidir.
Üç Rol ve Kurgu Ortam
Protokolün tanımladığı üçlü kursun sonuna kadar sürer. Barındırıcı, kullanıcıyla ve dil modeliyle konuşan uygulamadır: bağlamı tutar, izin listesini taşır, yan etkili bir çağrıda onayı ister. İstemci barındırıcının içinde yaşar ve sunucu başına bir tanedir: oturumu kurar, yetenek uzlaşmasını yürütür, mesajları zarflar. Sunucu araç tanımını, o tanımın arkasındaki işleyiciyi, varsa kaynak ve istem yeteneklerini barındırır; barındırıcıyı hiç görmez, yalnız istemciyle konuşur.
Yapay Zekâ Ajanları kursunda bu üç rol tek bir dosyaydı. Aşağıdaki kod aynı ölçüm ağı kurgusunu
alır ve araçları üç ayrı kurgu sunucuya dağıtır: olcum sayaç okur ve tüketim hesaplar, tarife
bedeli çıkarır, kayit bölge özeti verir ve kayıt yazar. Her sunucunun bir sürümü ve bir
aktarım biçimi vardır. mesaj her istek, yanıt ve bildirimi sayan kurgu zarftı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 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 # ---- KURGU ortam: olcum aginin abone 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, ISYERI_KAT = ((10, 4), (25, 7), (40, 11)), 16, 2 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 return (top + kalan * USTU) * (ISYERI_KAT if tip == "isyeri" else 1) def t_sayac(abone=None, **_): a = ABONE.get(abone) return {"hata": "abone yok"} if a is None else { "onceki": a["onceki"], "simdiki": a["simdiki"], "tip": a["tip"]} 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", **_): return {"hata": "eksik alan"} if m3 is None else {"tutar": _bedel(m3, tip)} def t_bolge(bolge=None, **_): if bolge not in BOLGE: return {"hata": "bolge yok"} n = sum(1 for a in ABONE.values() if a["bolge"] == bolge) return {"bolge": bolge, "abone": n} 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} # ---- KURGU sunucular: her biri yetenek bildirir SUNUCU = { "olcum": {"surum": 2, "aktarim": "yerel", "arac": {"sayac_oku": {"islev": t_sayac, "alan": ("abone",), "yan_etki": False}, "tuketim": {"islev": t_tuketim, "alan": ("onceki", "simdiki"), "yan_etki": False}}, "kaynak": ("abone_listesi",), "istem": ()}, "tarife": {"surum": 1, "aktarim": "uzak", "arac": {"tarife": {"islev": t_tarife, "alan": ("m3", "tip"), "yan_etki": False}}, "kaynak": ("basamak_tablosu",), "istem": ("bedel_aciklamasi",)}, "kayit": {"surum": 3, "aktarim": "uzak", "arac": {"bolge_ozet": {"islev": t_bolge, "alan": ("bolge",), "yan_etki": False}, "kayit_yaz": {"islev": t_kayit, "alan": ("abone", "sutun", "deger"), "yan_etki": True}}, "kaynak": (), "istem": ()}, } ISTEMCI_SURUM = {"olcum": 2, "tarife": 1, "kayit": 2} # kayit sunucusu ileride IZIN = ("sayac_oku", "tuketim", "tarife", "bolge_ozet") # kayit_yaz izin listesinde yok SAYIM = {"istek": 0, "yanit": 0, "bildirim": 0, "belirtec": 0, "gidis_donus": 0} def mesaj(tur, govde, aktarim="yerel"): """KURGU zarf. Gercek bir protokol uygulanmaz; sayilan sey zarfin bedelidir.""" SAYIM[tur] += 1 b = len(belirtecle(govde)) + 8 # zarf sabiti SAYIM["belirtec"] += b if tur == "istek": SAYIM["gidis_donus"] += 2 if aktarim == "uzak" else 1 return b def elsikismasi(istemci_surum=None, izin=None): """Yetenek uzlasmasi: surum uyusmazligi ve izin listesi arac kumesini daraltir.""" istemci_surum = ISTEMCI_SURUM if istemci_surum is None else istemci_surum izin = IZIN if izin is None else izin anlasilan, dusen = {}, [] for ad, s in SUNUCU.items(): mesaj("istek", f"yetenek sor {ad}", s["aktarim"]) mesaj("yanit", f"yetenek bildir {ad} surum {s['surum']} " + " ".join(s["arac"]) + " " + " ".join(s["kaynak"])) if istemci_surum.get(ad, 0) < s["surum"]: dusen.append((ad, "surum", s["surum"], istemci_surum.get(ad, 0))) continue for t, tan in s["arac"].items(): if t not in izin: dusen.append((ad, "izin", t, None)) continue anlasilan[t] = dict(tan, sunucu=ad, aktarim=s["aktarim"]) return anlasilan, dusen def cagir(anlasilan, ad, durum): if ad not in anlasilan: return {"hata": "arac bildirilmedi"} t = anlasilan[ad] kw = {a: durum[a] for a in t["alan"] if a in durum} mesaj("istek", f"{ad} " + " ".join(f"{k} {v}" for k, v in kw.items()), t["aktarim"]) s = t["islev"](**kw) mesaj("yanit", " ".join(f"{k} {v}" for k, v in s.items())) return s print("sunucu surum aktarim arac kaynak istem") for ad, s in SUNUCU.items(): print(f"{ad:<8} {s['surum']:>5} {s['aktarim']:<7} {', '.join(s['arac']):<23}" f" {len(s['kaynak']):>6} {len(s['istem']):>6}") print(f"bildirilen arac {sum(len(s['arac']) for s in SUNUCU.values())}" f" izin listesi {len(IZIN)} istemcinin bildigi surum {ISTEMCI_SURUM}")
sunucu surum aktarim arac kaynak istem
olcum 2 yerel sayac_oku, tuketim 1 0
tarife 1 uzak tarife 1 1
kayit 3 uzak bolge_ozet, kayit_yaz 0 0
bildirilen arac 5 izin listesi 4 istemcinin bildigi surum {'olcum': 2, 'tarife': 1, 'kayit': 2}
Bu tablo bir yetenek bildirimidir: her sunucu ne sunduğunu söyler. Beş araç bildiriliyor,
istemcinin izin listesi dördünü tanıyor ve kayit sunucusunun sürümü üç iken istemci iki
biliyor. Bildirilen şey ile kullanılabilecek şey aynı değildir; aradaki farkı yetenek uzlaşması
belirler.
Protokolsüz Taban ve Protokollü Kurulum
Ölçü için iki kurulum yan yana konur. protokolsuz işlevi araçları doğrudan çağırır: tanım aynı
dosyada olduğu için ne oturum kurulur ne mesaj sayılır. protokollu işlevi aynı işi protokol
üzerinden yapar: önce yetenek uzlaşması, sonra üç araçlık zincir. İkinci koşum aynı zinciri
başka bir abone için çalıştırır.
def protokolsuz(abone): """Taban cizgisi: arac ders icinde tanimli, el sikismasi yok, zarf sayilmiyor.""" a = t_sayac(abone=abone) m = t_tuketim(onceki=a["onceki"], simdiki=a["simdiki"]) return t_tarife(m3=m["m3"], tip=a["tip"])["tutar"] def protokollu(abone): """Ayni is, tanim karsi tarafta: once yetenek uzlasmasi, sonra zincir.""" for k in SAYIM: SAYIM[k] = 0 anlasilan, dusen = elsikismasi() el = dict(SAYIM) durum = {"abone": abone} for ad in ("sayac_oku", "tuketim", "tarife"): durum.update(cagir(anlasilan, ad, durum)) return durum["tutar"], anlasilan, dusen, el, dict(SAYIM) for abone in ("A017", "A031"): tutar, anlasilan, dusen, el, top = protokollu(abone) print(f"{abone} protokolsuz taban : sonuc {protokolsuz(abone):>4}" f" istek 0 yanit 0 zarf belirteci 0 gidis-donus 0") print(f"{abone} el sikismasi : istek {el['istek']} yanit {el['yanit']}" f" zarf belirteci {el['belirtec']} gidis-donus {el['gidis_donus']}") print(f"{abone} ucluk zincir : istek {top['istek'] - el['istek']}" f" yanit {top['yanit'] - el['yanit']}" f" zarf belirteci {top['belirtec'] - el['belirtec']}" f" gidis-donus {top['gidis_donus'] - el['gidis_donus']}") print(f"{abone} protokollu toplam : sonuc {tutar:>4} istek {top['istek']}" f" yanit {top['yanit']} zarf belirteci {top['belirtec']}" f" gidis-donus {top['gidis_donus']}") print("anlasilan arac", sorted(anlasilan), " dusen", dusen) print("izin listesinde olmayan arac :", cagir(anlasilan, "kayit_yaz", {"abone": "A017", "sutun": "bedel", "deger": 1}))
A017 protokolsuz taban : sonuc 844 istek 0 yanit 0 zarf belirteci 0 gidis-donus 0
A017 el sikismasi : istek 3 yanit 3 zarf belirteci 99 gidis-donus 5
A017 ucluk zincir : istek 3 yanit 3 zarf belirteci 80 gidis-donus 4
A017 protokollu toplam : sonuc 844 istek 6 yanit 6 zarf belirteci 179 gidis-donus 9
A031 protokolsuz taban : sonuc 89 istek 0 yanit 0 zarf belirteci 0 gidis-donus 0
A031 el sikismasi : istek 3 yanit 3 zarf belirteci 99 gidis-donus 5
A031 ucluk zincir : istek 3 yanit 3 zarf belirteci 80 gidis-donus 4
A031 protokollu toplam : sonuc 89 istek 6 yanit 6 zarf belirteci 179 gidis-donus 9
anlasilan arac ['sayac_oku', 'tarife', 'tuketim'] dusen [('kayit', 'surum', 3, 2)]
izin listesinde olmayan arac : {'hata': 'arac bildirilmedi'}
İki kurulum aynı sonucu veriyor: A017 için 844, A031 için 89. Hesap değişmedi, araçların kodu değişmedi, sıra değişmedi. Değişen tek şey tanımın nerede durduğu ve bunun bedeli dört sütunda yazılı: 6 istek, 6 yanıt, 179 zarf belirteci ve 9 gidiş-dönüş. Protokolsüz tabanda bu dört sayının hepsi sıfırdır.
Bedelin dağılımı beklenenin tersidir. İşi yapan üç çağrı 80 belirteç tutuyor, bağlantıyı kuran el sıkışması 99 belirteç; bağlantıyı kurmak işi yapmaktan 19 belirteç pahalı ve dokuz gidiş-dönüşün beşi orada harcanıyor. Nedeni el sıkışmasının her sunucuyla ayrı ayrı yapılmasıdır: zincir üç araç kullanıyor, uzlaşma üç sunucuyla konuşuyor.
İki koşum aynı sayıları veriyor. Bu bir tesadüf değil, zarfın ne ölçtüğünün sonucudur: mesajın gövdesi A017 ile A031 arasında değişiyor fakat belirteç sayısı aynı kalıyor, çünkü sayılan şey verinin kendisi değil sözleşmenin biçimidir. Bir araç bağlantısının sayısı aracın sayısı değil sözleşmenin sayısıdır; kursun kuralı budur ve on bir ders boyunca sürer.
Son iki satır ilk kayıptır. Uzlaşma sonrası anlaşılan küme üç araçtır, bildirilen ise beş.
dusen listesinde tek bir satır var: kayit sunucusu sürüm üç bildiriyor, istemci iki biliyor ve
sunucunun tamamı düşüyor. Bunun bedeli iki kez ödeniyor. Birincisi, kayit_yaz çağrıldığında
araç hiç yokmuş gibi davranılıyor. İkincisi ve daha sessiz olanı: el sıkışmasının 2 mesajı ve 2
gidiş-dönüşü hiçbir araç kazandırmayan bir sunucuya gitti. Uzlaşma bedeli, uzlaşma başarısız
olsa bile ödenir.
Taşınabilirliğin Sayısı
Ödenen bedelin karşılığı taşınabilirliktir ve o da sayılabilir. Ölçü şudur: aynı beş araç tanımı kaç yerde yazılır ve arayüz değiştiğinde kaç yer kırılır.
def tanim_metni(s): return " ".join(f"{a} ( {' , '.join(t['alan'])} )" for a, t in s["arac"].items()) TANIM_SATIR = sum(len(s["arac"]) for s in SUNUCU.values()) TANIM_BEL = sum(len(belirtecle(tanim_metni(s))) for s in SUNUCU.values()) for k in SAYIM: SAYIM[k] = 0 elsikismasi() EL_MESAJ, EL_BEL = SAYIM["istek"] + SAYIM["yanit"], SAYIM["belirtec"] print(f"bes arac tanimi {TANIM_SATIR} satir, {TANIM_BEL} belirtec;" f" bir oturumun el sikismasi {EL_MESAJ} mesaj, {EL_BEL} zarf belirteci") print("istemci protokolsuz: tanim kirilan yer protokollu: tanim kirilan yer" " mesaj zarf belirteci") for k in (1, 2, 3, 4): print(f"{k:>7} {k * TANIM_SATIR:>18} {k:>11} {TANIM_SATIR:>17} {0:>11}" f" {k * EL_MESAJ:>5} {k * EL_BEL:>14}")
bes arac tanimi 5 satir, 35 belirtec; bir oturumun el sikismasi 6 mesaj, 99 zarf belirteci
istemci protokolsuz: tanim kirilan yer protokollu: tanim kirilan yer mesaj zarf belirteci
1 5 1 5 0 6 99
2 10 2 5 0 12 198
3 15 3 5 0 18 297
4 20 4 5 0 24 396
Tek istemcide protokol hiçbir şey kazandırmıyor: tanım iki kurulumda da beş satır, kırılan yer iki kurulumda da bir tane — biri istemcide, öbürü sunucuda. Eklenen tek şey altı mesaj ve doksan dokuz belirteç. Bir araç tek bir uygulamada kullanılacaksa protokol saf bedeldir.
Fark istemci sayısıyla açılıyor. Dört istemcide protokolsüz kurulum 20 araç tanımı yazdırıyor
ve tuketim aracının alan adları değiştiğinde dört yeri kırıyor; protokollü kurulumda tanım
beş satır ve tek yerde duruyor, istemcilerde kırılacak bir şey yok. Karşılığında dört istemci
24 mesaj ve 396 zarf belirteci ödüyor: taşınabilirliğin oturum başına sabit bir bedeli vardır
ve bu bedel istemci sayısıyla doğrusal büyür.
“Kırılan yer” sütununun sıfır olması hata olmayacağı anlamına gelmez. kayit sunucusunun sürüm
sapması bunu göstermişti: istemcide düzeltilecek bir satır yoktu ve iki araç yine de kayboldu.
Değiştiğinde kimin kırılacağı yazılmayan bir arayüz ölçülmemiş sayılır; protokol o soruyu ortadan
kaldırmaz, yalnız tek bir yere taşır.
Özet
- Model bağlam protokolü üç rol tanımlar: barındırıcı bağlamı, izin listesini ve onayı tutar; istemci sunucu başına bir oturum kurar ve mesajları zarflar; sunucu araç tanımını ve işleyicisini barındırır.
- Üç kurgu sunucu beş araç bildiriyor, izin listesi dört araç taşıyor ve yetenek uzlaşması sonrası
anlaşılan küme üç araçta kalıyor;
kayitsunucusu sürüm sapmasıyla tamamen düşüyor. - Aynı üç araçlık zincir protokolsüz tabanda 844 sonucunu sıfır mesajla üretir; protokollü kurulumda aynı sonuç 6 istek, 6 yanıt, 179 zarf belirteci ve 9 gidiş-dönüş tutar.
- Bağlantıyı kurmak işi yapmaktan pahalıdır: el sıkışması 99 belirteç, zincir 80 belirteç; el sıkışmasının 2 mesajı ve 2 gidiş-dönüşü hiçbir araç kazandırmayan bir sunucuya gider.
- İki farklı abonenin koşumu aynı zarf sayısını verir; sayılan şey veri değil sözleşmenin biçimidir.
- Taşınabilirlik bir sayımdır: dört istemcide protokolsüz kurulum 20 tanım yazdırır ve dört yeri kırar, protokollü kurulum 5 tanımı tek yerde tutar ve istemci başına 6 mesaj ile 99 zarf belirteci ister.
Sonraki Adım
Bu derste üç rol adlandırıldı ve aralarındaki mesajlar sayıldı, ama hangi kalemin hangi rolde durduğu sıralanmadı. İzin listesi barındırıcıda mı istemcide mi durur, araç tanımının tek doğru yeri neresidir, oturumu kim tutar, onayı kim ister? Bu soruların yanıtı bir tercih değil bir bedeldir: bir kalem yanlış rolde durduğunda iki taraf onu birbirine anlatmak zorunda kalır ve her anlatma mesajdır. Sonraki ders on kalemi üç role dağıtır ve rol sınırını geçen her kalemin kaç mesaj eklediğini sayar.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.