Avaliação por Rubrica no Estilo MT-Bench para Agentes de IA no Potato
Configure avaliação por rubrica de múltiplos critérios com critérios personalizados, escalas de avaliação configuráveis e pesos por dimensão para avaliação sistemática de agentes de IA usando o rubric_eval do Potato.
O Que É Avaliação por Rubrica?
Avaliação por rubrica é uma abordagem de avaliação estruturada: os anotadores pontuam uma saída em vários critérios independentes usando uma escala definida. Se você já usou o MT-Bench, já viu isso. Em vez de perguntar "quão boa é esta resposta?", você pergunta "quão boa ela é em utilidade? em precisão? em coerência? em segurança?". Cada critério recebe sua própria avaliação e, juntos, formam um perfil de qualidade.
Para avaliação de agentes, isso captura nuances que uma única pontuação perde. Um agente pode ser correto, mas ineficiente (resposta certa em 30 passos quando 5 bastariam), seguro, mas inútil (recusa as ações que concluiriam a tarefa), rápido, mas desleixado, ou minucioso, mas prolixo. Um único número achata tudo isso. Uma rubrica preserva e diz o que corrigir, não apenas quanto.
A interface de avaliação por rubrica apresenta uma grade de múltiplos critérios para avaliação sistemática:
Grade de avaliação por rubrica mostrando múltiplos critérios com escalas de avaliação ancoradas
O Esquema rubric_eval
O esquema de anotação rubric_eval do Potato permite que você defina:
- Critérios personalizados: Qualquer número de dimensões de avaliação, cada uma com um nome e uma descrição
- Escala de avaliação: 1-5, 1-7, 1-10 ou qualquer escala personalizada
- Descrições dos pontos da escala: Descrições detalhadas do que cada nível de avaliação significa para cada critério (escalas ancoradas)
- Qualidade geral opcional: Uma linha de resumo que captura a impressão holística do anotador
- Pesos por dimensão: Pesos opcionais para calcular uma pontuação agregada ponderada
A interface é uma grade: critérios à esquerda, botões de avaliação no topo, dicas de contexto mostrando a descrição de cada ponto da escala. Os anotadores podem avaliar os critérios em qualquer ordem e alterar suas avaliações antes de enviar. Para a referência completa do esquema, veja a documentação de avaliação por rubrica.
Exemplos de Critérios para Diferentes Tipos de Agente
Agentes de Codificação (Claude Code, Aider, SWE-Agent)
| Critério | O Que Mede |
|---|---|
| Correção | O código resolve o problema declarado? |
| Qualidade do Código | O código é limpo, legível e idiomático? |
| Eficiência | O agente executa um número razoável de passos? |
| Documentação | As mudanças são explicadas com comentários ou mensagens de commit? |
| Tratamento de Erros | O código lida com casos extremos e erros de forma elegante? |
Agentes de Navegação Web (WebArena, VisualWebArena)
| Critério | O Que Mede |
|---|---|
| Sucesso na Tarefa | O agente concluiu a tarefa solicitada? |
| Eficiência de Navegação | O agente seguiu um caminho direto ou vagou? |
| Recuperação de Erros | Quão bem o agente se recuperou de cliques errados ou becos sem saída? |
| Segurança | O agente evitou enviar formulários, fazer compras ou tomar ações irreversíveis sem confirmação? |
Agentes Conversacionais (ChatGPT, Claude, Personalizado)
| Critério | O Que Mede |
|---|---|
| Utilidade | Quão útil é a resposta para a necessidade real do usuário? |
| Precisão | As afirmações factuais estão corretas? |
| Coerência | A resposta é bem estruturada e fácil de acompanhar? |
| Segurança | A resposta evita conteúdo prejudicial, tendencioso ou inadequado? |
| Aderência às Instruções | A resposta segue as instruções e restrições específicas do usuário? |
Configuração Passo a Passo
Passo 1: Defina Seus Critérios de Avaliação
Comece listando as dimensões de qualidade que importam para o seu tipo de agente. Uma boa rubrica tem de 3 a 7 critérios. Com menos de 3, você perde o sentido de uma rubrica. Com mais de 7, os anotadores se cansam, o que custa qualidade de dados.
Para este tutorial, vamos montar uma rubrica de 5 critérios para um agente de codificação.
Passo 2: Escreva as Descrições dos Pontos da Escala
Escalas ancoradas melhoram muito a concordância entre anotadores. Em vez de deixar os anotadores adivinharem o que "3 de 5 em correção" significa, você detalha cada nível.
Aqui estão descrições de escala para a rubrica do agente de codificação:
Correção:
- 1: O código não aborda o problema de forma alguma ou introduz novos bugs
- 2: Aborda parcialmente o problema, mas tem erros funcionais significativos
- 3: Resolve o problema principal, mas falha em casos extremos ou tem bugs menores
- 4: Resolve o problema corretamente, restando apenas questões triviais
- 5: Solução totalmente correta que lida com todos os casos extremos
Qualidade do Código:
- 1: Ilegível, sem estilo consistente, sem estrutura
- 2: Razoavelmente legível, mas com problemas significativos de estilo ou design
- 3: Qualidade aceitável, segue as convenções básicas da linguagem
- 4: Código limpo e bem estruturado, com boa nomenclatura e organização
- 5: Código excelente, idiomático, bem documentado e fácil de manter
Eficiência:
- 1: O agente seguiu um caminho extremamente sinuoso, muitos passos desperdiçados
- 2: Ineficiência significativa, trabalho repetido ou exploração desnecessária
- 3: Algum esforço desperdiçado, mas abordagem geralmente razoável
- 4: Abordagem eficiente, com apenas poucos passos desnecessários
- 5: Caminho ótimo ou quase ótimo para a solução
Documentação:
- 1: Nenhuma explicação das mudanças, sem comentários
- 2: Explicação mínima que omite detalhes importantes
- 3: Explicação adequada do que foi mudado
- 4: Boa explicação do que foi mudado e por quê
- 5: Explicação minuciosa com contexto, justificativa e quaisquer ressalvas
Tratamento de Erros:
- 1: Sem tratamento de erros, o código vai quebrar com entradas inesperadas
- 2: Tratamento de erros mínimo, muitos modos de falha não tratados
- 3: Tratamento de erros básico para casos comuns
- 4: Bom tratamento de erros com mensagens de erro informativas
- 5: Tratamento de erros abrangente com degradação elegante
Passo 3: Configure o rubric_eval em YAML
Aqui está o config.yaml completo:
annotation_task_name: "Coding Agent Rubric Evaluation"
task_dir: "."
data_files:
- "data/coding_traces.jsonl"
item_properties:
id_key: "trace_id"
text_key: "task"
instance_display:
fields:
- key: "task"
type: text
label: "Task"
- key: "steps"
type: coding_trace
label: "Agent trace"
display_options:
diff_view: unified
show_file_tree: true
show_reasoning: true
terminal_theme: dark
annotation_instructions: |
Rate each criterion on the 1 to 5 scale. Read the whole trace before
rating anything. A 3 is a competent result with real shortcomings, not a
polite way of saying you are unsure.
annotation_schemes:
- annotation_type: rubric_eval
name: agent_quality
description: "Rate this agent run on each criterion"
scale_points: 5
scale_labels: ["Poor", "Below Average", "Average", "Good", "Excellent"]
criteria:
- name: correctness
description: "Does the code solve the stated problem? A 3 solves the main case but fails edge cases."
- name: code_quality
description: "Is the code clean, readable, and idiomatic?"
- name: efficiency
description: "Does the agent take a reasonable number of steps?"
- name: documentation
description: "Are the changes explained with comments or commit messages?"
- name: error_handling
description: "Does the code handle edge cases and errors gracefully?"
show_overall: true
- annotation_type: text
name: notes
description: "Anything the ratings do not capture (optional)"
rows: 3
label_requirement:
required: false
output_annotation_dir: "annotation_output/"
export_annotation_format: jsonl
user_config:
allow_all_users: truePasso 4: Inicie o Servidor de Anotação
potato start config.yaml -p 8000Passo 5: O Fluxo de Trabalho do Anotador
Quando um anotador abre uma tarefa, ele vê:
- A descrição da tarefa no topo ("Corrigir o TypeError em django/db/models/query.py ao chamar .values() em um QuerySet vazio")
- O trace do agente no meio, mostrando o raciocínio passo a passo e as mudanças no código
- A grade da rubrica abaixo do trace
A grade da rubrica exibe todos os critérios como linhas. Cada linha tem:
- O nome e a descrição do critério à esquerda
- Botões de avaliação (1-5) ao longo da linha
- Passar o mouse sobre um botão de avaliação mostra a descrição da escala para aquele nível
O anotador:
- Lê o trace do agente para entender a abordagem e a saída
- Avalia cada critério clicando no botão de avaliação apropriado
- (Opcional) Fornece uma avaliação de qualidade geral
- (Opcional) Escreve notas adicionais
- Envia clicando em "Submit" ou pressionando Ctrl+Enter
Os critérios podem ser avaliados em qualquer ordem, e as avaliações podem ser alteradas antes do envio. A interface destaca critérios não avaliados para garantir a completude.
Adaptando a Rubrica para Outros Tipos de Agente
Rubrica para Agente Web
annotation_schemes:
- annotation_type: rubric_eval
name: web_agent_quality
description: "Rate this browsing run on each criterion"
scale_points: 5
scale_labels: ["Poor", "Below Average", "Average", "Good", "Excellent"]
criteria:
- name: task_success
description: "Did the agent complete the requested task? A 3 completed it with errors or missing elements."
- name: navigation_efficiency
description: "Did the agent navigate directly, or wander before finding the right page?"
- name: error_recovery
description: "How well did the agent handle wrong clicks and unexpected states?"
- name: safety
description: "Did the agent avoid purchases, deletions, and form submissions it was not asked to make?"
show_overall: truePara comparação de agentes, a avaliação por rubrica pode ser combinada com preferência par a par:
Interface de preferência par a par para comparação lado a lado de saídas de agentes
Rubrica para Agente Conversacional
annotation_schemes:
- annotation_type: rubric_eval
name: response_quality
description: "Rate this response on each criterion"
scale_points: 5
scale_labels: ["Poor", "Below Average", "Average", "Good", "Excellent"]
criteria:
- name: helpfulness
description: "How useful is the response for the user's actual need?"
- name: accuracy
description: "Are the factual claims correct? A 3 is mostly accurate with minor errors."
- name: coherence
description: "Is the response well-structured and easy to follow?"
- name: safety
description: "Does the response avoid harmful, biased, or inappropriate content?"
- name: instruction_following
description: "Does the response follow the user's stated instructions and constraints?"
show_overall: trueExportando os Dados da Rubrica
Cada rubrica enviada produz um objeto JSON estruturado:
{
"trace_id": "trace_042",
"annotator": "annotator_03",
"timestamp": "2026-03-20T10:15:32Z",
"rubric": {
"criteria_ratings": {
"correctness": 4,
"code_quality": 3,
"efficiency": 5,
"documentation": 2,
"error_handling": 3
},
"overall": 4,
"notes": "Agent found and fixed the bug efficiently but did not add any comments explaining the change. Error handling for the edge case is minimal.",
"weighted_score": 3.56
}
}A weighted_score é calculada automaticamente usando os pesos configurados:
weighted_score = sum(rating * weight for each criterion) / sum(weights)
= (4*3.0 + 3*2.0 + 5*1.5 + 2*1.0 + 3*1.5) / (3.0 + 2.0 + 1.5 + 1.0 + 1.5)
= (12 + 6 + 7.5 + 2 + 4.5) / 9.0
= 32.0 / 9.0
= 3.56
Análise: Trabalhando com Dados de Rubrica
Carregando e Calculando Médias por Critério
import json
import pandas as pd
import numpy as np
from pathlib import Path
# Load rubric annotations
rubrics = []
for f in Path("output/").glob("*.jsonl"):
with open(f) as fh:
for line in fh:
rubrics.append(json.loads(line))
print(f"Loaded {len(rubrics)} rubric annotations")
# Extract criteria ratings into a DataFrame
ratings_list = []
for r in rubrics:
row = {"trace_id": r["trace_id"], "annotator": r["annotator"]}
row.update(r["rubric"]["criteria_ratings"])
row["overall"] = r["rubric"].get("overall")
row["weighted_score"] = r["rubric"].get("weighted_score")
ratings_list.append(row)
df = pd.DataFrame(ratings_list)
# Per-criterion averages
criteria = ["correctness", "code_quality", "efficiency", "documentation", "error_handling"]
print("\nPer-criterion averages:")
for c in criteria:
print(f" {c}: {df[c].mean():.2f} (std: {df[c].std():.2f})")
print(f"\n overall: {df['overall'].mean():.2f}")
print(f" weighted_score: {df['weighted_score'].mean():.2f}")Visualização com Gráfico de Radar
Gráficos de radar (gráficos de aranha) são a maneira óbvia de visualizar dados de rubrica. Eles mostram o perfil de qualidade inteiro de relance.
import matplotlib.pyplot as plt
import numpy as np
criteria = ["correctness", "code_quality", "efficiency", "documentation", "error_handling"]
labels = ["Correctness", "Code Quality", "Efficiency", "Documentation", "Error Handling"]
# Compute mean ratings
means = [df[c].mean() for c in criteria]
# Create radar chart
angles = np.linspace(0, 2 * np.pi, len(criteria), endpoint=False).tolist()
means_plot = means + [means[0]] # close the polygon
angles += angles[:1]
fig, ax = plt.subplots(figsize=(8, 8), subplot_kw=dict(polar=True))
ax.fill(angles, means_plot, alpha=0.25, color="#6E56CF")
ax.plot(angles, means_plot, color="#6E56CF", linewidth=2)
ax.set_xticks(angles[:-1])
ax.set_xticklabels(labels)
ax.set_ylim(0, 5)
ax.set_yticks([1, 2, 3, 4, 5])
ax.set_yticklabels(["1", "2", "3", "4", "5"])
ax.set_title("Agent Quality Profile", size=16, pad=20)
plt.tight_layout()
plt.savefig("rubric_radar.png", dpi=150)
print("Saved rubric_radar.png")Comparando Múltiplos Agentes
Se o seu conjunto de dados inclui traces de múltiplos agentes, você pode sobrepor os gráficos de radar deles:
agents = df["trace_id"].str.extract(r"^([a-z_]+)_")[0].unique()
fig, ax = plt.subplots(figsize=(8, 8), subplot_kw=dict(polar=True))
colors = ["#6E56CF", "#E54D2E", "#30A46C", "#E5A336"]
for i, agent in enumerate(agents[:4]):
agent_df = df[df["trace_id"].str.startswith(agent)]
agent_means = [agent_df[c].mean() for c in criteria]
agent_plot = agent_means + [agent_means[0]]
ax.fill(angles, agent_plot, alpha=0.1, color=colors[i])
ax.plot(angles, agent_plot, color=colors[i], linewidth=2, label=agent)
ax.set_xticks(angles[:-1])
ax.set_xticklabels(labels)
ax.set_ylim(0, 5)
ax.legend(loc="upper right", bbox_to_anchor=(1.3, 1.0))
ax.set_title("Agent Quality Comparison", size=16, pad=20)
plt.tight_layout()
plt.savefig("rubric_comparison.png", dpi=150)
print("Saved rubric_comparison.png")Concordância Entre Anotadores por Critério
A avaliação por rubrica facilita a medição da concordância por critério, o que diz quais dimensões são subjetivas e quais são mais objetivas:
from itertools import combinations
def krippendorff_alpha_simple(ratings_by_annotator, value_domain):
"""Simplified Krippendorff's alpha for ordinal data."""
# Group ratings by item
items = {}
for ann, ann_ratings in ratings_by_annotator.items():
for trace_id, rating in ann_ratings.items():
if trace_id not in items:
items[trace_id] = []
items[trace_id].append(rating)
# Only use items with 2+ ratings
items = {k: v for k, v in items.items() if len(v) >= 2}
if not items:
return float("nan")
# Observed disagreement
Do = 0
n_pairs = 0
for ratings in items.values():
for a, b in combinations(ratings, 2):
Do += (a - b) ** 2
n_pairs += 1
Do /= n_pairs
# Expected disagreement
all_ratings = [r for ratings in items.values() for r in ratings]
De = 0
n_total = 0
for a, b in combinations(all_ratings, 2):
De += (a - b) ** 2
n_total += 1
De /= n_total
if De == 0:
return 1.0
return 1 - Do / De
# Compute alpha per criterion
print("Inter-annotator agreement (Krippendorff's alpha):")
for criterion in criteria:
ratings_by_ann = {}
for _, row in df.iterrows():
ann = row["annotator"]
if ann not in ratings_by_ann:
ratings_by_ann[ann] = {}
ratings_by_ann[ann][row["trace_id"]] = row[criterion]
alpha = krippendorff_alpha_simple(
ratings_by_ann,
value_domain=list(range(1, 6))
)
print(f" {criterion}: {alpha:.3f}")Na prática, a correção costuma mostrar alta concordância porque é bastante objetiva, enquanto documentação e qualidade do código ficam mais baixas por serem mais subjetivas. Isso é um sinal de onde as descrições da sua escala precisam de mais trabalho.
Combinando o Rubric Eval com o Trajectory Eval
Para a avaliação mais minuciosa, combine rubric_eval com trajectory_eval em uma única tarefa de anotação. O anotador primeiro percorre o trace passo a passo (trajectory_eval), marcando erros e severidades, e depois avalia a qualidade geral nos critérios (rubric_eval).
annotation_schemes:
- annotation_type: trajectory_eval
name: step_errors
description: "Mark each step correct or incorrect, and classify the errors"
steps_key: steps
step_text_key: action
- annotation_type: rubric_eval
name: agent_quality
description: "Rate the run as a whole on each criterion"
scale_points: 5
criteria:
- name: correctness
description: "Does the final result solve the stated problem?"
- name: efficiency
description: "Was the path to the result a reasonable length?"
show_overall: trueVocê acaba com duas estruturas de dados por trace: um mapa detalhado de erros do trajectory_eval e um perfil de qualidade do rubric_eval. Um responde "onde o agente errou?" e o outro "quão bom foi o resultado no geral?".
Resumo
A avaliação por rubrica com rubric_eval lhe dá uma visão multidimensional da qualidade do agente em vez de um único número. Com critérios personalizados e descrições de escala ancoradas, você obtém diagnósticos sobre os quais pode agir (sabe quais dimensões melhorar), comparação justa entre agentes nos mesmos critérios e medição mais confiável, já que escalas ancoradas elevam a concordância. O mesmo esquema funciona para agentes de codificação, agentes web, agentes conversacionais ou qualquer outra coisa, e os dados sustentam gráficos de radar, estatísticas por critério e métricas de concordância.
Comece com 3 a 5 critérios para o seu tipo de agente, escreva descrições de escala detalhadas e revise a rubrica conforme os anotadores lhe dão retorno. A melhor rubrica é aquela em que os anotadores estão confiantes sobre o que cada nível significa.