Não construí apenas um revisor; construí a coisa que me diz se o revisor funciona.
O harness em cinco linhas
harness/cases/eval_cases.yamlguarda trechos de Python com problemas plantados e rotulados (e linhas limpas como armadilhas de falso-positivo).- O revisor roda em cada trecho e emite um
ReviewResultvalidado (JSON). harness/matcher.pymapeia cada achado para o gabarito pordimension+tag, usando proximidade de linha como critério de desempate.harness/scoring.pycalcula detection_rate, false_positive_signal e severity_weighted_recall, por dimensão e no geral.harness/run_eval.pyescrevereports/eval_report.mdereports/eval_result.json.
Números mais recentes
6 casos · 16 achados plantados · modelo claude-sonnet-4-6.
| métrica | valor |
|---|---|
| detection_rate (recall) | 81% (13/16) |
| severity_weighted_recall | 88% (23/26) — todo problema alto/médio capturado |
| should_not_flag hits | 0 — nunca marca uma linha limpa |
Uma iteração que moveu o número
O harness guiou três mudanças de prompt, cada uma registrada em reports/:
| run | mudança | recall | should_not_flag |
|---|---|---|---|
| 1 | prompts baseline | 75% | 3 |
| 2 | citar linhas precisas + sempre checar type hints / docstrings | 88% | 1 |
| 3 | "um literal atribuído a uma constante nomeada não é um número mágico" | 81% | 0 |
A run 2 subiu o recall ao tornar o revisor minucioso; a run 3 matou o último falso-positivo (ele tinha começado a marcar TAX = 0.0825 — uma constante nomeada — como número mágico).
Lendo ofalse_positive_signal(~64%). Isso éunmatched_findings / total_findings. Está alto aqui não porque o revisor esteja errado, mas porque ele encontra problemas reais que o dataset nunca plantou — importsos/sysnão usados, um bug de falsy emage == 0, um context-manager faltando. Inspecionamos todos os achados não pareados e eram legítimos. A medida de falso-positivo projetada é should_not_flag hits (0): linhas deliberadamente limpas que o revisor não pode tocar.
Arquitetura
snippet → reviewer.review() → ReviewResult (validated JSON) → UI + Eval harness
analyze facts about the code
critique raw findings per dimension (high recall)
synthesize dedupe · rank · score · positive note
- A saída estruturada é o contrato (
src/schema.py) — UI e harness consomem o mesmo formato. - Agnóstico de provedor — toda chamada de modelo passa por
src/llm_client.py; trocar de fornecedor é uma linha. - Determinístico onde importa — matching e scoring são Python puro; só o revisor chama o modelo.
Início rápido
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
copy .env.example .env # depois cole sua ANTHROPIC_API_KEY no .env
python -m scripts.smoke # round-trip de um prompt
python -m scripts.review_one # revisa um trecho de exemplo → ReviewResult
python -m harness.run_eval # roda o harness → reports/
streamlit run app.py # UI: aba Review + aba Eval
Definição de pronto
streamlit run app.pyrevisa um trecho colado com saída estruturada e pontuada.python -m harness.run_evalproduz uma tabela de métricas sobre o dataset rotulado.- Zero segredos commitados — uma
ANTHROPIC_API_KEYno.env(ignorado pelo git).