AI Prompt Engineering · Aula

Calibração e vieses em avaliadores LLM

Viés de posição, viés de verbosidade e como reduzi-los nos prompts do avaliador.

Aula 4 de 413 etapas

Calibração e vieses em avaliadores LLM é uma aula grátis de AI Prompt Engineering no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de AI Prompt Engineering, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de AI Prompt Engineering inclui 4 aulas no total.

Por que a calibração do avaliador é importante

Um avaliador LLM que atribui sistematicamente a um tipo de resposta uma pontuação maior do que merece produz resultados de avaliação enganosos. Poderá colocar um modelo pior em produção porque o avaliador preferiu seu estilo prolixo — não sua qualidade real.

Calibração significa que as pontuações do avaliador refletem com precisão a qualidade verdadeira. Um avaliador calibrado concorda com avaliadores humanos a uma taxa mensurável e não favorece sistematicamente nenhum atributo não relacionado à qualidade.

Viés de posição: análise aprofundada

O viés de posição é o viés mais forte e mais estudado dos avaliadores LLM. Em comparações aos pares, os avaliadores preferem a primeira opção em 60–65% das vezes, independentemente da qualidade. Isso equivale a uma moeda que dá cara em 60% das vezes — uma diferença significativa em escala.

O viés existe porque os LLMs são treinados para gerar continuações — ver «Resposta A:» primeiro os induz a favorecer A antes de lerem 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

Viés de verbosidade: análise aprofundada

O viés de verbosidade faz com que os avaliadores prefiram respostas mais longas, mesmo quando as mais curtas são mais precisas e completas. Pesquisas mostram que os avaliadores LLM classificam respostas mais longas como «melhores» 1,5 a 2 vezes mais frequentemente em comparações aos pares, mantendo constante a qualidade do conteúdo.

Esse viés provavelmente resulta de dados de treinamento nos quais os avaliadores humanos também confundem extensão com qualidade.

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)')

Viés de autopreferência: análise aprofundada

Os avaliadores Claude atribuem, em média, pontuações mais altas a respostas geradas por Claude. Os avaliadores GPT-4 atribuem pontuações mais altas a respostas geradas por GPT-4. Isso foi demonstrado em vários estudos independentes.

O mecanismo é o seguinte: cada modelo tem um estilo característico — estrutura das frases, padrões de ressalvas e escolhas de vocabulário. O mesmo modelo reconhece e prefere o próprio estilo.

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?')

Mitigação 1: inverter a ordem

A mitigação isolada mais eficaz para o viés de posição é executar cada comparação aos pares duas vezes, invertendo a ordem, e usar apenas resultados consistentes. Implemente isso como uma função padrão pela qual passem todas as avaliações.

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}')

Mitigação 2: vários avaliadores diversificados

O viés de autopreferência é reduzido quando se usam vários modelos diferentes como avaliadores e se agregam seus veredictos. Quando Claude, GPT-4 e Gemini concordam, o resultado é muito mais confiável do que o veredicto de qualquer modelo isolado.

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}')

Mitigação 3: instruções contra a verbosidade

Instrua diretamente o avaliador a penalizar a verbosidade e recompensar a concisão. Isso neutraliza o viés de verbosidade que, de outra forma, faria as respostas mais longas parecerem melhores.

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')

Calibrando com avaliadores humanos

O padrão-ouro para a calibração do avaliador é comparar as pontuações do seu avaliador LLM com as pontuações de avaliadores humanos em um conjunto de calibração. Meça a concordância e identifique divergências sistemáticas.

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

Detectando padrões sistemáticos de viés

Analise os resultados do seu avaliador em diferentes categorias de respostas para detectar vieses sistemáticos. O avaliador atribui consistentemente pontuações mais altas às respostas de um modelo? Ele penaliza respostas sobre determinados tópicos?

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')

Lista de verificação para redução de viés

Uma lista de verificação a aplicar antes de colocar um avaliador LLM em produção:

  • Execute todas as comparações aos pares duas vezes, invertendo a ordem
  • Inclua instruções explícitas contra a verbosidade na rubrica
  • Use pelo menos 2 modelos diferentes como avaliadores em avaliações de alto impacto
  • Ancore explicitamente os níveis de pontuação para evitar a inflação
  • Calibre com avaliadores humanos usando uma amostra representativa
  • Registre e monitore as taxas de vitória por rótulo do modelo para detectar desvios
  • Adicione uma saída JSON estruturada para impedir que as pontuações fiquem ocultas em texto livre

Trilhas de auditoria e explicabilidade

Um avaliador calibrado também deve ser explicável. Se o avaliador atribuir uma pontuação de 4/5 a uma resposta, deve ser possível rastrear o motivo — quais critérios foram atendidos e quais ficaram aquém do esperado.

Exigir que o avaliador retorne JSON com pontuações por critério e uma justificativa breve cria uma trilha de auditoria natural. As partes interessadas podem analisar por que respostas específicas receberam determinada pontuação, e é possível identificar padrões recorrentes nas pontuações baixas.

Verificação de conhecimentos: mitigação da autopreferência

Qual estratégia de mitigação aborda MAIS diretamente o viés de autopreferência em avaliadores LLM?

Recapitulação: calibração e vieses em avaliadores LLM

Os avaliadores LLM apresentam quatro vieses sistemáticos principais: viés de posição (preferência pela primeira opção), viés de verbosidade (preferência por respostas mais longas), autopreferência (preferência pelo próprio estilo) e inflação das pontuações (concentração em 4–5/5). Mitigue cada um de forma específica: altere a ordem para combater o viés de posição, adicione instruções contra a verbosidade para combater o viés de verbosidade, use avaliadores de modelos diversos para combater a autopreferência e use rubricas ancoradas para combater a inflação. Calibre o avaliador comparando-o com avaliadores humanos em um conjunto rotulado e meça a correlação de Pearson. Monitore as taxas de vitória por rótulo ao longo do tempo para detectar padrões de viés emergentes antes que distorçam seu fluxo de avaliação.

Grátis para começar

Aprenda AI Prompt Engineering com um tutor de IA — grátis

Escreva e execute código real no seu navegador, obtenha ajuda instantânea de um tutor de IA 24/7 e continue de onde parou na web ou no app.

Cursos
53
Aulas
199

Perguntas Frequentes

A aula “Calibração e vieses em avaliadores LLM” é grátis?

Sim — o texto completo de “Calibração e vieses em avaliadores LLM” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de AI Prompt Engineering, atualize para CoddyKit PRO. O curso de AI Prompt Engineering inclui 4 aulas no total.

O que vou aprender em “Calibração e vieses em avaliadores LLM”?

Viés de posição, viés de verbosidade e como reduzi-los nos prompts do avaliador. Você pratica AI Prompt Engineering com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar AI Prompt Engineering?

Nenhuma experiência prévia é necessária. AI Prompt Engineering no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.

Quanto tempo leva a aula “Calibração e vieses em avaliadores LLM”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de AI Prompt Engineering?

Sim. Cada aula de AI Prompt Engineering inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Usando LLM para avaliar saídas de LLM
  2. Prompts de pontuação baseados em critérios
  3. Avaliação comparativa: A versus B
  4. Calibração e vieses em avaliadores LLM
← Voltar para AI Prompt Engineering