Documentação

O código é dono do limiar; o modelo só dá uma probabilidade

Junta algumas centenas de projetos reais lado a lado e o traço comum mais estável é este:

O modelo responde «qual é a probabilidade». O teu código responde «é suficiente».

Isto não é uma preferência de estilo. É a única conclusão segura a tirar do facto de que a confiança auto-reportada não é de confiança — e há medição independente por trás disso em Podemos confiar nas probabilidades.

Como é na prática

Choice e Score devolvem uma resposta com uma confidence associada; Noul devolve uma probabilidade de 0 a 1 diretamente. A própria interface não julga por ti — o limiar é teu. Nos projetos reais isso traduz-se em algo muito concreto:

  • Um filtro de linguagem obscena a correr num Cloudflare Worker mantém o seu limiar, a sua política de agregação max() e o seu esquema OpenAPI público todo no próprio código do Worker. O modelo é apenas uma função que ele chama.
  • Uma extensão de navegador que esconde comentários mantém 0.85 / 0.7 / 0.5 fixos na extensão, e mantém-se escondida quando a verificação falha — essa preferência também faz parte da política de limiar.
  • Uma ferramenta de triagem de incidentes define «paginar alguém» como P(SEV1) + P(SEV2) ≥ 0.80, e esse 0.80 vive na sua própria configuração, não no modelo.

Os três partilham uma propriedade: troca o modelo e o limiar não se move; reajusta o limiar e o modelo não se move. Entrega o limiar ao modelo e essas duas coisas tornam-se uma — altura em que «afinar o meu limiar» passa a significar editar um prompt.

Porque é que o princípio importa

Porque mantém separados dois tipos de falha:

  • O modelo respondeu mal — muda a pergunta, muda o estado, muda o modelo.
  • O limiar está mal fixado — muda o número no código.

Mistura-os e «a exatidão não é suficientemente boa» pode ser qualquer um dos dois, sem forma de saber qual. A ferramenta de triagem pode pôr 0.80 diretamente na configuração precisamente porque esse número pode ser revisto por si só.

O contraexemplo que tens de conhecer

O princípio assenta numa suposição: que o número que recebes é uma probabilidade calibrada.

Um recálculo independente descobriu que a confidence devolvida para perguntas de Score é frequentemente apenas a parte fracionária da pontuação, com essas saídas muito agrupadas (121 delas). Isso não é «o modelo está confiante» — parece um valor derivado da própria pontuação.

A diferença importa:

  • Se for uma probabilidade calibrada, 0.85 sustenta um raciocínio como «vou acertar em cerca de 85% dos casos como este».
  • Se for uma função da pontuação, 0.85 só significa «este aqui teve uma pontuação alta» e não diz nada sobre a frequência com que acerta — e fixar um limiar sobre ele significa fixar uma fasquia para um número sem significado probabilístico.

Separadamente, um relatório de medição independente comparou os campos auto-reportados do modelo com a verdade de base e descobriu que os valores são muito menos granulares do que a descrição sugere (ver Críticas públicas).

O que fazer em vez disso

Três passos, e a ordem importa:

  1. Usa o limiar operacionalmente, não semanticamente. Se 0.8 significa «80% correto» é irrelevante. O que importa é se, nos teus dados, os casos acima de 0.8 são mensuravelmente mais exatos. Isso podes verificar contra um conjunto de validação.
  2. Ajusta o limiar às tuas próprias etiquetas. Existe ferramenta exatamente para isto: pega nos teus dados anotados, ajusta o limiar por pergunta que atinge a tua exatidão-alvo, valida num conjunto de validação — e falha a CI quando uma atualização do modelo quebra um limiar bloqueado.
  3. Põe o limiar no código e dá-lhe uma data de revisão. Os limiares expiram com as versões do modelo, tal como os preços. É algo que uma pessoa tem de voltar a olhar, não algo que se fixa uma vez.

Numa frase

A fiabilidade do modelo deve aparecer no teu limiar, não no número que ele próprio reporta. Podes medir a primeira nos teus próprios dados; não podes medir a segunda.