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
,
a binomiális standard hiba pedig
,
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.
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.
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
példát futtatunk, a költség
ahol és tokenben, és pedig dollár per 1 millió tokenben értendő. A számpélda árai fiktívek, nem aktuális díjszabás: , . Ha átlagosan 70 input- és 20 output token kell példánként, 8 példa költsége dollár. A bíró hívásainak költségét külön hozzá kell adni.
A következő nyolc üzenet a dev-teszt halmazunk. A gold értékeket emberi annotálás rögzítette:
"A rendelésem nem érkezett meg, vissza szeretném kapni a 45 eurót."
→ yes, 4500"Köszönöm, minden rendben." → no, None"A bögre törött, pénzvisszafizetést kérek." → yes,
None"A futár nem találta a címet, de nem kérek visszatérítést."
→ no, None"Kérem, utalják vissza a 12,90 eurót." → yes, 1290"Sziasztok, mikor szállítják a csomagot?" → no,
None"Elállok a vásárlástól, visszatérítést kérek." → yes,
None"Hibás a termék, 5 eurót fizettem, azt kérem vissza." →
yes, 500A 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.
É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.
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.
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?
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?
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.
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).
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.
A pontosság
.
A standard hiba
,
azaz 10,8 százalékpont. A Wilson-intervallum
mellett körülbelül
,
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.
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.
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ő.
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.