Escalabilidade¶
O padrão atual funciona para clínicas pequenas a médias (até ~10 médicos, ~100 procedimentos). Além disso, rachaduras aparecem.
Limites observáveis¶
| Dimensão | Limite confortável | Quebra acima de |
|---|---|---|
| Médicos por clínica | 5-10 | ~12 (ambiguidade de nome) |
| Procedimentos por clínica | ~150 | ~300 (prompt gigante) |
| Convênios | ~20 | — |
| Mensagens/minuto por instância | ~30 | ~100 (fila Postgres) |
| Clínicas por servidor | ~5 | ~10 (memória Postgres + LLM concorrente) |
| Tamanho do system prompt | ~50k tokens | ~100k (custo estoura) |
Ponto #1 — resolução de médico¶
Coberto em primeiro nome do doutor. É o primeiro gargalo. Qualquer clínica com 12+ médicos vai encontrar duplicação de nome.
Mitigação: adotar slug / menu numerado antes de passar dos 10 médicos.
Ponto #2 — tamanho do system prompt¶
No Medcenter, o prompt tem ~660 linhas, ~30k tokens. Com 12 médicos e 200 procedimentos, estima-se ~60k tokens. Custos:
| Tokens input × turnos | Custo com gpt-4.1 (~$2.50/1M) |
|---|---|
| 30k × 10 turnos | $0.75 |
| 60k × 10 turnos | $1.50 |
| 100k × 10 turnos | $2.50 |
Mil sessões/mês com prompt de 100k = $2500/mês só em input. Não sustentável.
Mitigação:
- Mover preços, horários, telefones para tools.
- Paginar lista de procedimentos — o LLM pergunta "qual especialidade?" primeiro e a tool devolve só os procedimentos daquela área.
- Usar context caching da OpenAI (prompt fixo é cacheado; só o histórico de chat conta como novo).
Ponto #3 — fila Postgres como mensageria¶
n8n_fila_mensagens_* serve até ~100 INSERTs/segundo confortavelmente. Se
virar 500/s (ex: clínica com 50 atendentes paralelos), o índice telefone
começa a ter contenção.
Mitigação: migrar para Redis (LPUSH/BRPOP) — latência baixa e
compatível com debounce por padrão.
Ponto #4 — conexão única do PostgresSaver¶
Uma conexão por processo. Em caso de LLM concorrente alto (~20 sessões simultâneas rodando invoke), pode ter contenção em escrita de checkpoint.
Mitigação: psycopg_pool.ConnectionPool(min_size=5, max_size=20) +
PostgresSaver via pool.
Ponto #5 — 1 container = 1 clínica¶
Estratégia atual: cada clínica tem seu docker compose up separado. Na
prática, até ~5 clínicas em uma VM de 4 vCPU / 8 GB.
Mitigação para >10 clínicas:
- VM por cliente (isolamento máximo, preço alto).
- K8s namespace por clínica (médio — mais complexo mas compartilha infra).
- Multi-tenant em 1 container (mais barato, mas requer refatorar config por request e isolar checkpointer por clínica. Não recomendado hoje).
Ponto #6 — PostgresSaver ilimitado¶
Chat history nunca expira. Uma sessão de 3 meses acumula milhares de mensagens. O próximo invoke carrega tudo.
Mitigação: implementar truncamento via CONTEXT_WINDOW_LENGTH (variável
existente mas não usada nos projetos atuais). Quando histórico > N
mensagens, resumir as mais antigas e injetar o resumo.
Ponto #7 — OpenAI rate limits¶
gpt-4.1 tier 1 = 500 req/min. Se a clínica tem 20 atendentes paralelos e
cada sessão gera 5 invokes/min, pico de 100 req/min — ok. Duas clínicas
assim: 200 req/min. Cinco: chega perto do limite.
Mitigação:
- Subir tier na OpenAI (requer histórico de consumo).
- Implementar retry com backoff em caso de 429.
Roteiro recomendado conforme cresce¶
- Até 3 clínicas / 10 médicos cada: padrão atual é suficiente.
- 3-10 clínicas: externalizar config (YAML/DB), adotar pool Postgres,
implementar
CONTEXT_WINDOW_LENGTH. - 10+ clínicas: multi-tenant (um container, vários
thread_idprefixados com clínica), K8s para orquestração, fila Redis. - Grande volume (>1000 sessões/dia por clínica): LLM router (perguntas triviais → modelo mais barato, só complexas → gpt-4.1).
Custos — ordem de grandeza¶
| Cenário (mensal) | Custo aproximado |
|---|---|
| 1 clínica, 500 sessões/mês, 5 turnos, 30k prompt | ~$50 |
| 1 clínica, 2000 sessões/mês, idem | ~$200 |
| 5 clínicas × 2000 sessões/mês | ~$1000 |
Mídia (Gemini + Whisper) adiciona 10-20% a isso, dependendo do perfil.