---
title: 'Araç ve İşlev Çağrısı'
source: 'https://academia.sh/tr/kurslar/model-apileri/arac-ve-islev-cagrisi'
course: "Model API'leri ile Uygulama Geliştirme"
language: tr
updated: '2026-08-17T18:06:38+00:00'
license: 'CC BY-SA 4.0'
---

# Araç ve İşlev Çağrısı

Model çıktısının yürütülecek bir çağrıya bağlanmasının ölçülmesi: 120 kurgu talepte araç kataloğu isteme yazılmadığında geçerli çağrı oranı 0,0500 ve yanıtların 0,6750'si var olmayan bir araç adı uyduruyor. Yalnız adlar verildiğinde uydurma ad 0,1500'e düşüyor ama parametre hatası 0,0667'den 0,5583'e fırlıyor: hata yok olmuyor, yer değiştiriyor. Adlar ve parametreler birlikte verildiğinde geçerli oran 0,6917, doğru aracı çağıran oran 0,5750 oluyor ve bunun bedeli girişte 3694'ten 11614 belirtece çıkmaktır. Doğru araç başına belirteç yine de 750,5'ten 178,2'ye düşüyor. Doğrulama 37 çağrıyı yakalıyor ama geçerli sayılan 83 çağrının 14'ü kayıtlı fakat yanlış aracı çağırıyor ve bu kalıntıyı hiçbir şema yakalamıyor. Biçim hatası katalogla birlikte azalmıyor, çünkü kaynağı istem değil ağdır.

Önceki iki derste yanıt bir metindi ve onu bir insan ya da basit bir yönlendirme kuralı okudu.
Etiketin erken gelmesi işi erkene çekiyordu, ama işi yapan hep başka bir şeydi.

Bir model çıktısı doğrudan bir **kod yürütmesine** bağlandığında ölçüt değişir. Yanıtın
okunabilir olması yetmez: çağrılan işlevin **var olması**, parametre adlarının **tutması** ve
değerlerin **kabul edilebilir** olması gerekir. Çok adımlı devam, bellek ve planlama burada
**yoktur**; onlar Yapay Zekâ Ajanları kursuna bırakılır. Bu derste hiçbir araç **yürütülmez**,
yalnız çağrının geçerliliği sayılır.

- **AK17.** Kod bir **benzeticidir** ve **araç kaydı da kurgudur**: ölçüm ağının destek hattının
  kendi işlevleri. Talepler kurgudur, tohum **20260218**. Hiçbir araç çalıştırılmaz.
- **AK18. Araç kaydı beş işlevdir**, her biri bir konuya karşılık gelir; ikisinin iki parametresi
  vardır. Parametre kuralı ya **sayı** ya da kapalı bir değer kümesidir.
- **AK19. Doğrulayıcı dört hata sınıfı sayar:** biçim (çağrı hiç ayrıştırılamadı), **uydurma ad**
  (kayıtta olmayan işlev), parametre (eksik, fazla, ya da geçersiz değer), ve hatasız.
- **AK20. Katalog üç düzeyde verilir:** hiç, yalnız **adlar**, ya da **adlar ve parametreler**.
  Benzetici kayıtlı adı kullanma eğilimini bu üç duruma göre değiştirir; eğilim kurgudur,
  ölçülen şey düzeyler arasındaki farktır.
- **AK21. Kavram seçimi yalnız son kullanıcı mesajından okunur.** Böylece üç düzey arasında
  yalnız çağrının biçimi değişir, modelin hangi konuyu gördüğü değişmez.
- **AK22. Ağ katmanı sürer.** Hız sınırı, zaman aşımı ve yarıda kesilme, çağrı metnini bozar;
  bozulan çağrı biçim ya da uydurma ad sınıfına düşer. Bu yüzden **biçim hatasının bir kısmının
  kaynağı istem değil ağdır** ve katalogla azalmaz.
- **AK23. Ürün ölçütü doğru araç oranıdır:** hem doğrulamayı geçen hem de talebin konusuna karşılık
  gelen işlevi çağıran yanıt.
- **AK24.** Bedel giriş ve çıkış belirteci olarak yazılır; çağrı sayısı üç düzeyde de **120**'dir.

## Araç Kaydı, Ayrıştırıcı ve Doğrulayıcı

Bir işlev çağrısı, arayüzün ürettiği metnin **kayıtlı bir imzaya** oturtulmasıdır. Aşağıdaki kod
kaydı, çağrı ayrıştırıcısını ve doğrulayıcıyı kurar, sonra aynı talebi üç katalog düzeyinde
sorar.

```python
# BENZETICI -- KURGUDUR. Gercek bir uc nokta cagrilmaz; araclar da kurgudur ve
# hicbiri yurutulmez, yalniz cagrinin gecerliligi sayilir.
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):
    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"]
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"}
TUZAK = {"degis": "tarife", "kayit": "ariza", "ekip": "kesinti", "takip": "tarife"}
SAYAC = [0]

# KURGU arac kaydi: olcum aginin destek hattinin kendi ucuncu taraf olmayan islevleri
ARAC = {"fatura_getir": {"abone": "sayi"},
        "ariza_kaydi_ac": {"abone": "sayi", "konu": KONU},
        "sayac_endeks_sor": {"sayac": "sayi"},
        "tarife_bilgisi": {"abone": "sayi"},
        "kesinti_sorgula": {"bolge": "sayi"}}
DOGRU = dict(zip(KONU, ARAC))
UYDURMA = {"fatura": "fatura_sorgula", "ariza": "ariza_bildir", "sayac": "sayac_oku",
           "tarife": "tarife_getir", "kesinti": "kesinti_listele"}
YANLIS = {"abone": "abone_no", "sayac": "sayac_no", "bolge": "bolge_kodu",
          "konu": "konu_adi"}


def duzlestir(mesajlar):
    return " ".join(f"{r} : {i}" for r, i in mesajlar)


def cagir(mesajlar, tohum=TOHUM, sicaklik=0.6, en_uzun=EN_UZUN):
    """Yanit bir arac cagrisi metnidir; hicbir arac yurutulmez."""
    SAYAC[0] += 1
    istem = duzlestir(mesajlar)
    bel = belirtecle(istem)
    ilk = 1 + len(bel) // 40
    bos = {"giris": len(bel), "cikis": 0, "yanit": "", "ilk": ilk}
    if len(bel) > PENCERE:
        return dict(bos, durum="baglam_asimi")
    if SAYAC[0] % HIZ == 0:
        return dict(bos, durum="hiz_siniri")
    if len(bel) > 90 and cekilis(istem, tohum, 3) < 0.04:
        return dict(bos, durum="zaman_asimi")
    son = mesajlar[-1][1]                         # kavram yalniz son mesajdan okunur
    p = {k: 0.15 for k in KONU}
    for t in belirtecle(son):
        for tablo, w in ((IZ, 1.0), (TUZAK, 0.6)):
            if tablo.get(t) in p:
                p[tablo[t]] += w
    ad = sorted(p)
    from math import exp
    e = [exp(p[a] / sicaklik) for a in ad]
    k = ad[ayrik(cekilis(son, tohum, 5), [x / sum(e) for x in e])]
    kat, par = "arac" in bel, "param" in bel      # istemde katalog var mi
    u4 = cekilis(istem, tohum, 67)
    if u4 < (0.04 if kat else 0.12):              # cagri yerine serbest metin
        metin = f"talebiniz {k} konusunda kaydedildi"
    else:
        esik = 0.15 + (0.73 if kat else 0.0) + (0.06 if par else 0.0)
        adi = DOGRU[k] if cekilis(istem, tohum, 23) < esik else UYDURMA[k]
        no = next((x for x in istem.split() if x.isdigit()), "0")
        dogru_ad = par or cekilis(istem, tohum, 41) < 0.35
        bozuk_deger = cekilis(istem, tohum, 59) < 0.10
        alan = []
        for a, kural in ARAC[DOGRU[k]].items():
            anahtar = a if dogru_ad else YANLIS[a]
            if kural == "sayi":
                alan.append(f"{anahtar}={'bilinmiyor' if bozuk_deger else no}")
            else:
                alan.append(f"{anahtar}={'acil' if bozuk_deger else k}")
        metin = "cagri " + adi + " " + " ".join(alan)
    pl, durum = parcala(metin), "tamam"
    if len(pl) > en_uzun:
        pl, durum = pl[:en_uzun], "durduruldu"
    u = cekilis(istem, tohum, 91)
    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}


def cozumle(y):
    """Yanittan arac cagrisini cikarir: (ad, {parametre: deger}) ya da None."""
    p = y.split()
    if len(p) < 2 or p[0] != "cagri":
        return None
    d = {}
    for x in p[2:]:
        if "=" not in x:
            return None
        a, _, v = x.partition("=")
        d[a] = v
    return p[1], d


def dogrula(c):
    """Dort hata sinifi: bicim, uydurma ad, eksik/fazla parametre, gecersiz deger."""
    if c is None:
        return ["bicim"]
    adi, d = c
    if adi not in ARAC:
        return ["uydurma_ad"]
    sema = ARAC[adi]
    h = [f"eksik:{a}" for a in sema if a not in d]
    h += [f"fazla:{a}" for a in d if a not in sema]
    for a, kural in sema.items():
        if a not in d:
            continue
        if kural == "sayi" and not d[a].isdigit():
            h.append(f"sayi_degil:{a}")
        elif kural != "sayi" and d[a] not in kural:
            h.append(f"gecersiz:{a}")
    return h


KALIP = [("bu ayki fatura tutari gecen aya gore cok yuksek geldi", "fatura"),
         ("faturami odedim ama sistemde borc gorunuyor", "fatura"),
         ("fatura ayrintisini nereden gorebilirim", "fatura"),
         ("evde su akmiyor bir ariza var galiba", "ariza"),
         ("baglanti bozuk oldu ve hic calismiyor", "ariza"),
         ("ariza kaydi actim ama ekip gelmedi", "ariza"),
         ("sayac okumasi yanlis girilmis endeks tutmuyor", "sayac"),
         ("sayac degisimi icin randevu istiyorum", "sayac"),
         ("sayac uzerindeki endeks ile fatura ayni degil", "sayac"),
         ("hangi tarife basamagindayim ogrenmek istiyorum", "tarife"),
         ("tarife degisikligi icin ne yapmam gerekiyor", "tarife"),
         ("birim ucret abone tipine gore degisiyor mu", "tarife"),
         ("mahallede kesinti var ne zaman gelecek", "kesinti"),
         ("planli kesinti duyurusu nereden takip edilir", "kesinti"),
         ("aksamdan beri kesinti yasiyoruz", "kesinti")]
TALEP = []
for i in range(120):                              # 120 KURGU destek talebi
    r = uretec(TOHUM + i)
    k = KONU[ayrik(r(), [0.24, 0.22, 0.18, 0.20, 0.16])]
    TALEP.append({"no": 4001 + i, "konu": k,
                  "metin": [x for x in KALIP if x[1] == k][int(r() * 3)][0]})

YALIN = "destek talebini uygun bir islev cagrisiyla karsila ."
ADLAR = YALIN + " arac adlari : " + " , ".join(ARAC) + " ."
TAM = ADLAR + " parametreler : " + " , ".join(
    f"{a} ( {' '.join(s)} )" for a, s in ARAC.items()) + " ."

print("arac kaydi:", " , ".join(f"{a}({' '.join(s)})" for a, s in ARAC.items()))
for adi, onek in (("katalogsuz", YALIN), ("ad listesi", ADLAR),
                  ("ad ve parametre", TAM)):
    x = TALEP[0]
    s = cagir([("sistem", onek),
               ("kullanici", f"Talep {x['no']} : {x['metin']}")])
    h = dogrula(cozumle(s["yanit"]))
    print(f"  {adi:<16} giris {s['giris']:>3}  {s['yanit']}")
    print(f"                   hata {h if h else 'yok'}")
x = TALEP[0]
print("  ayni istek tohum 20260219 ile ->",
      cagir([("sistem", TAM), ("kullanici", f"Talep {x['no']} : {x['metin']}")],
            TOHUM + 1)["yanit"])
```

```
arac kaydi: fatura_getir(abone) , ariza_kaydi_ac(abone konu) , sayac_endeks_sor(sayac) , tarife_bilgisi(abone) , kesinti_sorgula(bolge)
  katalogsuz       giris  32  cagri kesinti_listele bolge_kodu=4001
                   hata ['uydurma_ad']
  ad listesi       giris  57  cagri kesinti_sorgula bolge_kodu=4001
                   hata ['eksik:bolge', 'fazla:bolge_kodu']
  ad ve parametre  giris  98  cagri kesinti_sorgula bolge=4001
                   hata yok
  ayni istek tohum 20260219 ile -> cagri sayac_endeks_sor sayac=4001
```

Üç satır aynı talebi, aynı konuyu ve üç ayrı hatayı gösteriyor. Katalogsuz düzeyde biçim
kusursuzdur: yanıt bir çağrıya benziyor, parametresi var, değeri doğru. Ama `kesinti_listele`
diye bir işlev **yoktur**. Bu, doğrulamanın en kolay yakaladığı ve en tehlikeli hatadır: kayıt
olmadan bakıldığında geçerli görünür.

İkinci satırda ad artık kayıtlıdır, fakat parametre adı `bolge_kodu` yazılmıştır ve kayıt
`bolge` bekler. Doğrulayıcı bunu iki hata olarak sayar: bir eksik anahtar, bir fazladan anahtar.
Üçüncü satırda hem ad hem parametre kayıtla uyuşuyor. Son satır kursun üçüncü kuralının
gereğidir: aynı istek ikinci bir tohumda **başka bir aracı** çağırdı, üstelik o çağrı da
doğrulamadan geçerdi.

## Üç Katalog Düzeyinin Sayıları

Aynı 120 kurgu talep üç düzeyde koşturulur ve hata sınıfları ayrı ayrı sayılır.

```python
def olc(onek, tohum=TOHUM):
    SAYAC[0] = 0
    g = c = agda = gecerli = uydurma = bicim = param = dogru_arac = 0
    for x in TALEP:
        s = cagir([("sistem", onek),
                   ("kullanici", f"Talep {x['no']} : {x['metin']}")], tohum)
        g, c = g + s["giris"], c + s["cikis"]
        agda += s["durum"] != "tamam"
        cg = cozumle(s["yanit"])
        h = dogrula(cg)
        if not h:
            gecerli += 1
            dogru_arac += cg[0] == DOGRU[x["konu"]]
        elif h == ["uydurma_ad"]:
            uydurma += 1
        elif h == ["bicim"]:
            bicim += 1
        else:
            param += 1
    n = len(TALEP)
    return (g, c, agda, gecerli / n, uydurma / n, bicim / n, param / n,
            dogru_arac / n)


DUZEY = [("katalogsuz", YALIN), ("ad listesi", ADLAR), ("ad ve parametre", TAM)]
print("duzey            giris  cikis  agda  gecerli A  gecerli B  uydurma  bicim"
      "   param  dogru arac")
for adi, onek in DUZEY:
    a, b = olc(onek), olc(onek, TOHUM + 1)
    print(f"{adi:<15} {a[0]:>6} {a[1]:>6} {a[2]:>5}  {a[3]:>9.4f}  {b[3]:>9.4f}"
          f"  {a[4]:>7.4f} {a[5]:>6.4f}  {a[6]:>6.4f}  {a[7]:>10.4f}")

a = olc(TAM)
print(f"\ndogrulama {round((1 - a[3]) * 120)} cagriyi yakaladi ;"
      f" gecerli sayilan {round(a[3] * 120)} cagrinin"
      f" {round((a[3] - a[7]) * 120)} tanesi yanlis araci cagiriyor")
print("dogru arac basina belirtec :", end=" ")
for adi, onek in DUZEY:
    z = olc(onek)
    print(f"{adi} {(z[0] + z[1]) / (z[7] * 120):.1f}", end="  ")
print()
SAYAC[0] = 0
n = 0
for x in TALEP:
    s = cagir([("sistem", TAM), ("kullanici", f"Talep {x['no']} : {x['metin']}")])
    cg = cozumle(s["yanit"])
    if cg and not dogrula(cg) and cg[0] != DOGRU[x["konu"]] and n < 3:
        n += 1
        print(f"  kalinti : konu {x['konu']:<8} -> {s['yanit']}")
```

```
duzey            giris  cikis  agda  gecerli A  gecerli B  uydurma  bicim   param  dogru arac
katalogsuz        3694    809    13     0.0500     0.0500   0.6750 0.2083  0.0667      0.0500
ad listesi        6694    825    12     0.2250     0.2833   0.1500 0.0667  0.5583      0.1833
ad ve parametre  11614    684    25     0.6917     0.6917   0.0500 0.1583  0.1000      0.5750

dogrulama 37 cagriyi yakaladi ; gecerli sayilan 83 cagrinin 14 tanesi yanlis araci cagiriyor
dogru arac basina belirtec : katalogsuz 750.5  ad listesi 341.8  ad ve parametre 178.2  
  kalinti : konu ariza    -> cagri tarife_bilgisi abone=4004
  kalinti : konu kesinti  -> cagri ariza_kaydi_ac abone=4011 konu=ariza
  kalinti : konu tarife   -> cagri fatura_getir abone=4012
```

İlk satır düzeneksiz istemcidir ve tek bir sayıyla özetlenir: yanıtların **0,6750**'si var
olmayan bir işlev adı taşıyor. Geçerli çağrı oranı **0,0500**, yani yirmi talebin birinde
yürütülebilir bir çağrı çıkıyor. Model bir arayüzü görmeden onun adını **uyduruyor** ve uydurduğu
adlar makul görünüyor; bir insan gözü onları hemen ayırt edemez.

İkinci satır bu dersin en öğretici satırıdır. Adları vermek uydurma ad payını **0,6750'den
0,1500'e** düşürüyor, ama geçerli oran yalnız **0,2250**'ye çıkıyor. Çünkü parametre hatası
**0,0667'den 0,5583'e** fırlıyor. Hata yok olmadı, **yer değiştirdi**: model artık doğru kapıyı
çalıyor fakat yanlış anahtarla. Tek bir sayıya bakan bir ölçüm bu kaymayı göremez.

## Doğrulamanın Yakaladığı ve Yakalamadığı

Üçüncü satır her iki bilgiyi birden verir: geçerli oran **0,6917**, uydurma ad **0,0500**,
parametre hatası **0,1000**. İki koşum farkı ikinci satırda 0,0583'tür ve düzeyler arasındaki
0,1750 ile 0,4667'lik farklar bunun kat kat üstündedir; bu kazançlar **ölçülmüştür**.

Bedel giriş sütununda durur: **3694'ten 11614 belirtece**, yani **3,14 kat**. Buna karşılık
doğru araç başına belirteç **750,5'ten 178,2'ye** düşüyor. Katalog pahalıdır ve yine de ucuzdur;
çünkü ödenen belirteç, atılan çağrı sayısından daha hızlı azalıyor.

Biçim sütunu düzeylerle birlikte inmiyor: 0,2083, sonra 0,0667, sonra 0,1583. Bunun nedeni yan
sütundadır. Ağ katmanında başarısız olan çağrı sayısı sırasıyla 13, 12 ve **25**'tir; en uzun
istemi gönderen düzey en çok kesilen düzeydir ve kesilen bir çağrı metni ayrıştırılamaz. Biçim
hatasının bir kısmının kaynağı istem değil **ağdır** ve hiçbir katalog onu azaltmaz.

Son iki satır doğrulamanın sınırını yazıyor. Doğrulayıcı **37 çağrıyı** yakaladı; geriye kalan 83
çağrının **14'ü** kayıtlı fakat **yanlış** işlevi çağırıyor. Kalıntı örneklerinde bir arıza talebi
için tarife bilgisi, bir kesinti talebi için arıza kaydı isteniyor. Bu çağrılar şemadan geçer,
yürütülür ve **yanlış sonucu** döndürür. Geçerlilik doğruluk değildir; bir şema neyin
çağrılabileceğini söyler, neyin çağrılması gerektiğini değil.

## Özet

- Araç kaydı, ayrıştırıcı ve dört hata sınıflı doğrulayıcı ders içinde standart kitaplıkla
  yazılır; hiçbir araç yürütülmez.
- Katalog verilmediğinde yanıtların 0,6750'si var olmayan bir işlev adı uydurur ve geçerli çağrı
  oranı 0,0500'de kalır.
- Yalnız adları vermek uydurma adı 0,1500'e düşürür ama parametre hatasını 0,5583'e çıkarır: hata
  yok olmaz, yer değiştirir.
- Adlar ve parametreler birlikte verildiğinde geçerli oran 0,6917, doğru araç oranı 0,5750 olur;
  giriş belirteci 3694'ten 11614'e çıkarken doğru araç başına belirteç 750,5'ten 178,2'ye iner.
- Biçim hatası katalogla azalmaz, çünkü kaynağının bir kısmı ağdır: başarısız çağrı sayısı en
  uzun istemde 25'e çıkar.
- Doğrulama 37 çağrıyı yakalar, ama geçerli sayılan 83 çağrının 14'ü kayıtlı fakat yanlış işlevi
  çağırır ve bu kalıntıyı hiçbir şema yakalamaz.

## Sonraki Adım

Bu derste geçerlilik **sonradan** denetlendi: yanıt geldi, ayrıştırıldı, doğrulandı ve geçmeyen
atıldı. Doğrulayıcı bir sayaç olarak iyi çalıştı, fakat şemadan geçmeyen 37 çağrı için yapabildiği
tek şey onları saymaktı. İstem Mühendisliği kursu biçimi **isteme yazarak** dayatmayı ölçmüş ve
uyum oranını 0,8000'e çıkarmıştı. Arayüzün kendisi üretimi şemanın dışına **çıkaramayacak** biçimde
kısıtlayabiliyorsa, o zaman istemle dayatma ile arayüzle dayatma arasında iki fark vardır: uyum
oranı ve belirteç. Sonraki ders bu ikisini yan yana basar ve arayüz düzeyindeki zorunluluğun neyi
kattığını, neyi katmadığını sayar.
