Um ETL que mantenho faz sincronização incremental, de hora em hora, de várias tabelas de um ERP. Um dia percebi um problema que não aparecia em nenhum log de erro: um sync "rodava com sucesso", sem exceção, mas trazia zero ou pouquíssimas mudanças quando deveria trazer centenas. Não era uma falha, era uma falha silenciosa, o tipo mais perigoso, porque tudo parece estar funcionando.
O problema com alertas baseados em erro
Meu monitoramento original só disparava alerta em exceção: timeout, erro de conexão, erro de schema. Isso pega os problemas óbvios. Não pega o caso em que a query roda, retorna um resultado tecnicamente válido, mas incompleto, por exemplo, por causa de um filtro de data mal calculado, ou uma conexão degradada que devolve resposta parcial sem erro explícito.
A solução: baseline estatístico simples
Antes de pensar em qualquer modelo sofisticado, tentei a solução mais simples possível: guardar o histórico do número de mutações (linhas inseridas ou atualizadas) por sync e por tabela, e comparar cada execução nova com a média e o desvio padrão das últimas semanas. Se o valor do dia estiver muito fora do esperado (um z-score alto), o sync é marcado como suspeito e dispara um alerta pra eu revisar.
media = historico.media()
desvio = historico.desvio_padrao()
z_score = (mutacoes_hoje - media) / desvio if desvio > 0 else 0
if abs(z_score) > 3:
alertar("sync suspeito", tabela, mutacoes_hoje, media)
Isso não é machine learning no sentido chamativo do termo. É estatística básica de um jeito bem aplicado. E resolveu a maior parte do problema: comecei a pegar syncs "silenciosamente quebrados" no mesmo dia, em vez de descobrir semanas depois que um relatório financeiro estava com dado desatualizado.
Quando isso não é suficiente
A primeira versão gerou alguns falsos positivos por causa de sazonalidade: fechamento de mês tem naturalmente muito mais movimento financeiro que um dia qualquer, e isso disparava alerta sem ser um problema real. Precisei ajustar o baseline pra considerar o dia do mês, não só a média geral, comparando cada dia com o mesmo período em ciclos anteriores em vez de com a média de todos os dias misturados.
Nem todo problema que parece pedir "IA" precisa de um modelo de linguagem ou de machine learning complexo. Um z-score bem calibrado, com o contexto certo do domínio (sazonalidade, volume esperado por tabela), resolveu com muito menos complexidade, mais velocidade e, principalmente, mais fácil de explicar quando alguém pergunta "por que esse alerta disparou".
Conclusão
Não descarto usar um modelo mais sofisticado no futuro, se o padrão de anomalia ficar mais complexo do que uma comparação estatística simples consegue capturar. Mas a lição que fica é: antes de reservar a solução mais complexa, vale testar a mais simples que resolve o problema real. Na maior parte das vezes, ela é mais barata de manter e mais fácil de confiar.