0Pricing
AI Prompt Engineering · Leçon

Étalonnage et biais des évaluateurs LLM

Biais de position, biais de verbosité et moyens de les atténuer dans les prompts d’évaluation.

Étalonnage et biais des évaluateurs LLM est une leçon AI Prompt Engineering gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage AI Prompt Engineering, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours AI Prompt Engineering comprend 4 leçons au total.

Pourquoi l’étalonnage de l’évaluateur est important

Un évaluateur LLM qui attribue systématiquement une note trop élevée à un type de réponse produit des résultats d’évaluation trompeurs. Vous pourriez déployer un modèle moins bon parce que l’évaluateur a préféré son style verbeux, et non sa qualité réelle.

L’étalonnage signifie que les notes de l’évaluateur reflètent fidèlement la qualité réelle. Un évaluateur correctement étalonné concorde avec les évaluateurs humains à un taux mesurable et ne favorise pas systématiquement un attribut particulier sans rapport avec la qualité.

Biais de position : analyse approfondie

Le biais de position est le biais des évaluateurs LLM le plus marqué et le plus étudié. Lors d’une comparaison par paires, les évaluateurs préfèrent la première option dans 60 à 65 % des cas, indépendamment de la qualité. Cela revient à utiliser une pièce qui tombe du côté face dans 60 % des lancers : l’effet est significatif à grande échelle.

Ce biais existe parce que les LLM sont entraînés à générer des suites : voir « Réponse A : » en premier les oriente vers A avant même qu’ils ne lisent B.

import anthropic

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

def measure_position_bias(question, n_pairs=20):
    """
    Measure position bias by comparing IDENTICAL responses.
    If both responses are the same, wins should be 50/50.
    Any deviation from 50/50 is pure position bias.
    """
    response = 'Machine learning is a subset of AI that learns from data.'
    first_wins = 0

    for _ in range(n_pairs):
        prompt = (
            f'Which response is better?\nQ: {question}\n'
            f'Response A: {response}\n'
            f'Response B: {response}\n'
            f'Reply with A or B.'
        )
        r = client.messages.create(
            model='claude-opus-4-5',
            max_tokens=5,
            messages=[{'role': 'user', 'content': prompt}]
        )
        if 'A' in r.content[0].text:
            first_wins += 1

    bias = first_wins / n_pairs
    print(f'First-position win rate with IDENTICAL responses: {bias:.0%}')
    print(f'Expected (no bias): 50%')
    print(f'Measured bias: {(bias - 0.5) * 100:+.0f}%')
    return bias

Biais de verbosité : analyse approfondie

Le biais de verbosité pousse les évaluateurs à préférer les réponses longues, même lorsque les réponses plus courtes sont plus exactes et plus exhaustives. Les recherches montrent que, lors de comparaisons par paires, les évaluateurs LLM jugent les réponses longues « meilleures » 1,5 à 2 fois plus souvent, à qualité de contenu équivalente.

Ce biais provient probablement de données d’entraînement dans lesquelles les évaluateurs humains confondent eux aussi la longueur et la qualité.

import anthropic

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

def measure_verbosity_bias(question, correct_answer):
    """
    Compare a concise correct answer against a verbose one with filler.
    A good judge should prefer the concise version or call it a tie.
    """
    concise = correct_answer
    verbose = (
        f'That is a great question! I am happy to help. '
        f'{correct_answer} '
        f'I hope this comprehensive explanation addresses all your needs. '
        f'Please feel free to ask if you need any further clarification!'
    )

    for label, resp in [('Concise', concise), ('Verbose', verbose)]:
        prompt = (
            f'Rate this response 1-5 for quality.\n'
            f'Q: {question}\nA: {resp}\n'
            f'Return only a number 1-5.'
        )
        r = client.messages.create(
            model='claude-opus-4-5',
            max_tokens=5,
            messages=[{'role': 'user', 'content': prompt}]
        )
        score = r.content[0].text.strip()
        print(f'{label} response score: {score}')
        print(f'  ({len(resp.split())} words)')

Biais de préférence pour soi : analyse approfondie

Les évaluateurs Claude attribuent en moyenne de meilleures notes aux réponses générées par Claude. Les évaluateurs GPT-4 attribuent de meilleures notes aux réponses générées par GPT-4. Plusieurs études indépendantes l’ont démontré.

Le mécanisme est le suivant : chaque modèle possède un style distinctif — structure des phrases, formulations prudentes et choix du vocabulaire. Le même modèle reconnaît son propre style et le préfère.

import anthropic
import openai

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

def test_self_preference(question):
    # Generate one response per model
    claude_answer = anthropic_client.messages.create(
        model='claude-opus-4-5', max_tokens=100,
        messages=[{'role': 'user', 'content': question}]
    ).content[0].text

    gpt_answer = openai_client.chat.completions.create(
        model='gpt-4o', max_tokens=100,
        messages=[{'role': 'user', 'content': question}]
    ).choices[0].message.content

    judge_prompt = (
        f'Which response is better?\nQ: {question}\n'
        f'Response A: {claude_answer}\n'
        f'Response B: {gpt_answer}\n'
        f'Reply: A or B'
    )

    # Claude judges the comparison
    claude_verdict = anthropic_client.messages.create(
        model='claude-opus-4-5', max_tokens=5,
        messages=[{'role': 'user', 'content': judge_prompt}]
    ).content[0].text.strip()

    print(f'Claude judge verdict: {claude_verdict}')
    print('(A=Claude response, B=GPT response)')
    print('Self-preference: did Claude prefer its own response?')

Mesure d’atténuation 1 : inverser l’ordre

La mesure unique la plus efficace contre le biais de position consiste à effectuer chaque comparaison par paires deux fois, en inversant l’ordre, et à ne retenir que les résultats cohérents. Implémentez cette opération sous la forme d’une fonction standard par laquelle passent toutes les évaluations.

import anthropic
import json

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

def debiased_compare(question, response_a, response_b, label_a='A', label_b='B'):
    def single_pass(first, second, first_label, second_label):
        prompt = (
            f'Q: {question}\n\n'
            f'{first_label}: {first}\n\n'
            f'{second_label}: {second}\n\n'
            f'Which is better? Reply with {first_label}, {second_label}, or TIE.'
        )
        r = client.messages.create(
            model='claude-opus-4-5',
            max_tokens=10,
            messages=[{'role': 'user', 'content': prompt}]
        )
        return r.content[0].text.strip()

    # Pass 1: A first
    p1 = single_pass(response_a, response_b, label_a, label_b)
    # Pass 2: B first — but labels stay the same (we just swap presentation order)
    p2 = single_pass(response_b, response_a, label_b, label_a)

    # Normalize p2: if judge said label_b in pass 2, that means they preferred first-shown
    # Need to map back: if p2 = label_b, the 'first' won; if p2 = label_a, the 'second' won
    if p1 == p2 and p1 != 'TIE':
        return p1, 'Consistent result'
    else:
        return 'TIE', f'Inconsistent: pass1={p1}, pass2={p2}'

winner, reason = debiased_compare(
    'What is Docker?',
    'Docker is a containerization platform.',
    'Docker allows you to package applications into containers for consistent deployment.'
)
print(f'{winner}: {reason}')

Mesure d’atténuation 2 : plusieurs évaluateurs différents

La préférence pour soi est réduite lorsque plusieurs modèles différents sont utilisés comme évaluateurs et que leurs verdicts sont agrégés. Lorsque Claude, GPT-4 et Gemini sont tous d’accord, le résultat est bien plus fiable que le verdict d’un seul modèle.

import anthropic
import openai

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

def multi_model_pairwise(question, response_a, response_b):
    results = {}

    # Judge 1: Claude
    r1 = anthropic_client.messages.create(
        model='claude-opus-4-5', max_tokens=5,
        messages=[{'role': 'user', 'content':
            f'Q: {question}\nA: {response_a}\nB: {response_b}\n'
            f'Which is better? Reply A, B, or TIE.'
        }]
    )
    results['Claude'] = r1.content[0].text.strip()

    # Judge 2: GPT-4o
    r2 = openai_client.chat.completions.create(
        model='gpt-4o', max_tokens=5,
        messages=[{'role': 'user', 'content':
            f'Q: {question}\nA: {response_a}\nB: {response_b}\n'
            f'Which is better? Reply A, B, or TIE.'
        }]
    )
    results['GPT4o'] = r2.choices[0].message.content.strip()

    print(f'Claude judge: {results["Claude"]}')
    print(f'GPT-4o judge: {results["GPT4o"]}')

    # Aggregate: majority vote
    votes = list(results.values())
    if votes.count('A') >= 2: return 'A'
    if votes.count('B') >= 2: return 'B'
    return 'TIE'

final = multi_model_pairwise(
    'Explain recursion.',
    'A function that calls itself.',
    'Recursion is when a function solves a problem by solving a smaller version of the same problem.'
)
print(f'Final verdict: {final}')

Mesure d’atténuation 3 : instructions contre la verbosité

Demandez directement à l’évaluateur de pénaliser la verbosité et de récompenser la concision. Cela contrecarre le biais de verbosité qui, autrement, ferait paraître les réponses longues meilleures.

ANTI_VERBOSITY_JUDGE = (
    'Evaluate this response. Apply these corrections for known judge biases:\n\n'
    'VERBOSITY CORRECTION: Do NOT rate a response higher simply because it is longer. '
    'A concise, accurate 20-word answer is better than a 200-word answer that says the same thing. '
    'Actively penalize unnecessary padding, filler phrases like "Great question!", '
    'and repetition.\n\n'
    'LENGTH PENALTY: If the response contains introductory filler, closing remarks, '
    'or restates the question, subtract 1 point from your score.\n\n'
    'Question: {question}\n'
    'Response: {response}\n\n'
    'Score 1-5 (apply verbosity correction above):'
)

# This instruction significantly reduces verbosity inflation in practice
print('Anti-verbosity instructions reduce the length-quality conflation')

Étalonner par rapport aux évaluateurs humains

La référence absolue pour l’étalonnage d’un évaluateur consiste à comparer les notes de votre évaluateur LLM à celles d’évaluateurs humains sur un ensemble d’étalonnage. Mesurez leur concordance et repérez les écarts systématiques.

import anthropic
import json
from scipy import stats  # pip install scipy

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

def calibrate_judge(calibration_set):
    """
    calibration_set: list of dicts with:
    {'question': str, 'response': str, 'human_score': float}
    """
    llm_scores = []
    human_scores = []

    for item in calibration_set:
        prompt = (
            f'Rate this response 1-5.\n'
            f'Q: {item["question"]}\nA: {item["response"]}\n'
            f'Return only a number.'
        )
        r = client.messages.create(
            model='claude-opus-4-5',
            max_tokens=5,
            messages=[{'role': 'user', 'content': prompt}]
        )
        try:
            llm_score = float(r.content[0].text.strip())
        except ValueError:
            llm_score = 3.0  # Default on parse error

        llm_scores.append(llm_score)
        human_scores.append(item['human_score'])

    correlation, p_value = stats.pearsonr(llm_scores, human_scores)
    print(f'LLM-Human correlation: {correlation:.3f} (p={p_value:.4f})')
    print(f'LLM mean score: {sum(llm_scores)/len(llm_scores):.2f}')
    print(f'Human mean score: {sum(human_scores)/len(human_scores):.2f}')
    return correlation

Détecter les schémas de biais systématiques

Analysez les résultats de votre évaluateur pour différentes catégories de réponses afin de détecter les biais systématiques. Attribue-t-il systématiquement de meilleures notes aux réponses d’un modèle particulier ? Pénalise-t-il les réponses portant sur certains sujets ?

import json
from collections import defaultdict

def analyze_judge_bias(log_file='pairwise_log.jsonl'):
    """
    Analyze pairwise logs to detect systematic bias.
    """
    wins_by_label = defaultdict(int)
    total_by_label = defaultdict(int)

    with open(log_file) as f:
        for line in f:
            entry = json.loads(line)
            winner = entry['winner']
            label_a = entry['label_a']
            label_b = entry['label_b']

            if winner == 'A':
                wins_by_label[label_a] += 1
            elif winner == 'B':
                wins_by_label[label_b] += 1

            total_by_label[label_a] += 1
            total_by_label[label_b] += 1

    print('Win rate by model:')
    for label in sorted(total_by_label):
        total = total_by_label[label]
        wins = wins_by_label[label]
        print(f'  {label}: {wins}/{total} = {wins/total:.0%}')

    # Flag if any model wins >60% — likely systematic bias
    for label in total_by_label:
        rate = wins_by_label[label] / total_by_label[label]
        if rate > 0.65 or rate < 0.35:
            print(f'WARNING: {label} win rate {rate:.0%} suggests systematic bias')

Liste de vérification pour réduire les biais

Liste de vérification à appliquer avant de déployer un évaluateur LLM en production :

  • effectuer toutes les comparaisons par paires deux fois en inversant l’ordre ;
  • inclure des instructions explicites contre la verbosité dans la grille ;
  • utiliser au moins 2 modèles différents comme évaluateurs pour les évaluations à forts enjeux ;
  • définir explicitement des repères pour les niveaux de notation afin de prévenir l’inflation des notes ;
  • étalonner les résultats par rapport à des évaluateurs humains sur un échantillon représentatif ;
  • journaliser et surveiller les taux de victoire selon le nom du modèle afin de détecter toute dérive ;
  • ajouter une sortie JSON structurée pour empêcher la dissimulation des notes dans du texte libre.

Traçabilité des audits et explicabilité

Un évaluateur étalonné doit également être explicable. Si l’évaluateur attribue une note de 4/5 à une réponse, vous devez pouvoir retracer la raison de cette note — quels critères ont été satisfaits et lesquels ne l’ont pas été.

Exiger que l’évaluateur renvoie du JSON avec une note pour chaque critère et une brève justification crée naturellement une piste d’audit. Les parties prenantes peuvent examiner pourquoi certaines réponses ont obtenu leur note, et vous pouvez repérer les tendances récurrentes dans les scores faibles.

Vérification des connaissances : atténuation de l’auto-préférence

Quelle stratégie d’atténuation répond MOST directement au biais d’auto-préférence des évaluateurs LLM ?

Récapitulatif : calibration et biais des évaluateurs LLM

Les évaluateurs LLM présentent quatre biais systématiques principaux : le biais de position (préférence pour la première option), le biais de verbosité (préférence pour les réponses plus longues), l’auto-préférence (préférence pour leur propre style) et l’inflation des scores (regroupement autour de 4-5/5). Atténuez chacun de manière ciblée : inversez l’ordre pour le biais de position, ajoutez des instructions anti-verbosité pour le biais de verbosité, utilisez des évaluateurs issus de modèles diversifiés pour l’auto-préférence et employez des grilles d’évaluation ancrées pour l’inflation. Étalonnez votre évaluateur par rapport à des évaluateurs humains sur un ensemble annoté et mesurez la corrélation de Pearson. Surveillez au fil du temps les taux de victoire par étiquette afin de détecter les biais émergents avant qu’ils ne faussent votre chaîne d’évaluation.

Questions Fréquemment Posées

La leçon « Étalonnage et biais des évaluateurs LLM » est-elle gratuite ?

Oui — le texte complet de « Étalonnage et biais des évaluateurs LLM » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours AI Prompt Engineering, passe à CoddyKit PRO. Le cours AI Prompt Engineering comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Étalonnage et biais des évaluateurs LLM » ?

Biais de position, biais de verbosité et moyens de les atténuer dans les prompts d’évaluation. Tu pratiques AI Prompt Engineering avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer AI Prompt Engineering ?

Aucune expérience préalable n'est requise. AI Prompt Engineering sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.

Combien de temps prend la leçon « Étalonnage et biais des évaluateurs LLM » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon AI Prompt Engineering ?

Oui. Chaque leçon AI Prompt Engineering inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Utiliser un LLM pour évaluer les sorties d’un LLM
  2. Prompts d’évaluation fondés sur une grille
  3. Évaluation comparative : A ou B
  4. Étalonnage et biais des évaluateurs LLM
← Retour à AI Prompt Engineering