Usando LLM para avaliar saídas de LLM
Por que os avaliadores baseados em LLM funcionam e onde falham em comparação com a avaliação humana.
Usando LLM para avaliar saídas de LLM é uma aula grátis de AI Prompt Engineering no CoddyKit. Esta é a aula 1 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 usar um LLM como avaliador?
As métricas tradicionais de avaliação — BLEU, ROUGE e correspondência exata — funcionam para saídas estruturadas, mas falham ao medir qualidades sutis como utilidade, precisão, tom e criatividade.
A avaliação humana capta nuances, mas é lenta e cara. LLM como avaliador oferece um caminho intermediário: avaliação automatizada que compreende significado semântico, contexto e qualidade subjetiva — em escala e a baixo custo.
Por que os avaliadores LLM funcionam
Os avaliadores LLM funcionam porque compartilham a mesma compreensão linguística do modelo que está sendo avaliado. Eles conseguem avaliar:
- se uma resposta é factualmente correta, e não apenas lexicalmente semelhante a uma referência
- se uma resposta é útil para a finalidade indicada
- se o tom atende aos requisitos
- se um resumo captura os principais points
Essas são qualidades que métricas simples de correspondência de cadeias de caracteres não conseguem medir.
Um avaliador LLM simples
O avaliador LLM mais básico: peça ao modelo que atribua uma nota a uma resposta em uma escala numérica, com uma breve justificativa. Essa é a base sobre a qual todos os padrões mais avançados de avaliação são construídos.
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}')Onde os avaliadores LLM falham: viés de posição
Viés de posição: quando duas respostas (A e B) são apresentadas, os avaliadores LLM tendem a preferir a que aparece primeiro — independentemente da qualidade. Estudos mostram que isso afeta de 60% a 70% das comparações par a par quando se usa uma instrução ingênua para o avaliador.
Isso significa que a ordem em que você apresenta as opções altera o veredito do avaliador.
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_baOnde os avaliadores LLM falham: viés de verbosidade
Viés de verbosidade: os avaliadores LLM tendem a atribuir notas mais altas a respostas mais longas e detalhadas — mesmo quando uma resposta concisa é objetivamente melhor. Uma resposta que usa 400 palavras para dizer o que 50 palavras poderiam dizer frequentemente recebe uma nota maior do que a versão concisa.
Mitigue isso instruindo explicitamente o avaliador a penalizar o comprimento quando ele for unnecessary.
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)Onde os avaliadores LLM falham: autopreferência
Viés de autopreferência: quando o modelo da Anthropic avalia duas respostas, tende a preferir respostas semelhantes às do modelo da Anthropic. Quando o GPT-4 avalia, prefere respostas semelhantes às do GPT-4. Esse é um viés sistemático que afeta todos os avaliadores LLM.
Mitigação: use vários modelos diferentes como avaliadores e agregue suas pontuações. A divergência indica um caso limítrofe que exige revisão humana.
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 avgInflação das pontuações
Inflação das pontuações: os avaliadores LLM tendem a atribuir notas altas (4–5 de 5) à maioria das respostas, comprimindo a distribuição e dificultando a distinção entre algo bom e algo excelente. Respostas que receberiam 3/5 frequentemente recebem 4–4,5/5.
Solução: use uma rubrica que imponha calibração ou use pontuação relativa (par a par), em vez de pontuação absoluta.
# 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 os avaliadores LLM funcionam melhor
Os avaliadores LLM são mais confiáveis quando:
- os critérios são claros e bem definidos
- a diferença na qualidade das respostas é grande (uma obviamente boa versus uma obviamente ruim)
- o domínio está dentro do conhecimento do modelo avaliador
- você está avaliando qualidades subjetivas (tom, utilidade) sobre as quais os avaliadores humanos também divergem
Eles são menos confiáveis ao avaliar conhecimento recente, domínios altamente técnicos ou erros factuais sutis que exigem conhecimento especializado para serem detectados.
Quando a avaliação humana é necessária
Mantenha pessoas no processo para:
- avaliar respostas em domínios especializados (medicina, direito e segurança)
- estabelecer a calibração com dados de referência confiáveis para o seu avaliador LLM
- tomar decisões de alto risco nas quais erros do avaliador LLM tenham consequências reais
- avaliar tarefas novas para as quais o modelo avaliador tenha poucos sinais de treinamento
- detectar erros factuais sutis que exigem conhecimento especializado do domínio
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}')Criando um fluxo de avaliação
Um fluxo prático de LLM como avaliador: gerar respostas → executar o avaliador LLM → encaminhar casos limítrofes para pessoas → agregar pontuações → informar métricas de qualidade. Registre tudo para manter trilhas de auditoria.
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')Avaliação sem referência versus baseada em referência
Os avaliadores LLM podem operar em dois modos:
- Baseada em referência: o avaliador compara a resposta com uma resposta correta conhecida. Tem alta precisão, mas exige dados rotulados.
- Sem referência: o avaliador avalia a resposta por seus próprios méritos (ela é consistente? útil? bem escrita?). É mais flexível, mas menos precisa quanto à exatidão factual.
Use a avaliação baseada em referência quando tiver respostas de referência confiáveis. Use a avaliação sem referência para tarefas abertas, como criação de resumos, avaliação de tom ou qualidade de escrita criativa.
Verificação de conhecimento: Viés de posição
O que é o viés de posição na avaliação com LLM como avaliador e o que ele causa?
Recapitulação: Avaliação de LLM como avaliador
Os avaliadores LLM compreendem nuances, precisão semântica e qualidade subjetiva — aspectos que as métricas tradicionais não conseguem medir. Eles falham em: viés de posição (preferem a primeira opção), viés de verbosidade (preferem respostas mais longas), autopreferência (preferem o próprio estilo) e inflação das pontuações (concentram-se em 4–5/5). Mitigue isso com: randomização da ordem das respostas, instruções explícitas contra a verbosidade, rubricas ancoradas que definam cada nível de pontuação e uso de vários modelos diferentes como avaliadores. Encaminhe pontuações limítrofes e domínios de alto risco para avaliadores humanos. Use avaliadores LLM em escala; use humanos para calibração e decisões de alto impacto.
Perguntas Frequentes
A aula “Usando LLM para avaliar saídas de LLM” é grátis?
Sim — o texto completo de “Usando LLM para avaliar saídas de 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 “Usando LLM para avaliar saídas de LLM”?
Por que os avaliadores baseados em LLM funcionam e onde falham em comparação com a avaliação humana. 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 1 de 4.
Quanto tempo leva a aula “Usando LLM para avaliar saídas de 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
- Usando LLM para avaliar saídas de LLM
- Prompts de pontuação baseados em critérios
- Avaliação comparativa: A versus B
- Calibração e vieses em avaliadores LLM