Seções ▾
Como a MIA funciona, de ponta a ponta
A MIA (da MiaConecta, dentro do Grupo Conecta) faz duas coisas: atende no WhatsApp os pacientes e leads de cada cliente em tempo real, e gera insights de melhoria a partir dessas conversas. O atendimento roda em Gemini Flash dentro do n8n; a análise roda em Claude de madrugada; tudo aparece num dashboard interno.
01 As camadas
Seis camadas, dois cérebros de IA com papéis que nunca se misturam: Gemini atende, Claude analisa.
O caminho da mensagem. O paciente escreve no WhatsApp; a Evolution API (gateway sobre o protocolo Baileys) entrega no Chatwoot fork fazer.ai (onde a conversa vive), que dispara um webhook pro n8n. Na volta, o n8n responde pelo mesmo caminho.
O bot em tempo real. Identifica o cliente, junta as mensagens do "burst", consulta o histórico, e um AI Agent rodando Gemini Flash decide a resposta — podendo buscar agenda, agendar, enviar mídia ou escalar pra humano. Não usa Claude.
A camada analítica, separada do atendimento. De madrugada o Claude headless lê as conversas já ocorridas + erros do n8n + Postgres e destila fatos, qualidade, comparação com o registro humano, insights, triagem e relatórios. Read-only em produção — só escreve em tabelas de análise. Não fala com paciente.
Onde tudo é persistido: Postgres :5433 (ciclo do paciente, fila de melhorias, config dos bots, schema por cliente), o Postgres do fork Chatwoot (mensagens reais) e o Qdrant (conhecimento dos bots, RAG).
O painel do Juca (painel.miaconecta.com.br) que só lê os dados. Não chama IA ao abrir tela nenhuma — funil e insights são SELECT + TypeScript determinístico. O relatório exportável é a peça que vai pro cliente.
MIA-SUPORTE (estação local — roda os crons do Claude) e MIA-01 / Hetzner (produção — n8n, Chatwoot, Evolution, todos os Postgres, Qdrant e o painel). Traefik faz roteamento e TLS.
02 Infra — onde tudo roda
Duas máquinas no SSH config. Os crons do Claude rodam 100% na primeira; toda a produção roda na segunda.
| Host | Endereço | Papel |
|---|---|---|
| MIA-SUPORTE (local) | 204.168.225.110 | Estação de orquestração — roda os crons do Claude, code-server, CCR, backend do dashboard legado (inativo) |
| MIA-01 (prod, Hetzner) | 178.156.206.230 | Produção — n8n, Chatwoot fork, Evolution, todos os Postgres, Qdrant, painel |
hetzner no SSH config. Nenhum host roda Ollama. Os crons do Claude rodam na MIA-SUPORTE, não no Hetzner.MIA-01 / Hetzner — containers principais (de 19)
| Container | Imagem | Papel | Porta |
|---|---|---|---|
n8n-coolify-n8n-editor-1 | n8nio/n8n:2.21.7 | n8n produção — editor + worker + queue no mesmo container | 5678 |
chatwoot-baileys-rails-1 | chatwoot-pro v4.14 fazer-ai | Chatwoot fork fazer.ai (canônico) | 3000 |
chatwoot-baileys-sidekiq-1 | chatwoot-pro | Worker Sidekiq do fork | 3000 |
chatwoot-baileys-evolution-api-1 | evolution-api:2.4.0-rc2 | Evolution API (gateway WhatsApp/Baileys) | 8080 |
chatwoot-baileys-postgres-1 | pgvector/pgvector:pg16 | Postgres do fork + Evolution | 5432 |
postgres_postgres.1… | postgres:16 | Postgres :5432 — banco n8n_queue (Swarm) | 5432 |
redis_redis.1… | redis:7 | Redis do n8n (fila Bull / queue mode) | 6379 |
postgres-api-s2-postgres-principal-1 | postgres:16 | Postgres :5433 — schemas cliente / mia_ciclo / mia_demandas / mia_internal | 5433 |
qdrant_qdrant.1… | qdrant/qdrant | Qdrant (vetorial — kb_*) | 6333 |
minio_minio.1… | minio/minio | MinIO (S3 — anexos do Chatwoot) | 9000 |
traefik-proxy | traefik:v3.6 | Reverse proxy / TLS (80, 443) | 80/443 |
painel-mia | painel-mia-painel | Painel MIA (Next.js) | 3100 |
Domínios → backend
| Domínio | Backend | Host |
|---|---|---|
| n8n + webhook.miaconecta.com.br | n8n editor (:5678) | Hetzner |
| chatwoot.miaconecta.com.br | Chatwoot fork :3000 (canônico) | Hetzner |
| chat / evopanel.miaconecta.com.br | Evolution API :8080 | Hetzner |
| painel.miaconecta.com.br | painel-mia:3000 | Hetzner |
| code / ccr.miaconecta.com.br | MIA-SUPORTE :3030 / :3456 | MIA-SUPORTE |
:5432 Swarm = n8n_queue · fork (pgvector) = Chatwoot + Evolution · :5433 = schemas de cliente / mia_ciclo / mia_demandas / mia_internal. O n8n não tem worker em container separado (o n8n-...-worker-1 citado em docs antigos não existe). Chatwoot só existe como fork fazer.ai; o antigo cwmkt está morto desde 05/05/2026.03 Canal — WhatsApp ↔ Evolution ↔ Chatwoot ↔ n8n
Dois componentes: a Evolution API (gateway WhatsApp) e o Chatwoot fork fazer.ai (inbox + fonte dos eventos).
Ida — paciente → IA
O paciente manda WhatsApp pro número do cliente. A Evolution recebe via Baileys e encaminha pro Chatwoot por webhook interno (entra como message_type=0, incoming). O Chatwoot dispara o webhook account-level → webhook.miaconecta.com.br/webhook/chatwoot-front, que alimenta o n8n. O agent_bots.outgoing_url fica NULL de propósito, pra evitar webhook concorrente.
Volta — IA → paciente
O n8n posta a resposta no Chatwoot via API REST (message_type=1, outgoing). O Chatwoot repassa pra Evolution, que envia ao WhatsApp.
evolution-api resolve pra IP privado do Docker; o ssrf_filter do fork bloqueava isso e jogava o WebhookJob em loop (incidentes 26/05 e 01/06). Fix = initializer zz_safe_fetch_allow_evolution.rb (allowlist).Mapa cliente → conta / inbox (tudo no fork)
| Cliente | account | inbox | inbox name | schema (:5433) |
|---|---|---|---|---|
| Dr Hugo | 3 | 18 | hugo | dr_hugo_ximenes |
| Dra Nathalya | 2 | 19 | nathalya | dra_nathalya |
| Dr Carlos | 5 | 17 | carlos | dr_carlos_hog |
| Mais Saúde | 6 | 16 | mais-saude | mais_saude |
| Explow | 4 | 15 | explow | explow |
| Dr Thiago | 7 | 14 | thiago | dr_thiago_valle |
Contas extras (fora dos 6): acc 1 = MIA / inbox 12 mia-test · acc 8 = Juca Pessoal / inbox 13 juca-pessoal (onde vivem os grupos de suporte MIA - <Cliente>) · acc 9 Jess · acc 10 HEALIX · acc 11 CEAFI_GERUZA. Total: 11 contas / 9 inboxes.
pending = IA conduzindo · resolved = fechada (reabre se o paciente escrever) · open = humano assumiu, bot cala. Handoff oficial = mudar pra open. Atribuir um agente não pausa o bot. Em workflows de IA, a chave de sessão é o conversation_id do Chatwoot (nunca o telefone sozinho, por causa de LID/fake_pn).04 Atendimento em tempo real — a arquitetura do bot
O cérebro de atendimento não é por cliente — é um par central na pasta Universais. Cada cliente só tem seu Config Loader + a suíte de ferramentas que o agente chama.
Os passos de uma mensagem
Chatwoot Trigger (1 por conta) → Config do cliente (chama o Config Loader) → Filter → IF horário comercial (só Hugo/Carlos) → Abrir Conversa (pending→open) → Encaminhar pro Universal → Info → IF tem mídia? (Gemini Mídia transcreve áudio / descreve imagem) → INSERT na fila → Wait (debounce) → DELETE RETURNING → Consolidar o burst → Histórico Chatwoot → Single Agent (AI Agent) → Enviar Humanizada → UPSERT status
Ferramentas do Single Agent (via $fromAI): informacoes_gerais (RAG), Buscar_janelas_disponiveis, Criar_agendamento, Atualizar_agendamento, Buscar_agendamentos_do_contato, Cancelar_agendamento, enviar_midia, Escalar_humano, Refletir.
Clientes × workflows
| Cliente | Suíte de workflows |
|---|---|
| Mais Saúde | Config Loader + 03/04/06/08/10 + 11/12 lembretes (inativos) |
| Dr Hugo | Config Loader + suíte clínica completa (03/04/06/08/10) |
| Dr Carlos | Config Loader + suíte clínica completa (03/04/06/08/10) |
| Dra Nathalya | Config Loader + suíte clínica completa (03/04/06/08/10) |
| Dr Thiago | só Config Loader — SDR-only |
| Explow | Config Loader + 03. Enviar Mídia (eventos, não agendamento) |
Google Gemini Chat Model (Gemini Flash), índice 0 do Single Agent. Fallback = OpenRouter gemini-flash-lite, índice 1. Nenhum Claude aqui — Claude só na análise de madrugada.05 O cérebro de análise — Claude, de madrugada
O Claude headless (claude -p, modelo herda o default do CLI = Opus) lê a operação já acontecida e destila entendimento. Read-only em produção — só escreve em tabelas de análise/demandas e nos arquivos de relatório mensal. Os scripts vivem em demandas-clientes/scripts/ e rodam todos na MIA-SUPORTE.
| Cron (UTC) | BRT / dias | Script | O que produz |
|---|---|---|---|
0 6 * * 2-6 | 03h ter–sáb | run-cron.sh conversas | Claude lê o fork → 4 blocos por conversa (fatos / qualidade / comparação / insight) → mia_ciclo.analise_conversas; insight recorrente (≥2) vira card em mia_demandas.demandas |
0 7 * * 2-6 | 04h ter–sáb | projetar-fatos.sh | Não é Claude — psql puro: UNNEST dos fatos → mia_ciclo.fatos_conversa (idempotente). 1h depois do anterior |
0 15,21 * * 1-5 | 12h e 18h seg–sex | run-cron.sh diario | Tria os grupos de suporte + varre erros do n8n nas últimas 24h (≥3 vira demanda) + digest no Telegram. 18h sempre; 12h só se houver novidade |
0 21 * * 0 | 18h domingo | run-cron.sh semanal | Coleta + qualidade do bot + insights + maturidade + hardening + resumo semanal |
0 12 1 * * | 09h dia 1º | run-cron.sh mensal | Escreve a seção por cliente em clientes/<x>/demandas-AAAA-MM.md (mês anterior) + digest |
0 13 * * * | 10h diário | healthcheck-cron.sh | Dead-man: alerta no Telegram se nenhum run terminou com sucesso há ≥36h |
0 11 * * * | 08h diário | healthcheck-qualidade.sh | Monitor proativo: cliente vivo sem análise / canal morto → alerta |
run-cron.sh ainda grava o status fazer_juntos, mas o painel já aposentou esse campo pra parecer_pronto (Fase 3, 18/06). Funciona com tolerância a legado, mas o script ainda não foi atualizado. O --permission-mode default é obrigatório nos runs (o settings global é bypassPermissions, que o CLI recusa rodando como root via cron).06 Dados — schemas e tabelas
O painel abre dois pools: dbSistema() → Postgres :5433 e dbFork() → Postgres do Chatwoot fork. Tudo read-only, exceto a decisão de demanda.
| Objeto | Tipo | Papel / volume |
|---|---|---|
mia_ciclo.fatos_conversa | tabela | Fatos extraídos das conversas — base do funil por arquétipo (~453) |
mia_ciclo.vw_funil_mes | view | Funil mês a mês (chegou/agendou/compareceu/no-show). Só clínica |
mia_ciclo.vw_reconciliacao | view | fatia_ia_pct — quanto dos agendamentos a IA fez vs equipe |
mia_ciclo.analise_conversas | tabela | Saída do cron das 03h: fatos/qualidade/comparação em JSONB |
mia_ciclo.eventos | tabela | Histórico de eventos do ciclo por contato (~4.003) |
mia_ciclo.vw_crm_contato | view | Ficha/CRM por contato — base das Fichas |
mia_ciclo.kanban_cards | tabela | Espelho do kanban fazer.ai (hoje só Hugo) — base do Quadro |
mia_demandas.demandas | tabela | Fila de demandas/reparos (~46). Única tabela escrita pelo painel |
mia_demandas.maturidade | tabela | Degraus M0–M6 por cliente (trilha de maturidade + upsell) |
mia_demandas.runs | tabela | Histórico das varreduras do cron |
mia_internal.tenants | tabela | Config dos bots: prompt, tools, KB, calendar_id, schema_pg, conta/inbox |
mia_internal.tenants_history | tabela | Histórico de mudanças (diff) — segredos nunca saem |
<schema>.n8n_fila_mensagens | tabela/cliente | A fila de 25s — mensagens esperando resposta agora |
fork messages / conversations / contacts | tabelas | Conversas reais, grupos MIA |
Qdrant kb_* (ex.: kb_hugo) | vetorial | Base de conhecimento dos bots (RAG) |
Arquétipos (fixos por slug em lib/funil.ts): clínica hugo · nathalya · carlos SDR thiago eventos explow — mais_saude sem arquétipo (inativo).
07 Vitrine — as telas e de onde cada coisa vem
Auth scrypt + JWT (cookie mia_sessao). Navegação de 5 itens: Início · Reparos · Clientes · Conversas · Bots. Todas as telas server-side, com degradação graciosa. Nenhuma rota chama IA ao abrir.
| Tela / rota | O que mostra | Fonte |
|---|---|---|
| barra de status | WhatsApp por cliente, erros 24h, reparos esperando | Evolution + n8n + mia_demandas |
/ Início | 3 perguntas: tá de pé? / o que precisa de você? / como vai a operação? + alertas | hoje + saúde + alertas |
/clientes | Os 6 com saúde, última resposta, erros 24h | saúde + n8n |
/cliente/[slug] | 4 abas: Visão · Insights (resumo determinístico + funil) · Relatórios · Histórico | saúde + funil + insights + ciclo + confiança |
…/melhorias | Análises de conversa (cron 03h) + cards + gaps | analise_conversas + mia_demandas |
…/quadro | Espelho do kanban (só Hugo) | kanban_cards |
/reparos | Decidir demanda: Aprovo / Não aprovo / Já comuniquei / Aguardar | mia_demandas (escreve) |
/numeros | Funil mês a mês + atividade do assistente | ciclo + atividade |
/fichas | Busca de pacientes + ficha + histórico do ciclo + conversa | ciclo + conversa |
/conversas | Grupos "MIA - <Cliente>" ao vivo (read-only, polling) | fork (conta 8 / inbox 13) |
/funil/[slug] | Vitrine do funil agêntico por arquétipo + citações auditáveis | fatos_conversa + vw_funil_mes |
/bots + /bots/[slug] | Gestor de IA: ativo, prompt, KB, fila/respostas, erros + diff de prompt | tenants + Qdrant + diff |
/relatorio/[slug] | Relatório mensal client-facing (PDF) | ciclo + funil + melhorias |
/semanal/[slug] | Relatório semanal leve | fork |
08 Como tudo se alimenta — os 2 fluxos
Um acontece na hora (atendimento, Gemini); o outro acontece em batch, de madrugada (análise, Claude). O primeiro gera os dados; o segundo os transforma em entendimento.
Fluxo A — atendimento em tempo real Gemini Flash
Paciente (WhatsApp)
│
▼
Evolution API ──webhook──► Chatwoot fork (inbox do cliente)
│ webhook account-level
▼
n8n: 01. Webhook-Loader (identifica o cliente, Config Loader)
▼
n8n: 02. Universal → INSERT fila → Wait (debounce) → DELETE RETURNING
▼
Single Agent ◄── LLM: GEMINI FLASH (fallback OpenRouter)
│ tools: buscar janela / criar agendamento / enviar mídia / escalar
▼
Enviar Humanizada ──► Chatwoot ──► Evolution ──► WhatsApp (paciente)
└─► grava status + appointments/Calendar + fila
Fluxo B — análise / insight de madrugada Claude Opus
Cron na MIA-SUPORTE (03h ter–sáb)
▼
run-cron.sh conversas ◄── LLM: CLAUDE (Opus), headless, READ-ONLY em prod
│ lê: fork (conversas do dia) + erros do n8n + Postgres :5433
│ destila por conversa: FATOS · QUALIDADE · COMPARAÇÃO · INSIGHT
▼
escreve mia_ciclo.analise_conversas
└─ insight recorrente (≥2) ──► mia_demandas.demandas
▼ (04h — psql puro, NÃO Claude)
projetar-fatos.sh: UNNEST ──► mia_ciclo.fatos_conversa
▼ (diário / semanal / mensal)
triagem dos grupos + maturidade + relatório por cliente
▼
DADOS ──SELECT determinístico (sem IA ao abrir)──► Painel ──► Juca lê, decide, exporta
09 Clientes & produto
| Cliente | Arquétipo | O que o bot faz | Estado |
|---|---|---|---|
| Hugo · ortopedia/quadril | Clínica que agenda | Bot Carol: atende, consulta Calendar, agenda/reagenda | Ativo único com funil completo (compareceu 170 / no-show 15) |
| Nathalya · dermato/estética | Clínica que agenda | Bot Bia: rota clínica vs estética → cria evento no Calendar | Ativo agendou 244 |
| Carlos · cirurgia de coluna | Híbrido tensão nos docs | Bot Ana: queixa → desambigua médico → qualifica (tools de agenda reativadas) | IA dormente aguardando QR conectar; só agendou 4 |
| Thiago · cirurgia plástica | SDR puro | Bot Sofia: qualifica via prompt, escala humano. Sem tool de agenda | Ativo zero evento (cego no funil) |
| Explow · buffet infantil | Eventos | Bot Clara: qualifica, envia portfólio, passa pro consultor | Ativo zero evento (cego no funil) |
| Mais Saúde · odontológica | Clínica que agenda | Detecta especialidade → busca janelas → agendamento (5 workflows) | Inativo contrato encerrado 14/06; vira template |
10 Lacunas honestas
O que ficou sem confirmar, ou que simplesmente ainda não existe. Sem maquiar.
- Insight cruzado de jornada não existe. O sistema extrai fatos e insights por conversa e por cliente, mas não há (no código) um insight que cruze a jornada inteira de um paciente entre conversas — "confirmou e depois desmarcou" vira dois fatos soltos, ninguém costura.
- Relatório é monomodal. A camada de entrega só serve clínica-que-agenda. SDR (Thiago) e Eventos (Explow) têm zero evento em
mia_ciclo— a captura de "lead qualificado/handoff" e "orçamento respondido" não existe. - Cobertura parcial: só 3 de 6 clientes têm dados em
mia_ciclo(Hugo, Nathalya, Carlos). - Tensão do Carlos não resolvida: agendamento ativo (doc do cliente) vs triagem/handoff (docs de produto). Precisa de decisão.
- Temperatura do Gemini não verificada no node (convenção interna = 1.0).
- Divergência script ↔ painel: o cron ainda grava
fazer_juntos; o painel já migrou praparecer_pronto. - A camada de confiança é hardcoded por cliente (hugo/nathalya/carlos), não derivada dos dados.
- Autonomia agêntica (autogerencial): a ideia do sistema melhorar a própria estrutura no n8n é futuro declarado — não existe hoje.