Partilhar
Engenharia

Construir Arquitetura SaaS Escalável: Lições de Plataformas IA Multi-Modelo

Construir Arquitetura SaaS Escalável: Lições de Plataformas IA Multi-Modelo

Como 14 Minutos de Downtime Podem Custar €47.000 em Reembolsos

Imagine este cenário: a base de dados primária de uma plataforma SaaS atinge 100% de utilização de CPU. Em 14 minutos, toda a plataforma fica sem resposta. Durante essa janela, 2.847 utilizadores perdem acesso a meio do workflow. Pedidos de modelos IA ficam em fila e expiram. Transações de créditos falham silenciosamente.

A causa raiz? Um único cliente a executar uma exportação em massa de 340.000 registos através de um endpoint de API que não estava propriamente limitado. Um tenant a derrubar toda a plataforma.

Este tipo de incidente força um repensar arquitetural completo. Os padrões abaixo mostram como plataformas evoluem para servir 3x o tráfego com 99,97% de uptime após aprender estas lições difíceis.

A Árvore de Decisão de Multi-Tenancy

Antes de escrever uma única linha de código, tens de decidir como os tenants partilham (ou não) recursos. Esta decisão afeta tudo a jusante.

Tudo Partilhado (Multi-Tenancy a Nível de Base de Dados)

Todos os tenants partilham a mesma base de dados, distinguidos por uma coluna tenant_id em cada tabela.

Vantagens:

  • Custo de infraestrutura mais baixo por tenant

  • Modelo de deployment mais simples

  • Analytics cross-tenant fácil

Desvantagens:

  • Problema de vizinho barulhento (um tenant afeta todos os outros)

  • Isolamento de dados complexo (cada query deve filtrar por tenant)

  • Desafios regulatórios (algumas indústrias requerem separação física)

Quando usar: SaaS em fase inicial com restrições de orçamento, base de clientes homogénea, sem requisitos de compliance estritos.

Erro comum: Muitas plataformas começam aqui. Quando clientes Enterprise pedem recursos dedicados, não conseguem oferecer sem uma migração major.

Infraestrutura Partilhada, Bases de Dados Isoladas

Cada tenant obtém a sua própria base de dados mas partilha servidores de aplicação e infraestrutura.

Vantagens:

  • Forte isolamento de dados

  • Backup e restore por tenant

  • História de compliance mais fácil

Desvantagens:

  • Gestão de pool de conexões torna-se complexa

  • Migrações de schema devem correr em todas as bases de dados

  • Maior overhead operacional

Quando usar: Indústrias reguladas, clientes com requisitos de residência de dados, B2B SaaS com requisitos contratuais de isolamento.

Totalmente Isolado (Deployments Single-Tenant)

Cada tenant obtém infraestrutura dedicada—as suas próprias instâncias de aplicação, bases de dados, e frequentemente o seu próprio namespace Kubernetes ou conta cloud.

Vantagens:

  • Isolamento completo (performance, segurança, compliance)

  • Customização por tenant possível

  • Fronteiras de segurança limpas

Desvantagens:

  • Custo mais alto por tenant

  • Complexidade de deployment escala linearmente com clientes

  • Upgrades tornam-se um pesadelo de coordenação

Quando usar: Clientes enterprise a pagar €10k+/mês, contratos governamentais, indústrias altamente reguladas.

A Nossa Abordagem Híbrida

Após o incidente de Março, implementámos isolamento por tiers:

Tier Standard: Base de dados partilhada com segurança a nível de linha. Dados de tenant filtrados na camada de aplicação e enforced na camada de base de dados usando políticas PostgreSQL RLS.

Tier Professional: Base de dados isolada por tenant, infraestrutura de aplicação partilhada. Connection pooling via PgBouncer com pools por tenant.

Tier Enterprise: Namespace Kubernetes dedicado com compute, storage e networking isolados. Efetivamente single-tenant dentro de infraestrutura partilhada.

Este modelo híbrido aumentou os nossos custos de infraestrutura em 40% mas eliminou totalmente o impacto de performance cross-tenant.

Desenhar para 100+ Modelos IA

O desafio único de plataformas IA multi-modelo: encaminhar pedidos para 100+ fornecedores de modelos IA, cada um com diferentes rate limits, preços, características de latência e modos de falha.

O Padrão Gateway

Cada pedido IA flui através de um gateway unificado que trata:

                    ┌─────────────────┐
│ API Gateway │
│ (Rate Limits) │
└────────┬────────┘

┌────────▼────────┐
│ Router Service │
│ (Model Selection)│
└────────┬────────┘

┌───────────────────┼───────────────────┐
│ │ │
┌────────▼─────┐ ┌────────▼─────┐ ┌────────▼─────┐
│ OpenAI │ │ Anthropic │ │ Google │
│ Adapter │ │ Adapter │ │ Adapter │
└──────────────┘ └──────────────┘ └──────────────┘

Lógica do Router Service:

  • Verificar tier e saldo de créditos do utilizador

  • Determinar modelo ótimo baseado no tipo de pedido e preferência do utilizador

  • Verificar health scores dos fornecedores (mantidos por monitores em background)

  • Aplicar regras de fallback se fornecedor primário estiver degradado

  • Encaminhar para adapter apropriado

Responsabilidades do Adapter:

  • Traduzir o nosso formato de API unificado para formato específico do fornecedor

  • Tratar autenticação e rotação de credenciais

  • Implementar padrões circuit breaker

  • Recolher métricas de latência e erros

Arquitetura do Sistema de Créditos

Os créditos são a moeda universal em todas as operações IA. O sistema de créditos deve ser:

  • Preciso: Os utilizadores confiam no seu saldo

  • Rápido: Não pode adicionar latência a cada pedido

  • Consistente: Sem gastos duplos, sem créditos perdidos

A nossa implementação usa um padrão event-sourced:

-- Eventos de crédito são append-only
CREATE TABLE credit_events (
id UUID PRIMARY KEY,
tenant_id UUID NOT NULL,
event_type VARCHAR(50), -- 'purchase', 'usage', 'refund', 'adjustment'
amount DECIMAL(10, 4),
model_id VARCHAR(100),
request_id UUID,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Saldo materializado para leituras rápidas
CREATE MATERIALIZED VIEW credit_balances AS
SELECT
tenant_id,
SUM(CASE WHEN event_type IN ('purchase', 'refund') THEN amount ELSE -amount END) as balance
FROM credit_events
GROUP BY tenant_id;

Para verificações de saldo em tempo real, mantemos uma cache em memória (Redis) que é atualizada assincronamente após cada transação. A view materializada serve como fonte autoritativa, refrescada a cada 5 minutos e on-demand para saldos disputados.

Lidar com Outages de Fornecedores

Fornecedores de IA caem. A OpenAI teve 7 outages significativos em 2024. A tua arquitetura deve lidar com isto graciosamente.

A nossa abordagem: Fallback automático com consentimento do utilizador

Os utilizadores configuram preferências de fallback:

  • Permitir fallback automático para modelos equivalentes (ex: GPT-4 → Claude 3.5 Sonnet)

  • Permitir fallback automático para modelos de tier inferior (ex: GPT-4 → GPT-4o-mini)

  • Sem fallback (falhar o pedido)

Quando o modelo primário não está disponível:

  • Circuit breaker abre após 3 falhas consecutivas

  • Sistema verifica preferências de fallback do utilizador

  • Encaminha para modelo de fallback se permitido

  • Regista modelo original e de fallback para transparência de faturação

Ajuste de créditos: Se o modelo de fallback custa menos, creditamos a diferença. Se custa mais, absorvemos a diferença. Isto constrói confiança.

Padrões de Escalabilidade Que Realmente Funcionaram

Padrão 1: Colocar em Fila Tudo Que Pode Esperar

Nem todos os pedidos precisam de processamento síncrono. Identificámos três categorias:

Síncrono (< 30s esperado):

  • Chat completions

  • Gerações simples

  • Análise em tempo real

Async-by-default (30s - 5min):

  • Geração de imagem

  • Processamento de documentos longos

  • Traduções em lote

Background (> 5min):

  • Jobs de fine-tuning

  • Exportações em massa

  • Geração de relatórios

Mover workloads async para filas (usamos Amazon SQS com worker pods) reduziu a carga do nosso servidor API em 60% e melhorou a latência P95 para pedidos síncronos de 4,2s para 890ms.

Padrão 2: Read Replicas para Analytics

Dashboards de utilizador mostrando histórico de uso, consumo de créditos e performance de modelos estavam a martelar a nossa base de dados primária.

Solução: Read replica dedicada para todas as queries de analytics. O lag de replicação de 2 segundos é invisível para dashboards históricos.

Detalhe de implementação: Encaminhamos queries baseadas no endpoint. /api/analytics/* vai para a read replica; tudo o resto vai para a primária.

Padrão 3: Edge Caching para Respostas IA Estáticas

Algumas queries IA são surpreendentemente cacheáveis:

  • Embeddings para o mesmo texto

  • Classificações para inputs idênticos

  • Traduções de frases idênticas

Implementámos uma cache semântica no edge (Cloudflare Workers KV):

  • Hash do input + modelo + parâmetros relevantes

  • Verificar cache antes de encaminhar para fornecedor

  • Taxa de cache hit: 23% em todos os pedidos

  • Poupámos aproximadamente €8.000/mês em custos de API

Estratégia de cache key:

const cacheKey = crypto.createHash('sha256')
.update(JSON.stringify({
model: request.model,
input: request.input,
temperature: request.temperature, // Apenas se determinístico (0)
// Excluir parâmetros que causam variação
}))
.digest('hex');

Monitorização e Observabilidade

Não consegues escalar o que não consegues ver. A nossa stack de observabilidade:

Métricas (Prometheus + Grafana):

  • Taxa de pedidos por modelo, tenant e endpoint

  • Percentis de latência (P50, P95, P99)

  • Velocidade de consumo de créditos

  • Health scores de fornecedores

Tracing (Jaeger):

  • Traces de pedidos end-to-end

  • Mapeamento de dependências cross-service

  • Identificação de queries lentas

Alerting (PagerDuty):

  • Taxa de erros excede 1% durante 5 minutos

  • Latência P99 excede 10 segundos

  • Falhas de escrita no sistema de créditos

  • Circuit breaker de fornecedor abre

O incidente de Março teria sido apanhado 6 minutos mais cedo com a nossa monitorização atual. Isso são €20.000 poupados.

Lições Aprendidas

1. Desenha para o cliente 10x desde o primeiro dia. O cliente que nos derrubou não era malicioso—era bem-sucedido. Constrói rate limits, quotas de recursos e isolamento desde o início.

2. O modo de multi-tenancy deve ser atualizável. Os clientes crescem. O que começa como tenant de base de dados partilhada pode tornar-se cliente enterprise a precisar de isolamento. Planeia caminhos de migração.

3. Async por defeito, sync quando necessário. A maioria dos workloads IA não precisa de respostas em tempo real. Coloca-os em fila. A tua arquitetura vai agradecer.

4. Diversidade de fornecedores é uma feature, não um fardo. Quando a OpenAI cai, ter Anthropic e Google como fallbacks não é apenas fiabilidade—é vantagem competitiva.

5. Sistemas de créditos são sistemas financeiros. Trata-os com o rigor de um processador de pagamentos. Audit trails, reconciliação e deteção de anomalias são inegociáveis.

Construir uma plataforma que serve 100+ modelos IA em escala é fundamentalmente um problema de sistemas distribuídos com restrições específicas de IA. Os modelos são a parte fácil. A infraestrutura que os torna acessíveis, fiáveis e economicamente viáveis—é aí que a engenharia real acontece.

Ricardo Mendes

Sobre o Autor

Ricardo Mendes

Cofundador da AIOBI. Engenheiro Informático com experiência em análise de dados, software e gestão financeira.