Como calculamos as probabilidades: o método completo
Esta página descreve, sem omitir nada, o método exato por trás dos números: o que é simulação estatística (Monte Carlo), onde (e apenas onde) entra o modelo de linguagem (Claude), quais constantes usamos, e quais limites impedem um boato de virar o tabuleiro. Os valores citados são os que estão no código em produção.
Visão geral: duas camadas, uma fonte de verdade matemática
A probabilidade de título de cada seleção não vem de nenhuma API e não é “chutada” por uma IA. Ela é computada por nós simulando o torneio dezenas de milhares de vezes. O pipeline tem duas camadas:
fato (texto livre)
└─ interpretFact() [Claude] → Adjustment[] (JSON estruturado)
└─ ground() [valida+limita] → Adjustment[] válidos
└─ applyAdjustments() → { ratingDelta, matchOverrides }
└─ monteCarlo() [simulação] → Probabilidades
└─ diff(base, ajustado) → resposta do cenárioCamada base (100% determinística, sem IA): a simulação Monte Carlo do chaveamento. Cada seleção tem um rating de força; o torneio é simulado 20.000 vezes e a frequência com que cada time é campeão vira a probabilidade. Os ratings são calibrados para reproduzir as odds de mercado.
Camada de fato (onde, e só onde, o Claude atua): o texto livre que você digita é lido pelo Claude, que devolve um ajuste estruturado e limitado nos inputs do simulador (ex.: França −90 pts de rating). O mesmo simulador roda de novo com esse input e gera as novas probabilidades. O Claude interpreta; a matemática computa.
1. Dados de entrada (e o que acontece sem chave de API)
- API-Football (
v3.football.api-sports.io,league=1&season=2026): grupos e times (standings), confrontos (fixtures) e odds de campeão (mercado “Winner”/outright). Cache: grupos/timesrevalidate 3600s, odds300s. - Zafronix (
api.zafronix.com): estádios com altitude (metros) e GPS, e histórico de Copas. Cache86400s. - Fallback estático: se uma chave faltar ou a chamada falhar, usamos um roster embutido com os 48 times (12 grupos do sorteio de dez/2025), jogadores-chave e as 16 sedes com altitude. O app nunca quebra por falta de dado externo.
Times vindos da API são mapeados para os mesmos IDs canônicos do roster por nome (inclusive nomes em inglês), de modo que flags, jogadores-chave e sedes permaneçam consistentes entre a simulação e a interpretação de fatos.
2. Rating de força e calibração às odds de mercado
Cada seleção recebe um rating tipo Elo (banda 1350–2100). Sem ancoragem, o modelo não sabe quem é favorito, então calibramos os ratings para que a simulação reproduza as probabilidades de mercado.
Probabilidade implícita do mercado. A partir das odds decimais, tomamos 1/odd de cada time e normalizamos para somar 1 (isso remove a “margem da casa”, que faz a soma bruta passar de 100%):
p_mercado_i = (1 / odd_i) / Σ (1 / odd_j)
Semente do rating. O rating inicial é uma função log da probabilidade de mercado, recortada à banda:
rating_i = clamp( 2000 + 70 · ln(p_mercado_i + 1e-4), 1350, 2100 )
Ajuste iterativo. Rodamos a simulação (com 5.000 iterações, mais barata) e empurramos cada rating na direção do erro, repetindo até 12 rodadas ou até o erro máximo cair abaixo de 1 ponto percentual (TOL = 0.01):
rating_i += η · ( ln(p_mercado_i) − ln(p_simulado_i) ) maxErr = max_i | p_mercado_i − p_simulado_i | η começa em 30 e decai ×0.85 por rodada (piso 5); para se maxErr < 0.01
Na prática converge em poucas rodadas (tipicamente 4) com maxErr ≈ 0.9 p.p., dentro da tolerância. O resultado calibrado (ratings + probabilidades sem fato) é o baseline, pré-computado e cacheado.
3. Modelo de partida (Poisson com viés de rating)
Cada jogo é resolvido sorteando o número de gols de cada lado de uma distribuição de Poisson. A média de gols esperada depende da diferença de rating:
d = gapShrink · (ratingA − ratingB) / 100 λ_A = 1.30 · exp( 0.50 · d + homeAdjA ) λ_B = 1.30 · exp( −0.50 · d + homeAdjB ) golsA ~ Poisson(λ_A) golsB ~ Poisson(λ_B)
MU = 1.30: gols médios por time por jogo.BETA = 0.50: o quanto a diferença de rating empurra os gols (escala: 100 pts de Elo).gapShrink: normalmente1; valores< 1(chuva, gramado ruim) encolhem a vantagem do favorito, aproximando do azarão.homeAdjA/homeAdjB(0–0.4): vantagem de mando / aclimatação (ver §9).
Mata-mata empatado → pênaltis. Se o tempo normal termina igual, o vencedor sai de um sorteio enviesado pela diferença de força (perto de 50/50):
P(A vence nos pênaltis) = 1 / ( 1 + exp( −0.40 · d ) ) // SHOOTOUT_BETA = 0.40
4. Simulação Monte Carlo do torneio
O formato real da Copa 2026: 12 grupos de 4 → os 2 primeiros de cada grupo (24) + os 8 melhores terceiros = 32 times → R32 → oitavas → quartas → semi → final.
- Fase de grupos: todos contra todos (6 jogos por grupo), 3 pts por vitória, 1 por empate. Desempate: pontos → saldo de gols → gols pró → moeda (sorteio). É uma simplificação auditável dos critérios oficiais da FIFA.
- Melhores terceiros: os 12 terceiros colocados são ordenados pelo mesmo desempate e os 8 melhores avançam.
- Chaveamento: um template fixo de 16 confrontos define quem encara quem no R32 (também uma simplificação auditável da matriz oficial). Daí em diante é eliminatória simples.
- Contagem por fase: a cada simulação registramos até onde cada time chegou; “alcançar a fase X” conta como ter passado por todas as anteriores. A frequência em N simulações vira a probabilidade exibida por fase.
N = 20.000 simulações no baseline e em cada cenário (erro de Monte Carlo da ordem de ±0.3 p.p.); 5.000 durante a calibração.
5. Mata-mata: a grade das oitavas à final (previsão × jogos reais)
A seção do mata-mata tem duas abas, que respondem a perguntas diferentes, por isso podem divergir nos confrontos intermediários:
Aba “Nossa previsão”. É a chave mais provável segundo o modelo: determinística e estável (não é um sorteio aleatório, que mudaria a cada visita). Construímos a partir do baseline calibrado (§2):
- Previmos a classificação de cada grupo (1º, 2º e os 8 melhores 3ºs) e montamos os 32 confrontos com o mesmo template do chaveamento (§4).
- Em cada confronto, avança a seleção com a maior probabilidade de título, exatamente a métrica que ordena o leaderboard (desempate por rating).
Usamos a probabilidade de título, e não o rating bruto, de propósito: a % de título embute a dificuldade do grupo e do chaveamento. Se decidíssemos por rating, um único ponto de Elo a mais poderia coroar um time que não é o favorito do leaderboard, uma contradição. Com esta regra, o campeão previsto coincide sempre com o nº 1 do leaderboard. (Confrontos intermediários ainda podem reservar uma “zebra” coerente: um time com % de título menor, mas num lado da chave mais fácil, pode avançar mais.)
Aba “Jogos reais”. São os confrontos e placares de verdade, puxados ao vivo da API-Football e classificados por fase (oitavas → final). Atualizam automaticamente: renderização inicial no servidor + atualização no navegador a cada 60s. Enquanto a fase de grupos não termina, os confrontos aparecem como “a definir” e a grade vai sendo preenchida sozinha conforme os jogos acontecem (placar, “ao vivo”, encerrado).
Ambas as abas mostram a mesma faixa, das oitavas à final (8 → 4 → 2 → 1 confrontos). As probabilidades por fase de cada seleção continuam no leaderboard e no painel de detalhe; aqui é a árvore.
6. Camada de fato: quando, e como, o Claude é usado
O modelo de linguagem (Claude, da Anthropic) é chamado exclusivamente em um ponto: traduzir o seu texto livre em ajustes estruturados. Ele roda no servidor; a chave de API nunca chega ao navegador. Ele nunca devolve probabilidades, só o JSON de ajuste.
Modelo e parâmetros: CLAUDE_MODEL (padrão claude-sonnet-4-6), temperature 0.2, max_tokens 1024. O Claude recebe o fato, a lista de times do torneio, os jogadores-chave por seleção e um resumo dos próximos confrontos.
O que ele devolve (validado por schema; resposta fora do formato dispara 1 nova tentativa e, se ainda falhar, retorna “sem ajustes” com um resumo de erro):
{
adjustments: [{
target: { type: 'team'|'player'|'match'|'condition', ref },
category: 'injury'|'suspension'|'coaching'|'weather'|
'travel'|'venue'|'morale'|'other',
effect: { kind: 'rating_delta', value } // pts Elo, escopo time
| { kind: 'gap_shrink', value } // 0..1, escopo partida
| { kind: 'home_edge', value }, // soma ao mando, escopo partida
scope: 'all'|'match'|'phase',
confidence: 0..1,
rationale: texto curto (≤ 240 chars)
}],
summary: explicação em linguagem natural (≤ 400 chars)
}Escala que instruímos o Claude a respeitar (ele propõe dentro disto; o sistema ainda recorta depois, ver §7):
- Lesão/suspensão de craque decisivo:
rating_deltade −120 a −60. - Titular importante fora: −50 a −20. Reserva/secundário: −15 a 0.
- Troca de técnico/esquema: −30 a +30 (confiança baixa).
- Chuva forte numa partida:
gap_shrink0.5–0.85. - Altitude/sede favorável numa partida:
home_edge0.05–0.30. - Evento extra-campo (namoro, polêmica pessoal): efeito ~0. Em geral lista vazia, com o motivo explicado no resumo.
Se a variável ANTHROPIC_API_KEY não estiver configurada, a interpretação fica desativada e o cenário é simulado sem ajustes (nada quebra).
7. Grounding e guardrails (o que impede um boato de virar o jogo)
Antes de tocar no simulador, cada ajuste do Claude passa por uma camada de validação determinística:
- Grounding (existência real): resolvemos
target.refcontra os dados. Time/jogador/estádio que não existe no torneio é descartado. Lesão de jogador é resolvida para o time dele: é nesse time que o efeito incide. - Limites por categoria (clamp): o valor proposto é recortado à banda da categoria. Se o tipo de efeito não combina com a categoria, o ajuste é descartado.
injury / suspension : rating_delta ∈ [−120, 0] coaching : rating_delta ∈ [ −30, 30] travel : rating_delta ∈ [ −25, 0] morale : rating_delta ∈ [ −10, 10] other : rating_delta ∈ [ −20, 20] weather : gap_shrink ∈ [ 0.4, 1] venue : home_edge ∈ [ 0, 0.4]
Teto global de impacto (TITLE_CAP = 0.08). Nenhum cenário pode mover a probabilidade de título de uma seleção em mais de ±8 pontos percentuais. Depois da simulação ajustada, medimos o maior |Δ campeão|; se ele estoura o teto, escalamos todos os ajustes por um fator 0.08 / Δmáx e re-simulamos. É isso que mantém um boato dentro de um impacto plausível.
8. Aplicação dos ajustes e re-simulação
Os ajustes validados viram dois efeitos no simulador:
rating_delta→ soma aos pontos de rating do time (escopo torneio inteiro).gap_shrink/home_edge→ sobrescrevem os fatores (gapShrink,homeAdj) de uma partida específica.
Com os ratings e fatores modificados, rodamos o mesmo Monte Carlo (20.000 simulações) e comparamos com o baseline: a resposta traz o antes, o depois, os deltas por seleção (ordenados por |Δ|) e o racional de cada ajuste.
9. Fatores de contexto: altitude e mando
Para cada confronto, olhamos o estádio. Quando uma seleção anfitriã (México, EUA ou Canadá) joga numa sede acima de 1.500 m de altitude (caso do Estádio Azteca, 2.240 m, e do Akron, em Guadalajara, 1.566 m), ela recebe homeAdj = +0.10, uma leve vantagem de aclimatação no modelo de gols. Fora disso, gapShrink = 1 e os mandos são neutros, salvo override de cenário (ex.: chuva).
10. Determinismo: o mesmo fato dá sempre o mesmo resultado
- RNG semeável (mulberry32): toda a aleatoriedade vem de um gerador com semente. A semente do cenário é um hash estável do seu texto (FNV-1a): mesmo texto, mesma sequência de sorteios, mesmo resultado.
- Cache da interpretação: a resposta do Claude é cacheada pelo hash do texto. O mesmo fato não é reinterpretado nem gera ajuste diferente.
11. Cache, performance e persistência
- Baseline: calculado no servidor (runtime Node, porque é intensivo em CPU) e mantido em memória por 6 horas, com uma versão derivada do hash dos grupos + odds. Só re-simulamos sob demanda nos cenários.
- Dados externos: revalidação de 3600s (times/grupos), 300s (odds) e 86400s (estádios/histórico).
- Cenários compartilháveis: persistidos em Postgres (Neon) por um
scenarioId(hash do texto + timestamp). SemDATABASE_URL, ficam em memória para o dev local.
12. Limitações honestas
- As constantes
MU,BETAeSHOOTOUT_BETAsão razoáveis, mas ainda em afinação contra o histórico real de Copas. A sensibilidade a grandesrating_deltaé alta: uma lesão de craque de um favorito tende a raspar o teto de ±8 p.p. - O template do chaveamento, a alocação dos terceiros e o desempate de grupo são simplificações auditáveis das regras oficiais.
- A calibração reflete as odds de mercado, com todos os seus vieses; não é uma verdade física.
Em resumo: a simulação faz a conta, o Claude só lê o fato, e há limites duros para tudo. Mesmo assim, são estimativas: o futebol tem uma quantidade generosa de caos.
13. O que esta plataforma não é
Não é aconselhamento de apostas. Não é previsão garantida. As probabilidades são estimativas; use como entretenimento, não aposte com base nisso.
Quer sentir o método na prática? Volte à home e brinque com o painel “E se…?”.