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étrica | Antes | Depois | Ganho |
|---|---|---|---|
| Precisão de Matching | 58% | 94.7% | +63% |
| Cobertura (ano encontrado) | 82% | 99.2% | +21% |
| Throughput (placas/min) | 120 | 1840 | +1433% |
| Taxa de Sucesso API | 82% | 97.3% | +19% |
| Chamadas HTTP/veículo | 150 | 8 | -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.
