Sistema de Disponibilidade e Enriquecimento de Produtos¶
Visão Geral¶
O sistema foi estendido para incluir verificação de disponibilidade e cálculo de preços em tempo real para produtos do tipo experience, ticket e transfer quando uma data é detectada no contexto da busca.
Arquitetura¶
Pipeline de Agentes¶
input_agent
↓
bigquery_agent
↓
enriquecimento_agent ← NOVO
↓
csv_agent
↓
slack_formatter_agent
Agentes¶
1. input_agent¶
- Extrai informações estruturadas do input do usuário
- Detecta datas, locais, tipo de produto, número de pessoas
- Gera
metadados_buscapara consulta semântica
2. bigquery_agent¶
- Consulta BigQuery usando embeddings semânticos
- Retorna lista de produtos relevantes
3. enriquecimento_agent (NOVO)¶
- Recebe: lista de produtos + contexto original do usuário
- Detecta se há data mencionada no contexto
- Para produtos elegíveis (experience/ticket/transfer):
- Consulta calendário de disponibilidade do mês
- Verifica horários disponíveis na data alvo
- Calcula preço de exemplo para o primeiro horário
- Adiciona campo
availabilityaos produtos - Produtos não elegíveis passam sem modificação
4. csv_agent¶
- Gera CSV com os produtos
- Faz upload para Google Cloud Storage
5. slack_formatter_agent¶
- Formata resposta em Markdown para Slack
- Exibe informações de disponibilidade quando presentes
- Mostra horários disponíveis, preços por horário, datas alternativas
Tools de Disponibilidade¶
1. disponibilidade_calendario_tool¶
Endpoint: GET /experiences/{id}/availability/{monthYear}
disponibilidade_calendario_tool(
product_id: int,
month_year: str # "2025-11" formato YYYY-MM
) -> dict
Retorno:
{
"product_id": 2,
"month_year": "2025-11",
"available_dates": ["2025-11-15", "2025-11-21", "2025-11-28"],
"error": null
}
2. disponibilidade_horarios_tool¶
Endpoint: GET /experiences/{id}/availability/{day}/hours
disponibilidade_horarios_tool(
product_id: int,
day: str # "2025-11-21" formato YYYY-MM-DD
) -> dict
Retorno:
{
"product_id": 2,
"day": "2025-11-21",
"available_hours": ["10:00", "14:00", "16:00"],
"error": null
}
3. calcular_preco_tool¶
Endpoint: POST /bookings/price
calcular_preco_tool(
product_id: int,
day: str,
period: str, # "10:00"
num_adult: int = 1,
num_child: int = 0,
num_half_price: int = 0,
hours: int = 2,
is_ifriend_car: bool = True,
customer_id: Optional[int] = None
) -> dict
Retorno:
{
"product_id": 2,
"day": "2025-11-21",
"period": "10:00",
"price_data": {
"currencyCode": "USD",
"total": 176,
"total_per_adult": 176,
"total_without_tax": 176,
...
},
"error": null
}
Estrutura de Dados Enriquecidos¶
Produto SEM Disponibilidade¶
{
"product_id": 5,
"product_type": "guia",
"title": "Guia João",
"price": 50,
"currency_code": "BRL",
"display_url": "https://...",
"rating": 4.8,
"review_count": 45,
"relevance": 92
}
Produto COM Disponibilidade¶
{
"product_id": 2,
"product_type": "experience",
"title": "Tour no Coliseu",
"price": 100,
"currency_code": "EUR",
"display_url": "https://...",
"rating": 4.5,
"review_count": 120,
"relevance": 85,
"availability": {
"month_dates": ["2025-11-15", "2025-11-21", "2025-11-28"],
"target_date_available": true,
"available_hours": ["10:00", "14:00", "16:00"],
"sample_price": {
"total": 176,
"total_per_adult": 176,
"currencyCode": "USD",
"period": "10:00"
},
"error": null
}
}
Formato de Saída no Slack¶
Produto com Disponibilidade na Data Alvo¶
> *<https://....|Tour no Coliseu>*
> 💰 *Preço:* EUR 100,00
> ⭐ *Nota:* 4.5 (120 reviews)
> 📈 *Relevância:* 85.0%
> 📅 *Disponível na data:* Sim
> 🕒 *Horários:* 10:00, 14:00, 16:00
> 💰 *Preço para 10:00:* USD 176,00
Produto SEM Disponibilidade na Data Alvo¶
> *<https://....|Tour no Coliseu>*
> 💰 *Preço:* EUR 100,00
> ⭐ *Nota:* 4.5 (120 reviews)
> 📈 *Relevância:* 85.0%
> 📅 *Disponível na data:* Não
> 📆 *Próximas datas:* 15/11, 28/11, 30/11
Variáveis de Ambiente¶
Adicionar ao .env:
# iFriend API configuration
API_BASE_URL=https://api.theifriend.com
API_TIMEOUT=30
Para ambiente de desenvolvimento local:
API_BASE_URL=http://localhost:8080
Fluxo de Detecção de Data¶
O enriquecimento_agent detecta data usando análise de linguagem natural:
Exemplos de detecção:
- "passeios em Roma para o dia 21 de novembro" → 2025-11-21
- "experiências em Paris no dia 15/11" → 2025-11-15
- "tours em janeiro" → 2025-01-01 (primeiro dia do mês)
- "de 15 a 20 de dezembro" → 2025-12-15 (data inicial)
Se NÃO detectar data:
- Produtos retornam sem campo availability
- Pipeline continua normalmente
Error Handling¶
Todas as tools têm tratamento robusto de erros:
- Timeout: Configurável via
API_TIMEOUT(padrão: 30s) - HTTP Errors: 404, 400, 500 são capturados e reportados
- Network Errors: Erros de conexão são tratados
- JSON Decode Errors: Respostas malformadas são tratadas
Erros são adicionados ao campo error dentro de availability:
"availability": {
"month_dates": [],
"target_date_available": false,
"available_hours": null,
"sample_price": null,
"error": "Timeout ao consultar disponibilidade (>30s)"
}
Tipos de Produtos Elegíveis¶
Apenas produtos destes tipos recebem verificação de disponibilidade:
- experience
- ticket
- transfer
Outros tipos (guia, hotel, etc.) passam sem modificação.
Testes¶
Para testar o sistema:
# Terminal local
python -m busca_produtos.agent
Exemplos de input: 1. "Quero passeios em Roma para o dia 21 de novembro" 2. "Procuro experiências em Paris no mês de dezembro" 3. "Tours em Londres" (sem data - não consulta disponibilidade)
Deploy¶
O sistema está pronto para deploy no Cloud Run. As tools usam aiohttp que já está no requirements.txt.
./deploy.sh
Próximas Melhorias¶
- [ ] Cache de disponibilidade no Firestore
- [ ] Suporte a múltiplas datas no mesmo pedido
- [ ] Integração com sistema de reservas
- [ ] Analytics de disponibilidade consultada