Kiértékelés
Az automatikus tesztelés második alapvető kérdése, hogy hogy értékeljük ki a válaszok helyességét. Nem akarunk ugyanis manuálisan átnézni minden adott választ. Erre ad megoldást a tesztelés modul.
A kiértékelés nem egyetlen jól definiált feladat, ugyanis az, hogy mennyire „jó“ egy válasz, nem egészen meghatározható. Azon túl, hogy a válasz mennyire tartalmazza a megfelelő információkat, érthetünk rajta akár nyelvtani vagy érzelmi helyességet, de tetszőleges aspektust vizsgálhatunk (tetszőleges segédinformációval megtámogatva).
Mindenesetre a konkrét kiértékelési módszerek leírásánál a megfelelő feladatot is definiáljuk.
Az infrastruktúra
A kiértékeléshez szükséges infrastruktúra nagyrészt az llmevalka modulban van definiálva, illetve ennek az osztályait app-specifikusan az llmevalka_inits.py fájlban inicializáljuk.
A kiértékelés alapegysége a metrika (ABC: MetricBase). A metrika interface szinten kizárólag egyetlen dolgot csinál, mégpedig hogy egy általa kívánt sample-t kiértékel. A kiértékelés eredményét jelenleg az egyszerűség kedvéért megkötjük, hogy számnak kell lennie. Az általunk definiált metrikákat később részletezzük.
A folyamat központja az AsyncEvaluator, melynek célja, hogy egységesíti a szükséges sample formátumot, elvégzi a megfelelő konverziókat, és meghívja a megadott metrikákat. A használt metrikákat és konverziós függvényeket az llmevalka_inits fájlban találjuk.
Segédeszközök
Most bemutatunk néhány segédeszközt, melyeket a metrikákon belül alkalmazunk.
Állításokra bontás
A ClaimExtractor a következő feladatot oldja meg:
Állítások kinyerése
Adott: Egy rövidebb szöveg (pl. mondat, bekezdés)
Feladat: Határozzuk meg az állításokat, melyeket a szöveg megfogalmaz.
Ezt a jelenlegi megoldás egyetlen LLM hívás segítségével végzi.
Logikai kapcsolatok elemzése
Az EntailmentAnalyzer a következő feladatot oldja meg:
Logikai következés
Adott: Egy \(t\) szöveg és egy \(s\) állítás
Feladat: Határozzuk meg, hogy \(s\) következik-e \(t\)-ből, ellentmond-e neki, vagy független tőle.
Jelenleg ezt a következő módon végezzük:
-
Meghatározzuk LLM segítségével párhuzamosan, hogy \(s\) következik-e \(t\)-ből és hogy \(s\) ellentmond-e \(t\)-nek
-
Megfejtjük a logikai következés feladatát a két eredmény aggregálásával
Információ tartalmazása
Az Informationless a következő feladatot oldja meg:
Információ-mentesség
Adott: Egy \(t\) szöveg
Feladat: Határozzuk meg, \(t\) tartalmaz-e bármiféle információt, vagy kizárólag formalitások találhatók benne (visszakérdezés, köszönés, stb…)
Ezt a jelenlegi megoldás egyetlen LLM hívás segítségével végzi.
Kiértékelési aspektusok, metrikák
Most rátérünk a különböző kérdésekre, melyek mentén definiáljuk a metrikákat.
Info
Jelenleg kizárólag a ClaimsFC metrikát alkalmazzuk az admin felületen keresztüli kiértékeléshez. Az általa kalkulált pontszámot továbbá 0.4 felett 1-re kerekítjük heurisztikus vizsgálatok alapján (ugyanis ezek valójában helyes válaszoknak bizonyultak az esetek nagy részében). A kerekítést a backend végzi, a python-service a nyers pontszámot szolgáltatja API-n keresztül.
Tényszerű pontosság
Az első és legalapvetőbb kérdés, amely mentén meghatározhatjuk, hogy mennyire jó egy válasz, hogy mennyire pontos. A mögöttes feladat a következő:
Tényszerű pontosság
Adott: \(a_0\) elvárt válasz és egy \(a\) adott válasz.
Feladat: Mondjuk meg, hogy \(a\) mennyire tényszerűen tükrözi \(a_0\)-t.
Erre két metrikát definiálunk. Az egyik az állítás-alapú, azaz a ClaimsFC. Ennek menete a következő:
- Állításokra bontjuk \(a\)-t, legyenek ezek \(\{c_1, ..., c_k\}\)
- Minden \(c_i\) állításra meghatározzuk, hogy \(c_i\) milyen logikai kapcsolatban áll \(a_0\)-lal.
- Számértékekké konvertáljuk a logikai kapcsolatokat:
KÖVETKEZIKesetén 1,ELLENTMONDesetén 0, ésFÜGGETLENesetén egy \(f \in [0,1]\) előre meghatározott érték. - Átlagoljuk logikai a kapcsolatoknak megfeleltetett számértékeket, ez az eredmény.
Hajtsuk végre fordítva!
Az így számolt módszer az adattudományban „recall“-nak nevezett értéknek többé-kevésbé megfeleltethető mérőszámot ad. Amennyiben \(a\) és \(a_0\) szerepét felcseréljük, úgy megkapjuk a „precision“-t. Végül a kettő segítségével kiszámolhatjuk az F1 értéket.
A másik megvalósítás a RubricsFC. Ehhez LLM-et használunk: megkérdezzük, hogy az alábbi 5 logikai kapcsolat közül melyik írja le \(a\) és \(a_0\) viszonyát:
- Ekvivalencia: \(a\) és \(a_0\) pontosan ugyanazt fogalmazza meg
- Implikált részhalmaz: \(a\) igaz \(a_0\) alapján, de \(a_0\) többet állít
- Implikált szuperhalmaz: \(a\) többet állít \(a_0\)-nál, és nem mond neki ellent
- Ellentmondás: \(a\) ellentmond \(a_0\)-nak
- Függetlenség: \(a\) és \(a_0\) elbeszél egymás mellett
Ehhez az 5 értékhez tetszőlegesen számokat rendelünk, ez lesz a végső pontszám.
Forráshitelesség
A virtuális asszisztens esetén nem feltétlen csak azt akarjuk mérni, hogy egy válasz mennyire pontos, hanem hogy mennyire beszél a rendelkezésre álló információk alapján és mennyire „saját kútfőből“. Ezt hivatott mérni a forráshitelesség.
Forráshitelesség
Adott: \(a\) válasz és \(S\) források.
Feladat: Mondjuk meg, \(a\) mennyire alapszik \(S\)-en, és mennyire saját „tudáson“.
A Faithfulness metrika ezt a következőképp kezeli:
- Állításokra bontjuk \(a\)-t, legyenek ezek \(\{c_1, ..., c_k\}\)
- Minden \(c_i\) állításra meghatározzuk, hogy \(c_i\) milyen logikai kapcsolatban áll \(S\) minden elemével. \(c_i\) állítást hitelesnek tekintünk, ha legalább egy forrásból
KÖVETKEZIK. - A végső pontszám a hiteles állítások aránya.
Forrásrelevancia
A források keresésének minősége elemi kérdés az asszisztens szempontjából.
Forrásrelevancia
Adott: \(q\) kérdés, \(a\) válasz és \(S\) források.
Feladat: Mondjuk meg, \(a\)-hoz mennyire voltak szükségesek a források.
A ContextRelevancy metrika ezt úgy kezeli, hogy minden forrásra LLM-mel eldöntjük, hogy szükséges (avagy inkább hasznos) volt-e az \(a\) válasz megírásához. A végső pontszám a szükségesek száma osztva az összes forrás számával.