IA AplicadaIntegraçõesRPA & AutomaçãoLeitura 5 min

Três Técnicas Avançadas que Aumentaram em 300% a Precisão do Nosso Sistema de Matching de Veículos

Jonas HamerskiData Engineer | RPA/Web Scraping | Backend Python11 de janeiro de 20265 min

Ao processar mais de 1 milhão de registros de veículos para enriquecimento com a API FIPE (Fundação Instituto de Pesquisas Econômicas), nos deparamos com um problema clássico de integração de dados: matching semântico entre fontes heterogêneas.

O problema? Os dados de entrada vinham sujos:

  • "L-200 CD TRITON" vs "L200 Triton HPE 3.2 CD TB Int.Diesel Aut"
  • "MERCEDES-BENZ C180" vs "C 180 CGI TURBO 16V"
  • "CG 150" vs "CG 150 Titan KS"

Matching exato? Falha de 78%. Fuzzy tradicional? 42% de falsos positivos.

Nossa solução? Três técnicas avançadas que elevaram a precisão para 94.7%.


Técnica #1: Hybrid Fuzzy Matching com Múltiplas Métricas

O Problema do Fuzzy Tradicional

Algoritmos de fuzzy matching tradicionais (Levenshtein, Jaro-Winkler) falham quando:

  • Textos têm tamanhos muito diferentes ("L-200" tem 5 caracteres, o match na API tem 45)
  • Palavras estão em ordem diferente ("TRITON CD L-200" vs "L200 CD TRITON")
  • Existem palavras extras irrelevantes ("HPE 3.2 TB Int.Diesel Aut")

Nossa Solução: Score Híbrido com 3 Métricas RapidFuzz

Implementamos uma função que combina três métricas diferentes e retorna o melhor score:

Por que funciona?

1. token_set_ratio: Compara apenas palavras em comum, ignorando o resto

  • "L-200 CD TRITON" vs "L200 Triton HPE 3.2 CD TB Int" → 85%
  • Fuzzy simples daria: ~28%

2. partial_ratio: Encontra melhor substring match

  • Ideal quando modelo curto está contido no longo
  • "CG 150" vs "CG 150 Titan KS" → 100%

3. token_sort_ratio: Ignora ordem das palavras

  • "TRITON CD L-200" vs "L200 CD TRITON" → ~95%

Resultado: De 42% para 87% de precisão no matching inicial.


Técnica #2: Busca Alternativa Multinível com Cache Persistente

O Problema da Busca Linear

Quando o ano do veículo não existe no modelo exato, é necessário buscar em variantes:

  • Honda Civic 2020 pode estar em "Civic LX", "Civic Sport", "Civic EX", etc.
  • Busca ingênua: Consulta API para cada variante = 150+ requisições HTTP por veículo
  • Timeout em 67% dos casos (API limita rate)

Nossa Solução: Busca Multinível com Cache PostgreSQL

Fase 1: Busca em Variantes Exatas (O(1) com Cache)

Cache persistente em PostgreSQL com estrutura JSON indexada por marca + modelo.

Ganho: Redução de 150 chamadas HTTP → 8 chamadas por veículo (economia de 94%)

Fase 2: Busca com Fuzzy Ranking (Sem Limites)

Se Fase 1 falha, ativa busca fuzzy em TODOS os modelos similares (não apenas top-N).

Ordenamos TODOS os modelos por similaridade fuzzy e buscamos até encontrar o ano correto.

Resultado: Cobertura de 99.2% (vs 82% com busca limitada a top-10)


Técnica #3: Processamento Assíncrono com Playwright + Retry Exponencial

O Problema de APIs Instáveis

APIs externas falham. A API AnyCar tinha:

  • 18% de timeouts aleatórios
  • 12% de respostas 500 em horários de pico
  • Rate limiting agressivo (429 Too Many Requests)

Nossa Solução: Retry Inteligente + Paralelismo Controlado

Retry com Backoff Exponencial

  • Tentativas automáticas com espera progressiva: 2s, 4s, 8s...
  • Backoff aleatório para evitar detecção de padrões
  • Separação de retry para POST (envio de placa) e GET (consulta resultado)

Paralelismo Controlado com Semaphore

Processamos 200 workers simultâneos ao invés de 5 sequenciais.

Ganhos Medidos:

  • Taxa de sucesso: 82% → 97.3% (retry eliminou 86% dos erros temporários)
  • Throughput: 120 placas/min → 1840 placas/min (paralelismo de 200 workers)
  • Tempo médio por placa: 12.5s → 0.7s (redução de 94.4%)

Resultados em Produção

MétricaAntesDepoisGanho
Precisão de Matching58%94.7%+63%
Cobertura (ano encontrado)82%99.2%+21%
Throughput (placas/min)1201840+1433%
Taxa de Sucesso API82%97.3%+19%
Chamadas HTTP/veículo1508-95%
Custo de Infraestrutura$2.4k/mês$0.6k/mês-75%

Total processado: 1.2M+ veículos em produção (rodando 24/7 desde Jan/2025)


Stack Técnica

  • Matching: RapidFuzz (Rust-based, 10x mais rápido que Python puro)
  • Cache: PostgreSQL com JSONB indexado + GIN index
  • Async: Python AsyncIO + Playwright (Chromium headless)
  • Orquestração: Prefect 3.x (flows agendados via Cron)
  • Observabilidade: Logs estruturados + métricas custom (Prefect Artifacts)

Conclusão: Quando Combinar Técnicas é Melhor que Otimizar Uma

Cada técnica isolada trouxe ganhos incrementais:

  • Hybrid Fuzzy: +29% precisão
  • Cache Multinível: +17% cobertura
  • Retry + Paralelismo: +15% taxa de sucesso

Mas a combinação das três gerou efeitos não-lineares (sinergia):

  • Menos falhas na API → menos reprocessamentos → cache mais efetivo
  • Cache mais efetivo → respostas mais rápidas → maior paralelismo viável
  • Maior paralelismo → throughput 15x maior → processamento em 1/15 do tempo

A lição? Em sistemas distribuídos com dados heterogêneos, arquitetura > algoritmo.

Não basta ter o melhor fuzzy matching se sua API falha 18% das vezes. Não adianta ter cache se seu matching tem 42% de precisão.

Otimize o sistema, não apenas o código.

Assuntos
FuzzyMatchingRapidFuzzPostgreSQLAsyncIOPlaywrightCacheAPIIntegrationDataEnrichment
Tem um caso parecido?

A gente coleta o dado na fonte e entrega dentro do seu sistema

Fale direto com quem constrói o robô. A conversa começa pela fonte, pelo volume e pelo destino do dado, não por proposta.