0Pricing
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.

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.

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