O Problema: Ajudar Viajantes Exploratórios a Encontrar o Próximo Destino
Sabe quando você abre o Airbnb sem saber para onde ir? Você não está só navegando — está explorando. Esses usuários "exploratórios" se comportam de forma diferente: pesquisam de forma ampla ("França"), visitam o app com menos frequência e raramente reservam de imediato. Mas eles representam uma oportunidade enorme de engajamento e conversão.
O time de engenharia do Airbnb enfrentou um desafio único: como recomendar destinos para usuários que nem eles mesmos sabem para onde querem ir? A solução é um modelo sofisticado de recomendação que mistura comportamento de curto prazo (pesquisas recentes, visualizações) com preferências de longo prazo (reservas passadas, padrões sazonais).
Este post detalha a arquitetura, estratégia de treinamento e implantação real desse sistema. Se você está construindo motores de recomendação ou funcionalidades de personalização, os insights aqui são diretamente aplicáveis.
Para entender como construir agentes de conhecimento sem embeddings, confira nosso guia sobre uso de filesystem e bash.

Arquitetura do Modelo: Transformers para Intenção de Viagem
A ideia central é simples, mas poderosa: tratar cada ação do usuário como um token, inspirado em modelos de linguagem. Veja como funciona:
- Entradas: Sequências de ações do usuário (reservas, visualizações, pesquisas) + sinais contextuais (horário atual, sazonalidade)
- Embedding: Cada ação é representada pela soma dos embeddings de cidade, região e "dias até hoje"
- Transformer: Um encoder transformer padrão processa essas sequências para capturar dependências de curto e longo prazo
# Pseudocódigo simplificado do forward pass do modelo
import torch
import torch.nn as nn
class DestinationTransformer(nn.Module):
def __init__(self, num_cities, num_regions, d_model=256, nhead=8):
super().__init__()
self.city_embed = nn.Embedding(num_cities, d_model)
self.region_embed = nn.Embedding(num_regions, d_model)
self.time_embed = nn.Linear(1, d_model) # dias até hoje
self.transformer = nn.TransformerEncoder(
nn.TransformerEncoderLayer(d_model, nhead),
num_layers=6
)
# Cabeças multi-tarefa: prever cidade e região
self.city_head = nn.Linear(d_model, num_cities)
self.region_head = nn.Linear(d_model, num_regions)
def forward(self, city_ids, region_ids, days_to_today):
# Embed cada ação
x = self.city_embed(city_ids) + self.region_embed(region_ids) + self.time_embed(days_to_today.unsqueeze(-1))
# Codificação transformer
x = self.transformer(x)
# Previsões multi-tarefa
city_logits = self.city_head(x[:, -1, :]) # usa o último token
region_logits = self.region_head(x[:, -1, :])
return city_logits, region_logits
Equilibrando Usuários Ativos e Inativos
Uma das decisões de design mais interessantes é como eles lidam com diferentes estados de usuário:
- Usuários ativos (ex.: alguém que pesquisou na Baía de São Francisco semana passada): Exemplos de treinamento usam dados atualizados de reservas, visualizações e pesquisas de 1 a 7 dias antes da reserva real.
- Usuários inativos (ex.: alguém que reservou ano passado e não voltou): Exemplos de treinamento usam apenas dados de reservas de 8 a 365 dias antes da reserva, simulando o estágio inicial de exploração.
Essa estratégia de treinamento duplo garante que o modelo funcione bem tanto para "sei para onde vou" quanto para "só estou olhando".

Melhorando o Entendimento Geográfico com Aprendizado Multi-Tarefa
Os dados de geolocalização do Airbnb são ricos: cidades como São Paulo e Campinas pertencem à mesma região (Estado de São Paulo). Para codificar isso, o modelo usa aprendizado multi-tarefa:
- Duas cabeças de predição: uma para nível de cidade, outra para nível de região
- Backbone transformer compartilhado: aprende representações úteis tanto para previsões granulares quanto grossas
- Restrição de consistência: incentiva o modelo a alinhar as previsões de cidade e região
Essa abordagem é elegante porque não requer engenharia manual de features — o modelo aprende a hierarquia a partir dos dados.
Aplicações no Mundo Real
O modelo alimenta duas funcionalidades:
- Autosuggest: Quando os usuários tocam na barra de pesquisa, veem recomendações personalizadas de cidades. Testes A/B mostraram ganhos significativos de reservas em regiões onde o inglês não é o idioma principal.
- E-mails de Pesquisa Abandonada: Se um usuário sai sem reservar, e-mails de acompanhamento destacam listagens de destinos previstos. Isso reengaja os usuários e gera conversões.
Para um estudo de caso real sobre escalabilidade de sistemas seguros, veja como o WhatsApp escalou Rust para bilhões de usuários.

Limitações e Cuidados
- Cold start: Usuários sem histórico recebem recomendações genéricas. O modelo depende muito de dados históricos.
- Privacidade: Usuários podem optar por sair da personalização, mas o padrão é ativo. Sempre respeite o consentimento do usuário.
- Viés sazonal: O modelo pode superajustar a padrões sazonais (ex.: sempre recomendar destinos de praia no verão).
- Interpretabilidade: Transformers são caixas-pretas. Depurar recomendações incorretas é difícil.
Próximos Passos para Aprendizado
- Explore redes neurais de grafos para codificar hierarquias de localização de forma mais explícita.
- Tente aprendizado por reforço para otimizar o engajamento de longo prazo, não apenas a reserva imediata.
- Experimente aprendizado contrastivo para separar melhor diferentes intenções de viagem (ex.: negócios vs. lazer).
Conclusão
O modelo de recomendação de destinos do Airbnb é uma aula magistral de como aplicar arquiteturas transformer a um problema real de personalização. As principais lições: trate ações do usuário como tokens, equilibre usuários ativos e inativos com design inteligente de dados de treinamento e use aprendizado multi-tarefa para codificar conhecimento de domínio. O resultado é um sistema que genuinamente ajuda os usuários a descobrir para onde ir — e gera impacto mensurável nos negócios.