Arquitetura Geral — iFriend Agents (GCP)
Documento de referência para estimativa de custos na GCP Calculator.
Última atualização: fevereiro/2026
1. Visão Macro dos Componentes
graph TB
subgraph INTERNET["Internet / Clientes"]
BROWSER["Navegador / WebChat\n(EventSource / SSE)"]
SLACK_C["Slack"]
TG_C["Telegram"]
WA_C["WhatsApp"]
end
subgraph GCP["Google Cloud Platform — projeto: ifriend-platform / região: us-central1"]
subgraph CICD["CI/CD"]
CB["Cloud Build\n(cloudbuild.yaml)\nBuild + Push + Deploy"]
AR["Container Registry\ngcr.io/ifriend-platform/\nifriend-agent-unified"]
end
subgraph RUNTIME["Runtime"]
CR["Cloud Run\nifriend-agent-unified\n─────────────────\nCPU: 4 vCPU\nMemória: 8 GiB\nTimeout: 90s\nMáx instâncias: 10\nConcurrency: default"]
end
subgraph DATA["Dados"]
CSQL["Cloud SQL\nMySQL 5.7\ninstância: ifriend-databases-production\ndb: ifriend_agent_v2\n─────────────────\nSession: tabela sessions\nMemory: tabela memories"]
REDIS["Redis (GKE / Memorystore)\n10.128.0.18:6379\n─────────────────\nSession TTL: 3600s\nMemory TTL: 7 dias\nJWT Lookup cache"]
end
subgraph SECRETS["Segredos"]
SM["Secret Manager\nJWT_SECRET_KEY\nJWT_PUBLIC_KEY\nJWT_PASSPHRASE"]
end
subgraph OBS["Observabilidade"]
CL["Cloud Logging\n(CLOUD_LOGGING_ONLY)"]
end
subgraph AI["IA"]
VERTEX["Vertex AI\nGemini 2.5 Flash\n(GOOGLE_GENAI_USE_VERTEXAI=1)\nTemperature: 0.7\nMax tokens: 2048"]
end
end
subgraph EXTERNAL["Serviços Externos"]
API_MAIN["API iFriend\napi.theifriend.com"]
API_TIQETS["Tiqets API\nproviders.theifriend.com"]
SENDGRID["SendGrid\n(e-mail)"]
MAILERSEND["MailerSend SMTP\n(e-mail)"]
GMAIL["Gmail API\nOAuth 2.0"]
end
%% Clientes → Cloud Run
BROWSER -->|"HTTPS / SSE\n(text/event-stream)"| CR
SLACK_C -->|"Webhook HTTPS"| CR
TG_C -->|"Webhook HTTPS"| CR
WA_C -->|"Webhook HTTPS"| CR
%% CI/CD
CB --> AR
AR -->|"gcr.io image"| CR
%% Cloud Run → Dados
CR -->|"Unix Socket\n/cloudsql/..."| CSQL
CR -->|"TCP 6379\nVPC privado"| REDIS
%% Cloud Run → GCP
CR --> SM
CR --> CL
CR -->|"Vertex AI API"| VERTEX
%% Cloud Run → Externos
CR --> API_MAIN
CR --> API_TIQETS
CR --> SENDGRID
CR --> MAILERSEND
CR --> GMAIL
2. iFriend Agent — Google ADK (root_agent)
flowchart TD
subgraph CALLBACKS["Callbacks do Agente"]
direction LR
CB_BEFORE["before_agent_callback\n─────────────────\n1. inject_jwt_before_agent\n (lê JWT do session.state,\n injeta no ToolContext)\n2. load_memories_callback\n (busca até 10 memórias\n no MemoryService;\n injeta em state['loaded_memories'])"]
CB_AFTER["after_agent_callback\n─────────────────\nsave_session_to_memory_callback\n(salva sessão completa\nno MemoryService\napós cada resposta)"]
end
subgraph ROOT["root_agent — LlmAgent (Gemini 2.5 Flash)"]
direction TB
LLM["🤖 Gemini 2.5 Flash\ntemperature: 0.7 · top_p: 0.95\nmax_output_tokens: 2048\nsystem_prompt: IFRIEND_CORE_AGENT_INSTRUCTION"]
subgraph DISCOVERY["Descoberta e Catálogo"]
T01["busca_produtos\n(busca por experiências\nno catálogo iFriend)"]
T02["tem_variacao\n(verifica se experience\ntem variações)"]
T03["listar_variacoes\n(lista variações\nde uma experience)"]
T04["listar_guias_experience\n(lista guias de\numa experience)"]
T05["detalhes_experience\n(detalhes completos\nda experience)"]
T06["detalhes_guia\n(detalhes do guia)"]
end
subgraph PRICING["Disponibilidade e Preços"]
T07["disponibilidade_calendario\n(datas disponíveis)"]
T08["disponibilidade_horarios\n(horários disponíveis\nem uma data)"]
T09["calcular_preco\n(calcula valor total\ncom opcionais)"]
T10["cotacao_moeda\n(cotação cambial\nBRL/USD/EUR etc)"]
end
subgraph BOOKING["Reservas"]
T11["buscar_usuario\n(busca usuário\npor e-mail/CPF)"]
T12["buscar_agencia\n(busca agência\npor ID/slug)"]
T13["criar_conta_agencia\n(cria conta de agência)"]
T14["criar_conta_viajante\n(cria conta de viajante)"]
T15["validar_dados_reserva\n(valida dados antes\nde emitir)"]
T16["emitir_reserva_guia\n(emite reserva\ncom guia)"]
T17["emitir_reserva_experience\n(emite reserva\nde experience)"]
T18["obter_reserva\n(consulta reserva\nexistente)"]
end
subgraph PAYMENT["Pagamento"]
T19["verificar_parcelas\n(opções de parcelamento)"]
T20["gerar_token_cartao\n(tokeniza cartão\nde crédito)"]
T21["processar_pagamento\n(processa pagamento\nvia cartão)"]
end
subgraph UTILS["Utilitários"]
T22["gerar_csv\n(gera CSV com\ndados de reservas)"]
T23["enviar_email_sendgrid\n(envia e-mail\nvia SendGrid)"]
T24["faq_tool\n(AgentTool → faq_agent\nrespostas de FAQ)"]
end
subgraph SEARCH["Busca Web"]
SA["search_agent — LlmAgent\n(AgentTool)\n─────────────────\ngoogle_search\n(Google Search API)"]
end
end
subgraph EXTERNAL_API["API iFriend (api.theifriend.com)"]
API1["GET /experiences\n(busca_produtos)"]
API2["GET /experiences/{id}\n(detalhes, variações,\nguias, disponibilidade)"]
API3["POST /reservas\n(emitir_reserva_*)"]
API4["POST /pagamentos\n(processar_pagamento)"]
API5["GET /usuarios · /agencias\n(buscar_usuario · buscar_agencia)"]
end
subgraph SESSION_MEM["Session + Memory"]
SS["SessionService\n(Redis ou CloudSQL)\nhistórico da conversa"]
MS["MemoryService\n(CloudSQL)\nconhecimento cross-session"]
end
%% Callbacks
CB_BEFORE --> LLM
LLM --> CB_AFTER
%% LLM decide qual tool usar
LLM --> T01 & T02 & T03 & T04 & T05 & T06
LLM --> T07 & T08 & T09 & T10
LLM --> T11 & T12 & T13 & T14 & T15 & T16 & T17 & T18
LLM --> T19 & T20 & T21
LLM --> T22 & T23 & T24
LLM --> SA
%% Tools → API
T01 & T02 & T03 & T04 & T05 & T06 --> API2
T01 --> API1
T07 & T08 & T09 --> API2
T16 & T17 --> API3
T19 & T20 & T21 --> API4
T11 & T12 & T13 & T14 & T15 & T18 --> API5
%% Session e Memory
CB_BEFORE -.->|"load"| MS
CB_AFTER -.->|"save"| MS
LLM -.->|"eventos da sessão"| SS
classDef toolNode fill:#2d5a8e,stroke:#1a3a5e,color:#fff,rx:4
classDef agentNode fill:#3a7d44,stroke:#1e5228,color:#fff
classDef callbackNode fill:#7d5a3a,stroke:#5e3a1e,color:#fff
classDef apiNode fill:#555,stroke:#333,color:#fff
class T01,T02,T03,T04,T05,T06,T07,T08,T09,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24 toolNode
class SA,T24 agentNode
class CB_BEFORE,CB_AFTER callbackNode
class API1,API2,API3,API4,API5 apiNode
| Grupo |
Tools |
Propósito |
| Descoberta |
busca_produtos, tem_variacao, listar_variacoes, listar_guias_experience, detalhes_experience, detalhes_guia |
Explorar o catálogo de experiências e guias |
| Disponibilidade e Preços |
disponibilidade_calendario, disponibilidade_horarios, calcular_preco, cotacao_moeda |
Verificar datas, horários e valores |
| Reservas |
buscar_usuario, buscar_agencia, criar_conta_*, validar_dados_reserva, emitir_reserva_*, obter_reserva |
Fluxo completo de criação de reservas |
| Pagamento |
verificar_parcelas, gerar_token_cartao, processar_pagamento |
Tokenização e processamento de cartão |
| Utilitários |
gerar_csv, enviar_email_sendgrid, faq_tool |
Exportação, e-mail e FAQ |
| Busca Web |
search_agent (AgentTool → google_search) |
Informações externas e turismo em geral |
3. Camada de Messaging (detalhe)
graph LR
subgraph ENDPOINTS["FastAPI Endpoints"]
E1["POST /sse/chat\n→ inicia stream"]
E2["GET /sse/stream/{id}\n→ EventSource"]
E3["POST /webhook/{platform}\n→ Slack · WA · Telegram"]
E4["POST /webchat/message\n→ resposta síncrona"]
end
subgraph ADAPTERS["AdapterFactory — register_from_env()"]
SSE["SSEAdapter\n(SSE_ENABLED=true)"]
SLKA["SlackAdapter"]
TGA["TelegramAdapter"]
WCA["WebChatAdapter"]
WAA["WhatsAppAdapter"]
end
subgraph SSE_INTERNAL["SSE — StreamManager"]
SM2["Stream\n(stream_id, user_id,\nsession_id, status)"]
Q["asyncio.Queue\n(eventos por stream)"]
EVTS["Eventos emitidos:\n• stream_start\n• text_chunk\n• tool_call\n• tool_result\n• stream_end\n• keepalive (30s)"]
TTL["TTL: 300s\nCleanup automático"]
end
PROC["ConversationProcessor\n(Slack · WA · Telegram)\n+ JWTContextManager"]
RUNNER["Google ADK Runner\nrunner.run_async()"]
E1 --> SSE --> SM2
E2 --> Q
SM2 --> Q --> EVTS
SSE -->|"streaming direto"| RUNNER
E3 --> SLKA & TGA & WAA --> PROC --> RUNNER
E4 --> WCA --> RUNNER
4. Session Layer
| Backend |
Env SESSION_BACKEND |
Tecnologia GCP |
Observações |
| ✅ Cloud SQL (ADK native) (em uso) |
cloudsql |
Cloud SQL MySQL 5.7 |
DatabaseSessionService ADK. Unix socket via Cloud SQL Proxy. TTL: 120min |
| Redis |
redis |
Redis em GKE / Memorystore |
TTL: 3600s. Reconexão automática |
| Firestore |
firestore |
Cloud Firestore |
Coleção adk_sessions |
| InMemory |
inmemory |
— |
Apenas dev/testes |
5. Memory Layer
| Backend |
Env MEMORY_BACKEND |
Tecnologia GCP |
Observações |
| ✅ Cloud SQL (em uso) |
cloudsql |
Cloud SQL MySQL 5.7 |
Memória cross-session (longo prazo). Unix socket |
| OpenMemory |
openmemory |
PostgreSQL + pgvector (self-hosted) |
Busca vetorial. Não recomendado para produção neste stack |
| Redis |
redis |
Redis em GKE / Memorystore |
TTL: 7 dias |
| InMemory |
inmemory |
— |
Retorna None — agente funciona sem persistir |
6. Infraestrutura GCP — Recursos para Calculadora de Custos
5.1 Cloud Run
| Parâmetro |
Valor atual |
| Serviço |
ifriend-agent-unified |
| Região |
us-central1 |
| CPU |
4 vCPU |
| Memória |
8 GiB |
| Timeout de requisição |
90 s |
| Máximo de instâncias |
10 |
| Mínimo de instâncias |
0 (cold start) |
| VPC Egress |
private-ranges-only |
| Cloud SQL Connection |
via --set-cloudsql-instances (Unix socket) |
| Plataforma |
managed |
Para a calculadora: estimar número médio de requisições/mês, tempo médio de CPU ativa por requisição (inclui tempo do LLM ~5–20s para streaming), pico de instâncias simultâneas.
5.2 Cloud SQL (MySQL 5.7)
| Parâmetro |
Valor atual |
| Instância |
ifriend-platform:us-central1:ifriend-databases-production |
| Engine |
MySQL 5.7 |
| Database |
ifriend_agent_v2 |
| Tabelas |
sessions, memories |
| Conexão |
Unix socket via Cloud SQL Proxy (embutido no Cloud Run) |
Para a calculadora: tipo de máquina (db-n1-standard-X), storage em GB, backup habilitado, HA (se aplicável).
5.3 Redis
| Parâmetro |
Valor atual |
| Host |
10.128.0.18:6379 (VPC privado) |
| Configuração |
GKE self-managed ou Memorystore |
| DB index |
0 |
| Uso |
Session TTL 3600s · Memory TTL 7 dias · JWT Lookup cache |
Para a calculadora: se Memorystore → tier Basic ou Standard (HA), capacity tier (1GB / 5GB / etc).
5.4 Vertex AI
| Parâmetro |
Valor atual |
| Modelo |
gemini-2.5-flash |
| Uso |
GOOGLE_GENAI_USE_VERTEXAI=1 |
| Temperatura |
0.7 |
| Top-P |
0.95 |
| Top-K |
40 |
| Max output tokens |
2048 |
Para a calculadora: estimar tokens de entrada (system prompt + histórico de sessão + tools = ~8k–20k tokens/req) e tokens de saída (~500–2048 tokens/req). Multiplicar pelo número de requisições/mês.
5.5 Cloud Build
| Parâmetro |
Valor atual |
| Timeout |
900s |
| Logging |
CLOUD_LOGGING_ONLY |
| Steps |
Build Docker → Push → Deploy Cloud Run |
Para a calculadora: número de builds/mês × ~10–15 min/build. Tier gratuito: 120 min/dia.
5.6 Container Registry
| Parâmetro |
Valor atual |
| Imagem |
gcr.io/ifriend-platform/ifriend-agent-unified:latest |
| Storage |
~1–2 GB por imagem (Python 3.11-slim + deps) |
Para a calculadora: storage de imagens em GB × número de versões retidas.
5.7 Secret Manager
| Secret |
Uso |
api-jwt-secretkey |
Assinatura JWT (RS256) |
api-jwt-publickey |
Verificação JWT |
api-jwt-passphrase |
Passphrase da chave privada |
Para a calculadora: número de acessos/mês (cada instância Cloud Run acessa uma vez no startup). Custo por 10k acessos é baixo (~$0.03).
5.8 Cloud Logging
- Configurado como
CLOUD_LOGGING_ONLY no Cloud Build.
- Logs do Cloud Run enviados automaticamente.
Para a calculadora: volume de logs em GiB/mês (primeiros 50 GiB gratuitos).
5.9 VPC / Networking
- Cloud Run configurado com
--network=default --subnet=default --vpc-egress=private-ranges-only
- Redis acessado via IP interno da VPC (sem custo de saída)
- Cloud SQL via Unix socket (sem custo de rede)
- Egresso para internet (APIs externas, Vertex AI): estimar GB/mês
7. Checklist para GCP Pricing Calculator
- [ ] Cloud Run — requisições/mês + CPU-segundos + memória GB-segundos
- [ ] Vertex AI — tokens de entrada (input) + tokens de saída (output) × volume de req/mês
- [ ] Cloud SQL MySQL — tipo de máquina + storage (GB) + backup
- [ ] Redis / Memorystore — tier + capacity
- [ ] Cloud Build — minutos de build/mês
- [ ] Container Registry — storage de imagens (GB)
- [ ] Secret Manager — acessos/mês (versões × instâncias)
- [ ] Cloud Logging — GiB ingeridos/mês
- [ ] VPC Networking — egresso de saída para internet (GB/mês)
| Plataforma |
Env |
Endpoint |
Observação |
| SSE (WebChat) |
SSE_ENABLED=true |
POST /sse/chat + GET /sse/stream/{id} |
Streaming nativo. Keepalive 30s. TTL stream 300s |
| Slack |
SLACK_BOT_TOKEN |
POST /webhook/slack/events |
JWT Lookup via Redis |
| Telegram |
TELEGRAM_BOT_TOKEN |
POST /webhook/telegram/webhook |
Polling ou webhook |
| WhatsApp Evolution |
WHATSAPP_EVOLUTION_* |
POST /webhook/whatsapp/webhook |
JWT Lookup via Redis |