Spring AI · Model cavablarının qiymətləndirilməsi · Dərs 1

LLM cavabları üçün keyfiyyət meyarları

Spring AI qiymətləndiriciləri ilə böyük dil modelinin (LLM) cavablarının keyfiyyətini, faktlara uyğunluğunu və verilən kontekstə əsaslanmasını yoxla.

LLM cavabları üçün keyfiyyət meyarları

Giriş modulundakı Study Coach mətn qaytarır, amma HTTP 200 izahın faydalı və ya düzgün olduğunu göstərmir. Spring Boot 3.5.9 və Spring AI 1.1.8 istifadə edən eyni Java 21 layihəsində davam et. Bu dərsdə model əsaslı qiymətləndirici əlavə etməzdən əvvəl nəyi yoxlayacağımızı müəyyən edəcəyik.

1. “Yaxşı cavab” anlayışını ayrı suallara böl

İzahı olmayan tək keyfiyyət rəqəmi əvəzinə ayrı meyarlar istifadə et:

MeyarVeriləcək sualUyğun sübut
Tətbiq müqaviləsiCavab var və göstərilmə limitimizə uyğundur?Deterministik Java testi
UyğunluqÖyrənənin sualına cavab verir?Nəzərdən keçirilmiş nümunələr və sonra qiymətləndirici
Faktların düzgünlüyüJava haqqında iddialar doğrudur?Etibarlı mənbə və texniki baxış
Kontekstə əsaslanmaİddialar verilmiş kontekstlə dəstəklənir?Məhz həmin kontekstlə müqayisə
Tədris dəyəriİzah aydındır və nümunə uyğundur?Yazılı meyarlar əsasında insan yoxlaması
İcra davranışıGecikən və ya uğursuz çağırışda nə baş verir?İnteqrasiya testləri və ölçülmüş icra məlumatları

Bu meyarlar fərqli nəticələr verə bilər. Suala uyğun cavabda yanlış iddia ola bilər; faktları düzgün olan cavab isə sualı cavabsız qoya bilər. Kontekstə əsaslanma konkret istinad mətninin cavabı dəstəkləməsidir, istinadın özünün düzgünlüyünün sübutu deyil. Struktur yoxlamasını “dəqiqlik” adlandırma.

2. Kiçik, yoxlanıla bilən nümunə ilə başla

src/main/java/academy/study/InheritanceReference.java faylını saxla. Bu, əl ilə hazırlanmış tədris istinadıdır, axtarışla gətirilmiş kurs məzmunu deyil:

Java
package academy.study;

public final class InheritanceReference {
    public static final String ID = "java-inheritance-v1";
    public static final String QUESTION = "Can a Java class extend two classes?";
    public static final String CONTEXT = """
            A Java class other than Object has one direct superclass.
            A class may implement multiple interfaces.
            """;

    private InheritanceReference() {}
}

İstinad Java dilinin qaydalarına əsaslanır: Object istisna olmaqla, sinfin bir birbaşa üst sinfi olur, sinif isə bir neçə interfeysi implementasiya edə bilər. Bu, hər üst sinifdən irs almağın mümkün olduğunu demir; final, sealed, görünürlük və konstruktor qaydaları yenə qüvvədədir. Java 21-də üst sinif və interfeys qaydaları

Sabit nümunə ID-si nəyin qiymətləndirildiyini qeyd etməyə imkan verir. Sual və ya istinad əhəmiyyətli dərəcədə dəyişəndə nümunənin versiyasını da dəyiş. Sonrakı dərslər bu istinadı məhdud qiymətləndirici nümunəsində istifadə edəcək. Adi Study Coach generatoru hələ yalnız əvvəlki system təlimatlarını və sualı alır; bu Java sinfinin əlavə edilməsi RAG yaratmır.

3. Bir deterministik göstərilmə qaydası yaz

src/main/java/academy/study/AnswerChecks.java faylını saxla:

Java
package academy.study;

public final class AnswerChecks {
    public static final int MAX_LENGTH = 4000;

    public enum Result { PASS, EMPTY, TOO_LONG }

    private AnswerChecks() {}

    public static Result check(String answer) {
        if (answer == null || answer.isBlank()) {
            return Result.EMPTY;
        }
        if (answer.length() > MAX_LENGTH) {
            return Result.TOO_LONG;
        }
        return Result.PASS;
    }
}

Qayda mətnin boş olmamasını və ən çox 4 000 UTF-16 kod vahidindən ibarət olmasını tələb edir. Limit bu tətbiq üçün tədris seçimidir, Spring AI və ya model limiti deyil. Boşluqlar daxil olmaqla ilkin mətn sayılır. Bu, token büdcəsi, bayt limiti və ya məna ölçüsü deyil.

Yoxlama generasiyadan sonra işləyir, ona görə provayderin həddən uzun cavab yaratmasının və buna görə xərc hesablamasının qarşısını almır. Mətn bu metoda çatana qədər istifadə edilən yaddaşı da məhdudlaşdırmır. Üçüncü dərsdə onu qiymətləndirilən icra yoluna tətbiq edəcəyik; mövcud ümumi endpoint hələ dəyişmir.

4. Qaydanı və məhdudiyyətini sübut et

src/test/java/academy/study/AnswerChecksTest.java faylını saxla:

Java
package academy.study;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

class AnswerChecksTest {
    @Test
    void rejectsMissingText() {
        assertEquals(AnswerChecks.Result.EMPTY, AnswerChecks.check(null));
        assertEquals(AnswerChecks.Result.EMPTY, AnswerChecks.check(""));
        assertEquals(AnswerChecks.Result.EMPTY, AnswerChecks.check(" \n\t"));
    }

    @Test
    void checksExactLengthBoundary() {
        assertEquals(AnswerChecks.Result.PASS,
                AnswerChecks.check("x".repeat(4000)));
        assertEquals(AnswerChecks.Result.TOO_LONG,
                AnswerChecks.check("x".repeat(4001)));
    }

    @Test
    void countsUtf16CodeUnits() {
        String symbol = "\uD83D\uDE00";
        assertEquals(2, symbol.length());
        assertEquals(AnswerChecks.Result.PASS,
                AnswerChecks.check(symbol.repeat(2000)));
        assertEquals(AnswerChecks.Result.TOO_LONG,
                AnswerChecks.check(symbol.repeat(2001)));
    }

    @Test
    void doesNotClaimToDetectFalseStatements() {
        assertEquals(AnswerChecks.Result.PASS,
                AnswerChecks.check("A Java class can extend two classes."));
    }
}

Son test Java haqqında yanlış iddianı qəsdən qəbul edir. Bu dar funksiyanın düzgün davranışıdır: o, faktları deyil, strukturu yoxlayır. Unicode nümunəsi Java sətir uzunluğunun niyə görünən simvolların sayı ilə eyni olmaya biləcəyini göstərir. Bu dörd test model çağırışı etmir və provayder açarı tələb etmir.

5. Bal toplamazdan əvvəl meyarları yaz

İrsilik nümunəsində cavabı yalnız bir neçə birbaşa üst sinifdən irs almağı rədd edirsə və istinada zidd deyilsə, fakt baxımından məqbul kimi qeyd et. İnterfeyslərdən danışmaq faydalıdır, amma üst sinif haqqında sualı cavablandırmağı əvəz etmir. Cavabdakı Java nümunəsini ayrıca kompilyasiya et; oxunaqlı kod da kompilyasiya xətası verə bilər.

Nümunə dəstini məqsədli genişləndir: ingilis dilində sual, onun Azərbaycan dilində qarşılığı, əlçatmaz qapalı fəsli istəyən sual və cavabı qeyri-müəyyən olan sual. Hər nümunə üçün tək dəqiq cümlə yox, gözlənilən davranış müəyyən et. Əlçatmaz fəsil üçün gözlənti fəsil məzmununu uydurmaq deyil, girişin və ya kontekstin olmadığını bildirməkdir.

Nümunə ID-sini, prompt versiyasını, provayder/model identifikatorunu, istinad versiyasını, meyar nəticələrini və yoxlayan şəxsin qeydlərini saxla. İstifadəsinə icazə verilən, məxfi olmayan nümunələr seç. Kiçik dəst geriləmələri tapmağa kömək edir, amma ümumi dəqiqlik faizini müəyyən etmir. Prompt-u yaxşılaşdırmaq üçün istifadə etdiyin nümunələri nəticəni qiymətləndirdiyin nümunələrdən ayır.

6. Yoxlamaları işə sal və əks nümunəni izah et

Layihənin kökündən icra et:

sh
env -u RUN_LIVE_EVALUATION mvn clean verify

İndi on offline test metodu var: əvvəlki altı və bu dörd test. Əmr növbəti dərsdə istifadə edilən real qiymətləndirmə seçimini mühitdən çıxarır. Maven asılılıqları endirə bilər, amma model çağırılmır.

Tapşırıq: AnswerChecks yoxlamasından keçən bir yanlış cavab və yalnız uzunluğa görə rədd edilən bir düzgün cavab yaz. Sonra hər problemi hansı meyarın müəyyən etdiyini seç.

Cavabın yoxlanması: istənilən qısa, boş olmayan yanlış iddia struktur qaydasından keçə bilər. 4 000 kod vahidindən uzun düzgün izah həqiqət yoxlamasından deyil, göstərilmə qaydasından kəsilir. Prompt-u, tətbiq limitini və ya qiymətləndirmə istinadını dəyişmək barədə qərar verəndə bu nəticələri qarışdırma.