RUNBOOK — como executar o benchmark ainda hoje
Tempo estimado: **5 minutos** para validar e ensaiar; **1 a 2 dias** para uma rodada ao viva completa (a maior parte do tempo é espera de API e da auditoria humana).
Fase 0 — Verificação local (hoje, sem chaves, sem custo)
cd /home/matheus/benchmark-cego
# 1. Banco íntegro? (700 itens, schema, duplicatas, balanceamento)
make validate
# 2. Testes do pipeline (banco, cegueira, estatística)
make test
# 3. Rodada completa simulada, ponta a ponta
make demo
# 4. Inspecionar
cat resultados/demo/leaderboard.md
head -3 resultados/demo/resultados.csv
`make validate` imprime as contagens e a lista de erros. **Saída esperada:** `erros: []`, `total: 700`, `pt 238 / en 231 / zh 231`, `mcq 420 / aberto 175 / cálculo 105`.
`make demo` aplica 637 itens (90% do banco) a 15 sistemas simulados, com júri de 3 juízes, adjudicação e relatório. Duração típica: **< 2 segundos**.
Fase 1 — Calibração (metade do dia)
Objetivo: fixar ancoragem da rubrica, medir concordância entre juízes e descartar itens defeituosos **antes** de gastar com a rodada cheia.
# aplica os 63 itens de calibração em todos os participantes, em modo mock
make calib
# ou, ao vivo, apenas um domínio e poucos itens por participante:
python3 harness/run.py --live --only-domain juridica --limit 5 --out resultados/calibracao
Checklist da calibração:
- [ ] taxa de acerto por item entre 20% e 95% (art. 16);
- [ ] concordância interjuiz aceitável; calibrar
juizes.perfisse a divergência for sistêmica; - [ ] paridade de dificuldade entre pt/en/zh — diferença de nota média por idioma < 5 pontos;
- [ ] revisar manualmente os 10 itens com pior desempenho (
itens mais difíceisno relatório).
Fase 2 — Rodada ao vivo
2.1 Configurar chaves
Edite `harness/config.json` apenas para confirmar `model` e `base_url` de cada participante. As chaves **não** vão no arquivo: defina-as no ambiente.
export OPENAI_API_KEY="..."
export ANTHROPIC_API_KEY="..."
export GOOGLE_API_KEY="..."
export LLAMA_API_KEY="..."
export XAI_API_KEY="..."
export MSAI_API_KEY="..."
export AWS_BEARER_TOKEN_BEDROCK="..."
export COHERE_API_KEY="..."
export MISTRAL_API_KEY="..."
export AI21_API_KEY="..."
export DEEPSEEK_API_KEY="..."
export DASHSCOPE_API_KEY="..."
export MOONSHOT_API_KEY="..."
export ZHIPU_API_KEY="..."
export ARK_API_KEY="..."
Sem uma chave, o runner avisa e **cai em modo mock** para não travar o ensaio — confira a linha `[ok] modo=...` antes de confiar no resultado.
2.2 Escalonar (recomendado)
Uma rodada completa são 15 × 637 = **9.555 chamadas** de modelo, mais 3 juízes por item aberto (2625 chamadas de júri, na prova). Rode em fatias para controlar custo:
# por domínio, um de cada vez
for d in juridica medica proptech compliance bank energia negocios; do
python3 harness/run.py --live --only-domain $d --out resultados/live-$d
done
# ou amostra de controle antes da rodada cheia
python3 harness/run.py --live --limit 40 --out resultados/live-amostra
Consolidação manual: some os `pontos` por participante a partir dos `itens.csv` de cada fatia (o `resumo.json` de cada execução já traz o recorte aplicado).
2.3 Rodada completa
python3 harness/run.py --live --out resultados/live-2026Q4
Ou, se todas as chaves estiverem definidas:
make live
2.4 Reprodutibilidade
python3 harness/run.py --live --seed 20261111 --out resultados/live-2026Q4
A semente fixa a ordem dos itens e os rótulos `SISTEMA-XX`. O `resumo.json` registra `banco_hash`, semente, modelos exatos, temperatura e `max_tokens`.
Fase 3 — Auditoria humana e consolidação (1 dia)
- Amostra: extraia 10% dos itens abertos (mínimo 3 por domínio e idioma):
python3 - <<'PY'
import csv, random
rows = [r for r in csv.DictReader(open('resultados/live-2026Q4/itens.csv', encoding='utf-8'))
if r['type'] == 'open']
random.seed(20261111)
amostra = random.sample(rows, max(30, len(rows)//10))
with open('resultados/live-2026Q4/auditoria_humana.csv','w',newline='',encoding='utf-8') as fh:
w = csv.DictWriter(fh, fieldnames=list(rows[0].keys()) + ['nota_humana','revisor'])
w.writeheader()
for r in amostra:
r['nota_humana'], r['revisor'] = '', ''
w.writerow(r)
print('amostra:', len(amostra))
PY
- Dois revisores pontuam às cegas contra a rubrica do item (
q+rubricno - Itens com desvio humano–média > 1,0 ponto são anulados na rodada (art. 26).
- Recalcule as notas com os itens anulados fora e publique.
`banco/
Fase 4 — Publicação
Entregáveis (art. 41):
leaderboard.md— classificação, IC 95%, recortes por domínio e idioma, Elo, latência, recusa;resultados.csv— tabela completa;itens.csv— nota de cada item por sistema (evidência);resumo.json— metadados da rodada e hash do banco;- nota de rodapé com elenco e versões (
participantes/ias.csv).
Divulgação dos itens da prova: **90 dias** após a rodada (art. 42).
Solução de problemas
| Sintoma | Causa provável | Ação |
|---|---|---|
BANCO INVÁLIDO | JSONL corrompido ou contagem fora do padrão | python3 harness/bank.py banco lista os erros por item |
sem chave de API para: ... | variável de ambiente ausente | exportar a chave; sem ela o runner cai em mock |
falha após 3 tentativas | rate limit ou endpoint incorreto | reduzir --limit, conferir base_url e model |
Nota de calc sempre 0 | unidade/tolerância incompatível | conferir tol e unit no item; a resposta deve trazer o número |
| Muitas adjudicações | juízes com perfis muito distantes | calibrar juizes.perfis na Fase 1 |
| Resultado não reproduz | semente diferente ou banco alterado | usar a mesma --seed e o mesmo banco_hash |
Comandos de referência
| Comando | O que faz |
|---|---|
make validate | valida o banco de 700 itens |
make test | 19 testes unitários |
make demo | rodada completa em modo mock |
make calib | aplica os 63 itens de calibração (mock) |
make live | rodada ao vivo |
python3 harness/run.py --help | todas as opções (--limit, --only-domain, --seed, --out, --sem-calibracao) |