01 — Visão Geral da Arquitetura
O que estamos construindo
Plataforma de agentes conversacionais WhatsApp multi-tenant. Cada agente é um produto independente que serve múltiplos clientes simultaneamente, com configuração isolada por cliente.
Diagrama de alto nível
┌──────────────────────────────────────────────────────────────────┐│ CAMADA DE ENTRADA ││ ││ Evolution API Stevo ││ (clientes Kommo) (clientes GHL) ││ │ │ ││ └──────┬───────────────┘ ││ ↓ ││ Webhook Triadeflow ││ (api.triadeflow.com.br/webhooks/{provider}/{tenant}) ││ ↓ ││ Fila BullMQ (Redis) │└──────────────────────────────────────────────────────────────────┘ ↓┌──────────────────────────────────────────────────────────────────┐│ CAMADA DE PROCESSAMENTO ││ ││ Worker Python (LangChain + LangGraph) ││ ├── Identifica tenant pela instance ││ ├── Carrega config.yaml do tenant ││ ├── Carrega histórico (Redis) ││ ├── Busca contexto (Qdrant via RAG) ││ ├── Executa LangGraph com Claude ││ ├── Chama tools necessárias ││ └── Envia resposta via provider │└──────────────────────────────────────────────────────────────────┘ ↓┌──────────────────────────────────────────────────────────────────┐│ CAMADA DE INTEGRAÇÃO ││ ││ CRM Tools Calendar Pagamento Helpdesk ││ Kommo / GHL Google Stripe/Asaas Asana ││ ││ Catálogo Sistemas LGPD Notificação ││ Qdrant Verticais Compliance Telegram │└──────────────────────────────────────────────────────────────────┘ ↓┌──────────────────────────────────────────────────────────────────┐│ CAMADA DE OBSERVABILIDADE ││ ││ Langfuse self-hosted (Hetzner) ││ ├── Traces (todo I/O do agente) ││ ├── Datasets (casos de eval) ││ ├── Annotations (revisão humana) ││ ├── Prompts versionados ││ └── Scores (LLM-as-judge + métricas) │└──────────────────────────────────────────────────────────────────┘ ↓┌──────────────────────────────────────────────────────────────────┐│ CAMADA DE VISUALIZAÇÃO ││ ││ Langfuse UI (técnico) Power BI (executivo/cliente) ││ ├── Trace explorer ├── Dashboard por cliente ││ ├── Sessions ├── KPIs de negócio ││ ├── Comparação de runs ├── ROI ││ └── Custo por modelo └── Relatórios mensais │└──────────────────────────────────────────────────────────────────┘Fluxo de uma mensagem real
Exemplo: cliente USA Salus tem agent-sdr ativo. Lead chega via WhatsApp.
1. Lead manda "Oi, vi anúncio sobre emagrecimento" ↓2. Stevo (porque USA Salus é GHL) recebe ↓3. Stevo dispara webhook para api.triadeflow.com.br/webhooks/stevo/usa_salus ↓4. Webhook handler valida e empurra pra fila BullMQ ↓5. Worker do agent-sdr pega da fila ↓6. Worker identifica: - tenant_id: usa_salus - agent_type: sdr - provider: stevo ↓7. Carrega tenants/usa_salus/config.yaml ↓8. Carrega histórico do Redis (key: conv:usa_salus:5585999...) ↓9. Inicia trace no Langfuse com metadata ↓10. Executa LangGraph: - Nó 1: classifica intenção - Nó 2: busca contexto no Qdrant (collection: usa_salus_kb) - Nó 3: chama Claude Sonnet com prompt + contexto + tools ↓11. Claude decide: responder + iniciar qualificação ↓12. Worker formata resposta e envia via Stevo API ↓13. Stevo entrega no WhatsApp do lead ↓14. Worker salva no Redis (histórico atualizado) ↓15. Worker chama tool: atualiza GHL com etapa "primeiro contato" ↓16. Trace fechado no Langfuse: - input/output completo - tools chamadas - latência: 1.8s - tokens: 1200/80 - custo: $0.012 ↓17. Em background, LLM-as-judge avalia o trace e gera scoreRepositórios envolvidos
triadeflow-org/ GitHub Organization├── triadeflow-core/ Biblioteca compartilhada├── agent-template/ Template para novos agentes├── agent-sdr/ Produto: SDR├── agent-vendas/ Produto: Vendas├── agent-suporte/ Produto: Suporte├── agent-agendamento/ Produto: Agendamento├── agent-recuperacao/ Produto: Recuperação├── agent-cobranca/ Produto: Cobrança├── agent-pos-venda/ Produto: Pós-venda├── agent-prospeccao-ativa/ Produto: Prospecção├── agent-pesquisa-nps/ Produto: NPS├── triadeflow-admin/ Painel multi-tenant└── triadeflow-docs/ Esta documentaçãoInfraestrutura de produção
| Componente | Onde roda | Porta | Domínio |
|---|---|---|---|
| Workers (todos os agentes) | Hetzner Cloud (CPX21) | - | - |
| Webhook API | Hetzner + Caddy | 443 | api.triadeflow.com.br |
| Langfuse | Hetzner + Docker | 3000 | langfuse.triadeflow.com.br |
| Qdrant | Hetzner + Docker | 6333 | qdrant.triadeflow.com.br |
| Redis (BullMQ + memória) | Hetzner + Docker | 6379 | (interno) |
| Postgres (Langfuse + tenants) | Hetzner + Docker | 5432 | (interno) |
| Power BI | Microsoft Cloud | - | - |
Decisões arquiteturais críticas
1. Por que separar agentes em produtos independentes?
Decisão: cada tipo de agente (SDR, vendas, suporte, etc) é repositório, deploy e produto separado.
Motivo:
- Manutenção isolada (bug em vendas não afeta SDR)
- Pricing modular
- Métricas claras por produto
- Times podem ser donos de produtos diferentes
- Novo tipo de agente = clonar template, sem refatoração
Trade-off aceito:
- Mais repositórios para manter
- Algum código duplicado (mitigado pelo
triadeflow-core)
2. Por que multi-tenant na mesma instância e não 1 deploy por cliente?
Decisão: uma instância de cada agente serve N clientes simultaneamente.
Motivo:
- Custo de infraestrutura escala bem (1 worker, N clientes)
- Atualização do código atinge todos de uma vez
- Onboarding de novo cliente = só criar pasta
tenants/{tenant_id}/ - Compartilhamento de modelos e custos da Anthropic API
Trade-off aceito:
- Bug afeta todos os clientes ao mesmo tempo (mitigado por testes e canary deploy)
- Limites de rate da Anthropic API são compartilhados
3. Por que Langfuse self-hosted?
Decisão: Langfuse rodando no Hetzner em Docker, não SaaS.
Motivo:
- Compliance LGPD (dados dos clientes não saem da infra Triadeflow)
- Custo previsível (volume alto fica caro no SaaS)
- Sem limite de retenção
- Possibilidade de customização
Trade-off aceito:
- Manutenção da infraestrutura é responsabilidade da Triadeflow
- Updates manuais
4. Por que sem orquestrador entre agentes?
Decisão: múltiplos agentes do mesmo cliente = múltiplos números WhatsApp distintos. Não há um “agente mestre” roteando entre eles.
Motivo:
- Clareza para o cliente final (cada número, uma função)
- Times humanos podem ser diferentes (vendas vs CS)
- Métricas separadas por canal
- Implementação mais simples
- Deploy independente
Trade-off aceito:
- Cliente precisa direcionar público para o número certo (resolvido com material de marketing)
Próximos documentos
- 02-principios.md — Princípios arquiteturais detalhados
- 03-stack-tecnologico.md — Stack completo
- 04-decisoes-tecnicas.md — Mais decisões e trade-offs