---
title: 'Uzun Süreli Bellek'
source: 'https://academia.sh/tr/kurslar/yapay-zeka-ajanlari/uzun-sureli-bellek'
course: 'Yapay Zekâ Ajanları'
language: tr
updated: '2026-08-17T18:06:32+00:00'
license: 'CC BY-SA 4.0'
---

# Uzun Süreli Bellek

Üç yazma politikasının aynı 48 görevlik ikinci kümede ölçülmesi: her adımın gözlemini ayrı kayıt yapmak 74 kayıt biriktiriyor ve 44 adım kazandırıyor, görev başına tek yanıt kaydı yazmak 24 kayıtla 199 adım kazandırıyor ama başarımı 0,9167'den 0,5833'e düşürüyor, plana giren gözlemleri tek kayıtta birleştiren seçici politika ise yine 24 kayıtla 118 adım kazandırıyor. Kazandıran şey kayıt sayısı değil kaydın birimidir.

Kısa süreli bellek pencereyle sınırlıdır, ama asıl kayıp sınırda değil: **döngü bittiği anda o
bağlamın tamamı silinir.** Ajan sayacı okur, endeks farkını hesaplar, tarifeyi uygular ve yanıtı
verir. Aynı abone başka bir soruyla döndüğünde sayaç **yeniden** okunur.

Uzun süreli bellek (long-term memory) bu boşluğu doldurur: döngüden bağımsız yaşayan, sonraki
görevlerin okuyabildiği bir kayıt kümesi. Buradaki soru **neyin geri getirileceği** değildir — parçalama, sıralama ve
erişim isabeti Gömme Vektörleri ve Erişim Artırılmış Üretim kursunda ölçüldü, tekrarlanmaz.
Buradaki soru **neyin yazılacağıdır**: aynı geri çağırma düzeneğiyle üç yazma politikası
koşturulur, her birinde saklanan kayıt sayısı ile sonraki görevlerde kazanılan adım yan yana
basılır.

- **AB61.** Kod bir **benzeticidir**; gerçek bir model uç noktası, araç sunucusu ya da bellek
  servisi çağrılmaz. Ortam, araçlar ve görevler **kurgudur**, tohum **20260218**.
- **AB62.** Bellek bir **kayıt listesidir**; her kayıt aranabilir bir metin ve alanlarıdır.
  Gözlem ve yanıt kayıtları **abone koduyla**, belge kayıtları **soru metniyle** anahtarlanır.
- **AB63. Geri çağırma tek okumadır:** istekle ortak belirteci en çok olan kayıt döner, eşitlikte
  en son yazılan.
- **AB64.** Üç yazma politikası: **her adım** (her adımın gözlemi ayrı kayıt), **yalnız sonuç**
  (görev başına tek yanıt kaydı), **seçici** (planın adımlarına giren gözlemler **tek kayıtta**
  birleşir).
- **AB65.** Geri çağrılan alanlar başlangıç durumuna yazılır, çıktısı bilinen adım **atlanır**;
  plan tümüyle bellekten karşılanırsa döngü hiç başlamaz.
- **AB66.** Kayıtlar **24 görevlik ilk kümeden** yazılır; ölçüm **aynı abonelere sorulan 48 yeni
  soruda** yapılır. Adım bütçesi 8, taban çizgisi **belleksiz döngüdür**.

## Döngü Bittiğinde Geriye Kalan

Aşağıdaki blok ortak tanımı kurar ve tek bir aboneye iki ayrı soru sorar.

```python
# KURGU ortam ve KURGU ajan. Gercek bir model ucu, arac sunucusu ya da bellek
# servisi cagrilmaz. Abone kayitlari, belgeler ve gorevler kurgudur, tohum 20260218.
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


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)


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"])


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


CAGRI[0] = 0
g1 = GOREV[4]
g2 = dict(g1, ad="G05b", tur="tuketim", dizi=("sayac_oku", "tuketim"),
          istek=f"{g1['abone']} abonesinin bu donem tuketimi kac metrekup")
print("gorev kumesi:", {t: sum(g["tur"] == t for g in GOREV)
                        for t in ("bedel", "tuketim", "belge", "kayit")})
print(g1["abone"], "iki ayri soru:", [x[0] for x in ajan(g1)["iz"]],
      [x[0] for x in ajan(g2)["iz"]], "; arac cagrisi", CAGRI[0])
```

```
gorev kumesi: {'bedel': 6, 'tuketim': 8, 'belge': 7, 'kayit': 3}
A026 iki ayri soru: ['sayac_oku', 'tuketim', 'tarife'] ['sayac_oku', 'tuketim'] ; arac cagrisi 5
```

Aynı abonenin sayacı iki kez okundu. İkinci sorunun ilk iki adımı birincinin birebir tekrarıdır;
beş araç çağrısının ikisi yeni bilgi getirmiyor. Kayıp döngünün kusuru değil, **kalıcı bir yazma
yerinin olmamasıdır**.

## Üç Yazma Politikası

Ajan döngüsünün tek farkı, başlangıç durumunun bellekten gelmesi ve çıktısı bilinen adımın
atlanmasıdır.

```python
PLAN = {"bedel": (("sayac_oku", "tuketim", "tarife"),
                  "{a} abonesinin bu donem bedeli nedir"),
        "tuketim": (("sayac_oku", "tuketim"),
                    "{a} abonesinin bu donem tuketimi kac metrekup"),
        "belge": (("belge_ara",), "sayac donusunde endeks farki nasil hesaplanir"),
        "kayit": (("sayac_oku", "tuketim", "tarife", "kayit_yaz"),
                  "{a} abonesinin bedelini hesapla ve kayda yaz")}
TUR = ("bedel", "tuketim", "belge", "kayit")
CIKTI = {"sayac_oku": ("onceki", "simdiki", "tip", "bolge"), "tuketim": ("m3",),
         "tarife": ("tutar",), "belge_ara": ("kod",)}
SONUC = {"tuketim": "m3", "tarife": "tutar", "belge_ara": "kod"}


def sonraki_kume(n=48):
    """Ayni abonelere sorulan YENI sorular; recete GOREV ile birebir ayni."""
    k = []
    for i in range(n):
        r = uretec(TOHUM + 7919 * (i + 101))
        ab = GOREV[int(r() * 24)]["abone"]
        t = TUR[ayrik(r(), [0.30, 0.22, 0.20, 0.28])]
        k.append({"ad": f"H{i + 1:02d}", "tur": t, "abone": ab,
                  "dizi": PLAN[t][0], "istek": PLAN[t][1].format(a=ab)})
    return k


def geri_cagir(bellek, istek):
    """Tek okuma: ortak belirteci en cok olan, esitlikte en son yazilan kayit."""
    b, en, kayit = set(belirtecle(istek)), 0, None
    for metin, alanlar in bellek:
        o = len(b & set(belirtecle(metin)))
        if o >= en and o > 0:
            en, kayit = o, alanlar
    return kayit


def ajan_b(g, bellek, tohum=TOHUM, en_cok_adim=8):
    """Ortak dongunun tek farki: baslangic durumu bellekten gelir ve
    ciktisi zaten bilinen adim atlanir."""
    r = uretec(tohum ^ izno(g["ad"]))
    kayit = geri_cagir(bellek, g["istek"])
    c = {"adim": 0, "okundu": kayit is not None, "alan": len(kayit or {}),
         "kayit": [], "yolda": {}}
    alan = {"abone": g["abone"], "anahtar": g["istek"], "sutun": "bedel"}
    alan.update(kayit or {})
    if "sonuc" in alan:
        return dict(c, yanit=alan["sonuc"])
    adim, k, dizi = 0, 0, g["dizi"]
    while k < len(dizi) and dizi[k] in CIKTI and all(x in alan for x in CIKTI[dizi[k]]):
        alan["sonuc"] = alan.get(SONUC.get(dizi[k]), alan.get("sonuc"))
        k += 1
    if k == len(dizi):
        return dict(c, yanit=alan.get("sonuc"))
    while adim < en_cok_adim:
        adim += 1
        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) else ARAC_ADI[int(r() * len(ARAC_ADI))]
        if sec == "kayit_yaz":
            alan["deger"] = alan.get("sonuc")
        s = cagir_arac(sec, alan)
        gozlem = {x: s[x] for x in CIKTI.get(sec, ()) if x in s}
        c["kayit"].append(gozlem)
        if "hata" in s:
            continue
        alan.update({kk: vv for kk, vv in s.items() if kk != "hata"})
        if sec in SONUC:
            alan["sonuc"] = s[SONUC[sec]]
        if sec == hedef:
            c["yolda"].update(gozlem)
            k += 1
    return dict(c, adim=adim, yanit=alan.get("sonuc"))


def kosum(politika, tohum=TOHUM, n=48):
    """Once ilk kume kosulur ve politikaya gore yazilir, sonra yeni kume."""
    bellek = []
    for g in GOREV:
        s = ajan_b(g, [], tohum)
        ah = g["istek"] if g["tur"] == "belge" else g["abone"]
        yaz = (s["kayit"] if politika == "her adim" else [s["yolda"]]
               if politika == "secici" else [{"sonuc": s["yanit"]}]
               if politika == "yalniz sonuc" else [])
        bellek += [(ah + " " + " ".join(f"{x} {v}" for x, v in a.items()), a)
                   for a in yaz if None not in a.values()]
    CAGRI[0] = 0
    adim = dogru = okuma = isabet = alan = 0
    for g in sonraki_kume(n):
        s = ajan_b(g, bellek, tohum)
        d = s["yanit"] == dogru_yanit(g)
        adim, dogru, okuma = adim + s["adim"], dogru + d, okuma + s["okundu"]
        alan, isabet = alan + s["alan"], isabet + (d and s["okundu"])
    return (len(bellek), okuma, alan, isabet / max(okuma, 1), adim, CAGRI[0], dogru / n)


POL = ("belleksiz", "her adim", "yalniz sonuc", "secici")
print("politika       kayit okuma alan  isabet  adim cagri basarim | 2. kosum")
for p in POL:
    a, b = kosum(p), kosum(p, TOHUM + 1)
    print(f"{p:<14} {a[0]:>5} {a[1]:>5} {a[2]:>4} {a[3]:>7.4f} {a[4]:>5} {a[5]:>5}"
          f"  {a[6]:>6.4f} | {b[4]:>4} adim  {b[6]:.4f}")
```

```
politika       kayit okuma alan  isabet  adim cagri basarim | 2. kosum
belleksiz          0     0    0  0.0000   212   166  0.9167 |  222 adim  0.8958
her adim          74    47   99  0.8936   168   132  0.8958 |  176 adim  0.8542
yalniz sonuc      24    45   45  0.5556    13    10  0.5833 |   14 adim  0.6250
secici            24    47  166  0.8511    94    74  0.8542 |   96 adim  0.8958
```

Taban çizgisi 48 görevi 212 adım ve 166 araç çağrısıyla bitiriyor, başarım 0,9167. Üç politika bu
satırın üstüne kurulur.

**Yalnız sonuç** en çarpıcı satırdır. 24 kayıtla 212 adımı **13'e** indiriyor, yani 199 adım
kazandırıyor; araç çağrısı 166'dan 10'a düşüyor. Ama başarım **0,5833'e** iniyor. Nedeni şudur:
kayıt, abone koduyla anahtarlanmış bir **yanıttır**, oysa yanıt bir soruya aittir. Abonenin tüketim
yanıtı saklanır, sonraki görev aynı abonenin **bedelini** sorar; değer doğru, soru başkadır.

**Her adım** politikası 74 kayıt biriktiriyor, üç katı, ve yalnızca 44 adım kazandırıyor (212'den
168'e). Sebep okuma sütununda görünür: 47 okumanın getirdiği toplam alan **99**, okuma başına iki
alan. Her adımın gözlemi ayrı bir kayıt olduğu için tek okuma **tek adımın** çıktısını getiriyor.
**Seçici** politika aynı 24 kayıtla 118 adım kazandırıyor (212'den 94'e) ve 47 okumada **166 alan**
getiriyor; plana giren gözlemler tek kayıtta birleştiği için bir okuma bütün ön koşulları taşıyor.

## Kayıt Sayısı Değil Kaydın Birimi

Tablonun iki sıralaması çakışmıyor. Kayıt sayısına göre en cömert politika her adımdır, kazanılan
adıma göre yalnız sonuçtur; seçici ise her adımın üçte biri kadar kayıtla onun **2,68 katı** adım
kazandırıyor. Belirleyici olan kaç kayıt yazıldığı değil, bir kaydın **hangi birimi**
kapsadığıdır: bir adım mı, bir görev mi, bir varlığın bütün alanları mı.

Hangi farkın bulgu sayılacağını ikinci koşum söylüyor. Taban çizgisi 0,9167 ve 0,8958 veriyor, iki
koşum farkı **0,0417**. Yalnız sonucun kaybı iki koşumda 0,3334 ve 0,2708, ikisi de bandın çok
üstünde ve **ölçülmüştür**. Seçicinin kaybı ise bir koşumda 0,0625, ötekinde **0,0000**; bandın
etrafında salınıyor ve **ölçülmemiş sayılır** — 118 adımlık kazancın bir başarım bedeli olduğu bu
kurulumda gösterilemedi.

Kural sadedir: belleğe **soruya bağlı bir yanıt** yazmak, o yanıtı soru değiştiğinde yanlış hâle
getirir. Yazılması gereken şey sorudan bağımsız **gözlemdir** — sayaç okuması, abone tipi, belge
kodu. Yanıtın her görevde yeniden üretilmesi, yanlış yanıttan ucuzdur.

## Özet

- Döngü bittiğinde kısa süreli bellek silinir; aynı abonenin sayacı sonraki soruda yeniden okunur.
- Ölçülen şey erişim değil **yazma kararıdır**: aynı geri çağırma düzeneğiyle üç politika üç ayrı
  sonuç veriyor.
- Yalnız sonuç 24 kayıtla 199 adım kazandırıyor ama başarımı 0,9167'den 0,5833'e düşürüyor; kayıp
  iki koşum farkının sekiz katıdır ve ölçülmüştür.
- Her adım 74 kayıtla 44, seçici 24 kayıtla 118 adım kazandırıyor; okuma başına gelen alan 99'a
  karşı 166'dır.
- Kayıt sayısı değil kaydın birimi belirleyicidir; soruya bağlı yanıt yerine gözlem yazmak yanlış
  yanıtı ortadan kaldırır.

## Sonraki Adım

Bu ders belleği görevler **arasında** ele aldı. Görev **içinde** sorun tersine döner: bağlam
silinmiyor, büyüyor, ve pencere dolduğunda bir şeyin atılması gerekiyor. Atma kararı yazma
kararının aynasıdır. Sonraki ders sıkıştırmanın iki yolunu ölçer: gözlemleri özetlemek ve yalnız
ilgili olanı tutmak. Sıkıştırma oranı arttıkça taşınan belirteç düşer, ama düşen her alan bir
sonraki adımın girdisi olabilir. Ölçülecek olan bu ikisidir: kazanılan belirteç ve **atılan alanın
gerektiği görev sayısı**.
