---
title: 'Çoklu Ajan Düzenleri'
source: 'https://academia.sh/tr/kurslar/yapay-zeka-ajanlari/coklu-ajan-duzenleri'
course: 'Yapay Zekâ Ajanları'
language: tr
updated: '2026-08-17T18:06:31+00:00'
license: 'CC BY-SA 4.0'
---

# Çoklu Ajan Düzenleri

Aynı görev kümesinde tek ajan ile iki ajanın yan yana ölçülmesi: sekiz adımlık bütçe ikiye bölünüp iş bir okuyucu ile bir hesapçıya dağıtıldığında toplam başarım iki koşumda da 23/24'te kalıyor, ama adım 97'den 140'a çıkıyor ve devredilen bağlam 363 belirteç götürüyor. Bölme, dört araçlık kayıt görevlerini 2/3'ten 3/3'e çıkarırken iki araçlık tüketim görevlerini 8/8'den 7/8'e düşürüyor. Devir paketi ucuzlatıldığında 178 belirteç kazanılıyor, karşılığında 68 alan kayboluyor ve başarım 23/24'ten 18/24'e iniyor; kaybolan alan abone tipi olduğu için işyeri abonelerinin bedeli tam yarısı çıkıyor. Dört adımlık bütçe ikiye bölündüğünde düzen 21/24'ten 19/24'e ve 20/24'ten 16/24'e düşüyor.

Önceki ders denetleyen gözü döngünün içinde bıraktı: ajan kendi izine kendi baktı ve iz temiz
göründüğünde hiçbir şey göremedi. Gözü dışarı çıkarmanın en doğrudan yolu **işi bölmektir**.

Bölme bedava değildir. Tek bir döngüde biriken durum ortak bir sözlükte durur; iki ajan aynı
belleği paylaşmaz ve aradaki her şey **açıkça devredilmek** zorundadır. Devredilen şey bir
metindir, yani belirteçle ölçülür. Bölme burada araç kümesine göredir; planlayıcı–yürütücü ayrımı
değildir, iki ajan da yürütür.

- **AM47.** Kurulum ortaktır: ölçüm ağının **kurgu** abone kayıtları, **kurgu** belge dağarcığı,
  beş **kurgu** araç, yirmi dört **kurgu** görev ve ders içinde yazılmış bir **ajan benzeticisi**.
  Gerçek bir model ucu ya da araç sunucusu çağrılmaz.
- **AM48.** Taban çizgisi **düzeneksiz döngüdür**: tek ajan, aynı küme, aynı toplam bütçe.
- **AM49.** Düzen iki roldür. **Okuyucu** yalnız `sayac_oku`, `tuketim` ve `belge_ara`, **hesapçı**
  yalnız `tarife` ve `kayit_yaz` araçlarını görür; rol döngüsü ortak döngünün aynısıdır.
- **AM50.** Toplam adım bütçesi **ikiye bölünür** ve devir **bir adım** sayılır.
- **AM51.** **Devir paketi** bir metindir: taşınacak alanlar `ad=deger` biçiminde yazılır, bedeli o
  metnin belirteç sayısıdır ve taşınmayan her alan **kaybolur**. **Tam devir** sekiz alanı taşır,
  **özet devir** yalnız `abone`, `sutun`, `m3` ve `sonuc` alanlarını.
- **AM52.** İkinci koşum tohum **20260219**; iki koşum farkı bu kümede **bir görevdir** (0,0417)
  ve altındaki her fark **ölçülmemiş sayılır**.

## Devirde Kaybolan Alan

Önce tek bir görevde iki paket biçimi yan yana konur. `G23` bir kayıt görevidir, abonesi işyeri.

```python
# ORTAK KURGU KURULUM -- olcum aginin 60 kurgu abonesi, 5 kurgu belge,
# 5 kurgu arac, 24 kurgu gorev ve ders icinde yazilmis ajan benzeticisi.
# Gercek bir model ucu, arac sunucusu ya da calisma zamani 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


# ---- 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)


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)


# ---- 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


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



# ---- Bu derste eklenen parca: iki ajanli duzen ve devir paketi

ROL = {"okuyucu": ("sayac_oku", "tuketim", "belge_ara"),
       "hesapci": ("tarife", "kayit_yaz")}
DEVIR_ALAN = ("abone", "sutun", "onceki", "simdiki", "tip", "bolge", "m3", "sonuc")
OZET_ALAN = ("abone", "sutun", "m3", "sonuc")


def rol_ajani(g, rol, alan, en_cok_adim, tohum):
    """Ortak dongunun aynisi; arac kumesi ve baslangic durumu disaridan verilir."""
    r = uretec(tohum ^ izno(rol + "|" + g["ad"]))
    adlar = ROL[rol]
    dizi = [a for a in g["dizi"] if a in adlar]
    iz, adim, bel, k = [], 0, 0, 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:
            if r() < 0.88:
                break
            sec = adlar[int(r() * len(adlar))]
        else:
            sec = hedef if r() < gorme(k + 1) else adlar[int(r() * len(adlar))]
        if sec == "kayit_yaz":
            alan["deger"] = alan.get("sonuc")
        s = cagir_arac(sec, alan)
        iz.append(sec)
        bel += 30
        if "hata" in s:
            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 alan, adim, bel


def devir_paketi(alan, tasinan):
    """Devredilen baglam bir metindir; bedeli belirtecle olculur."""
    p = " ".join(f"{a}={alan[a]}" for a in tasinan if a in alan)
    kayip = [a for a in DEVIR_ALAN if a in alan and a not in tasinan]
    return p, len(belirtecle(p)), kayip


def paketi_ac(p):
    d = {}
    for parca in p.split():
        a, _, v = parca.partition("=")
        d[a] = int(v) if v.lstrip("-").isdigit() else v
    return d


g = GOREV[22]
alan = {"abone": g["abone"], "anahtar": g["istek"], "sutun": "bedel"}
alan, adim, bel = rol_ajani(g, "okuyucu", alan, 4, TOHUM)
print(g["ad"], g["tur"], "-- okuyucu bitti, adim", adim, "belirtec", bel)
for ad, tasinan in (("tam  ", DEVIR_ALAN), ("ozet ", OZET_ALAN)):
    p, bl, kayip = devir_paketi(alan, tasinan)
    b2, a2, e2 = rol_ajani(g, "hesapci", paketi_ac(p), 4, TOHUM)
    print(f"{ad} paket {bl:>2} belirtec, kayip {len(kayip)} {kayip}"
          f" -- yanit {b2.get('sonuc')}, dogrusu {dogru_yanit(g)}")
```

```
G23 kayit -- okuyucu bitti, adim 3 belirtec 306
tam   paket 18 belirtec, kayip 0 [] -- yanit 1132, dogrusu 1132
ozet  paket  8 belirtec, kayip 4 ['onceki', 'simdiki', 'tip', 'bolge'] -- yanit 566, dogrusu 1132
```

Fark on belirteçtir ve karşılığı tam bir yanlış yanıttır. Özet paket `tip` alanını taşımadığı için
`tarife` aracı kendi varsayılanına düşüyor ve bedeli mesken tarifesiyle hesaplıyor; sonuç tam
**yarısı** çıkıyor. Araç hata vermiyor ve o değer kayda yazılıyor. **Kaybolan alan, araç hatası
olarak değil, yanlış ama geçerli bir sonuç olarak görünür.**

## İkinci Ajanın Kattığı ve Ödettiği

Şimdi bütün küme koşturulur; tür kırılımı da tabloda durur. Belge görevleri her düzende 7/7
çıktığı için tabloda yer almaz.

```python
TUR = ("belge", "tuketim", "bedel", "kayit")


def kosum(tohum, butce, tasinan=None):
    """tasinan None ise tek ajan. Degilse butce ikiye bolunur: okuyucu kendi
    isini bitirir, devir paketini yazar, hesapci paketle baslar."""
    CAGRI[0] = 0
    d = {"dogru": 0, "adim": 0, "bel": 0, "devir": 0, "kayip": 0,
         "tur": {t: [0, 0] for t in TUR}}
    for g in GOREV:
        if tasinan is None:
            s = ajan(g, en_cok_adim=butce, tohum=tohum)
            yanit, d["adim"], d["bel"] = (s["yanit"], d["adim"] + s["adim"],
                                          d["bel"] + s["belirtec"])
        else:
            alan = {"abone": g["abone"], "anahtar": g["istek"], "sutun": "bedel"}
            alan, a1, b1 = rol_ajani(g, "okuyucu", alan, butce // 2, tohum)
            paket, pb, kayip = devir_paketi(alan, tasinan)
            son, a2, b2 = rol_ajani(g, "hesapci", paketi_ac(paket),
                                    butce // 2, tohum)
            d["adim"] += a1 + 1 + a2
            d["bel"] += b1 + pb + b2
            d["devir"] += pb
            d["kayip"] += len(kayip)
            yanit = son.get("sonuc", alan.get("sonuc"))
        d["tur"][g["tur"]][1] += 1
        d["tur"][g["tur"]][0] += yanit == dogru_yanit(g)
        d["dogru"] += yanit == dogru_yanit(g)
    d["cagri"] = CAGRI[0]
    return d


for t in (TOHUM, TOHUM + 1):
    print(f"\ntohum {t}")
    print("butce duzen           tuket bedel kayit toplam  adim cagri"
          "  belirt devir kayip")
    for butce in (4, 8):
        for ad, tas in (("tek ajan", None), ("iki ajan, tam", DEVIR_ALAN),
                        ("iki ajan, ozet", OZET_ALAN)):
            d = kosum(t, butce, tas)
            p = "".join(f"{d['tur'][x][0]}/{d['tur'][x][1]:<5}" for x in TUR[1:])
            print(f"{butce:>5} {ad:<15}{p}{d['dogru']:>2}/24{d['adim']:>6}"
                  f"{d['cagri']:>6}{d['bel']:>8}{d['devir']:>6}{d['kayip']:>6}")
```

```
tohum 20260218
butce duzen           tuket bedel kayit toplam  adim cagri  belirt devir kayip
    4 tek ajan       8/8    5/6    1/3    21/24    84    64    9402     0     0
    4 iki ajan, tam  6/8    4/6    2/3    19/24   109    63    8162   358     0
    4 iki ajan, ozet 6/8    1/6    1/3    15/24   109    63    7984   180    68
    8 tek ajan       8/8    6/6    2/3    23/24    97    74   11978     0     0
    8 iki ajan, tam  7/8    6/6    3/3    23/24   140    69   11703   363     0
    8 iki ajan, ozet 7/8    2/6    2/3    18/24   140    69   11525   185    68

tohum 20260219
butce duzen           tuket bedel kayit toplam  adim cagri  belirt devir kayip
    4 tek ajan       8/8    4/6    1/3    20/24    83    67    9366     0     0
    4 iki ajan, tam  6/8    1/6    2/3    16/24   108    63    8083   361     0
    4 iki ajan, ozet 6/8    0/6    1/3    14/24   108    63    7895   173    72
    8 tek ajan       8/8    6/6    2/3    23/24    98    74   11994     0     0
    8 iki ajan, tam  8/8    5/6    3/3    23/24   143    75   12358   372     0
    8 iki ajan, ozet 8/8    2/6    2/3    19/24   143    75   12170   184    72
```

Sekiz adımlık bütçede toplam başarım iki düzende de **23/24** ve iki koşumda da aynı: ikinci ajan
toplama hiçbir şey katmıyor. Bedeli açık — adım 97'den **140**'a, devredilen bağlam **363
belirteç**. Çağrı ise 74'ten 69'a düşüyor, çünkü hesapçının işi olmayan on beş görevde ajan bir
adım harcayıp hiçbir araç çağırmadan çıkıyor. İletişim maliyeti bir çağrı kalemi değildir.

Kırılım toplamın gizlediğini gösteriyor. Dört araçlık **kayıt** görevleri iki koşumda da 2/3'ten
**3/3**'e çıkıyor: bölme derinliği her ajan için sıfırdan başlatıyor ve yanlış seçim beş araç
yerine iki ya da üç araç arasından geliyor. Aynı mekanizma kısa dizide ters çalışıyor — **tüketim**
görevleri birinci koşumda 8/8'den 7/8'e, **bedel** görevleri ikincide 6/6'dan 5/6'ya iniyor. Kayıt
alt kümesi üç görevliktir; yön aynı, büyüklüğü **ölçülmemiş sayılır**.

Özet devir satırı ikinci bedeli yazıyor. Paketi ucuzlatmak 363 belirteci **185**'e indiriyor;
karşılığı **68 kaybolan alan** ve 23/24'ten **18/24**'e düşen başarımdır. Kayıp bedel görevlerinde
toplanıyor: 6/6'dan **2/6**'ya. **Belirteçle ölçülen bir tasarruf, görevle ödeniyor.**

Dört adımlık bütçe satırlarında düzen tek ajanın **altında** kalıyor: 19/24 ve 16/24. Her ajana
kalan pay dizisini bitirmeye yetmiyor. **Bir işi bölmek, bölünecek kadar bütçe varsa bir
düzendir.**

## Özet

- İki ajan ortak bellek paylaşmaz; aralarındaki her alan **açıkça devredilir** ve bedeli
  belirteçle ölçülür.
- Eşit toplam bütçede ikinci ajan başarıma iki koşumda da **hiçbir şey katmıyor** (23/24 → 23/24);
  adım 97'den 140'a çıkıyor, devredilen bağlam 363 belirteç tutuyor. Çağrı ise 74'ten 69'a
  **düşüyor**: iletişim maliyeti adım kalemindedir.
- Kırılım toplamın gizlediğini açıyor: kayıt görevleri 2/3'ten 3/3'e çıkarken tüketim ve bedel
  görevleri birer görev kaybediyor.
- Devir paketini ucuzlatmak 178 belirteç kazandırıp 68 alan kaybettiriyor ve başarımı 18/24'e
  indiriyor; kaybolan alan **yanlış ama geçerli bir sonuç** olarak görünüyor.
- Dört adımlık bütçe ikiye bölündüğünde düzen tek ajanın altına düşüyor (19/24 ve 16/24).

## Sonraki Adım

İki derste denetim önce döngünün içine, sonra ikinci bir ajana verildi; ikisinde de karar
**düzeneğin kendisinde** kaldı. `G23` görevinde yanlış değer bir kayda yazıldı ve bunu durduran
hiçbir şey yoktu, çünkü `kayit_yaz` **yan etkili** tek araçtır ve öbür araçlarla aynı muameleyi
gördü. Sonraki ders o aracın önüne bir **onay noktası** koyar: onay açıkken ve kapalıyken kaç kayıt
yazılıyor, onay kaç yanlış yazımı durduruyor ve bunun için insana kaç kez soruluyor.
