Skip to content

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_busca para 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 availability aos 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