0Pricing
AI Prompt Engineering · Lezione

Uso degli LLM per valutare gli output degli LLM

Perché i giudici LLM funzionano e in quali aspetti falliscono rispetto alla valutazione umana

Uso degli LLM per valutare gli output degli LLM è una lezione AI Prompt Engineering gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento AI Prompt Engineering, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso AI Prompt Engineering include 4 lezioni in totale.

Perché usare un LLM come giudice?

Le metriche di valutazione tradizionali — BLEU, ROUGE, corrispondenza esatta — funzionano per gli output strutturati, ma non riescono a valutare qualità più sfumate come utilità, accuratezza, tono e creatività.

La valutazione umana coglie le sfumature, ma è lenta e costosa. LLM-as-judge offre una via di mezzo: una valutazione automatizzata che comprende il significato semantico, il contesto e la qualità soggettiva, su larga scala e a basso costo.

Perché i giudici LLM funzionano

I giudici LLM funzionano perché condividono la stessa capacità di comprensione linguistica del modello valutato. Possono stimare:

  • Se una risposta è accurata dal punto di vista fattuale, non solo lessicalmente simile a un riferimento
  • Se una risposta è utile per lo scopo dichiarato
  • Se il tono soddisfa i requisiti
  • Se un riepilogo coglie i punti essenziali

Si tratta di qualità che le semplici metriche basate sul confronto tra stringhe non possono misurare.

Un giudice LLM semplice

Il giudice LLM più semplice consiste nel chiedere al modello di valutare una risposta su una scala numerica, fornendo una breve motivazione. Questa è la base su cui si fondano tutti i modelli di giudice più avanzati.

import anthropic
import json

client = anthropic.Anthropic(api_key='sk-ant-...')

def simple_llm_judge(question, response, criterion):
    judge_prompt = (
        f'Rate the following response on {criterion} from 1 to 5.\n\n'
        f'Question: {question}\n'
        f'Response: {response}\n\n'
        f'Return JSON: {{"score": <1-5>, "reason": "<one sentence>"}}'
    )
    r = client.messages.create(
        model='claude-opus-4-5',
        max_tokens=100,
        messages=[{'role': 'user', 'content': judge_prompt}]
    )
    try:
        result = json.loads(r.content[0].text)
        return result['score'], result['reason']
    except Exception:
        return None, r.content[0].text

score, reason = simple_llm_judge(
    question='What is recursion in programming?',
    response='Recursion is when a function calls itself.',
    criterion='clarity and completeness'
)
print(f'Score: {score}/5 — {reason}')

Dove i giudici LLM falliscono: bias di posizione

Bias di posizione: quando vengono presentate due risposte (A e B), i giudici LLM tendono a preferire quella che compare per prima, indipendentemente dalla qualità. Gli studi mostrano che questo fenomeno riguarda il 60-70% dei confronti a coppie quando si usa un prompt ingenuo per il giudice.

Ciò significa che l'ordine in cui presenta le opzioni cambia il verdetto del giudice.

import anthropic

client = anthropic.Anthropic(api_key='sk-ant-...')

def demonstrate_position_bias(question, response_a, response_b):
    def ask_judge(first, second, order):
        prompt = (
            f'Question: {question}\n\n'
            f'Response 1: {first}\n\n'
            f'Response 2: {second}\n\n'
            f'Which response is better? Reply with 1 or 2.'
        )
        r = client.messages.create(
            model='claude-opus-4-5',
            max_tokens=10,
            messages=[{'role': 'user', 'content': prompt}]
        )
        choice = r.content[0].text.strip()
        # Map back to original labels
        if order == 'AB':
            return 'A' if choice == '1' else 'B'
        else:  # BA
            return 'B' if choice == '1' else 'A'

    result_ab = ask_judge(response_a, response_b, 'AB')
    result_ba = ask_judge(response_b, response_a, 'BA')

    print(f'Order A-B: Judge picked {result_ab}')
    print(f'Order B-A: Judge picked {result_ba}')
    if result_ab != result_ba:
        print('Position bias detected: different results!')

    return result_ab, result_ba

Dove i giudici LLM falliscono: bias della prolissità

Bias della prolissità: i giudici LLM tendono a valutare più positivamente le risposte più lunghe e dettagliate, anche quando una risposta concisa è oggettivamente migliore. Una risposta che usa 400 parole per dire ciò che se ne potrebbe dire in 50 riceve spesso un punteggio più alto della versione concisa.

Per ridurre questo effetto, chieda esplicitamente al giudice di penalizzare la lunghezza non necessaria.

import anthropic

client = anthropic.Anthropic(api_key='sk-ant-...')

def length_aware_judge(question, response):
    judge_prompt = (
        f'Evaluate this response for quality. Be aware of verbosity bias: '
        f'do NOT score longer responses higher just because they are longer.\n\n'
        f'Question: {question}\n'
        f'Response: {response}\n\n'
        f'Evaluate on:\n'
        f'1. Accuracy (does it correctly answer the question?)\n'
        f'2. Conciseness (does it avoid unnecessary filler?)\n'
        f'3. Helpfulness (does it serve the user well?)\n\n'
        f'Penalize responses that add filler, repetition, or irrelevant information.\n'
        f'Score each 1-5 and provide an overall score. Return JSON.'
    )
    r = client.messages.create(
        model='claude-opus-4-5',
        max_tokens=200,
        messages=[{'role': 'user', 'content': judge_prompt}]
    )
    print(r.content[0].text)

Dove i giudici LLM falliscono: preferenza per se stessi

Bias di auto-preferenza: quando Claude valuta due risposte, tende a preferire quelle che assomigliano alle risposte di Claude. Quando valuta GPT-4, tende a preferire quelle che assomigliano alle risposte di GPT-4. Si tratta di un bias sistematico che riguarda tutti i giudici LLM.

Per ridurlo, usi più modelli diversi come giudici e aggreghi i loro punteggi. Un disaccordo segnala un caso borderline che richiede una revisione umana.

import anthropic
import openai

anthropic_client = anthropic.Anthropic(api_key='sk-ant-...')
openai_client = openai.OpenAI(api_key='sk-...')

def multi_model_judge(question, response):
    judge_prompt = (
        f'Rate this response 1-10 for overall quality.\n'
        f'Q: {question}\nA: {response}\n'
        f'Reply with only a number.'
    )

    # Judge 1: Claude
    r_claude = anthropic_client.messages.create(
        model='claude-opus-4-5',
        max_tokens=10,
        messages=[{'role': 'user', 'content': judge_prompt}]
    )
    score_claude = float(r_claude.content[0].text.strip())

    # Judge 2: GPT-4o
    r_gpt = openai_client.chat.completions.create(
        model='gpt-4o',
        max_tokens=10,
        messages=[{'role': 'user', 'content': judge_prompt}]
    )
    score_gpt = float(r_gpt.choices[0].message.content.strip())

    avg = (score_claude + score_gpt) / 2
    print(f'Claude judge: {score_claude}, GPT judge: {score_gpt}, Average: {avg}')
    if abs(score_claude - score_gpt) > 2:
        print('WARNING: High disagreement — consider human review')
    return avg

Inflazione dei punteggi

Inflazione dei punteggi: i giudici LLM tendono ad assegnare punteggi elevati (4-5 su 5) alla maggior parte delle risposte, comprimendo la distribuzione e rendendo difficile distinguere una risposta buona da una eccellente. Risposte che meriterebbero 3/5 ricevono spesso un punteggio di 4-4,5/5.

Per risolvere il problema, usi una rubrica che imponga una calibrazione oppure preferisca un punteggio relativo (a coppie) a uno assoluto.

# Anti-inflation judge prompt with explicit score anchors
CALIBRATED_JUDGE_PROMPT = (
    'Rate this response 1-5 using these STRICT score definitions:\n'
    '1 = Completely wrong, harmful, or completely off-topic\n'
    '2 = Partially relevant but contains significant errors or omissions\n'
    '3 = Correct and addresses the question but lacks depth or precision\n'
    '4 = Correct, reasonably complete, and clearly expressed\n'
    '5 = Exceptional: correct, complete, insightful, and concise\n\n'
    'Only give 5 if the response is genuinely outstanding.\n'
    'Give 3 for any adequate-but-not-impressive response.\n\n'
    'Question: {question}\n'
    'Response: {response}\n\n'
    'Score (1-5) and one-sentence reason:'
)

# Compare to non-anchored prompt which tends to cluster at 4-5
print('Anchored rubrics force the judge to use the full scale')

Quando i giudici LLM funzionano meglio

I giudici LLM sono più affidabili quando:

  • I criteri sono chiari e ben definiti
  • La differenza nella qualità delle risposte è ampia (una risposta chiaramente buona rispetto a una chiaramente scadente)
  • Il dominio rientra nelle conoscenze del modello giudice
  • Si valutano qualità soggettive (tono, utilità) sulle quali anche i valutatori umani non sono concordi

Sono meno affidabili quando valutano conoscenze recenti, domini altamente tecnici o sottili errori fattuali che richiedono conoscenze specialistiche per essere individuati.

Quando è necessaria la valutazione umana

Coinvolga persone nel processo per:

  • Valutare risposte in domini specializzati (medicina, diritto, sicurezza)
  • Stabilire una valutazione di riferimento per calibrare il giudice LLM
  • Prendere decisioni ad alto rischio, nelle quali gli errori del giudice LLM hanno conseguenze concrete
  • Valutare compiti nuovi per i quali il modello giudice dispone di pochi segnali di addestramento
  • Rilevare sottili errori fattuali che richiedono competenze di dominio
def triage_for_human_review(question, response, llm_score, confidence_threshold=0.7):
    """
    Route low-confidence or high-stakes evaluations to human review.
    """
    # Route to human if judge is uncertain
    if llm_score is None:
        return 'human_review', 'LLM judge failed to produce a score'

    # Route to human for borderline scores (near decision boundaries)
    if 2.5 <= llm_score <= 3.5:
        return 'human_review', f'Borderline score {llm_score} — needs human judgment'

    # Route to human for domain-specific high-risk content
    HIGH_RISK_KEYWORDS = ['medication', 'legal advice', 'financial advice', 'security']
    if any(kw in question.lower() for kw in HIGH_RISK_KEYWORDS):
        return 'human_review', 'High-risk domain — human verification required'

    # Else: LLM score is sufficient
    return 'auto_accept', f'Score {llm_score} — LLM judgment sufficient'

routing, reason = triage_for_human_review('What medication should I take?', 'Take aspirin.', 4.5)
print(f'{routing}: {reason}')

Costruire una pipeline di valutazione

Una pipeline pratica basata su LLM-as-judge segue questo flusso: generare le risposte → eseguire il giudice LLM → sottoporre i casi borderline a revisori umani → aggregare i punteggi → riportare le metriche di qualità. Registri tutto per creare tracce di audit.

import anthropic
import json

client = anthropic.Anthropic(api_key='sk-ant-...')

def evaluate_batch(examples, product_under_test, criteria):
    results = []
    for ex in examples:
        response = product_under_test(ex['question'])
        score, reason = simple_llm_judge(ex['question'], response, criteria)

        results.append({
            'question': ex['question'],
            'response': response,
            'score': score,
            'reason': reason,
            'needs_review': score is None or 2.5 <= (score or 0) <= 3.5
        })

    # Summarize
    valid_scores = [r['score'] for r in results if r['score'] is not None]
    avg_score = sum(valid_scores) / len(valid_scores) if valid_scores else 0
    review_count = sum(1 for r in results if r['needs_review'])

    print(f'Average score: {avg_score:.2f}/5')
    print(f'Cases needing review: {review_count}/{len(results)}')
    return results, avg_score

# results, avg = evaluate_batch(test_cases, my_product, 'helpfulness')

Valutazione senza riferimento e basata su un riferimento

I giudici LLM possono operare in due modalità:

  • Basata su un riferimento: il giudice confronta la risposta con una risposta corretta nota. Offre un'elevata accuratezza, ma richiede dati etichettati.
  • Senza riferimento: il giudice valuta la risposta in base ai suoi meriti (è coerente? utile? ben scritta?). È più flessibile, ma meno precisa nel valutare l'accuratezza fattuale.

Usi la valutazione basata su un riferimento quando dispone di risposte gold standard. Usi quella senza riferimento per attività a risposta aperta, come la sintesi, la valutazione del tono o della qualità della scrittura creativa.

Verifica delle conoscenze: bias di posizione

Che cos'è il bias di posizione nella valutazione con LLM come giudice e che cosa provoca?

Riepilogo: valutazione con LLM come giudice

I giudici LLM comprendono le sfumature, l'accuratezza semantica e la qualità soggettiva, aspetti che le metriche tradizionali non possono misurare. Presentano limiti con: bias di posizione (preferenza per la prima opzione), bias della prolissità (preferenza per le risposte più lunghe), auto-preferenza (preferenza per il proprio stile) e inflazione dei punteggi (concentrazione tra 4 e 5/5). Riduca questi bias randomizzando l'ordine delle risposte, impartendo istruzioni esplicite contro la prolissità, utilizzando rubriche con ancoraggi che definiscano ogni livello di punteggio e impiegando più modelli diversi come giudici. Affidi i punteggi borderline e i domini ad alto rischio a valutatori umani. Utilizzi i giudici LLM per la scalabilità e i valutatori umani per la calibrazione e le decisioni ad alto impatto.

Domande Frequenti

La lezione «Uso degli LLM per valutare gli output degli LLM» è gratuita?

Sì — il testo completo di «Uso degli LLM per valutare gli output degli LLM» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso AI Prompt Engineering, passa a CoddyKit PRO. Il corso AI Prompt Engineering include 4 lezioni in totale.

Cosa imparerò in «Uso degli LLM per valutare gli output degli LLM»?

Perché i giudici LLM funzionano e in quali aspetti falliscono rispetto alla valutazione umana Eserciti AI Prompt Engineering con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare AI Prompt Engineering?

Non è richiesta alcuna esperienza precedente. AI Prompt Engineering su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.

Quanto tempo richiede la lezione «Uso degli LLM per valutare gli output degli LLM»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione AI Prompt Engineering?

Sì. Ogni lezione AI Prompt Engineering include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Uso degli LLM per valutare gli output degli LLM
  2. Prompt di valutazione basati su rubriche
  3. Valutazione comparativa: A contro B
  4. Calibrazione e bias nei giudici LLM
← Torna a AI Prompt Engineering