27.3 LLM mint sztochasztikus komponens

Az LLM-kimenet értékelése akkor válik tudományos feladattá, amikor a kérdés már nem az, hogy „egy demóban működik-e”, hanem az, hogy milyen hibával, milyen bizonytalansággal és milyen költséggel lehet a rendszerre támaszkodni. Ebben az alfejezetben egy szövegkinyerő feladat specifikációját építjük fel fizetős hívás nélkül. A tanulási helyzet a következő: egy ügyfélszolgálati csapat automatizálná a visszatérítési szándék (refund request) kinyerését rövid üzenetekből. Nincs valós ügyfél; a példaszövegek mesterségesek. A megfigyelési egység egy üzenet, a bemenet message szöveg, a kimenet két mező: refund_request ∈ {yes, no} és amount_minor (pozitív egész EUR-cent vagy None). A cél egy LLM-jelölt összehasonlítása egy reguláris kifejezéses baseline-nal. Induló becslés: ha 50 tesztpéldából 42 lesz teljesen helyes, akkor a pontosság p̂=42/50=0,84\hat p = 42/50 = 0{,}84, a binomiális standard hiba pedig 0,84⋅0,16/50≈0,052\sqrt{0{,}84\cdot 0{,}16/50}\approx 0{,}052, vagyis körülbelül 5,2 százalékpont. Ellenőrizze ezt a kézi számítást, mielőtt továbblép.

27.3.1 Miért sztochasztikus komponens az LLM?

Ugyanaz a prompt és bemenet nem garantálja ugyanazt a kimenetet. A mintavételezési hőmérséklet, a top_p, a szerveroldali routing, sőt a modellfrissítés is változtathatja a választ. Ezért az LLM-hívást úgy kezeljük, mint egy véletlenszerű komponenst: az értékelés nem egyetlen kimenetet, hanem a lehetséges kimenetek eloszlását vizsgálja. A bizonytalanságnak két rétege van: a modell belső sztochasztikája, amelyet ismételt hívásokkal és rögzített seed/alacsony hőmérséklettel csökkenthetünk, és a tesztkészlet mintavételi bizonytalansága, amelyet a korábbi fejezetekben tanult módon (Bootstrap a megfelelő mintavételi egységgel) standard hibával, konfidenciaintervallummal vagy bootstrappal jellemzünk. A kettőt nem szabad összemosni.

27.3.2 Az értékelési specifikáció hét eleme

Prompt version. A prompt nem „szöveg”, hanem verziózott artefaktum. Rögzíteni kell: a sablont, a rendszerutasítást, a modell azonosítóját, a temperature, top_p, max_tokens értékeket, a few-shot példák azonosítóit és a befagyasztás időpontját. Példa rekord:

PROMPT_VERSION = {
    "name": "refund_extract_v1.2",
    "model_id": "hypothetical-local-chat-v0",  # szemléltető név, nem valós modell
    "temperature": 0.2,
    "top_p": 0.9,
    "max_tokens": 40,
    "system": "Extract refund request and amount_minor as JSON. Amount is integer cents or null.",
    "template": "Message: {message}\nJSON:",
    "few_shot_ids": ["dev_01", "dev_02"],
    "frozen_at": "2026-10-20T12:00:00Z",
}

Reference set. Ez az ember által annotált aranykészlet (gold labels). Legalább két annotátor dolgozzon rajta, és az eltéréseket felülvizsgálattal oldják fel. A fejlesztéshez használt dev-rész és az egyszer használt teszt-rész külön fájl legyen.

Rubric. A pontozási útmutató kimondja, mi számít helyesnek. Itt két részfeladat van: a refund igen/nem döntés és az összeg. Minden példa 0–2 pontot érhet: 1 pont a refund mezőért, 1 pont az amount mezőért. Ha a refund értéke no, a modell által adott bármilyen összeg hallucinációnak minősül, tehát 0 pont az amountra, akkor is, ha a goldban None szerepel.

Judge bias. Ha a kiértékelést is LLM-bíró végzi, a bíró maga is sztochasztikus és torzíthat. Gyakori torzítások: a hosszabb, határozottabb válasz előnyben részesítése, a pozíciótorzítás (az első megjelenített válasz preferálása), valamint a saját stílusú válasz felé húzás. Ellenőrzés: a bíró promptjában véletlen sorrendbe állított párok, vak bírálat a gold címkére nézve, és emberi kalibráló minta.

Leakage. A tesztpéldák se a few-shot promptba, se a finomhangoló halmazba, se a bíró példái közé nem kerülhetnek. Ha a bíró látja a gold címkét, az egyetértés felfúvódik. A fejlesztés során a tesztet egyszer, a végső jelentéskor használjuk; a többszöri rápillantás adaptív adathasználat, amely optimista torzítást okoz (visszautalás: Hiperparaméter és nested értékelés).

Latency. A pontosság mellett a válaszidő is része a szerződésnek. Mérjük a kliens oldali időtartamot másodpercben, és adjuk meg a p50, p95 és maximum értéket. A specifikációban timeout is szerepeljen, például 5 másodperc; ha a p95 efölé kerül, az élesítési döntést meg kell állítani.

Token cost. A tokenek száma a modell tokenizálójától függ, nem az egyszerű szótagszámtól. Pontos mérés a válasz usage mezőjéből jön; tervezéskor felső becslést használunk. Ha nn példát futtatunk, a költség

C=∑i=1ntin(i)⋅pin+tout(i)⋅pout106, C = \sum_{i=1}^{n} \frac{t_{\text{in}}(i)\cdot p_{\text{in}} + t_{\text{out}}(i)\cdot p_{\text{out}}}{10^6},

ahol tint_{\text{in}} és toutt_{\text{out}} tokenben, pinp_{\text{in}} és poutp_{\text{out}} pedig dollár per 1 millió tokenben értendő. A számpélda árai fiktívek, nem aktuális díjszabás: pin=3p_{\text{in}}=3, pout=15p_{\text{out}}=15. Ha átlagosan 70 input- és 20 output token kell példánként, 8 példa költsége 8⋅(70⋅3+20⋅15)/106=0,004088\cdot(70\cdot 3+20\cdot 15)/10^6 = 0{,}00408 dollár. A bíró hívásainak költségét külön hozzá kell adni.

27.3.3 Mini példa: nyolc elemű reference set és két jelölt

A következő nyolc üzenet a dev-teszt halmazunk. A gold értékeket emberi annotálás rögzítette:

  1. "A rendelésem nem érkezett meg, vissza szeretném kapni a 45 eurót." → yes, 4500
  2. "Köszönöm, minden rendben." → no, None
  3. "A bögre törött, pénzvisszafizetést kérek." → yes, None
  4. "A futár nem találta a címet, de nem kérek visszatérítést." → no, None
  5. "Kérem, utalják vissza a 12,90 eurót." → yes, 1290
  6. "Sziasztok, mikor szállítják a csomagot?" → no, None
  7. "Elállok a vásárlástól, visszatérítést kérek." → yes, None
  8. "Hibás a termék, 5 eurót fizettem, azt kérem vissza." → yes, 500

A baseline szabály: ha a szövegben bármelyik kulcsszó ("vissza", "visszatérítés", "pénz") szerepel, refund yes; az összeget az euró előtti számból nyeri ki. A mock LLM a "pénzvisszafizetést" összetett szót nem ismeri fel, ezért a 3. példán no-t ad, minden más esetben a baseline szabályt követi. A mock determinisztikus, de a valódi LLM sztochasztikus viselkedését modellezi; itt most a protokoll bemutatása a cél.

Az alábbi kód nem hív távoli modellt. A mock_llm_predict helyettesíti a valódi hívást, a kimenetek pedig elméletileg várt értékek; a könyv írásakor a kód nem lett futtatva.

import math
import re

REFERENCE = [
    {"text": "A rendelésem nem érkezett meg, vissza szeretném kapni a 45 eurót.",
     "refund": "yes", "amount": 4500},
    {"text": "Köszönöm, minden rendben.", "refund": "no", "amount": None},
    {"text": "A bögre törött, pénzvisszafizetést kérek.", "refund": "yes", "amount": None},
    {"text": "A futár nem találta a címet, de nem kérek visszatérítést.",
     "refund": "no", "amount": None},
    {"text": "Kérem, utalják vissza a 12,90 eurót.", "refund": "yes", "amount": 1290},
    {"text": "Sziasztok, mikor szállítják a csomagot?", "refund": "no", "amount": None},
    {"text": "Elállok a vásárlástól, visszatérítést kérek.", "refund": "yes", "amount": None},
    {"text": "Hibás a termék, 5 eurót fizettem, azt kérem vissza.",
     "refund": "yes", "amount": 500},
]

def baseline_predict(text: str) -> dict:
    t = text.lower()
    has_refund = any(k in t for k in ["vissza", "visszatérítés", "pénz"])
    m = re.search(r"(\d+(?:[.,]\d{1,2})?)\s*euró", t)
    if has_refund and m:
        s = m.group(1).replace(",", ".")
        amount = int(round(float(s) * 100))
    else:
        amount = None
    return {"refund": "yes" if has_refund else "no", "amount": amount}

def mock_llm_predict(text: str) -> dict:
    # szándékos hiba: az összetett szót nem ismeri fel
    if "pénzvisszafizetést" in text.lower():
        return {"refund": "no", "amount": None}
    return baseline_predict(text)

def score_pair(gold: dict, pred: dict) -> int:
    s = 0
    if gold["refund"] == pred["refund"]:
        s += 1
    if gold["amount"] == pred["amount"]:
        s += 1
    return s

def evaluate(predict_fn):
    full_correct = 0
    for item in REFERENCE:
        pred = predict_fn(item["text"])
        if score_pair(item, pred) == 2:
            full_correct += 1
    return full_correct

def wilson_ci(x: int, n: int, z: float = 1.96) -> tuple[float, float]:
    p = x / n
    denom = 1 + z*z / n
    center = (p + z*z / (2*n)) / denom
    half = z * math.sqrt(p*(1-p)/n + z*z / (4*n*n)) / denom
    return (center - half, center + half)

# elméletileg várt, szemléltető kimenet:
# baseline: 7/8, Wilson 95% CI (0.53, 0.98)
# mock_llm: 6/8, Wilson 95% CI (0.41, 0.93)
for name, fn in [("baseline", baseline_predict), ("mock_llm", mock_llm_predict)]:
    x = evaluate(fn)
    n = len(REFERENCE)
    lo, hi = wilson_ci(x, n)
    print(f"{name}: {x}/{n} full accuracy, 95% Wilson CI ({lo:.2f}, {hi:.2f})")

A kód értelmezése: a pontosság itt a teljesen helyes példák aránya; a Wilson-intervallum azért jobb a normális közelítésnél, mert 8 elemnél a sikerarány a széleken van, és a degenerált bootstrap replikációk félrevezetnének. A két intervallum nagymértékben átfedi egymást, tehát ebből a 8 elemű mintából nem állítható, hogy a baseline jobb vagy rosszabb a mocknál. A hibatábla viszont már most megmutatja a különbséget: a baseline a tagadást nem kezeli (4. példa), a mock pedig az összetett szót nem ismeri fel (3. példa). Ezért a hibataxonómia gyakran értékesebb, mint egyetlen pontszám.

27.3.4 Feladatok

  1. Értelmezés. A mock LLM a 3. üzeneten hibázik, de egy demóban a 2. üzenetre helyesen válaszolt. Miért nem elegendő ez a demó a rendszerértékeléshez? Válaszában nevezze meg a sztochasztikus komponens és a tesztkészlet-mintavétel szerepét.

  2. Implementálás. Írjon prompt_version rekordot a fenti feladathoz úgy, hogy a few-shot példák a dev halmazból származzanak, és adjon meg egy ötkategóriás hibataxonómiát a kinyerési hibákra.

  3. Hibadiagnózis. Tegyük fel, hogy egy értékelő script a bíró promptjában gold példaként véletlenül a tesztpélda címkéjét is megjeleníti. Milyen irányban torzít ez, és milyen két konkrét javítást tenne?

  4. Megváltozott feltétel. A költségkeret 5 dollárról 1 dollárra csökken, ezért a tesztkészlet 50-ről 12 példára zsugorodik. Tételezzük fel, hogy 10 példa lesz teljesen helyes. Számítsa ki a pontosságot, a binomiális standard hibát és a 95%-os Wilson-intervallumot. Mit tanácsol a döntéshozónak a bizonytalanság alapján?

27.3.5 Megoldások és indoklás

  1. Egyetlen demó nem reprezentál semmit: a sztochasztikus komponens miatt ugyanazt a bemenetet ismételve más kimenetet kaphatunk, a 2. példa pedig csak egyetlen, könnyűnek bizonyuló eset. A tesztkészlet-mintavétel bizonytalansága miatt egy példán a pontossági becslés legfeljebb 0 vagy 1, a konfidenciaintervallum gyakorlatilag használhatatlan. Ellenőrzés: a mock a 3. példán hibázik, holott a 2.-n jól teljesített; a hibák nem eloszlásfüggetlenek.

  2. Példa prompt rekord:

PROMPT_VERSION = {
    "name": "refund_extract_v1.3",
    "model_id": "hypothetical-local-chat-v0",
    "temperature": 0.1,
    "top_p": 0.95,
    "max_tokens": 60,
    "system": "Extract refund_request as yes/no and amount_minor as integer cents or null. Return JSON.",
    "template": "Message: {message}\nJSON:",
    "few_shot_ids": ["dev_03", "dev_07"],
    "frozen_at": "2026-10-21T09:30:00Z",
}

Hibataxonómia: refund_fp (nincs igény, de yes), refund_fn (van igény, de no), amount_wrong (explicit összeg rossz), amount_hallucination (nincs összeg, de a modell ad), format_error (nem a séma szerinti JSON vagy nem egész cent).

  1. A gold címke a bíró promptjában szivárgás. A bíró idomul a megadott goldhoz, így az LLM-jelölt hibáit is „megbocsátja”; az egyetértési arány felfúvódik, a valódi hibák rejtve maradnak. Javítás: a gold címkét törölni kell a bíró bemenetéből, a bírálat legyen vak; második lépésként emberi kalibráló részhalmazon ellenőrizzük a bíró döntéseit, és a végső pontszámot csak a kalibrált bíró adja.

  2. A pontosság p̂=10/12=0,833\hat p = 10/12 = 0{,}833. A standard hiba 0,833⋅0,167/12≈0,108\sqrt{0{,}833\cdot 0{,}167/12}\approx 0{,}108, azaz 10,8 százalékpont. A Wilson-intervallum z=1,96z=1{,}96 mellett körülbelül [0,61;1,00][0{,}61; 1{,}00], a felső határt 1-re vágva. Ez azt jelenti, hogy az igazi pontosság akár 61% is lehet, ami egy refund-automatizálásnál valószínűleg elfogadhatatlan. Javaslat: ne ebből a 12 elemű mintából döntsünk; inkább csökkentsük a hívásonkénti tokenköltséget (rövidebb few-shot, kisebb max_tokens), vagy használjunk olcsóbb szűrőmodellt az előválogatáshoz, és a kiértékelést nagyobb mintán futtassuk. A bizonytalanságot a döntési célhoz kell viszonyítani, nem pedig elfogadni egyetlen pontszámot.

27.3.6 Gyakori tévedés ellenpéldával

A leggyakoribb tévedés az, hogy egyetlen látványos promptpéldát vagy egy LLM-bíró pontszámát rendszerértékelésnek tekintjük. Például: „A 2. üzenetre az LLM tökéletes JSON-t adott, tehát a kinyerő kész.” A 3. üzeneten azonban elbukott, és a 8 elemű tesztből sem tudhatjuk, hogy ez ritka hiba vagy szisztematikus. A rendszerértékeléshez kell a prompt verziója, a reference set, a rubrika, a bíró torzításának ellenőrzése, a szivárgásmentes protokoll, valamint a latency- és költségmérés. Egyetlen szám vagy demó ennek nem helyettesítője.

27.3.7 Önellenőrzés

Mielőtt továbblépne, ellenőrizze: rögzítette-e a promptverziót? A few-shot példák a dev-halmazból jönnek, nem a tesztből? A bíró vak a gold címkére? A pontossági intervallum módszere illik a 12 vagy 50 elemű mintához? Mért latency és tokenfelhasználás is szerepel? Ha bármelyik válasz nem, az értékelési protokoll még nem tudományos. A Bootstrap a megfelelő mintavételi egységgel alfejezetben tanult bootstrapnél a kis, degenerált replikációk figyelmeztetnek; itt a Wilson-intervallum megbízhatóbb választás. A Hibaszeletek és felelős értékelés hibaszelet-tanulsága szerint a 8–12 elemű csoportok bizonytalansága túl nagy ahhoz, hogy határozott rangsorolást tegyünk.

Az LLM-válaszok értékelésében külön kezelendő a feladatminőség, a válaszformátum helyessége, a ténybeli megalapozottság és a költség/latencia. Egyetlen automatikus pontszám nem elegendő.

27.3.8 Rövid összefoglaló

Az LLM-értékelés nem egyetlen prompt kipróbálása, hanem verziózott mérési protokoll: rögzített promptváltozat, annotált reference set, rubrika, vak és kalibrált bíró, leakage-mentes split, latency- és tokenköltség-keret. A pontosságot binomiális mintavételi bizonytalansággal kell közölni; 8–12 elemű tesztnél a konfidenciaintervallum gyakran túl széles a döntéshez. A hibataxonómia értékesebb a győztesválasztásnál: megmutatja, hogy a hiba tagadásból, összetett szóból vagy hallucinációból ered. A következő alkalmazás: ugyanezt a protokollt lefuttatni egy valódi, költségkeretes LLM-hívással, és a mért latency-, token- és hibaszeleteket a döntési célhoz viszonyítani.