Ugrás a tartalomhoz
14

Observability

Ha nem látod, mi történik a rendszeredben, akkor nem üzemelteted — csak reménykedsz. Egy nemdeterminisztikus, több model callból, retrievalből, toolból és agent-lépésből álló rendszernél az observability nem utólagos díszítés, hanem az egyetlen módod arra, hogy megértsd, mi ment félre, mennyibe került, és hol javíts.

🔵 Alkalmazásépítés ⏱ ~21 perc olvasás Felülvizsgálva:

Miért érdekel ez téged?

Egy hagyományos webalkalmazásnál a „mennyi ideig tartott a kérés" gyakran elég jó összefoglaló. Egy AI-rendszernél nem az: egyetlen felhasználói kérés a háttérben szétágazik tucatnyi lépésre — több model call, retrieval, reranking, tool hívások, retry-ok, guardrailek —, és bármelyik lehet a lassulás, a hiba vagy a felesleges költség forrása.

Gondolj az observabilityre úgy, mint egy repülőgép fekete dobozára és műszerfalára egyben: a műszerfal (metrikák) folyamatosan mutatja, egészséges-e a rendszer, a fekete doboz (trace-ek) pedig egy incidens után pontosan visszajátssza, mi történt lépésről lépésre. AI-rendszernél mindkettőre szükséged van, mert ugyanaz a prompt máskor máshogy viselkedhet, és nem elég azt tudnod, hogy „hibás volt" — azt is látnod kell, melyik lépésben és miért.

A monitoring és az observability nem szinonimák, és a különbség itt élesebb, mint bárhol máshol a szoftveriparban. A monitoring előre ismert kérdésekre válaszol: „fut-e a szolgáltatás", „mennyi az 5xx arány". Az observability arra képesít, hogy előre nem sejtett kérdéseket is fel tudj tenni utólag, kód-módosítás nélkül: „miért adott ez a konkrét felhasználó tegnap 14:32-kor rossz választ, pontosan melyik chunk került a kontextusába, és hányadik retry után?". Egy determinisztikus CRUD-alkalmazásnál a monitoring gyakran elég. Egy nemdeterminisztikus, elágazó LLM-pipeline-nál nem: itt a hibák többsége nem „a szerver leállt" típusú, hanem „a rendszer működött, csak rosszat csinált" — és ezt csak a mély, lépésenkénti láthatóság deríti fel.

A három pillér AI-kontextusban

A klasszikus observability három adattípusra épül: logok (diszkrét események), metrikák (idősorosan aggregált számok) és trace-ek (egy kérés útja a rendszeren át). AI-rendszernél mindhárom megkapja a maga csavarját. A log itt nem csak „exception a 42. sorban", hanem strukturált esemény, amely tartalmazhat prompt- és válaszrészletet — épp ezért adatvédelmi felület is (lásd lentebb). A metrika nem csak CPU és memória, hanem token, költség, groundedness. A trace pedig nem néhány DB-hívást ölel fel, hanem egy egész agent-loopot, esetleg több agent handoffját is.

Klasszikus web-appAI-rendszer
DeterminizmusUgyanaz a bemenet → ugyanaz a kimenetUgyanaz a prompt máskor más választ ad
Tipikus hiba500-as hiba, timeout, null pointer„Működött, de rossz/hallucinált választ adott"
Latencia tartomány10–200 ms1–30 s, streaminggel több lépcsőben
KöltségmodellFix infra, kérésenként ~0Kérésenként tokenalapú, akár 0,01–1 USD
Fő debug-eszközStack trace + logDistributed trace + eval score + prompt-verzió

A tanulság: a meglévő APM- és logging-tudásod nem dobod ki, de ki kell egészítened. Egy AI-feature ugyanolyan production szolgáltatás, mint bármi más — csak több és furcsább módon tud elromlani, ezért többet és máshogy kell mérned.

Trace-elned kell

A trace egy felhasználói kérés teljes „útvonalterve": egymásba ágyazott span-ek sorozata, ahol minden span egy művelet (egy model call, egy retrieval, egy tool hívás), a saját idejével, be- és kimenetével, státuszával. Olyan, mint egy orvosi lelet, amely nem csak azt írja le, hogy „a beteg rosszul van", hanem lépésről lépésre bemutatja, melyik vizsgálat mit mutatott — így nem tippelned kell a diagnózist, hanem kiolvasod. Az alábbi lépéseket mind fel kell venned a trace-be, mert bármelyik hiánya vakfoltot hagy.

chat_request — 1 trace (span-fa) retrieval 310 ms · 8 chunk rerank 690 ms · top-4 model call #1 540 ms · tool decision model call #2 1780 ms · final answer tool call 180 ms · get_order retry +1000 ms · rate limit
Egyetlen kérés trace-e mint span-fa: a gyökér request span alá csorog a retrieval, a rerank és a model callok, azok alá pedig a tool call és a rejtett retry. A behúzás a hívási hierarchiát, a span-idők a szűk keresztmetszetet mutatják — egy sima „request duration" ezt mind elrejtené.

Span, trace, context propagation — a fogalmi alap

Egy trace egyetlen logikai kérést jelöl, és egy közös trace_id-t hordoz. Ezen belül minden művelet egy span, saját span_id-vel és egy parent_span_id-vel, amely a hívási hierarchiát adja: a gyökér span alá csorog a retrieval span, az alá a rerank, mellette a model call, és így tovább. Ettől lesz a trace fa, nem lista. A kulcsfogalom a context propagation: a trace_id-t végig kell vinned minden határon át — szinkron függvényhíváson, async taskon, message queue-n, sőt külön mikroszolgáltatáson keresztül is. Ha ez elszakad, a trace-ed darabokra hullik, és pont a legérdekesebb átmeneteket veszíted el. Analógia: a trace_id olyan, mint a csomagküldésnél a nyomkövetési szám — ha bármelyik átadásnál lecserélik, onnantól nem tudod végigkövetni az útját.

  • Teljes request A gyökér span a felhasználói kérés belépésétől a válasz elküldéséig — ez adja a végponttól végpontig tartó időt és a keretet, amelybe minden más lépés belóg, így egy pillantással látod, mekkora a teljes kép. Ehhez érdemes már itt csatolni a user_id, session_id és tenant_id attribútumokat, hogy később egy konkrét felhasználó vagy ügyfél összes kérését ki tudd szűrni.
  • Minden model call Külön span minden LLM-hívásnak a latenciájával, token-számával és paramétereivel, mert egyetlen requestben több hívás is lehet, és látnod kell, melyik a lassú vagy drága. Egy tipikus agentic feladatban 3–10 model call is összejöhet — ha ezeket nem bontod szét, egy 18 másodperces trace-nél fogalmad sem lesz, hogy egy lassú hívás vagy nyolc közepes tette-e ki az időt.
  • Prompt- és modellverzió Rögzítsd, pontosan melyik prompt-sablon és melyik pinnelt modellverzió futott, különben egy csendes prompt- vagy provider-frissítés után nem tudod majd megmondani, mitől romlott el hirtelen a viselkedés. Konkrét példa: ha prompt_version: "checkout-v7" és gpt-4.1-2025-04-14 szerepel a spanben, egy regresszió után egyetlen szűréssel látod, hogy a hiba a v6→v7 váltással vagy egy modellfrissítéssel esett egybe.
  • Retrieval A keresés lekérdezése, a visszakapott chunkok és relevancia-pontszámaik, mert a rossz válasz oka gyakran nem a modell, hanem az, hogy rossz vagy hiányos kontextust kapott (lásd 4. RAG). Rögzítsd a chunkok forrás-azonosítóit és score-jait: ha a helyes választ tartalmazó dokumentum a 8. helyen jött vissza, de te csak top-5-öt adsz a modellnek, a hiba a retrievalben van, nem a generálásban.
  • Reranking A reranker bemenete és a végső sorrend, hogy lásd, valóban a legrelevánsabb találatok kerültek-e a válasz elé, vagy a reranker elrontott egy egyébként jó retrievalt. A reranker jellemzően 100–500 ms-ot tesz hozzá a latenciához, ezért külön spanként érdemes mérni: ha a p95 hirtelen megugrik, azonnal látod, a reranker-e a bűnös.
  • Tool call Minden eszközhívás a nevével, argumentumaival, eredményével és időzítésével, mert egy hibás tool-választás vagy rossz argumentum gyakran itt bukik le, nem a modell szövegében (lásd 7. Tool engineering). Ha a modell egy get_order(order_id="ASAP") hívást indít, azt a tool-span argumentumaiból azonnal észreveszed — a végső szöveges válaszból soha.
  • Agent handoff Amikor egy agent átadja a vezérlést egy másiknak, rögzítsd az átadott kontextust és okot, különben multi-agent rendszerben lehetetlen lesz kideríteni, melyik szereplő hibázott (lásd 6. Multi-agent). A handoff a leggyakoribb hibaforrás ezekben a rendszerekben: itt vész el kontextus, itt keletkezik félreértés a delegáló és a végrehajtó agent között.
  • Retry Minden újrapróbálkozás a kiváltó hibával és a backoff-fal, mert a felszínen sikeres kérés mögött lehet három csendes retry, ami latenciát és költséget zabál. Egy exponenciális backoff (1s, 2s, 4s) mellett három retry akár 7 másodperc néma várakozást is jelenthet — a felhasználó csak azt látja, hogy „lassú", te viszont a spanekből pontosan tudod, miért.
  • Guardrail A biztonsági és tartalomszűrő ellenőrzések eredménye, hogy lásd, mikor és miért blokkolt vagy módosított a rendszer egy be- vagy kimenetet — ez a hamis pozitívok és a valódi támadások megkülönböztetéséhez kell (lásd 15. AI security). Ha a guardrail-blokkolási arány hirtelen 0,5%-ról 8%-ra ugrik, az vagy támadási hullám, vagy egy túl agresszív szabály — a trace mondja meg, melyik.
  • Human approval Ahol ember hagy jóvá egy műveletet, rögzítsd ki, mikor és mit döntött, mert ez az auditálhatóság alapja a pénzügyi vagy destruktív lépéseknél. Egy „5000 EUR feletti utalást ember hagyott jóvá" bejegyzés nemcsak debughoz, hanem compliance-hez és felelősség-tisztázáshoz is kell.
  • Tokenhasználat Az input-, output- és reasoning tokenek lépésenkénti bontása, mert a tokenszám a költséged és a context-terhelésed közvetlen mértéke, és csak így látod, hol fúj feleslegesen tele az ablakot valami. Ha egy span input tokenszáma 40 000 fölé kúszik, valószínűleg a teljes beszélgetéstörténetet vagy a fél knowledge base-t beletömöd a promptba — ezt csak lépésenkénti bontással veszed észre.
  • Költség A tokenekből és modellárakból számított pénzérték spanenként, hogy egy drágulás forrását azonnal a konkrét lépéshez tudd kötni, ne csak a hónap végi számlához. Ha input tokenre 5 USD / 1M és outputra 15 USD / 1M az ár, egy 40k input + 2k output hívás ~0,23 USD — spanenként számolva rögtön látod, melyik lépés viszi a büdzsé felét.
  • Cache hit Jelöld, hogy egy hívás prompt- vagy semantic cache-ből jött-e, mert a cache-találati arány közvetlenül magyarázza a latencia- és költségingadozást (lásd 12. Optimalizáció). Egy prompt-cache hit tipikusan a beviteli token árának töredékébe kerül és sokszorosan gyorsabb — ha a cache hit rate 60%-ról 20%-ra esik, az egyszerre magyarázza a hirtelen dráguló számlát és a lassuló p50-et.
  • Output validation A séma- és üzletiszabály-ellenőrzés eredménye, hogy lásd, hányszor adott a modell érvénytelen kimenetet, amit repair vagy retry javított — ez a structured output megbízhatóságának mérőszáma (lásd 3. Structured output). Egy 3% fölé kúszó validációs hibaarány gyakran egy prompt- vagy modellváltás első, csendes tünete.
  • Eval score Csatold a trace-hez a rá futtatott online eval pontszámokat (correctness, groundedness), hogy a minőséget közvetlenül a konkrét production kéréshez tudd kötni, ne csak offline datasethez (lásd 11. Evals). Így nemcsak azt látod, hogy egy trace lassú vagy drága volt, hanem azt is, hogy volt-e — a három dimenzió (sebesség, költség, minőség) egy helyen áll össze.
Python Egy model call span OTel GenAI attribútumokkal
with tracer.start_as_current_span("chat gpt-4.1") as span:
    span.set_attribute("gen_ai.system", "openai")
    span.set_attribute("gen_ai.request.model", "gpt-4.1-2025-04-14")
    span.set_attribute("gen_ai.request.temperature", 0.2)
    resp = client.responses.create(model="gpt-4.1-2025-04-14", input=prompt)
    span.set_attribute("gen_ai.usage.input_tokens", resp.usage.input_tokens)
    span.set_attribute("gen_ai.usage.output_tokens", resp.usage.output_tokens)

A lényeg nem a konkrét mezőnevek bemagolása, hanem az elv: minden lépés egy strukturált, kereshető span, konzisztens attribútumokkal — így egy incidenskor nem log-sorokat grepelsz, hanem egy fát böngészel.

Az egymásba ágyazott span-fa a gyakorlatban

Nézzük meg, hogyan néz ki egy RAG-alapú support-agent egyetlen kérésének span-fája. A behúzás a hierarchiát, a végén az idő a span időtartamát mutatja. Ebből azonnal kiolvasható a történet: a felhasználó kérdezett, két retrieval és egy rerank hozta a kontextust, a modell egy tool-hívással lekérdezte a rendelést, majd megfogalmazta a választ — és a rerank vitte az idő nagy részét.

Text Egy support-kérés span-fája (idő + költség)
chat_request                          3820ms   $0.041   [OK]
├─ guardrail.input_check                42ms
├─ retrieval.vector_search             310ms            8 chunk
├─ retrieval.keyword_search            120ms            5 chunk
├─ rerank.cross_encoder                690ms            top-4
├─ model_call #1 (tool decision)       540ms   $0.006   1200 tok
│  └─ tool.get_order                   180ms            order=A123
├─ model_call #2 (final answer)       1780ms   $0.035  12k tok
│  └─ retry (rate_limit, backoff 1s)  1000ms
└─ guardrail.output_check               38ms

Mit tanulj belőle: a végső 3820 ms-ból a leglassabb egyetlen lépés a második model call egy rejtett retry-jal, a rerank a második legdrágább időben, és a költség 85%-a a nagy kontextusú záró híváson csapódik le. Egy sima „request duration: 3,8s" ennek a semmijét sem árulná el — a span-fa viszont három konkrét optimalizálási célt tár eléd.

Sampling: mit tarts meg és mit dobj el

Ha minden production trace-t teljes tartalommal megtartasz, a tárolási és feldolgozási költség hamar felfalja a rendszer hasznát — nagy forgalomnál a trace-adat könnyen többe kerülhet, mint maga az inferencia. A megoldás a sampling: a head-based sampling a trace elején dönt (pl. minden 10. kérést tartja meg), egyszerű, de vakon dobhat el érdekes hibákat. A tail-based sampling a trace végén dönt, amikor már látja, mi történt — így megtarthatod minden hibás, lassú vagy drága trace-t, és a sikeresekből csak egy mintát. Ez az AI-nál kifejezetten értékes: a hosszú farokban ülő, ritka hibák a legtanulságosabbak, és épp azokat nem szeretnéd véletlenszerűen elveszíteni.

Elkészült trace-ek Head-based elején dönt · pl. minden 10. Kockázat: hibát is vakon eldob Tail-based végén dönt · látja, mi történt hibás / lassú / drága → mind megtart sikeres (OK) → csak minta
Head-based vs. tail-based sampling: a head-based az elején, tartalom ismerete nélkül dönt, ezért vakon eldobhatja a ritka hibás eseteket; a tail-based a végén dönt, így minden hibás, lassú és drága trace-t megtart, a sikeresekből pedig csak mintát — pont ezért ez az érték az AI-debugban.

Fontos metrikák

A trace egy-egy kérés mikroszkópja; a metrikák a rendszer egészének műszerfala. A leggyakoribb hiba, hogy csak az átlagot nézed — pedig az átlag hazudik. Ha egy étterem átlagos várakozási ideje 5 perc, az még bőven jelentheti, hogy minden tizedik vendég fél órát vár: az átlag elrejti a farokban ülő, dühös felhasználókat. Ezért a latenciát mindig percentilisekben nézd.

MetrikaMit mér és miért fontos
p50 / p95 / p99 latencyA válaszidő eloszlása, nem az átlaga. A p50 a tipikus élmény, a p99 a legrosszabb 1%-é — production SLO-t szinte mindig p95-re vagy p99-re tűzöl ki, mert a farok fáj a felhasználónak.
TTFT (time-to-first-token)Streamingnél mennyit vár a felhasználó az első jelig. UX szempontból gyakran fontosabb, mint a teljes válaszidő — a korai első token „élőnek" érezteti a rendszert.
End-to-end completion timeA teljes feladat ideje, az összes model call, tool és retry együtt. Ez az, amit a felhasználó ténylegesen megtapasztal, nem az egyes hívások ideje.
Input / output / reasoning tokensA három tokentípus fogyasztása. A reasoning token rejtett költség: nem látod a kimenetben, de fizetsz érte és tölti a budgetet.
Cost / requestAz egy hívásra jutó átlagos költség. Alap kapacitástervezési szám, de önmagában félrevezető, ha sok a sikertelen próbálkozás.
Cost / successful taskA valódi üzleti költség: a sikeres feladatra vetített ár, amelybe a hozzá vezető sikertelen kísérletek is beleszámítanak. Ez a metrika mutatja meg, mennyibe kerül tényleg egy megoldott ügy.
Tool calls / requestHány eszközt hív egy kérés. Hirtelen megugrás gyakran rossz tervezés vagy tool-választási hiba jele.
Retries / requestHány újrapróbálás átlagosan. Magas érték instabil providerre, rossz promptra vagy törékeny sémára utal.
Agent turnsHány ciklust futott az agent-loop egy feladatra. A kiugró értékek végtelen loopot vagy rossz kilépési feltételt jeleznek.
Success rateA feladatok hány százaléka teljesült ténylegesen. A legfontosabb minőségi mutató, de definiálnod kell, mit jelent a „siker" az adott use case-ben.
Hallucination / groundedness scoreMennyire támaszkodik a válasz a valós forrásokra a kitalálás helyett. Eval-alapú, folyamatos mérőszám (lásd 11. Evals), nem egyszeri teszt.
Human takeover rateHányszor kellett emberi beavatkozás. Az automatizáltság foka és egyben a bizalmi szint mérője — ha nő, valami romlik.
Abandonment rateHány felhasználó hagyja félbe a folyamatot. Csendes elégedetlenség-jelző: nem panaszkodnak, csak elmennek.
Error taxonomyA hibák típus szerinti osztályozása (timeout, rate limit, séma-validációs hiba, refusal, tool-hiba). Enélkül minden hiba egyforma „error", és nem tudod, mit javíts először.
Provider availabilityA külső modellprovider elérhetősége és hibaaránya. Mivel egy külső szolgáltatástól függsz, ezt is monitoroznod kell, hogy fallbacket tudj indítani (lásd 13. Production architektúra).

Miért hazudik az átlag — egy konkrét példa

Tegyük fel, hogy 1000 kérésed van, 950 közülük 1,2 s alatt lefut, 50 pedig 12 s-ig tart (egy lassú provider vagy egy retry-hullám miatt). Az átlag ~1,7 s — ránézésre kiváló. A p95 viszont már a lassú tartományban ül, a p99 pedig teljes egészében a 12 s-os fájdalom. Ha az SLO-dat az átlagra tűzöd ki, „zöld" a dashboard, miközben minden huszadik felhasználó tízszer lassabb élményt kap. Ezért kötsz production SLO-t szinte mindig p95-re vagy p99-re: ezek reprezentálják a valós felhasználói fájdalmat, nem egy statisztikai fikciót.

A cost per successful task a valódi észak

Az AI-rendszereknél a legfélrevezetőbb metrika a puszta „cost per request". Képzeld el, hogy egy agent átlagosan 0,04 USD-ből válaszol egy kérésre — olcsónak tűnik. De ha a feladatok 40%-a csak a harmadik nekifutásra sikerül (két sikertelen, drága próbálkozás után), a valós cost per successful task ennek a többszöröse lehet. Ez a szám köti össze a technikai és az üzleti valóságot: ez alapján tudod eldönteni, hogy egy AI-feature egyáltalán megéri-e, és ez mutatja meg leghamarabb, ha egy „olcsóbb" modellre váltás valójában drágább lett, mert több retry-t igényel.

Python Cost per successful task számítása egy időablakra
def cost_per_successful_task(traces):
    total_cost = sum(t.cost_usd for t in traces)      # minden próbálkozás
    successful = sum(1 for t in traces if t.success)  # csak a megoldott ügyek
    if successful == 0:
        return float("inf")   # égető jelzés: fizetsz, de semmi sem sikerül
    return total_cost / successful

# 1000 trace, 620 sikeres, összesen 41 USD  ->  0.066 USD / sikeres feladat
print(cost_per_successful_task(last_hour_traces))

Mit tanulj belőle: az összes költséget a sikeres feladatokra osztod, nem az összesre. Ha ez a szám romlik, miközben a cost/request javul, biztosan nő a sikertelen próbálkozások aránya — pont ezt a csapdát rejti el a naiv átlag.

Dashboardök és alerting: mit tegyél a képernyőre

A metrika önmagában holt adat, amíg valaki nem néz rá időben. Építs egy „arany jelek" dashboardot, amely egy képernyőn mutatja a p95 latenciát, a hibaarányt, a cost per successful taskot és a success rate-et — ez a napi egészség-műszerfal. Az alertek küszöbeit relatíve, ne abszolút értékre húzd meg, mert az AI-forgalom természetesen ingadozik: „a hibaarány 3× a tegnapi azonos időszakhoz képest" hasznosabb riasztás, mint „a hibaarány > 2%". A finomabb minőségi romlásokhoz — amelyek nem dobnak hibát, csak butábban válaszol a rendszer — az online eval score-ok trendjét figyeld, mert egy prompt-drift vagy egy csendes modellfrissítés gyakran csak a groundedness lassú csúszásában látszik.

Hibakeresés a gyakorlatban

Az observability akkor ér valamit, ha egy incidens során percek, nem órák alatt jutsz a gyökérokhoz. Egy AI-rendszernél a debug ritkán stack trace-olvasás — sokkal inkább nyomozás: melyik lépésen csúszott el a fa, és miért. Érdemes egy ismételhető gondolatmenetet követned ahelyett, hogy random logokat grepelnél.

„Lassú a rendszer" panasz

  • Nézd a p95/p99 latenciát, ne az átlagot — kik a lassú farokban?
  • Szűrj a lassú trace-ekre, és nézd a span-fát: egy lassú lépés vagy sok közepes?
  • Ellenőrizd a retry-okat és a cache hit rate esését — gyakori rejtett ok.
  • Vizsgáld a provider availabilityt: nem a te kódod, hanem a modellprovider lassult-e?

„Rossz választ adott" panasz

  • Nyisd meg a konkrét trace-t user_id + időbélyeg alapján.
  • Nézd a retrieval spant: benne volt-e egyáltalán a helyes forrás a kontextusban?
  • Ha benne volt, de a rerank kidobta → reranker probléma; ha be sem került → retrieval probléma.
  • Ha jó volt a kontextus, de a modell mégis rosszul válaszolt → prompt- vagy modellverzió-kérdés, csatolt eval score.

A kulcs, hogy a trace-ből egyértelműen szét tudd választani a retrieval-hibát a generálási hibától — mert ez a két ok teljesen más javítást igényel. A rossz retrievalt jobb chunkolással, hybrid kereséssel vagy rerankerrel javítod (lásd 4. RAG); a rossz generálást prompt-átírással, modellváltással vagy structured output kényszerítéssel (lásd 3. Structured output). Ha nem látod, melyikről van szó, vaktában optimalizálsz.

Korreláció: trace, log és metrika összekötése

A három adattípus akkor válik igazán hasznossá, ha összeköthető. Egy közös trace_id-t vigyél be a strukturált logokba is, hogy egy metrika-alert (pl. hibaarány-ugrás) → egy példa trace → a hozzá tartozó logsorok útvonalon másodpercek alatt navigálhass. Az AI-nál külön értékes egy stabil request_id, amit a felhasználónak is megmutatsz a hibaüzenetben: amikor beír egy support-jegyet, hogy „a rendszer hülyeséget mondott, azonosító: R-8842", te egyetlen kereséssel előhúzod a teljes trace-t. Ez a visszakövethetőség a különbség a „nem tudjuk reprodukálni" és a „megvan, itt a hiba" között.

Metrika-alert hibaarány-ugrás Példa trace span-fa Strukturált log a hibás sorok Support-jegy: R-8842 trace_id trace_id request_id
Korrelációs útvonal: a közös trace_id köti össze a metrika-alertet, a példa trace-t és a hozzá tartozó logsorokat, a felhasználónak megmutatott request_id pedig egy support-jegyből is ugyanazt a trace-t nyitja meg — így másodpercek alatt navigálsz a tünettől a gyökérokig.

Privacy és adatvédelem

Az AI observability legkényesebb feszültsége: a debugoláshoz a legszívesebben minden promptot és választ eltárolnál, de éppen ezek tartalmazzák a legérzékenyebb adatokat — felhasználói üzeneteket, dokumentumrészleteket, személyes információkat. Az EU-ban a GDPR keretei között ez nem opcionális kérdés: a promptban és a válaszban simán lehet személyes adat, így annak kezelésére ugyanazok a jogalapi, célhoz kötöttségi, adatminimalizálási és tárolási korlátozási szabályok vonatkoznak, mint bármely más személyes adatra.

A megoldás nem az, hogy nem trace-elsz, hanem hogy tudatosan szabályozod, mi kerül el hozzád és meddig marad ott. A következő eszközök együtt adnak biztonságos observabilityt:

Nyers prompt + válasz Opt-in content kapu Collector redaction + hashing Trace store retention + access control Debug-nézet: redaktált, mintavett Audit-nézet: teljes, naplózott
Privacy by design feldolgozási sor: a nyers tartalom csak az opt-in kapun át indul, a redaction és a hashing még a tárolás előtt, a collectorban takarja ki az érzékeny mezőket, a trace store-t retention policy és access control védi, olvasásra pedig külön redaktált debug- és naplózott audit-nézet szolgál.
  • Opt-in content capture Alapból csak metaadatot (idő, token, státusz) rögzíts, a nyers prompt- és válaszszöveget csak explicit, indokolt beleegyezés vagy jogalap mellett. A tartalommentés legyen tudatos döntés, ne a rendszer alapértelmezése. Sok observability-tool alapból mindent felszív — ezt a kapcsolót kifejezetten át kell állítanod, különben az „alapértelmezés" dönt helyetted.
  • Redaction A mentés előtt automatikusan takard ki az érzékeny mezőket (név, e-mail, kártyaszám, egészségügyi adat). Olyan ez, mint egy nyilvánosságra hozott dokumentum feketével kihúzott sorai: a kontextus megmarad, a személyes adat nem. A redactionnek a tárolás előtt, a folyamatban (pl. az OTel collectorban) kell megtörténnie — ha már beírtad a DB-be, elkéstél.
  • Hashing Ahol nem a tartalom, csak az azonosság vagy az ismétlődés érdekel (pl. „ugyanaz a felhasználó vagy dokumentum tért-e vissza"), tárold a nyers érték helyett annak hash-ét — így korrelálni tudsz anélkül, hogy az eredeti adatot megőriznéd. Használj sózott hash-t, különben egy kis értékkészletnél (pl. telefonszámok) a hash visszafejthető.
  • Sampling Nem kell minden kérés teljes tartalmát megőrizni: elég egy reprezentatív minta, ahogy egy közvéleménykutatás sem kérdez meg mindenkit. A mintavétel csökkenti a tárolt érzékeny adat mennyiségét és a tárköltséget is, miközben a trendek láthatók maradnak. A privacy és a költség itt ugyanabba az irányba húz — kevesebb tárolt tartalom kevesebb kockázat és kevesebb számla.
  • Retention policy Határozd meg, meddig őrzöd az egyes adattípusokat, és automatikusan töröld a lejártakat. A GDPR tárolási korlátozás elve tiltja az „örökre megtartjuk" hozzáállást — a retention policy ezt kényszeríti ki gépiesen. Tipikus felállás: a nyers tartalom rövid (pl. 7–30 nap), az aggregált, anonimizált metrika hosszú (hónapok–évek) megőrzéssel.
  • Access control A trace-ekhez és különösen a nyers tartalomhoz csak az férjen hozzá, akinek tényleg kell, szerepkör alapján. A megfigyelőrendszer maga is támadási felület: egy túl bőkezű hozzáférés az egész adatvagyont kiteszi (lásd 15. AI security). Ha a fél cég olvashatja az összes felhasználói beszélgetést, az önmagában adatvédelmi kockázat.
  • Külön audit- és debugnézet Válaszd szét a nézeteket: a fejlesztő debughoz lásson redaktált, mintavett adatot, míg a teljes, ki nem takart tartalom csak szigorúan kontrollált, naplózott audit-hozzáféréssel legyen elérhető, konkrét jogalap mellett. Maga a nyers tartalomhoz való hozzáférés is legyen naplózott esemény — az auditált audit a végső biztosíték.

Data residency és a provider mint adatfeldolgozó

EU-s közönségnél két további kérdést sem hagyhatsz figyelmen kívül. Az egyik a data residency: hol tárolódnak fizikailag a trace-adatok és a promptok? Ha egy US-alapú observability-SaaS-ba küldöd a nyers felhasználói tartalmat, azzal határon átnyúló adattovábbítást végzel, aminek megvannak a maga jogi feltételei. A másik, hogy a modellprovider is adatfeldolgozó: tisztázni kell, betanít-e az adataidon, meddig őrzi meg a kéréseidet, és van-e megfelelő adatfeldolgozási szerződés (DPA). Sok vállalati üzemeltetés épp emiatt választ regionális endpointot, zero-retention beállítást vagy self-hosted modellt (lásd 16. AI Platform) — nem teljesítmény, hanem adatvédelmi okból.

Összefoglalás

Az observability az a réteg, amely egy AI-demót üzemeltethető production rendszerré tesz. Egyetlen „request duration" metrika kevés: minden lépést trace-elned kell — model callt, retrievalt, reranking-et, tool hívást, agent handoffot, retry-t, guardrailt, tokent, költséget, cache hitet, validációt és eval score-t —, lehetőleg az OpenTelemetry GenAI semantic conventions szabványos attribútumaival, hogy a trace-eid hordozhatók legyenek. A trace-t egy egymásba ágyazott span-faként képzeld el, ahol a context propagation tartja össze a képet, és tail-based samplinggel épp a hibás, drága, lassú eseteket őrzöd meg.

A metrikáknál ne az átlagot, hanem az eloszlást (p50/p95/p99) és a valódi üzleti mutatókat (cost per successful task, success rate, groundedness) figyeld, és mérd a technikai és a minőségi oldalt is. A hibakeresésnél a trace-ből egyértelműen tudd szétválasztani a retrieval- és a generálási hibát, mert más javítást igényelnek, és köss össze trace-t, logot és metrikát egy közös azonosítón át. A privacy pedig nem utólagos gond: a teljes prompt- és válaszlogolás könnyen adatvédelmi incidens, ezért opt-in tartalommentéssel, redactionnel, hashinggel, samplinggel, retention policyval, hozzáférés-kontrollal, elkülönített audit-nézettel és tudatos data residency döntésekkel kell GDPR-konform megfigyelést építened. Ha ezt jól csinálod, nem reménykedsz — látsz.