A Northstar szintetikus rendelési adataihoz képzeljünk el egy
bővítést: minden rendeléshez tartozhat egy rövid, opcionális
ügyfélmegjegyzés. A feladat: azonosítsuk, mely megjegyzések utalnak
szállítási sürgősségre vagy panaszra. A bemenet egy szöveg, a kimenet
egy bináris címke: shipping_related (1, ha a szöveg
szállítással kapcsolatos). Az elemzési egység egy megjegyzés. A modellt
egy külső provider LLM API-ján keresztül hívjuk, nem helyben. A cél: úgy
kialakítani a futtatási és értékelési protokollt, hogy a későbbi elemzés
megismételhető legyen.
Előzetes becslés: egy kulcsszó-alapú baseline (például a „delivery”, „shipping”, „late” szavak keresése) körülbelül 70%-os pontosságot érhet el ezen a kis szintetikus készleten. Az LLM várhatóan jobb, de a cél itt nem a maximális pontosság, hanem a reprodukálhatósági szerződés bemutatása.
A külső modell esetén a modellverziót explicit módon kell rögzíteni.
Egy API-név, mint például gpt-4o, egy alias, amely mögött a
provider idővel más modellt is kiszolgálhat. A reprodukálhatósághoz a
provider által kiadott, dátumozott verzióazonosítót kell használni,
például gpt-4o-2024-08-06. A futtatási naplóba a
modellverzió mellett a promptverzió és a kódverzió is bekerül.
Kézi kontroll: ha két futtatás ugyanazt a promptot és bemenetet kapja, de eltérő modellverzióval, a kimenetek eltérhetnek. A verzióhármas (kód, modell, prompt) együttesen azonosítja a futtatást.
A provider határánál pontosan meg kell adni, mely adatok hagyják el a helyi környezetet. A titkos adatok (API kulcsok, személyes azonosítók) nem küldhetők feleslegesen. A szöveges bemenet elküldése előtt ellenőrizni kell, hogy az adatvédelmi szerződés megengedi-e a továbbítást. A Northstar szintetikus adat nem tartalmaz valós személyes adatot, így a példában a továbbítás megengedett, de a protokollt akkor is dokumentálni kell.
A gyorsítótár csökkenti a költségeket és a latenciát, de a cache kulcsának tartalmaznia kell a modellverziót, a promptverziót és a bemenetet. Ha a cache kulcsa csak a bemenetre épül, egy modellfrissítés után a régi eredményt kapjuk vissza, ami hamis reprodukálhatóságot mutat.
Az LLM-kimenetek sztochasztikusak: ugyanaz a bemenet és hőmérséklet mellett is eltérhet a kimenet. A provider általában nem garantál bitazonos kimenetet még azonos seed mellett sem. Ezért az értékeléshez ismételt futtatásokból származó mintavételi bizonytalanságot kell számolni, például a tévesztési arány konfidenciaintervallumát (lásd Predikciós, paraméter- és Monte Carlo intervallum).
Az értékelési protokollt előre rögzíteni kell: a tesztkészlet, a referencia megoldások, a metrikák és a döntési küszöbök. A tesztkészlet nem használható a promptfejlesztés során; a promptot validációs készleten iteráljuk, és a tesztkészlet csak a végső kiértékeléskor kerül elő. Ez a Küszöb, kalibráció és ritka esemény alfejezetben bemutatott küszöbválasztási elv kiterjesztése külső modellre.
A következő kód szemléltető, nem futtatott. Célja a verziókezelés, a cache és a titkok kezelésének bemutatása. A mock LLM egy egyszerű kulcsszó-alapú osztályozót szimulál, hogy ne igényeljen külső API-t.
import hashlib
import json
import os
from pathlib import Path
# Futtatási konfiguráció: kód-, modell- és promptverzió
run_config = {
"code_version": "commit:1a2b3c4",
"model_version": "gpt-4o-2024-08-06",
"prompt_version": "prompt-shipping-v3",
"temperature": 0.0,
}
# Mock LLM: csak szemlélteti az interfészt
def llm_classify(text: str, config: dict) -> str:
# Valós hívás helyett determinisztikus szimuláció
keywords = {"delivery", "shipping", "late", "urgent"}
if any(k in text.lower() for k in keywords):
return "shipping_related"
return "other"
# Cache réteg: kulcs = modellverzió + promptverzió + bemenet hash
cache = {}
def cached_classify(text: str, config: dict) -> str:
key = (
config["model_version"],
config["prompt_version"],
hashlib.sha256(text.encode()).hexdigest(),
)
if key in cache:
return cache[key]
result = llm_classify(text, config)
cache[key] = result
return result
# Titokkezelés: a kulcsot környezeti változóból olvassuk, nem a kódba
api_key = os.environ.get("LLM_API_KEY")
# A kód nem írja ki az api_key értékét a naplóba.
# Példa bemenetek
examples = [
("Please deliver before Friday, it is urgent.", "shipping_related"),
("I would like to add a gift note.", "other"),
("The last delivery was late.", "shipping_related"),
]
# Futtatás és naplózás
results = []
for text, expected in examples:
predicted = cached_classify(text, run_config)
results.append({
"text": text,
"expected": expected,
"predicted": predicted,
"model_version": run_config["model_version"],
"prompt_version": run_config["prompt_version"],
})
# Napló kiírása (api_key nélkül)
print(json.dumps(results, indent=2))Elméletileg várt kimenet (szemléltető, nem mért):
[
{
"text": "Please deliver before Friday, it is urgent.",
"expected": "shipping_related",
"predicted": "shipping_related",
"model_version": "gpt-4o-2024-08-06",
"prompt_version": "prompt-shipping-v3"
},
{
"text": "I would like to add a gift note.",
"expected": "other",
"predicted": "other",
"model_version": "gpt-4o-2024-08-06",
"prompt_version": "prompt-shipping-v3"
},
{
"text": "The last delivery was late.",
"expected": "shipping_related",
"predicted": "shipping_related",
"model_version": "gpt-4o-2024-08-06",
"prompt_version": "prompt-shipping-v3"
}
]A mock LLM mindhárom példát helyesen osztályozza, mert a kulcsszavak
egyértelműek. A valódi LLM esetén a kimenet nem determinisztikus, ezért
a három példa nem elegendő az értékeléshez: több száz vagy ezer
megjegyzésre és ismételt futtatásokra van szükség. A cache kulcs
helyesen tartalmazza a modell- és promptverziót, így egy modellfrissítés
után a régi cache bejegyzések nem használhatók fel tévesen. A naplóban
az api_key nem szerepel, csak a verzióadatok.
Külső modellhívásnál a modellazonosító önmagában nem garantál bitazonos reprodukciót. Rögzítsük az API-verziót, a paramétereket, az input hashét és a visszakapott kimenetet az adatvédelmi szabályok betartásával.
Értelmezés. Miért nem elegendő az API-név
(például gpt-4o) a reprodukálhatósághoz? Adj egy példát
arra, hogyan változhat a kimenet azonos API-név mellett.
Megvalósítás. Írj egy
cached_llm_call függvényt, amely a
model_version, prompt_version és
input_text alapján tárol és visszakeres. A cache tárolja a
kimenetet és a hívás időpontját is. Feltételezheted, hogy az
llm_call(text, config) függvény adott.
Hibadiagnózis. Egy kolléga a cache kulcsát csak
hashlib.sha256(text.encode()).hexdigest() alapján képezi. A
modellfrissítés után a régi cache bejegyzések miatt a rendszer
stabilitást mutat, de a valódi kimenetek megváltoztak. Mi a hiba, és
hogyan javítanád?
Megváltozott feltétel. A feladat többosztályossá
bővül: a megjegyzések három kategóriába sorolhatók:
shipping_related, billing_related,
other. Hogyan módosítanád a futtatási konfigurációt és az
értékelési protokollt? Milyen további adatvédelmi megfontolást
igényelne, ha a megjegyzések valós ügyfélneveket
tartalmaznának?
1. Értelmezés. Az API-név egy alias, amely mögött a
provider idővel frissítheti a modellt. Például a gpt-4o
alias 2024 augusztusában más súlyokat jelentett, mint 2025 januárjában.
Azonos prompt és bemenet mellett a kimenet eltérhet, mert a modellsúlyok
megváltoztak. A reprodukálhatósághoz a provider által kiadott,
dátumozott verzióazonosítót kell rögzíteni, például
gpt-4o-2024-08-06.
2. Megvalósítás. A cache függvény:
import hashlib
import time
cache = {}
def cached_llm_call(text: str, config: dict) -> str:
key = (
config["model_version"],
config["prompt_version"],
hashlib.sha256(text.encode()).hexdigest(),
)
if key in cache:
return cache[key]["result"]
result = llm_call(text, config)
cache[key] = {
"result": result,
"timestamp": time.time(),
}
return result3. Hibadiagnózis. A cache kulcs nem tartalmazza a
modellverziót és a promptverziót. Ha a modell frissül, a régi
bejegyzések továbbra is érvényesnek tűnnek, mert a bemenet hash-je
változatlan. A javítás: a kulcsba be kell építeni a verziókat, például
(model_version, prompt_version, input_hash). Így a
modellfrissítés után a cache automatikusan új bejegyzéseket hoz
létre.
4. Megváltozott feltétel. A futtatási
konfigurációban a promptverziót módosítani kell a többosztályos
feladatra, például prompt-shipping-billing-v1. A kimenet
most három címkét vehet fel, ezért az értékeléshez konfúziós mátrixot és
osztályonkénti pontosságot kell számolni. A referencia megoldásokat a
tesztkészleten frissíteni kell. Ha valós ügyfélnevek szerepelnének, a
provider felé történő továbbítás előtt anonimizálni kell a szövegeket,
vagy a modellt helyben kell futtatni. Az adatvédelmi döntést a jogi és
szervezeti szabályok szerint kell meghozni, nem technikai alapon.
Gyakori tévedés, hogy az API-név rögzített modellt garantál. Példa:
egy kutató a gpt-4o alias-t használja, és a kísérletet 2024
augusztusában futtatja. Három hónappal később a provider frissíti a
modellt ugyanazon alias alatt; a kutató a régi prompttal újra futtat, és
eltérő eredményt kap. A hiba oka, hogy a modellverzió nem volt rögzítve
a futtatási naplóban. A Robusztusság és korlátokkal
írt modellkártya modellkártya elve itt is érvényes: a modellverzió a
kártya része. Önellenőrzés: a futtatási napló tartalmazza-e a kód-,
modell- és promptverziót? A cache kulcsa tartalmazza-e mindhármat?
A külső LLM-modell használatakor a reprodukálhatóság nem automatikus. A futtatást a kód-, modell- és promptverzió hármasa azonosítja; az API-név ehhez nem elegendő. A provider határánál explicit módon döntenünk kell az adattovábbításról és a titkok kezeléséről. A gyorsítótár kulcsa legyen verzióérzékeny, különben a modellfrissítés után régi eredményeket adunk vissza. Az LLM-kimenet nem determinisztikus, ezért az értékeléshez ismételt futtatásokból számolt mintavételi bizonytalanság kell. Az értékelési protokollt előre befagyasztjuk: a tesztkészlet, a referencia megoldások és a metrikák rögzítettek. A következő lépésben ezt a protokollt alkalmazzuk a szöveges baseline-ok összehasonlítására a Szöveges baseline és ritka mátrix egységben.