TL;DR
A maior parte do tráfego automatizado é fácil de travar. Uma expressão regular de user-agent e um CAPTCHA apanham a base do mercado. O tráfego que importa não vive aí. Navegadores com patch de stealth, scrapers com proxy residencial e agentes orientados por LLM correm motores de navegador reais, carregam fingerprints limpas e movem um ponteiro como uma pessoa o faz. Uma fingerprint limpa não prova um humano, e um endereço de datacenter não prova um bot.
Este é um relatório de campo sobre uma stack de deteção construída para esse adversário: uma camada determinística de regras mais dois modelos neuronais compactos, um a ler sinais de fingerprint e de rede e outro a ler comportamento, combinados por um OR lógico. O embedding congelado do modelo comportamental separa bots de humanos quase na perfeição. Uma busca por 16 arquiteturas mostra que o teto de desempenho vem do sinal, não do modelo. E o resultado honesto: na população total de produção, num orçamento estrito de falsos positivos, o recall fica abaixo da fasquia que a stack ultrapassa na sua distribuição de treino, por razões de composição da população e não de qualidade do modelo.
Sinais de deteção específicos, nomes de features e thresholds são omitidos por desenho, para que a engenharia seja reproduzível em espírito sem se tornar um guia de evasão.
O adversário que vale a pena combater
Uma regex de user-agent e um CAPTCHA travam a base do mercado de automatização e deixam passar o resto. Os adversários que vale a pena combater não estão nesse nível inferior. Correm Chromium real. Alteram a superfície de fingerprint que as verificações ingénuas leem. Usam proxy através de espaço de endereçamento residencial. Os mais capazes são agentes de modelo de linguagem que perseguem um objetivo ao longo de um fluxo de múltiplos passos em vez de repetir um script fixo.
A propriedade definidora deste adversário é que nenhum observável isolado resolve a questão. Esta é a mesma razão por que os CAPTCHAs já não fazem trabalho real contra automatização motivada, e por que os stealth browsers e navegadores anti-deteção existem como categoria de produto. Não consegue ler a resposta a partir de um só valor. Tem de combinar sinais independentes e aceitar que cada um, por si só, está errado parte do tempo.
A stack de deteção: uma camada determinística e dois modelos compactos
A stack decide se um visitante é automatizado com uma cascata de duas fases precedida por uma camada determinística de regras.
- Camada determinística de regras. Codifica o punhado de condições que constituem prova de automatização por si só.
- Modelo 1, fingerprint (MorphNet). Pontua uma única avaliação de página a partir de sinais de dispositivo, navegador e rede.
- Modelo 2, comportamento (GammaNet). Pontua uma sessão inteira a partir de telemetria comportamental, e recebe a pontuação do primeiro modelo como entrada.
O rótulo final é o OR lógico dos três. Um visitante é sinalizado se a camada de regras dispara, ou se qualquer modelo dispara. Essa estrutura tem uma consequência que molda todo o resto: como a camada de regras já apanha os casos que consegue provar, os modelos não precisam de o fazer. Os modelos treinam apenas sobre o residual, o tráfego que as regras não conseguem resolver, que é tanto a parte difícil do problema como a parte onde um modelo conquista o seu lugar.
A fasquia mantida ao longo de todo o processo é um recall de pelo menos 0.90 a uma taxa de falsos positivos de no máximo 0.01, medida em tráfego de produção real ao nível da sessão.
Como a avaliação se mantém honesta
Os números abaixo só significam algo por causa de como a avaliação é construída, por isso vale a pena enunciar primeiro as salvaguardas.
Os dados de treino e de avaliação são avaliações de página reais agrupadas em sessões. Os rótulos são determinísticos, aplicados apenas quando um sinal constitui prova; tudo o que é ambíguo é deixado sem rótulo em vez de adivinhado, o que mantém o ruído de rótulos fora da verdade de base. Para as classes de stealth que evitam o fingerprinting por construção, a verdade de base vem de um arnês controlado de geração de tráfego que corre automatização conhecida contra alvos instrumentados, por isso o rótulo é conhecido pela proveniência e não inferido.
Três salvaguardas contra fugas mantêm os números reportados honestos:
- Os sinais que a camada determinística de regras lê são excluídos do treino do modelo, para que o modelo aprenda o residual em vez de re-memorizar o que as regras já dominam.
- Os eventos que anunciam diretamente um agente de automatização são retirados do fluxo comportamental antes de calcular as features, para que o modelo comportamental aprenda estrutura de movimento e timing em vez da presença de um tipo de evento revelador.
- A cascata é ligada com pontuações out-of-fold: a contribuição do primeiro modelo para o segundo é a sua pontuação validada por cruzamento, nunca uma previsão de um modelo que já viu a sessão.
Cada divisão é por sessão, nunca por linha, uma vez que várias avaliações partilham uma sessão e uma divisão ao nível da linha deixaria a mesma sessão aparecer em ambos os lados. Todos os resultados usam uma seed fixa.
Modelo 1: MorphNet, o modelo de fingerprint
O primeiro modelo lê cerca de 90 features por avaliação que descrevem coerência de fingerprint, características da camada de transporte e contexto de rede. A primeira versão de produção era um ensemble de árvores com gradient boosting. Era exato em tráfego fácil, pesado para enviar para um caminho de pedido sensível à latência, e difícil de introspecionar. Foi substituído por uma rede construída de raiz.
A MorphNet dá a uma rede minúscula a forma expressiva de um ensemble de árvores: uma redução linear aprendida para um espaço interno compacto, depois ativações por canal onde cada canal ajusta a sua própria curva de resposta, depois uma camada de interação de baixo rank que deixa pares de sinais modularem-se mutuamente, uma leitura ponderada e um funil curto para uma única saída. O modelo inteiro tem cerca de 6,500 parâmetros e treina em cerca de 25 segundos num GPU de portátil.
Duas falhas latentes no primeiro rascunho foram apanhadas na revisão de desenho, antes de se escrever qualquer código de treino. Uma era um softmax terminal sobre uma única saída, que é matematicamente constante e não transporta gradiente, por isso o modelo não conseguia aprender. A outra era uma leitura de interação que colapsava num vetor constante, uma camada morta que nada contribui. Uma terceira lição veio do treino: a escolha de normalização é determinante. As estatísticas correntes da batch normalization baixaram o AUC de validação de 0.99 para 0.50, e a layer normalization é o ajuste correto para o modelo de exemplo único que corre em produção.
Numa divisão honesta ao nível da sessão, os resultados da MorphNet:
| Métrica | Valor |
|---|---|
| AUC | 0.9994 |
| Recall no ponto de operação | 0.9959 |
| Recall em 5 seeds | 0.9962 ± 0.0007 |
| Concordância numérica inferência-vs-treino | within 5e-7 |
Cada seed ultrapassa a porta, e a concordância entre o grafo de inferência exportado e o framework de treino significa que o modelo servido é o modelo treinado.
O contraste com o baseline antigo é mais nítido no conjunto residual difícil, o tráfego que a camada de regras não consegue resolver. Numa divisão de stress reservada de 6,004 sessões:
| Modelo | Recall no conjunto residual difícil |
|---|---|
| Versão A anterior com gradient boosting | 0.139 |
| Versão B anterior com gradient boosting | 0.039 |
| MorphNet | 0.996 |
A reconstrução não é um ganho marginal nesta fatia. É a diferença entre um modelo que funciona nos casos difíceis e dois que não funcionam.
Modelo 2: GammaNet, o modelo comportamental
O comportamento é mais difícil do que a fingerprint, por isso o segundo modelo tem mais estrutura. Lê 179 entradas comportamentais agregadas que descrevem a forma de uma sessão, e é construído em duas peças.
O front end é um encoder de autoencoder que mapeia as entradas limpas e padronizadas para baixo através de uma camada oculta até um latente de 32 dimensões na hiperesfera unitária. Este encoder é treinado uma vez, sem rótulos, e depois congelado. O back end é uma pequena cabeça supervisionada: cada canal latente passa por uma não-linearidade aprendida compacta, inicializada para que o treino comece a partir da representação congelada, seguida de um funil linear curto para uma única saída. O modelo tem cerca de 14,000 parâmetros, a maior parte deles no encoder congelado e apenas algumas centenas treináveis na cabeça.
Congelar o encoder é a decisão que faz este modelo comportar-se bem. Um encoder treinado para reconstruir generaliza para tráfego em produção; um treinado para separar as classes da forma mais nítida possível não generaliza. Numa divisão reservada ao nível da sessão, a GammaNet atinge um AUC de 0.9989 e um recall de 0.9964 no ponto de operação, a um fio de distância de um baseline de árvores recém-retreinado na divisão idêntica. Num replay em produção contra bots conhecidos, o seu recall só de modelo foi 99.4%, contra 96.4% do modelo comportamental anteriormente implementado.
O embedding comportamental separa quase na perfeição
O artefacto mais marcante do projeto é a geometria do latente congelado da GammaNet. Cerca de 17,000 sessões foram mapeadas através do encoder para ver onde bots e humanos aterram. Ficam em regiões opostas da esfera.
| Métrica | Valor | O que significa |
|---|---|---|
| Pureza do vizinho mais próximo (k=1) | 99.6% | O vizinho mais próximo de quase todos os pontos partilha a sua classe |
| Separação cosseno dos centroides | -0.99 | Os centroides de bot e de humano ficam quase antipodais na esfera |
| Entropia local média (k=20) | 0.010 | Quase nenhuma mistura de classes em vizinhanças locais |
Na prática não há zona de confusão. As classes ficam perto de polos opostos, a região entre elas detém quase nenhuma massa de probabilidade, e o modelo está confiante em quase todo o lado.
A projeção abaixo torna essa geometria tangível: cada ponto é uma sessão mapeada através do encoder congelado, e as variações sintéticas de stress afastam-se do agrupamento do campo real em vez de se fundirem nele. Arraste para rodar.
A separação não é obra de uma única direção. Quando cada eixo latente é pontuado por si só, o poder discriminativo está espalhado pela representação, com uma dúzia ou mais de eixos a transportar cada um sinal real em vez de um eixo a fazer o trabalho. Essa distribuição importa para um modelo de segurança. Uma representação que concentrasse o seu sinal num eixo também concentraria o alvo do adversário. Uma distribuída não oferece esse ponto único para pressionar.
A busca de arquiteturas, e um muro
Este é o ponto onde um relato costuma declarar vitória. Aconteceu o oposto: uma tentativa de bater o modelo. Se 32 dimensões separam as classes de forma tão limpa, talvez um embedding mais rico elevasse ainda mais o desempenho em produção.
O teste foi um confronto de 16 famílias de modelos sobre o conjunto de features comportamentais, pontuadas numa bateria que incluía a tarefa de produção em produção. O conjunto foi deliberadamente amplo: autoencoders variacionais de vários tipos, objetivos supervised-contrastive e hiperesféricos, encoders parametrizados por rotação e fatorados por grupo de features, backbones hipercomplexos de quaterniões e octoniões, variantes denoising e contractive, e um transformer de self-attention sobre blocos de features.
Voltaram duas conclusões, e ambas foram claras.
Primeiro, o teto em produção é invariante à arquitetura. Cada família, desde um autoencoder tied simples a uma rede de octoniões e a um transformer, aterrou numa banda estreita, e o melhor deles apenas igualou o encoder existente. A sofisticação arquitetural não moveu o limite.
Segundo, uma separação mais nítida dentro da distribuição acompanhava uma pior generalização em produção. Os modelos com a divisão mais nítida na distribuição de treino, os objetivos contrastive agressivos que atingiram recall perfeito nos dados de treino, estavam entre os mais fracos em tráfego de produção. Separar em excesso a distribuição de treino é overfitting com outro nome, que é exatamente por que o encoder é congelado em vez de remodelado pelo classificador.
Depois o controlo que resolveu a questão: descartar inteiramente o embedding e treinar classificadores diretamente sobre as features em bruto. Uma árvore com gradient boosting sem restrição, recebendo todas as features em bruto sem qualquer estrangulamento, um modelo linear sobre as mesmas features e o embedding compacto aterram todos essencialmente no mesmo AUC em produção: um teto rígido que medimos em vez de assumir. O teto em produção é uma propriedade do que mede e não de como modela. Esse é um resultado mais útil do que mais uma casa decimal de AUC, porque diz, com evidência, que mais trabalho de modelação sobre os sinais atuais é um beco sem saída, e que o caminho a seguir é um sinal novo e independente.
Uma nota de rodapé tornou-se um modelo. Como os melhores generalizadores eram as cabeças generativas, a equipa construiu uma. A VMFNet pontua uma sessão com uma mistura von Mises-Fisher por classe sobre a esfera, comparando a verosimilhança sob uma mistura humana contra uma mistura de bot. Com cerca de um terço do tamanho da stack de embedding anterior, atinge o mesmo teto de features em bruto. As cabeças generativas generalizaram de forma mais estável do que as discriminativas, a mesma lição que levou a congelar o encoder.
Defesa em profundidade: camadas que falham de forma independente
A exatidão dentro da distribuição é por si só uma garantia fraca, por isso cada modelo foi sujeito a red team interno contra perturbação de entrada e telemetria parcial. Os orçamentos de perturbação são omitidos, uma vez que esses números equivalem a uma receita, mas o quadro qualitativo guia o desenho. O modelo de fingerprint degrada-se graciosamente sob ruído de entrada moderado e tolera telemetria incompleta, que é o que um modelo no caminho do pedido precisa quando por vezes vê dados parciais.
A conclusão sobre a qual o desenho atua é que nenhum modelo isolado deve carregar o sistema. É por isso que a stack é uma cascata em vez de um único classificador. Um adversário que degrade a evidência mais forte de um modelo ainda enfrenta a camada determinística e um segundo modelo que lê uma família de sinais inteiramente diferente, e a decisão final dispara se qualquer um dos três disparar. A resiliência aqui vem de manter vários sinais reveladores não correlacionados ao mesmo tempo em vez de um forte. Derrotar a stack significa derrotá-los todos em conjunto.
Pegada de produção
Como a stack foi desenhada para o caminho do pedido desde o início, a versão neural é leve além de exata.
| Medida | Stack de árvores | Stack neural | Mudança |
|---|---|---|---|
| Tamanho em disco (ONNX) | 6.465 MB | 0.079 MB | cerca de 82x mais pequeno |
| RAM de inferência adicionada | +89 MB | +14 MB | cerca de 6.4x mais leve |
| Throughput | 0.56 M rows/s | 1.74 M rows/s | cerca de 3x mais rápido |
A métrica que importa mantém-se estável enquanto a pegada cai por perto de duas ordens de magnitude. O modelo comportamental implementado inteiro tem 79 kilobytes, pequeno o suficiente para ser tratado como negligenciável face ao resto do caminho do pedido.
Cobertura por classe, e o número honesto
Na avaliação gold-standard, 5,997 bots rotulados e 7,964 humanos retirados de logs de produção com divisões ao nível da sessão e salvaguardas contra fugas, a cascata implementada apanha cada classe de adversário com recall total.
| Classe de adversário | Recall da stack implementada |
|---|---|
| Automatização básica | 100% |
| Stealth browsers difíceis | 100% |
| Agentes LLM | 100% |
| Stealth + patch de fingerprint | 100% |
| Bots em produção não mapeados | 100% |
Isso inclui as classes difíceis: stealth browsers com fingerprints alteradas, agentes de modelo de linguagem e bots em produção que se comportam como utilizadores comuns. Sessões que um modelo anterior pontuava perto de zero pontuam agora perto de um após uma correção dirigida à distribuição de onde vieram.
Depois o resultado que mantém o trabalho honesto. No ponto de operação estrito, o recall na população total de produção fica abaixo da fasquia que a stack ultrapassa na sua distribuição de treino. A razão vale a pena enunciar com clareza, porque não é um problema de qualidade do modelo. A lacuna é sobre a composição da população e o custo de um orçamento estrito de falsos positivos. Uma população humana real contém grupos grandes cujo tráfego se assemelha a automatização nesse orçamento, por isso manter esse orçamento deixa necessariamente recall por apanhar. A busca de arquiteturas já mostrou que quase todo o sinal de separação que as features atuais contêm foi extraído. Fechar a lacuna restante exige um sinal novo e independente, ou pontos de operação específicos por população, em vez de um classificador melhor sobre as mesmas entradas.
O que isto significa para equipas que correm deteção
Retire as especificidades e algumas lições operacionais transferem-se para qualquer equipa que tente separar humanos de automatização construída para parecer humana:
- Verificações só de fingerprint e só de rede falham o adversário que importa. As classes que lhe custam dinheiro passam essas verificações por desenho. Os sinais comportamentais e de runtime são onde se separam.
- O teto é o sinal, não o modelo. Quando uma busca de modelos converge para o mesmo número ao longo de 16 famílias, mais modelação não vai ajudar. O próximo ganho vem de um sinal novo e independente capturado onde o bot realmente executa.
- Construa camadas que falham de forma independente. Uma cascata de uma camada determinística mais modelos não correlacionados é mais difícil de evadir do que um classificador forte, porque um atacante tem de derrotá-los todos de uma vez.
- Escolha pontos de operação por população e por ação. Um único threshold global num orçamento estrito de falsos positivos deixa recall por apanhar. Limite a decisão à ação, e afine o orçamento a quem está a proteger.
É também aqui que a cside encaixa operacionalmente. A cside observa o runtime do navegador em tempo real, captura o dispositivo e o IP real do cliente, expõe sinais de script de runtime e de automatização, lê coerência de fingerprint e continuidade de sessão, e sinaliza agentes IA e stealth browsers dentro da página, depois expõe esses sinais via API para que possa impulsionar uma decisão de permitir, monitorizar, desafiar ou bloquear no seu próprio fluxo de trabalho. Essa telemetria da camada do navegador é exatamente o sinal independente que uma stack só de fingerprint ou só de rede esgota, e a camada onde um humano, um bot bom e um agente malicioso finalmente deixam de se parecer. Para a mecânica dos sinais subjacente a essa decisão, consulte o guia para detetar tráfego de agentes IA e como bloquear agentes IA no seu site.
Mais leituras na cside
- Guia para detetar tráfego de agentes IA no seu site
- Stealth browsers e navegadores anti-deteção, explicados
- Porque os CAPTCHAs estão mortos
- Como bloquear agentes IA no seu site
- cside AI Agent Detection
Os números e as métricas neste relatório são extraídos de artefactos de modelos em cache e de avaliações de tráfego de produção. Sinais de deteção específicos, nomes de features e thresholds de decisão são omitidos por desenho.





