Zespół dokłada do produktu czat oparty na LLM, tester pisze pierwszy test automatyczny i po godzinie pyta, co ma assertować, skoro model na to samo pytanie odpowiada za każdym razem innymi słowami. Tę scenę widziałem w kilku projektach. Sam na co dzień buduję evale LLM w Langfuse i spinam je z pipeline’ami CI, więc opisuję proces, który u mnie działa: golden set, sędzia LLM z progiem, ocena po wymiarach, bramka w CI i monitoring produkcji.
Dlaczego «przechodzi / nie przechodzi» nie działa dla LLM?
Bo model językowy jest niedeterministyczny: to samo pytanie zadane dwa razy dostaje dwie różnie sformułowane odpowiedzi. Assert porównujący odpowiedź ze wzorcowym stringiem obleje test nawet wtedy, gdy obie wersje są merytorycznie poprawne. Funkcję z LLM oceniam w skali, a nie zero-jedynkowo.
W klasycznym teście funkcja zwraca 42 albo nie zwraca i na tym dyskusja się kończy. Model zapytany o odwołanie wizyty odpowie raz «Wizyta odwołana», a raz «Gotowe, usunąłem rezerwację z kalendarza». Obie odpowiedzi są dobre i żadna nie pokrywa się ze wzorcem znak po znaku. W jednym z projektów zastałem testy porównujące stringi: zespół wyłączył je po dwóch tygodniach, bo czerwony pipeline przestał cokolwiek znaczyć. Obniżenie temperatury zmniejsza rozrzut odpowiedzi, ale go nie usuwa, a przed zmianą zachowania po aktualizacji modelu nie chroni wcale.
Jak oceniać niedeterministyczne odpowiedzi modelu?
Golden setem i sędzią LLM. Golden set to zestaw pytań-wzorców, zwykle od 50 do 200 pozycji, który opisuje oczekiwane zachowanie funkcji: pytanie, kontekst i wzorcową odpowiedź albo kryteria, jakie dobra odpowiedź musi spełnić. Sędzia LLM (LLM-as-judge) to osobny model, który porównuje odpowiedź testowanej funkcji ze wzorcem i wystawia ocenę od 0 do 1; test przechodzi, gdy wynik przekracza próg, u mnie najczęściej 0,8.
Golden set składam z realnych pytań użytkowników i dokładam przypadki brzegowe: pytania podchwytliwe, niepełne dane, tematy spoza zakresu funkcji. Sędzia dostaje rubrykę oceny napisaną wprost, z kryteriami i przykładami, zamiast ogólnego «oceń jakość odpowiedzi». Sam sędzia też bywa chwiejny, więc kalibruję go na próbce kilkudziesięciu odpowiedzi ocenionych ręcznie i sprawdzam, jak często zgadza się z człowiekiem. Dopiero po kalibracji wpuszczam go do pipeline’u.
Co testować w funkcji opartej na LLM?
Pięć wymiarów: poprawność faktyczną, halucynacje, bezpieczeństwo, trzymanie się instrukcji i zachowanie w rozmowie wieloturowej. Jeden zbiorczy wynik zaciera obraz, bo funkcja potrafi wzorowo trzymać format i równocześnie zmyślać fakty. Każdy wymiar dostaje u mnie osobny scoring i osobny próg.
- Poprawność faktyczna. Sędzia porównuje odpowiedź ze źródłem: bazą wiedzy, dokumentacją, danymi z systemu. Ocenę obniża każda informacja niezgodna ze źródłem.
- Halucynacje. Sprawdzam, czy model nie dopisuje danych, których nie dostał w kontekście: zmyślonych cen, terminów, numerów zamówień. W projektach, które przejmowałem, to najczęstszy powód zgłoszeń od użytkowników.
- Bezpieczeństwo i red-team. Osobny zbiór promptów próbuje wyciągnąć prompt systemowy, obejść ograniczenia i wstrzyknąć instrukcje przez dane wejściowe. Rozbudowuję go po każdym znalezionym obejściu.
- Trzymanie się instrukcji. Format JSON, limit długości, ton, zakazane tematy. Tę część często da się sprawdzić klasycznym kodem, bez udziału sędziego.
- Rozmowy wieloturowe. Testuję całe scenariusze zamiast pojedynczych wymian: czy model po pięciu turach pamięta ustalenia z pierwszej i czy nie zmienia zdania pod naciskiem użytkownika.
Jak spiąć testy AI z CI/CD?
Evale wchodzą do pipeline’u jako zwykły krok z bramką. Po zbudowaniu wersji pipeline uruchamia golden set na środowisku testowym, sędzia liczy oceny, a wynik poniżej progu blokuje wdrożenie. Regresję jakości bramka traktuje tak samo jak oblany test jednostkowy.
W obecnym projekcie mam to spięte z Jenkinsem: job po merge’u odpala evale zdefiniowane w Langfuse i porównuje wynik z poprzednim przebiegiem. Bramka zadziałała też wtedy, gdy dostawca po cichu podmienił wersję modelu. Kod się nie zmienił, a średnia ocena spadła poniżej progu i pipeline stanął przed produkcją. Bez tej bramki o spadku jakości powiedzieliby nam użytkownicy.
Ten sam mechanizm polecam zespołom kodującym z asystentami AI, opisałem go w tekście czy kod z AI jest bezpieczny. Różni się to, co bramka mierzy: tam testy i metryki kodu, tu oceny sędziego na golden secie.
Jak monitorować jakość AI na produkcji?
Narzędziem do obserwowalności LLM, które zapisuje trace każdej interakcji: pełny przebieg zapytania przez łańcuch promptów, koszt w tokenach, latencję i oceny jakości. Ja korzystam z Langfuse. Golden set sprawdza funkcję przed wdrożeniem, a monitoring wyłapuje to, czego zbiór testowy nie przewidział.
Na produkcji uruchamiam evale na próbce ruchu, bo ocenianie sędzią każdej odpowiedzi kosztuje. Do tego alerty: spadek średniej oceny, skok latencji, dzienny koszt tokenów powyżej ustalonej kwoty. Pytania, na których funkcja się wyłożyła, przenoszę do golden setu, więc zbiór testowy rośnie razem z produktem. Konfigurację krok po kroku pokazuję w tekście obserwowalność testów AI z Langfuse.
Jak pomagam w QA Sensei
Od 20 lat pracuję w IT, od siedmiu jako inżynier jakości, a evale LLM i pipeline’y CI buduję na co dzień. W QA Sensei robię Bilans Jakości: przegląd projektu, który pokazuje, czy funkcje AI w produkcie mają siatkę testów, czego w niej brakuje i od czego zacząć, z planem wdrożenia, nie samą diagnozą. Pracuję zdalnie w całej Polsce, a w okolicach Wrocławia także u klienta.
To część szerszego podejścia do jakości kodu z asystentów AI, QA dla kodu tworzonego z AI.