Înapoi la blog

AI evals: cum evaluezi un model AI (LLM) în producție

Un LLM care „merge bine în demo" cade tăcut în producție: regresii la fiecare schimbare de prompt, halucinații intermitente, drift. Iată cum construiești un harness de evals care prinde problemele înainte să le vadă utilizatorii.

Categorii:

De ce evaluarea unui LLM nu seamănă cu testarea software clasică

Când scrii o funcție care adună două numere, un test o verifică o dată și rămâne verde până schimbi codul. Un model AI (LLM) nu funcționează așa. Același prompt, trimis de două ori, poate întoarce două răspunsuri diferite. Comportamentul depinde de temperatură, de versiunea modelului, de un cuvânt în plus în context și de o mie de factori pe care nu îi controlezi complet.

Asta face ca „am testat manual și pare bine" să fie una dintre cele mai scumpe iluzii din ingineria AI. Un sistem bazat pe LLM eșuează în moduri care nu apar la primul click:

  • Non-determinism. Nu poți verifica un output cu assertEquals. Ai nevoie de metrici care tolerează variații de formulare, dar prind erori de fond.
  • Regresii tăcute. Schimbi un cuvânt în system prompt ca să rezolvi un caz și, fără să știi, strici alte cincizeci. Nimic nu „crapă" — răspunsurile devin doar puțin mai proaste. Le vezi în review-uri negative peste trei săptămâni, nu în CI.
  • Halucinații intermitente. Modelul inventează un număr de factură, o secțiune de lege sau un endpoint de API care nu există. Nu de fiecare dată — doar suficient de rar cât să nu prinzi în testarea manuală și suficient de des cât să facă rău în producție.
  • Drift. Furnizorul actualizează modelul din spatele aceluiași nume de API, distribuția întrebărilor reale se schimbă, iar comportamentul de acum două luni nu mai e cel de azi.

Evals (de la evaluations) sunt răspunsul inginerilor la aceste probleme: un set de teste automate și semi-automate care măsoară, obiectiv și repetabil, cât de bun este un sistem AI. Nu „pare bine", ci „scor 0,86 pe golden set, +0,02 față de versiunea anterioară, zero regresii peste prag". Evals transformă calitatea LLM-ului dintr-o senzație într-un număr pe care îl poți urmări în timp și pe care îl poți pune ca poartă în CI/CD.

Dashboard de AI evals: scor de calitate pe golden set, faithfulness RAG, rată de refuz, latență p95 și cost pe cerere

Acest ghid parcurge tot ce îți trebuie ca să construiești evals serioase: tipurile de evaluare, metodele de scoring (inclusiv capcanele LLM-as-a-judge), construirea unui golden set, regression testing în CI, metricile operaționale și un workflow concret de la zero la un harness funcțional.

Offline vs online: două lumi de evaluare care se completează

Prima distincție pe care trebuie să o faci este unde rulezi evaluarea.

Evals offline — pe golden dataset

Rulezi modelul pe un set fix de exemple cu răspunsuri așteptate (golden set sau golden dataset), într-un mediu controlat, înainte de deploy. E echivalentul suitei de teste unitare pentru un LLM. Avantaje:

  • Repetabilitate. Aceleași intrări de fiecare dată, deci poți compara versiuni de prompt și de model cap la cap.
  • Rapiditate și cost controlat. Rulezi câteva sute de cazuri în minute, nu aștepți trafic real.
  • Rulează în CI. Poate deveni o poartă automată care blochează un merge care strică calitatea.

Limitarea: golden set-ul reflectă ce ai anticipat tu, nu neapărat ce trimit utilizatorii reali mâine.

Evals online — în producție, pe trafic real

Aici măsori comportamentul pe cereri reale, live. Metodele tipice:

  • Sampling + scoring asincron. Iei un eșantion din traficul real (de exemplu 1–5% din cereri) și îl treci printr-un evaluator, fără să blochezi răspunsul către utilizator.
  • Semnale implicite. Utilizatorul a reformulat imediat întrebarea (semn de răspuns prost)? A dat thumbs up/down? A abandonat conversația? A copiat răspunsul (semn că i-a fost util)?
  • A/B testing și canary. Trimiți un procent mic de trafic către noul prompt sau model și compari metricile între variante înainte de a face rollout complet.

Online prinde exact ce ratează offline: distribuția reală a întrebărilor, edge case-urile pe care nimeni nu le-a scris, drift-ul din timp. Regula practică: offline îți dă viteză și siguranță în CI, online îți dă adevărul. Ai nevoie de amândouă, iar cazurile care eșuează online trebuie să se întoarcă în golden set-ul offline — despre asta mai jos.

Automat vs cu oameni

Ortogonal pe axa offline/online, ai și axa cine evaluează:

  • Automat — metrici programatice sau un LLM-judecător. Scalează la mii de cazuri, e ieftin și rapid, dar poate rata nuanțe.
  • Cu oameni (human-in-the-loop) — evaluatori umani care notează după o rubrică. Scump și lent, dar rămâne standardul de aur pentru sarcini subiective și pentru calibrarea evaluatorilor automați. Nu evaluezi manual mii de cazuri la fiecare deploy; evaluezi câteva zeci periodic ca să verifici că judecătorul automat încă e de acord cu oamenii.

Metode de scoring: de la exact match la LLM-as-a-judge

Metrici clasice și deterministe

Pentru sarcini cu răspuns bine definit, cele mai fiabile evals sunt și cele mai simple:

  • Exact match / normalized match — răspunsul modelului coincide cu cel așteptat (după normalizarea spațiilor, a majusculelor etc.). Ideal pentru clasificare, extragere de câmpuri, răspunsuri închise.
  • Verificare structurală — output-ul e JSON valid? Respectă schema? Câmpurile obligatorii sunt prezente și de tipul corect? Pentru function calling și output structurat, asta prinde majoritatea regresiilor fără niciun LLM implicat.
  • Reguli și assertions — răspunsul conține obligatoriu un anumit token, nu conține o listă de cuvinte interzise, se încadrează într-o limită de lungime, citează o sursă. Ieftin, determinist, rulabil în CI.

Regula de aur: dacă poți verifica ceva determinist, fă-o determinist. Nu chema un LLM-judecător pentru a verifica dacă un JSON e valid.

LLM-as-a-judge: puternic, dar cu capcane

Pentru sarcini deschise (rezumate, răspunsuri conversaționale, redactare) nu există un răspuns unic corect. Aici intervine LLM-as-a-judge: folosești un al doilea model, cu o rubrică explicită, ca să noteze output-ul primului. Îi dai judecătorului criterii clare („evaluează pe o scală 1–5 corectitudinea factuală, apoi separat claritatea") și, ideal, cazuri de referință.

Funcționează surprinzător de bine, dar are biasuri documentate pe care trebuie să le controlezi, altfel scorurile tale mint:

  • Position bias. Într-o comparație A vs B, judecătorul tinde să prefere răspunsul dintr-o anumită poziție (des, primul). Mitigare: rulează comparația în ambele ordini (A-B și B-A) și păstrează verdictul doar dacă e consistent; altfel marchează egalitate.
  • Verbosity bias. Judecătorul confundă „mai lung" cu „mai bun" și premiază răspunsurile stufoase. Mitigare: rubrică ce penalizează explicit redundanța; controlează pentru lungime în analiză.
  • Self-preference bias. Un model tinde să prefere output-uri generate de el însuși sau de modele din aceeași familie. Mitigare: folosește ca judecător un model diferit de cel evaluat (de exemplu, evaluezi output de la Sonnet 5 cu un judecător Gemini 3.1 Pro), sau chiar mai puternic (Claude Fable 5, Opus 4.8).
  • Inconsistență. Același judecător poate da note diferite la aceeași intrare. Mitigare: temperatură joasă, cere note pe o scală discretă cu criterii ancorate, agregă mai multe rulări.

Cea mai importantă disciplină: calibrează judecătorul pe oameni. Ia 50–100 de cazuri notate de evaluatori umani și verifică cât de mult corelează notele judecătorului cu ale lor. Dacă acordul e slab, rubrica ta e proastă sau modelul-judecător e nepotrivit — repari asta înainte să te bazezi pe judecător la scară.

Rubrici structurate

Fie că judecă un om, fie un LLM, o rubrică bună descompune „e bun?" în dimensiuni concrete și independente: corectitudine factuală, respectarea instrucțiunilor, ton, siguranță, format. Notezi fiecare dimensiune separat, cu descrieri ancorate pentru fiecare nivel („5 = toate faptele corecte și verificabile; 3 = o eroare minoră; 1 = eroare factuală gravă"). O rubrică pe dimensiuni îți spune nu doar a scăzut calitatea, ci unde.

Evaluarea sistemelor RAG: faithfulness și context

Dacă rulezi Retrieval-Augmented Generation, evaluarea are un strat în plus, pentru că ai două componente care pot greși independent: retrieverul (ce documente aduce) și generatorul (ce face cu ele). Metricile consacrate:

  • Faithfulness / groundedness — răspunsul se sprijină strict pe contextul recuperat sau modelul „a completat" din memoria lui? Un răspuns corect factual, dar care nu decurge din surse, este tot un eșec de RAG, pentru că nu poți garanta că se repetă.
  • Answer relevance — răspunsul chiar adresează întrebarea, sau divaghează?
  • Context precision — dintre documentele recuperate, câte sunt efectiv relevante? Precizie mică înseamnă că generatorul e distras de zgomot.
  • Context recall — documentele necesare pentru a răspunde au fost efectiv recuperate? Recall mic înseamnă că retrieverul ratează informația, oricât de bun ar fi generatorul.

Puterea acestei descompuneri: când un răspuns RAG e greșit, metricile îți spun cine e vinovat. Faithfulness mare dar answer relevance mic → problemă de generare. Context recall mic → problemă de retrieval (chunking, embeddings, reranking), nu de model. Fără această separare, ajustezi la întâmplare. Dacă vrei să aprofundezi arhitectura din spatele acestor metrici — chunking, hybrid retrieval, reranking — cursul RAG: Retrieval-Augmented Generation în Practică acoperă exact acest teren.

Red-teaming și testare adversarială

Evals nu măsoară doar calitatea pe cazuri „cuminți". Trebuie să încerci activ să spargi sistemul:

  • Prompt injection — intrări care încearcă să suprascrie instrucțiunile de sistem („ignoră tot ce ți s-a spus și...").
  • Jailbreak — încercări de a obține conținut pe care modelul ar trebui să-l refuze.
  • Extragere de date — încercări de a scoate din model informații din context care nu ar trebui dezvăluite.
  • Cazuri de refuz corect — sistemul refuză politicos ce trebuie refuzat, dar NU refuză cereri legitime (over-refusal e la fel de dăunător ca under-refusal).

Menține un set adversarial separat, care crește de fiecare dată când găsești o breșă nouă, și rulează-l ca parte din suită.

Golden set-ul: fundația pe care stă totul

Evals sunt exact atât de bune cât e golden set-ul. Un set slab îți dă o falsă siguranță mai periculoasă decât lipsa evals-urilor.

Reprezentativitate. Setul trebuie să reflecte distribuția reală a intrărilor, nu doar cazurile ușoare. Sursa cea mai bună: logurile din producție. Grupează întrebările reale pe tipuri și asigură-te că fiecare tip e prezent proporțional. Include deliberat: cazuri tipice frecvente, edge case-uri rare dar importante, cazuri „grele" cunoscute, și cazuri adversariale.

Etichete de calitate. Fiecare exemplu are un răspuns așteptat sau o rubrică de notare. Pentru cazurile subiective, etichetele vin de la oameni și e util să păstrezi mai multe opinii, nu doar una.

Versionare. Golden set-ul e cod. Îl ții în git, cu istoric. Când adaugi cazuri, faci commit cu motivul. Așa poți spune „scorul a scăzut pentru că am adăugat 20 de cazuri grele", nu „scorul a scăzut misterios". Nu suprascrii niciodată setul în tăcere.

Creștere continuă. Cel mai valoros mecanism: fiecare bug real din producție devine un caz nou în golden set. Așa te asiguri că o problemă rezolvată nu se mai întoarce niciodată — exact ca un regression test în software clasic.

Igienă anti-contaminare. Ține setul de evaluare separat de orice date folosite la fine-tuning sau la few-shot prompting. Dacă modelul a „văzut" cazurile de test, scorul e umflat și nu-ți spune nimic despre generalizare.

Regression testing în CI/CD: poarta care oprește degradarea

Aici evals devin cu adevărat operaționale. Ideea: niciun prompt și niciun model nu ajunge în producție dacă a scăzut calitatea sub un prag.

Practic, tratezi prompturile ca pe cod:

  • Versionezi prompturile într-un repository, cu istoric și review, exact ca orice altă sursă.
  • La fiecare modificare de prompt sau schimbare de versiune de model, un job de CI rulează suita de evals pe golden set.
  • Compari scorul cu baseline-ul versiunii curente din producție.
  • Definești praguri: dacă scorul general scade sub X, sau dacă orice metrică critică (de exemplu faithfulness sau rata de halucinație) trece pragul, build-ul e roșu și merge-ul e blocat.

Pipeline de evals: golden set, rulare model, scoring cu LLM-as-a-judge și metrici, gate de regresie în CI, apoi producție cu monitoring și feedback loop

Câteva reguli care fac diferența între un gate util și unul enervant:

  • Prag pe regresie, nu pe absolut. Nu blochezi pentru că scorul e „doar" 0,84; blochezi pentru că a scăzut cu 0,05 față de producție. Contează delta.
  • Toleranță la zgomot. Din cauza non-determinismului, rulează fiecare caz de mai multe ori și lucrează cu media; setează pragul dincolo de banda de zgomot ca să nu ai build-uri roșii aleatorii.
  • Metrici critice ca gate dur, restul ca raport. Halucinațiile și breșele de siguranță blochează. Un scor de ton ușor mai mic poate fi doar un avertisment.

Alături de gate-ul de calitate, adaugă guardrails în runtime: validare de schemă pe output, filtre pe conținut interzis, detectoare de prompt injection, verificări de PII. Guardrails prind în producție exact clasele de erori pe care evals le măsoară în CI.

Dacă vrei să transformi toate aceste principii într-un harness funcțional, cu golden set-uri, judecători calibrați și integrare CI, cursul AI Evals pentru LLM-uri în Producție parcurge pas cu pas construirea unui sistem complet de evaluare, pe exemple reale.

Metrici operaționale: calitatea nu e singura dimensiune

Un model care dă răspunsuri excelente în 8 secunde, la un cost pe care nu ți-l permiți, este un model prost pentru producție. Evals serioase urmăresc calitatea împreună cu operaționalul:

  • Latență — nu media, ci p95 și p99. Coada distribuției e ce simt utilizatorii reali în momentele proaste. Măsoară și time-to-first-token dacă faci streaming.
  • Cost — pe cerere și pe 1.000 de cereri, defalcat pe tokeni de intrare și de ieșire. Aici alegerea modelului contează enorm: pentru sarcini simple, un model rapid și ieftin (de exemplu Haiku 4.5) poate egala calitatea unuia scump la o fracțiune din cost; îl afli doar comparând pe evals, nu presupunând.
  • Rata de refuz — cât de des refuză modelul cereri? Un refuz prea des (over-refusal) frustrează utilizatorii legitimi; prea rar poate însemna că guardrails nu funcționează.
  • Rata de eroare de format — cât de des ratează output structurat valid, când e nevoie.
  • Throughput și rate limits — câte cereri pe secundă susții și cum te comporți la limitele furnizorului.

Un cadru practic: privește fiecare schimbare ca pe un trade-off pe trei axe — calitate, latență, cost. Un model nou poate crește calitatea cu 3% dar dubla costul; decizia se ia pe date, nu pe entuziasm. Aceste compromisuri sunt la inima integrării serioase a LLM-urilor, iar Integrare Avansată LLM în Aplicații de Producție tratează în detaliu cum arhitecturezi sisteme care le echilibrează.

Mini-workflow: de la zero la un harness de evals

Iată un traseu concret, aplicabil săptămâna aceasta, indiferent de stack:

  1. Adună 30–50 de cazuri reale. Extrage din logurile de producție (sau, la început de tot, scrie manual) exemple reprezentative. Pentru fiecare, notează intrarea și ce ar însemna un răspuns bun. Ăsta e golden set-ul v1. Pune-l în git.

  2. Definește metricile. Pentru fiecare caz, stabilește cum îl notezi: exact/structural match unde se poate, rubrică + LLM-as-a-judge unde răspunsul e deschis. Scrie rubrica explicit, pe dimensiuni.

  3. Scrie harness-ul minim. Un script care: încarcă cazurile, rulează modelul pe fiecare (cu versiunea de prompt și de model prinse explicit), aplică scoring-ul, agregă un scor per dimensiune și unul general, și salvează rezultatul cu un tag de versiune. Nu ai nevoie de infrastructură fancy — un script și un fișier de rezultate sunt suficiente la început.

  4. Calibrează judecătorul. Notează manual 20–30 de cazuri și compară cu ce spune LLM-judecătorul. Ajustează rubrica până când acordul e rezonabil. Fără pasul ăsta, nu ai voie să te bazezi pe judecător.

  5. Stabilește baseline-ul. Rulează harness-ul pe versiunea din producție și salvează scorurile. Ăsta e reperul față de care compari totul.

  6. Bagă în CI. Un job care rulează suita la fiecare modificare de prompt/model și compară cu baseline-ul. Definește pragurile de regresie și metricile-gate dure (halucinații, siguranță).

  7. Închide bucla cu producția. Pornește sampling pe trafic real, colectează semnale (feedback explicit, reformulări, abandon), și adaugă în golden set fiecare caz de eșec descoperit live. Setul crește, evals devin din ce în ce mai relevante, iar acoperirea urmărește realitatea, nu presupunerile inițiale.

Cheia: începe mic și itererează. Un harness de 50 de cazuri care rulează în CI de mâine bate un sistem perfect pe care îl construiești „luna viitoare".

Evals și monitoring: două jumătăți ale aceluiași sistem

Evals și monitoringul de producție nu sunt lucruri separate — sunt aceeași disciplină în două momente. Evals măsoară calitatea înainte de deploy (offline, în CI); monitoringul o măsoară după (online, pe trafic real). Semnalele din monitoring — spike de latență, creștere a ratei de refuz, scădere a feedback-ului pozitiv, alerte de drift — devin surse pentru cazuri noi de evals. Iar cazurile noi de evals întăresc gate-ul din CI. E o buclă închisă: producția hrănește golden set-ul, golden set-ul protejează producția.

Fără evals, deploy-urile sunt pariuri. Cu evals, fiecare schimbare de prompt sau de model devine o decizie măsurată, cu o poartă automată care oprește degradarea înainte să ajungă la utilizatori. Este diferența dintre a spera că modelul e bun și a ști cât de bun este.

Întrebări frecvente

Ce sunt AI evals și de ce am nevoie de ele? AI evals sunt teste automate și semi-automate care măsoară obiectiv și repetabil calitatea unui sistem bazat pe LLM. Pentru că modelele sunt non-deterministe (același prompt poate da răspunsuri diferite), testarea manuală ratează regresiile tăcute, halucinațiile intermitente și drift-ul. Evals transformă calitatea dintr-o senzație („pare bine") într-un număr pe care îl poți urmări în timp și pune ca poartă în CI/CD.

Care e diferența dintre evals offline și online? Evals offline rulează modelul pe un golden set fix, într-un mediu controlat, înainte de deploy — sunt repetabile, rapide și pot bloca un merge în CI, dar reflectă doar ce ai anticipat tu. Evals online măsoară comportamentul pe trafic real, prin sampling, semnale implicite (reformulări, thumbs up/down, abandon) și A/B testing — prind distribuția reală a întrebărilor și drift-ul. Ai nevoie de amândouă, iar cazurile care eșuează online se întorc în golden set-ul offline.

Ce este LLM-as-a-judge și care sunt capcanele lui? LLM-as-a-judge înseamnă să folosești un al doilea model, cu o rubrică explicită, ca să noteze output-ul primului — util pentru sarcini deschise unde nu există un răspuns unic corect. Capcanele documentate sunt position bias (preferă răspunsul dintr-o anumită poziție), verbosity bias (confundă „mai lung" cu „mai bun") și self-preference bias (preferă output de la modele din aceeași familie). Le mitighezi rulând comparațiile în ambele ordini, folosind rubrici care penalizează redundanța, alegând un model-judecător diferit de cel evaluat și calibrând judecătorul pe note umane.

Cum evaluez un sistem RAG? Pe lângă calitatea generală a răspunsului, un sistem RAG se evaluează pe metrici specifice care separă retrieverul de generator: faithfulness/groundedness (răspunsul se sprijină strict pe contextul recuperat, nu pe memoria modelului), answer relevance (chiar adresează întrebarea), context precision (câte documente recuperate sunt relevante) și context recall (documentele necesare au fost efectiv recuperate). Descompunerea îți spune cine e vinovat când un răspuns e greșit: recall mic → problemă de retrieval; faithfulness mic → problemă de generare.

Ce metrici operaționale urmăresc pe lângă calitate? Latența (mai ales p95 și p99, nu media), costul pe cerere și pe 1.000 de cereri (defalcat pe tokeni de intrare/ieșire), rata de refuz (peste care frustrezi utilizatori legitimi), rata de eroare de format la output structurat și throughput-ul față de rate limits. Fiecare schimbare de model sau prompt se privește ca un trade-off pe trei axe — calitate, latență, cost — și se decide pe date, nu pe entuziasm.

Cum pun evals în CI/CD? Versionezi prompturile ca pe cod, iar la fiecare modificare de prompt sau versiune de model un job de CI rulează suita de evals pe golden set și compară scorul cu baseline-ul din producție. Definești praguri pe regresie (delta față de producție, nu valoare absolută), tolerezi zgomotul rulând fiecare caz de mai multe ori, și tratezi metricile critice (halucinații, siguranță) ca gate dur care blochează merge-ul. În runtime adaugi guardrails: validare de schemă, filtre de conținut și detectoare de prompt injection.

Ți-a plăcut articolul? Lasă o apreciere sau salvează-l pentru mai târziu.
Comunitate

Întrebări & sugestii

Ce au întrebat cititorii despre acest articol — și răspunsurile echipei Cursuri AI.

Mesajele sunt verificate de un moderator înainte de publicare.

Fii primul care lasă o întrebare sau o sugestie pe acest articol.

Continuă să înveți

Aplică ce ai citit pe platformă

Cursuri interactive, exerciții practice și progres salvat. Începe cu un plan potrivit pentru tine.