Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4.4 KiB
newwhats.clube67.com — Secretária IA (plugin secretaria)
Específico deste projeto. Atendente virtual de IA do newwhats, no plugin
backend/plugins/secretaria/(gerenciado por Knex, tabelassec_*).
Arquitetura
- Agente (
sec_agents): define provider/modelo/temperatura/context_window. - Cérebro = nós (
sec_brain_nodes), tipos:persona,knowledge,rules,calendar,escalation. Obrain.ts(buildSystemPrompt) monta o system prompt concatenando os nós ativos + data/hora + protocolo + resumo. - Resposta:
callAIcom fallback de providers (config do plugin:openai_key,gemini_key,anthropic_key— em Admin → Plugins → Secretária IA). - Conversas/mensagens:
sec_conversations/sec_messages(com telemetriausage_tokens/provider_used/model_used). - UI:
/secretaria(abas Conversas, Cérebro, Agenda, Agentes, Números) + ícone de Ajuda com modelos prontos por nó (botão "Usar este modelo").
RAG na Base de Conhecimento (SEM pgvector)
Por que sem pgvector: a extensão não está disponível no Postgres da
VPS3 nem na imagem do pgdev, e o role newwhats não é superuser
(CREATE EXTENSION negado). Solução adotada (decisão 28/jun/2026):
embeddings.ts: chunking + embed (OpenAItext-embedding-3-small@1536d ou Geminigemini-embedding-001@768d, conforme a chave) + cosseno — em Node. Ordem de preferência: OpenAI → Gemini (em qualquer falha do OpenAI, cai para o Gemini — uma chave OpenAI sem créditos não derruba o RAG).- Tabela
sec_knowledge_chunks: vetor serializado em JSON/text (sem extensão) + índices emagent_id/node_id. brain.ts: no nóknowledge, injeta só os top-4 trechos relevantes à pergunta. Indexação lazy (reindexa quando o conteúdo muda — hash MD5).- Fallback: sem chave de embedding ou em qualquer erro → injeta o conteúdo inteiro (comportamento anterior). Nunca regride.
Para bases pequenas (clínica/empresa) é rápido e suficiente. Quando a VPS3 tiver
pgvector, dá para migrar a busca ao banco sem mudar a interface.
⚠️ Chaves de embedding (estado dev, 28/jun/2026)
openai_keyconfigurada (não versionada, no Dragonfly), porém a conta OpenAI está sem quota (429 insufficient_quota) → embeddings OpenAI não funcionam até acertar billing. Rotacionar a chave exposta.gemini_keyconfigurada e funcional → embeddings caem no Gemini (gemini-embedding-001@768d).text-embedding-004foi descontinuado (404).- Incompatibilidade de dimensões: OpenAI (1536d) ≠ Gemini (768d). Ao habilitar
o OpenAI (billing) o provider preferido muda → é obrigatório reindexar
(
sync-knowledge+ memória de contato), senão o cosseno mistura espaços e o retrieval fica sem sentido.
Memória de longo prazo por contato
A secretária lembra do cliente entre conversas (tabela sec_contact_memory):
- Extração (na sumarização, a cada ~10 trocas): um LLM extrai fatos
duradouros do cliente a partir da conversa; cada fato vira embedding e é salvo
com dedup (cosseno > 0.92). Chave do contato =
ext_chat_id(oucontact_name). - Recuperação:
buildSystemPromptinjeta=== MEMÓRIA DO CLIENTE ===com os fatos mais relevantes à pergunta (cosseno). Sem chave de embedding → usa os mais recentes. Fallback silencioso em qualquer falha (não regride). - Reusa o mesmo embedding do RAG (
openai_key/gemini_key); sem pgvector.
Modo teste / segurança
DISABLE_OUTBOUND=true(kill switch global, verambiente-dev.md) bloqueia todo envio — inclusive respostas automáticas da secretária — em dev.- ⚠️ Ao conectar uma sessão WhatsApp real em dev, a secretária responde sozinha (bots/IA). Mantenha o kill switch ligado nos testes.
Migrations (Knex) — cuidado
O migrate.ts cria tabelas if (!hasTable) e adiciona colunas novas com
blocos hasColumn/alterTable (idempotentes). Ao adicionar coluna usada em
runtime, adicione também o bloco de migração — senão bancos antigos quebram
(ex.: faltava sec_messages.usage_tokens/provider_used/model_used → erro 42703,
corrigido).
Futuro
Roadmap de humanização e memória de longo prazo (memória por contato, Whisper,
TTS, ritmo humano, frameworks Mem0/Zep/Letta) em secretaria-ia-evolucao.md.