LLM-as-a-Judge: avaliação automatizada do seu agente de ofertas sem abrir planilha
Você montou um agente de ofertas. Ele lê a intenção do usuário, busca produtos, compara preços, resume reviews e cospe uma recomendação. Bonito no demo. Em produção, você não tem ideia se ele está acertando.
Hoje, a forma "padrão" de avaliar isso é abrir uma planilha. Você cola 30 outputs, lê linha por linha, marca certo/errado de olhômetro. Sexta à noite. Café frio. Achismo virando KPI.
Dá pra fazer melhor. LLM-as-a-Judge é uma prática simples: um modelo pontua cada resposta do agente contra uma rubrica que você escreveu. Score por dimensão. Reproduzível. Versionado. Roda no CI antes do deploy. Roda em produção em uma amostra do tráfego. E a planilha pode descansar.
Neste post você vai sair com uma rubrica concreta para um agente de ofertas (preço correto, link válido, sentimento de review coerente), o prompt do juiz, um exemplo de integração em Laravel com Prism e os biases que matam um juiz mal feito antes que ele te traia em produção.
TL;DR
- O que é: usar um LLM com rubrica estruturada para avaliar a saída de outro LLM, dimensão por dimensão.
- Stack: Laravel 11+, Prism, Claude Haiku/Sonnet 4.6 como juiz, dataset golden versionado em CSV.
- Custo/Acesso: chave de API paga. Haiku 4.5 cabe em qualquer orçamento; rode Sonnet só onde a nuance pede.
- Link útil: Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena (Zheng et al., NeurIPS 2023) e o guia da Anthropic Demystifying Evals for AI Agents.
O contexto: por que parar de avaliar agente no olho
Agente de ofertas tem três coisas que falham silenciosamente:
- Preço errado. O agente extrai R$ 1.299, mas o produto está R$ 1.499. Cliente clica, vê o preço real, sai.
- Link quebrado ou trocado. Aponta para o tênis errado, para uma página 404, ou pior: para o concorrente.
- Resumo de review enviesado. O agente diz "ótimas avaliações" e a média no site é 3,1 estrelas com reclamação de durabilidade.
Nenhuma dessas falhas explode na cara. Elas vazam confiança aos poucos. E você só percebe quando a métrica de conversão começa a degradar, duas semanas depois.
A boa notícia: juízes LLM fortes alcançam mais de 80% de concordância com avaliadores humanos, no mesmo nível da concordância humano-humano, segundo o MT-Bench paper de Zheng et al.. Não é mágica. É medição.
A Anthropic recomenda combinar três tipos de avaliador: código (rápido, objetivo, frágil a variações válidas), modelo (flexível, captura nuance, não-determinístico) e humano (caro, lento, qualidade máxima). Avaliação séria não escolhe um. Combina os três.
LLM-as-a-Judge é o pilar do meio. E é onde a maioria dos times deixa dinheiro na mesa por achar que basta um prompt genérico de "dê uma nota de 0 a 10".
Não basta. E é por isso que você está aqui.
A rubrica: saia do "score de 0 a 10"
Antipattern clássico:
Avalie a resposta abaixo de 0 a 10 considerando precisão, clareza, utilidade e tom.
Esse prompt é lixo de avaliação. O juiz não sabe o que pesa mais. Mistura quatro dimensões em um número e você perde rastreabilidade. Quando o score cair de 8.2 para 7.4, você não vai saber o que quebrou.
Pattern certo: rubrica binária ou de baixa cardinalidade, uma dimensão por juiz. A LangSmith e a Anthropic apontam para o mesmo lugar, escalas finas (1 a 10) introduzem ruído porque LLM não calibra meio ponto direito. Binário (passa/falha) ou ternário (ruim/aceitável/bom) é mais confiável.
Para o agente de ofertas, a rubrica fica assim:
| Dimensão | Tipo | Pergunta que o juiz responde |
|---|---|---|
preco_correto |
binário | O preço citado bate com o preço extraído da loja? |
link_valido |
binário | A URL aponta para o produto correto e está acessível? |
sentimento_review_coerente |
0/1/2 | A leitura de sentimento bate com a média real das reviews? |
aderencia_intencao |
0/1/2 | A oferta atende ao que o usuário pediu? |
tom_claro |
binário | Resposta direta, sem firula de marketing? |
Cinco dimensões. Cinco juízes. Sim, são cinco chamadas por output avaliado. É o preço da confiabilidade, e você só roda em uma amostra, não em 100% do tráfego.
A Anthropic é direta: "create clear, structured rubrics to grade each dimension of a task, and then grade each dimension with an isolated LLM-as-judge rather than using one to grade all dimensions". Tradução: um juiz por dimensão. Sempre.
Pré-requisitos
- Chave de API da Anthropic (ou OpenAI, se preferir).
- Laravel 11+ rodando, PHP 8.3+.
- Prism instalado:
composer require prism-php/prism. - Um dataset golden de 30 a 100 exemplos com label humano: input do usuário, output do agente, e o que um humano experiente marcaria em cada dimensão. Sem isso, você não consegue calibrar, vai estar avaliando o juiz no olho, exatamente o que estamos tentando matar.
Mão na massa: montando o juiz no Prism
Passo 1: escrever a rubrica em texto
Cada juiz tem um prompt focado em uma única dimensão. Aqui está o juiz de preco_correto:
Você é um avaliador de ofertas. Sua única tarefa é decidir se o
preço citado pelo agente bate com o preço real do produto na loja.
Você recebe três coisas:
- A resposta do agente.
- O preço extraído oficialmente da página do produto (fonte da verdade).
- Tolerância: +/-R$ 1,00 para arredondamentos.
Responda apenas com:
- "passa" se o preço da resposta cair dentro da tolerância.
- "falha" se estiver fora.
- "indeterminado" se a resposta não citar preço de forma extraível.
Nunca tente adivinhar. Se faltar dado, retorne "indeterminado".
A última linha é deliberada. A Anthropic recomenda explicitamente "give the LLM a way out", sem essa válvula, o juiz alucina veredictos quando o dado é ambíguo.
Passo 2: integrar no Prism com structured output
O Prism usa structured outputs nativos da Anthropic por padrão, o que garante que o veredicto venha no schema certo sem parser de string frágil:
use Prism\Prism\Prism;
use Prism\Prism\Enums\Provider;
use Prism\Prism\Schema\ObjectSchema;
use Prism\Prism\Schema\StringSchema;
$schema = new ObjectSchema(
name: 'veredicto_preco',
description: 'Avaliação binária do preço',
properties: [
new StringSchema('veredicto', 'passa | falha | indeterminado'),
new StringSchema('justificativa', 'uma frase curta'),
],
requiredFields: ['veredicto', 'justificativa'],
);
$response = Prism::structured()
->using(Provider::Anthropic, 'claude-haiku-4-5')
->withSchema($schema)
->withSystemPrompt($promptDoJuizPreco)
->withPrompt(<<<MSG
Resposta do agente: {$output}
Preço oficial extraído: R$ {$precoReal}
Tolerância: R\$ 1,00.
MSG)
->asStructured();
$veredicto = $response->structured['veredicto'];
Note duas coisas. Primeiro, o juiz é o Haiku 4.5, barato, rápido e suficiente para julgamento binário. Reservar Sonnet ou Opus para os juízes que pedem nuance (sentimento_review_coerente, por exemplo).
Segundo, o agente de produção provavelmente roda em outro modelo. Isso não é detalhe. É mitigação ativa de self-enhancement bias, falamos disso no próximo bloco.
Passo 3: rodar contra o dataset golden e calcular concordância
Você tem o dataset com label humano. Para cada linha, roda os cinco juízes, salva o veredicto, compara com o label e calcula concordância:
$concordancias = collect($datasetGolden)->map(function ($exemplo) {
$juiz = avaliarPrecoCorreto($exemplo['output'], $exemplo['preco_real']);
return $juiz === $exemplo['label_humano_preco'];
});
$taxa = $concordancias->filter()->count() / $concordancias->count();
echo "Concordância juiz x humano: " . round($taxa * 100, 1) . "%";
Meta: entre 75% e 90% de concordância com o label humano antes de promover esse juiz para CI ou produção. Abaixo de 75% o juiz é ruído. Acima de 90% é provável que seu dataset esteja viesado ou pequeno demais, refaça com casos mais difíceis.
Os biases que vão te morder
Juiz LLM tem vícios documentados em paper. Ignorá-los é construir uma régua torta e medir tudo com ela.
Positional bias. O juiz tende a preferir a primeira resposta quando você compara duas. O paper Judging the Judges mostra que esse viés é amplamente influenciado pelo gap de qualidade entre as respostas. Mitigação: se você usa o juiz para comparação A/B (resposta nova vs. baseline), alterne a ordem aleatoriamente entre as chamadas e descarte o resultado se a inversão de ordem mudar o veredicto.
Verbosity bias. Juiz prefere resposta mais longa, mesmo quando a curta é melhor. Mitigação: na rubrica, instrua explicitamente "não considere o tamanho da resposta na avaliação" e pontue só o conteúdo objetivo. Para o agente de ofertas isso é crítico, uma resposta curta com o preço certo deve ganhar de uma longa com preço errado.
Self-enhancement bias. Juiz prefere respostas que ele mesmo geraria. Se o agente roda em Sonnet 4.6, o juiz não pode ser Sonnet 4.6. Use família diferente (GPT-4o, Gemini) ou um modelo bem menor da mesma família (Haiku para julgar Sonnet).
Limited reasoning. Juiz erra em raciocínio matemático e lógico complexo. Mitigação: para o juiz de preco_correto, não peça que ele "calcule" se R$ 1.299 está dentro de tolerância de 0,1% sobre R$ 1.300. Faça você o cálculo no código, e dê para o juiz a comparação binária pronta.
A regra geral: o juiz é mais confiável quanto mais cirúrgica for a pergunta. Quanto mais ele tiver que "pensar", mais ele falha.
Calibração: o passo que ninguém pula impunemente
Calibrar é rodar o juiz contra o dataset golden e comparar com o label humano. É chato. É essencial.
Sem calibração, você está confiando que o prompt da rubrica é suficiente. Não é. Toda rubrica que parece óbvia no Notion vira ambígua quando bate com casos reais.
O loop:
- Rode o juiz no dataset golden.
- Olhe só os casos onde juiz e humano discordaram. Geralmente são 5 a 15 exemplos.
- Para cada discordância: o humano errou? A rubrica está ambígua? O juiz está alucinando? Anote.
- Refine o prompt. Adicione exemplos few-shot dos casos limítrofes. Rode de novo.
- Repita até passar de 80%.
Esse loop é onde mora o resultado. A Anthropic chama isso de "iteração cuidadosa para validar acurácia" e adverte que pular isso é como deployar sem testar, você vai descobrir o problema em produção.
E uma vez calibrado, o mesmo juiz roda em três lugares: durante desenvolvimento, em pre-release como gate de CI, e em produção numa amostra. A LangSmith é firme nisso: usar avaliadores diferentes em cada estágio quebra a comparabilidade dos scores.
Limitações e pontos de atenção
- Custo. Cinco juízes x N exemplos x cada deploy não é grátis. Para 1000 exemplos diários, conte com algumas centenas de reais por mês só de juízes. Sample. Não rode em 100% do tráfego.
- Não substitui humano. Calibra contra humano. Roda em escala. Mas para casos novos (mudança de domínio, tipo de produto novo, idioma novo) você volta a precisar de label humano para recalibrar.
- Privacidade. Se a resposta do agente contém dado pessoal do usuário, mascarar antes de mandar para o juiz. Não envie endereço, telefone ou histórico de compra para a API do juiz sem necessidade.
- Drift do modelo. Anthropic e OpenAI atualizam modelos. Um juiz que estava em 85% de concordância pode cair para 72% depois de um update silencioso. Reexecute a calibração mensalmente, no mínimo.
Próximo passo no Clã
Construir agente é a parte fácil. Provar que ele funciona é a parte que separa quem vai colocar IA em produto sério de quem vai ficar fazendo demo bonito.
No Clã Beer & Code a galera está construindo agentes em PHP/Laravel com avaliação contínua, RAG calibrado, observabilidade real. Sem hype. Com engenharia.
Se você quer sair do achismo, é o ambiente certo.
FAQ rápido
Qual modelo eu uso como juiz?
Haiku 4.5 para julgamento binário e tarefas simples. Sonnet 4.6 onde tem nuance (sentimento, aderência à intenção). Opus 4.7 só em juízes críticos onde erro custa caro. Sempre família ou tamanho diferente do agente avaliado, para mitigar self-enhancement bias.
Quantos exemplos preciso no dataset golden?
Comece com 30 cuidadosamente escolhidos cobrindo casos felizes e bordas. Para casos de risco (compliance, dinheiro, saúde), 100+. O que importa é diversidade, não volume.
Posso rodar o juiz em produção 24/7?
Pode, mas em amostra. 5 a 10% do tráfego já te dá métrica estatisticamente útil sem custo absurdo. O resto roda só em deploys novos como gate de CI.
E se o juiz e o humano discordarem muito?
Boa notícia: significa que você descobriu cedo. Olhe os casos discordantes um por um. Quase sempre o problema é rubrica ambígua, não juiz "ruim". Refine o prompt e rode de novo.
Conclusão
Você saiu da planilha. Agora tem rubrica, juiz, dataset golden, calibração e um loop de melhoria que roda sozinho. Cada deploy passa por um portão objetivo antes de tocar o usuário.
O próximo passo dessa linha é agent-as-a-judge: avaliar não só a resposta final, mas a trajetória inteira do agente, quais ferramentas chamou, em que ordem, com que argumentos. Mas isso é assunto pro próximo post.
Até lá, fecha a planilha. Abre o editor. Escreve a primeira rubrica.
{AI Engineer} — apaixonado por Laravel, arquitetura de software e construir produtos com impacto. Compartilho aqui tutoriais, descobertas e reflexões sobre o dia a dia de engenharia.
Você também pode gostar
Cross-encoder reranker: o componente que mais eleva qualidade do seu agente por dólar
Retrieval traz 100 candidatos, reranker escolhe os 10 certos. Entenda o trade-off latência x precisão, quando rerankar 50 vs. 200 documentos e por que cross-encoder é o investimento de melhor ROI antes de trocar para um LLM mais caro.
Seu LLM não sabe o preço de nada: o problema do conhecimento congelado em apps de compra
Seu modelo foi treinado há meses, mas o mercado muda em horas. O LLM responde com a mesma confiança de sempre — só que com preço errado, produto descontinuado e estoque do ano passado. Esse é o conhecimento congelado, e ele mata qualquer app sério de recomendação. Veja por que perguntar "qual o melhor notebook até 5 mil?" direto pro LLM é receita pra demo bonita e cliente bravo — e como a arquitetura certa (tool use + RAG) resolve em Laravel.
Top-10 da busca não é top-10 do usuário: por que a SERP bruta sabota seu agente
A primeira página do Google não foi feita pra alimentar agente de IA. Ela foi feita pra ranquear sites. E essas duas coisas, em 2026, não são mais a mesma coisa. Plugar a SERP bruta no seu agente é amplificar SEO spam, MFA e conteúdo gerado por IA na escala. Veja por que o top-10 da busca não é o top-10 do usuário e como montar um pipeline de filtros + rerank que devolve confiança ao seu agente.
Chatbot não é agente: o teste dos 3 turnos que separa brinquedo de produto
Três perguntas simples sobre um produto real — preço hoje, reviews recentes, disponibilidade no CEP — quebram qualquer chatbot cru. O que separa brinquedo de produto não é o modelo. É o harness: a camada que transforma um LLM em agente confiável, com tool use, estado e validação contra o mundo real.