Menuabrir
EstávelAtualizado em 14 de mai. de 2026, 00:06

Este módulo depende de

5
  • whatsappQueries em whatsapp_message, whatsapp_thread para engagement, sentimento
  • crmLê crm_contact, crm_deal, tags para L1 scores e churn risk
  • emailLê email_send para engagement (opens, clicks)
  • businessLê objections, price_inquiries, appointments para refresh L1 (churn indicators)
  • diaryConta agregadas apenas (sem conteúdo) para crisis detection

Módulos que dependem deste

8
  • councilcross_module.read_intelligence_insights L1/L3/L5 para decisões com evidência
  • diaryCrisis detection consome counts agregados (sem conteúdo) de entries
  • whatsappEmite eventos delivered/read para cálculo de engagement e atributos
  • emailEmite eventos opened/clicked para calcular engagement_score
  • meetingsResume transcript via run_conversation_summary
  • agentsread_contact_attributes, read_patterns para decisão informada
  • programsEmbeddings de acervo para busca semântica por temas/conceitos
  • crmRecebe purchase_intent_level de run_relationship_health

Intelligence (Cérebro/Observatório)

Status: 🟢 Estável (Sprints 1.A → 2.A deployadas) Code: backend/app/modules/intelligence UI: frontend/src/app/(admin)/[slug]/admin/intelligence Última revisão deste doc: 2026-05-13 por Felipe + Claude Dependências fortes: whatsapp + crm + email + business + diary (lê dados crus L0); council + agents (consomem L1/L3/L5); tenant_router (multi-tenant)


1. Identidade

O que faz (uma frase)

Observatório do negócio: agrega dados crus dos módulos (whatsapp, crm, email, business, diary), calcula atributos por contato (L1), descobre padrões persistentes (L3), registra observações de IA (L5), e expõe tudo via tools que Conselho e Agentes consomem para tomar decisões com evidência.

Por que existe (negócio)

Sem Intelligence, cada decisão de IA seria stateless e estatisticamente cega:

  • Conselheiro responderia "como vai a saúde do cliente?" sem ter um score calculado.
  • Agente Hari não saberia que o lead já desistiu 3x antes de responder a 4ª.
  • Felipe não veria padrões tipo "no-show de yoga sempre na segunda manhã" sem ter alguém olhando.

A camada Intelligence resolve isso operando como observatório passivo + analítico ativo:

  • Atributos por contato (L1): churn_risk_score, engagement_score, ltv, tags comportamentais — tudo calculado e cacheado.
  • Padrões (L3): "campanhas com vídeo convertem 3x mais que com imagem" — discovered via causality sub-agent.
  • Insights pontuais (L2): anomalias, sumários, crisis detection.
  • Observações de IA (L5): log do que o Conselho/Agente viu antes de cada decisão (auditabilidade).

Por que existe (técnico)

Intelligence é o agregador-único entre módulos. Sem ele:

  • CRM teria que importar whatsapp.message, email.send, billing.invoice (acoplamento).
  • Conselho/Agentes refariam queries pesadas em cada turn (sem cache).
  • Sem padrão pra "explicabilidade" — cada módulo inventaria seu jeito.

Como módulo dedicado:

  • Refresh determinístico com formula_version + inputs_hash (skip se nada mudou).
  • Provenance nativoconfidence, churn_explanation, health_explanation, at_risk_reason em cada atributo.
  • Catálogo de behavior tags universal: dormant, new_lead, objection_open, no_show_chronic, at_risk_customer, repeat_buyer, etc.
  • Append-only history (contact_attribute_history) pra reconstruir trajetória.
  • Tools cross-módulo que Conselho usa direto sem precisar entender 7 schemas diferentes.

Status atual

  • Sprint 1.A deployada (2026-05-13) — atribuição (campaign + touchpoint + crm_contact.attribution_*, mig 0094). emit_event em council/diary/whatsapp delivered/read/reaction.
  • Sprint 1.B + 1.C deployadas (2026-05-13) — alembic 0095+0096. L1 contact_attribute (3758 rows mais-consciente), L3 intelligence_pattern, L5 brain_observation, sub-agent causality, 13 tools novas no Council. Telas /admin/intelligence/{contact-attributes,patterns,observations}.
  • Sprint 2.A "Contact OS" deployada (2026-05-13) — alembic 0101 + commit c8ca39e2. L1 ganhou provenance (formula_version, inputs_hash, confidence), explainability nativa, 4 tags novas, refresh v2 cruzando objections+price_inquiry+appointment, skip-on-no-change, contact_attribute_history append-only, tool Council read_contact_attribute_history, endpoint /health do catálogo, UI estendida. Validado em 3758 contatos mais_consciente.

Próxima mudança planejada: L4 (truth) implementação completa (regras derivadas em runtime); embeddings para knowledge_entry busca semântica.


2. Cases de uso reais

Case 1: Conselho responde "como está minha taxa de churn?"

Situação: Felipe pergunta no Conselho.

Fluxo:

  1. CEO chama tool read_intelligence_insights(severity=warning, sub_agent=churn_detection).
  2. Tool roda cross_module.list_intelligence_insights → retorna últimos N insights de churn.
  3. Brain monta resposta narrativa: "X contatos em risco crítico, top 3 razões: dormant, objection_open, low_engagement..."
  4. Mostra contatos específicos via read_contact_attributes(behavior_tag='at_risk_customer', limit=10).

Impacto: Felipe entende health do negócio sem abrir 5 telas de CRM.

Case 2: Agente Hari evita oferecer produto a contato com objection_open

Situação: Lead tem objeção registrada ("preço alto") em product X, agora pergunta sobre product Y.

Fluxo:

  1. Brain de Hari chama read_contact_objections(contact_id, unresolved_only=True).
  2. Detecta objeção aberta.
  3. Brain ajusta resposta: cita product Y mas aborda objeção de preço primeiro ("entendo que valor era preocupação...").

Impacto: Conversão não morre por agente "robô" ignorando histórico.

Case 3: Padrão descoberto pelo causality sub-agent

Situação: Causality roda diariamente, snapshot de cohorts × outcomes.

Fluxo:

  1. causality.discover_patterns(tenant_id) coleta:
    • Campaign cohorts → conversão
    • Channel analysis → engagement
    • Product affinity → cross-sell
    • Objection distribution
    • Appointment patterns (no-show por weekday/hour)
    • Churn signals
  2. Manda JSONs estruturados (não dados crus de pessoa) pro Claude.
  3. Claude retorna padrões com evidência: {kind, scope_kind, title, evidence: {metric, comparison, base}, confidence, sample_size, severity}.
  4. Persiste em intelligence_pattern com status=provisional, discovered_by=causality.
  5. Felipe revê em /admin/intelligence/patterns, marca confirmed ou invalidated.

Exemplo real: "Yoga no-show 60% segunda 9h vs 12% terça 19h" (n=42, confidence=0.85).

Impacto: Felipe descobre padrões que jamais identificaria manualmente; ajusta horários, comunicação, oferta.

Case 4: Refresh L1 hora a hora — provenance + skip-on-no-change

Situação: Beat refresh_contact_attributes (30min).

Fluxo:

  1. Pega N contatos do tenant (limit 5000 default).
  2. Pra cada contato: ~16 queries determinísticas (engagement_30d, ltv, quote_count, purchase_count, objections, price_inquiries, appointments, last_touch).
  3. Calcula scores: churn_risk_score, relationship_health_score, engagement_score_*.
  4. Calcula inputs_hash = sha256(snapshot_estável).
  5. Compara com inputs_hash anterior:
    • Igual → atualiza só refreshed_at (skip materializar).
    • Diferente → recalcula tudo + grava novos atributos + insere em contact_attribute_history (mudanças materiais).
  6. confidence proporcional a volume de sinais.
  7. churn_explanation + health_explanation: lista de fatores ponderados.

Impacto: 3758 contatos refreshados em 2-5s; ~70% skip materializar; histórico append-only permite reconstruir trajetória.


3. Oportunidades de negócio

  • Vender Intelligence como camada standalone: "Mandir Insights" (subset com L1+L3+L5) para empresas que já têm CRM/WhatsApp próprios mas querem atribuição + patterns + churn risk como API.
  • Causality como produto premium: descoberta automática de padrões via Claude — "pague por padrão confirmado". Diferencial sobre BIs tradicionais (Looker, Metabase) que só mostram, não descobrem.
  • Compliance LGPD: explainability nativa (churn_explanation, etc.) é argumento legal. "Por que você está em risco?" → resposta auditável.
  • Marketplace de patterns por vertical: padrões descobertos em e-commerce funcionam pra outros e-commerces. Anonimização + share + adapt.
  • Predição como serviço: ChurnAttribute → predição de churn em 90d com confidence. API pricing por inferência.
  • Brain Observatory cross-tenant (L5): insights agregados (anonimizados) ajudam o Mandir a melhorar produto. Telemetria opt-in.

Riscos comerciais:

  • Custo LLM em escala (causality + crisis_detection rodam por tenant).
  • Privacy: refresh de L1 lê dados sensíveis — LGPD exige consentimento + auditoria.
  • Padrões "óbvios" que Claude vai inventar sem cuidado (mitigação: confidence ≤ 0.3 se sample_size < 10).

4. Arquitetura interna

Camadas L0-L5 (Brain Observatory)

L0 — Cru (vive em outros módulos)
   whatsapp_message, crm_deal, email_send, contact_touchpoint,
   product_objection, price_inquiry, appointment, campaign

   ↓ refresh_contact_attributes (Beat 30min)

L1 — Atributos por contato (contact_attribute)
   scores, tags, provenance, recência, explanations

   ↓ scoring/threshold rules

L2 — Insights pontuais (intelligence_insight)
   summary, anomaly, crisis_detection, churn_detection

   ↓ causality sub-agent (LLM)

L3 — Padrões persistentes (intelligence_pattern)
   cohort_behavior, cross_channel_correlation, no_show_pattern, ...

   ↓ regras derivadas em runtime

L4 — Verdade (não persistida — TBD)
   "se churn_risk ≥ 70 then contato em risco"

   ↓ logged when consulted

L5 — Observações de IA (brain_observation)
   "advisor X consultou Y antes de decidir Z"

Arquivos do módulo

ArquivoPropósito
models.py7 tabelas
routes.py29+ endpoints
contact_attributes.pyL1 refresh engine (provenance, skip-on-no-change, hash)
segments.pyQuery builder (criteria JSONB → contact list)
segment_evaluation.pyMaterialization de intelligence_segment_member
sub_agents.pyDeterminísticos: summary, engagement_score, anomaly, churn, cohort
llm_agents.pyLLM-based: chat_query, crisis_detection, thread_sales_analysis, relationship_health_batch
llm_tools.py8 tools: count_contacts, list_contacts, count_emails, count_whatsapp_messages, list_segments, count_segment_members, deals_summary, members_summary
causality.pyPattern discovery (snapshots → Claude → IntelligencePattern)
tasks.pyBeat tasks

Tasks Celery (Beat schedule)

TaskCronMulti-tenant?Notas
intelligence.refresh_contact_attributes*/30 * * * *Sim — loop tenants ativosCrítico, ~5000 contatos / 2-5s
intelligence.refresh_segment_members5 * * * *SimMaterializa segments
intelligence.run_summary0 8 * * *SimAgregado diário
intelligence.run_engagement_score0 9 * * *SimTop contatos
intelligence.run_churn_detection0 6 * * *SimThreshold 50 default
intelligence.run_cohort_analytics0 10 * * 0SimSemanal (domingo)
intelligence.analyze_threadOn-demand (whatsapp callback)SimThread sales analysis

Todas usam tenant_router.worker_session(tenant_id) (NullPool por task).


5. Tabelas + relacionamentos (7)

intelligence_insight (L2)

Descobertas pontuais por sub-agent.

Coluna chaveTipoNotas
tenant_idUUIDidx
sub_agentVARCHARsummary / engagement_score / anomaly / crisis_detection / churn_detection / chat_query / dynamic_segment / event_trigger / causality
subject_typeVARCHARcontact / deal / tenant / global (ou NULL)
subject_idUUIDID do objeto referenciado
severityVARCHARinfo / warning / critical
title / body_md
payloadJSONBEstruturado por sub-agent
acknowledged_at / acknowledged_by_user_id

Índices: (tenant, severity), (tenant, sub_agent), (tenant, subject_type, subject_id).

intelligence_segment + intelligence_segment_member

Segmentos dinâmicos.

intelligence_segment: slug (UQ), name, criteria JSONB, member_count, is_active, refreshed_at. intelligence_segment_member: segment_id, contact_id, added_at — materializado por beat 05:00 UTC.

contact_attribute (L1) ⭐

Atributos agregados por contato.

Coluna chaveTipoNotas
tenant_idUUIDidx
contact_idUUIDUNIQUE (1 row por contato)
engagement_score_30d / engagement_score_90dINTwa_in×3 + wa_out×2 + email_open×1 + email_click×4, capped 100
churn_risk_scoreINT0-100 (factors weighted)
relationship_health_scoreINT0-100 (baseline 40)
lifetime_value_brlDECIMALSoma de purchases
quote_count / purchase_count / quote_to_purchase_ratioINT/FLOAT
last_interaction_at / last_purchase_at / days_since_last_interactionRecência
no_show_rate / no_show_patternFLOAT/JSONBPor weekday/hour
top_objectionsJSONB array
channels_used / preferred_channel / best_time_to_contact
attribution_kind / attribution_channelSprint 1.A
Provenance (Sprint 2.A):
formula_versionVARCHARv2 (atual). Bump força reprocessamento.
inputs_hashVARCHAR(64)sha256 de snapshot estável. Igual = skip materializar.
confidenceFLOAT0..1 baseado em volume de sinais
churn_explanationJSONB{factors: [{factor, weight, value}], score}
health_explanationJSONBidem
at_risk_reasonVARCHARLabel curto do fator dominante
behavior_tagsJSONB arrayhigh_engagement, low_engagement, price_sensitive, repeat_buyer, at_risk_customer, dormant, new_lead, objection_open, no_show_chronic
refreshed_atTIMESTAMP(tz)

Índices: (tenant, churn_risk_score DESC), (tenant, relationship_health_score DESC), (tenant, engagement_score_30d DESC), (tenant, last_interaction_at DESC).

contact_attribute_history (append-only)

Mudanças materiais ao longo do tempo.

Coluna chaveTipoNotas
tenant_id / contact_idUUID
attribute_nameVARCHARengagement_score_30d, churn_risk_score, behavior_tags, etc.
value_text / previous_value_textTEXT
delta_kindVARCHARfirst_value / score_jump_up / score_jump_down / tag_added / tag_removed
changed_atTIMESTAMP(tz)

Quando escreve: Δ ≥ 10 em scores trackeados; tag add/remove; primeira vez (first_value). Índices: (tenant, contact, time), (tenant, attribute, time).

intelligence_pattern (L3)

Padrões persistentes descobertos.

Coluna chaveTipoNotas
tenant_idUUIDidx
kindVARCHARcohort_behavior / contact_behavior / cross_channel_correlation / temporal / product_affinity / churn_predictor / conversion_path / objection_pattern / no_show_pattern
scope_kindVARCHARglobal / cohort / contact / campaign / product / segment / channel
scope_idUUIDQuando aplicável
titleVARCHAR(80)
description_mdTEXT2-4 linhas pt-BR com números
evidenceJSONB{metric, comparison: "62% vs 8%", base: "n=42"}
confidenceFLOAT0..1
sample_sizeINT
severityVARCHARinfo / warning / critical / opportunity
statusVARCHARprovisional / confirmed / invalidated / stale
discovered_byVARCHARcausality (futuro: outros)
discovered_at / last_seen_at / invalidated_atTIMESTAMPLifecycle
acknowledged_by_user_id / notes_mdFelipe revisa

Índices: (tenant, kind), (tenant, status), (tenant, scope_kind, scope_id).

brain_observation (L5)

Log do que IA observou antes de cada decisão.

Coluna chaveTipoNotas
advisor_slugVARCHARceo, commercial, low_ticket_sales, etc.
conversation_idUUIDContexto
message_id / contact_idUUID
trigger_kindVARCHARcontact_pre_interaction / campaign_launch_eligibility / diary_engagement
observed_factsJSONB{contact_engagement: 75, churn_risk: 42, ...}
patterns_usedJSONB arrayIDs dos intelligence_pattern consultados
decision_mdTEXTRaciocínio em markdown

Relacionamentos cross-módulo

DireçãoOutro móduloComoPor quê
↗ LêwhatsappQueries em whatsapp_message, whatsapp_threadengagement, sentimento
↗ Lêcrmcrm_contact, crm_deal, crm_contact_taglifecycle, deals, tags
↗ Lêemailemail_sendopens, clicks
↗ Lêbusinessproduct_objection, price_inquiry, appointmentsinais de churn
↗ Lêdiarydiary_entry (apenas counts agregados — sem conteúdo cru)crisis detection
↘ Escrevecrm_contactsentiment_trend, conversation_health_score (Sprint 2.A)Coloca scores no CRM
↗ Lêattributioncrm_contact.attribution_*, contact_touchpoint, campaignatribuição de conversão
↘ Escreve via toolscouncilcross_module.read_intelligence_insights, etc.Conselho consulta
↘ Escreve via toolsagentsread_contact_attributes, read_patternsAgentes ajustam respostas

6. API / Endpoints (29+)

Prefixo /api/intelligence.

Insights (L2)

MétodoRotaO que faz
GET/insightsLista (filtros: severity, sub_agent, limit)
POST/run/summarySync com window_days
POST/run/engagement-scoreTop N contatos
POST/run/crisis-detectionLLM batch (diary + WA inbound)
POST/run/anomalyQueda de engajamento
POST/run/churn-detectionThreshold-based
POST/run/cohort-analyticsPrograma × conclusão
POST/insights/{id}/ackMarca acknowledge

Segments (Dinâmicos)

MétodoRotaO que faz
GET / POST / PATCH / DELETE/segmentsCRUD
POST/segments/{id}/refreshRecalc count
GET/segments/{id}/membersLista contatos
POST/segments/previewPreview sem persist

Contact Attributes (L1)

MétodoRotaO que faz
GET/contact-attributesLista (filtros: min_engagement, max_churn_risk, behavior_tag, q_text)
GET/contact-attributes/healthCobertura por atributo (sentinela)
GET/contact-attributes/{id}Detail completo (explanations)
GET/contact-attributes/{id}/historyTimeline append-only
POST/contact-attributes/refreshSync batch (force ignora hash)

Patterns (L3)

MétodoRotaO que faz
GET/patternsLista (kind, status, severity, min_confidence)
PATCH/patterns/{id}Update status, severity, notes, acknowledge
POST/run/causalitySync LLM discovery

Observations (L5)

MétodoRotaO que faz
GET/observationsLista (contact_id, conversation_id, advisor_slug filters)

Chat Query (LLM Tool Use)

MétodoRotaO que faz
POST/chat-queryPergunta natural → resposta via tools (loop até 8 iter)

WhatsApp Intelligence

MétodoRotaO que faz
POST/analyze/thread/{id}On-demand: sentiment + purchase intent + summary
GET/whatsapp/sentiment-trendsDistribuição últimos N dias
GET/whatsapp/purchase-intent-signalsThreads por sinal
GET/whatsapp/relationship-healthContatos com trend + upsell
POST/run/relationship-healthBatch LLM (90d default)

7. Sub-agentes

Sub-AgentTipoO que faz
summaryDeterminísticoAgregado: contatos, deals, email opens, WA messages, diary entries (counts)
engagement_scoreDeterminísticoTop N contatos por wa_in×3 + wa_out×2 + email_open×1 + email_click×4
chat_queryLLM (Claude)Pergunta natural → tool use (8 tools) → resposta narrativa
dynamic_segmentDeterminísticoAvalia criteria JSONB → IntelligenceSegmentMember
crisis_detectionLLMDiary + WA inbound → tom de crise (warning/critical)
event_triggerTBDNão implementado
anomalyDeterminísticoQueda eng prev_window > 0 e curr = 0
causalityLLMSnapshots cohort + Claude → IntelligencePattern (L3)
thread_sales_analysisLLMThread WA → sentimento + purchase intent + care score
relationship_health_batchLLMHistórico contato → sentiment trend + health score
cohort_analyticsDeterminísticoPrograma × turma → taxa conclusão
churn_detectionDeterminísticoContactAttribute.churn_risk_score ≥ threshold
refresh_contact_attributesDeterminísticoCrítico — recalcula L1 em batch
refresh_all_segmentsDeterminísticoRecompila segments ativos

8. Contact Attribute (L1) — Refresh Pipeline

Princípios cravados (Sprint 2.A):

  1. formula_version: cada linha carrega versão (v2 atual). Bump força reprocessamento com force=true.
  2. inputs_hash: sha256 de snapshot estável (eng, ltv, quote_count, purchase_count, appt_count, ns_count, churn_risk, health_score, tags, at_risk_reason, last_int_at, last_pur_at). Idêntico → skip materializar (atualiza apenas refreshed_at).
  3. confidence: 0..1 baseado em volume de sinais (wa_in, wa_out, purchases, touches).
  4. Explicabilidade: churn_explanation + health_explanation são dicts com fatores ponderados — UI mostra "por que risco?"

Catálogo de behavior tags

TagCritério
high_engagementengagement_score_30d ≥ 60
low_engagementengagement_score_30d ≤ 10
repeat_buyerpurchase_count ≥ 3
price_sensitivequote_to_purchase_ratio < 0.34 com ≥ 3 quotes
at_risk_customercustomer + engagement_30 ≤ 5
dormantsem interação > 60 dias
objection_open≥ 1 objeção sem resolução
no_show_chronicno_show_rate ≥ 0.3 com ≥ 3 appointments
new_leadcriado < 14 dias

Heurísticas de scoring (determinísticas, sem LLM)

  • engagement_score = wa_in×3 + wa_out×2 + email_open×1 + email_click×4, capped 100
  • churn_risk_score (0-100):
    • eng_30 crítico (+30)
    • eng_90 queda (-20)
    • 60d sem interação (+20)

    • customer sem compra 180d (+15)
    • objeção aberta (+10)
    • no_show_rate ≥ 0.3 (+12)
  • relationship_health_score (0-100):
    • Baseline 40
    • eng_30 ≥ 40 (+25)
    • comprou (+15)
    • 3+ compras (+10)
    • objeção aberta (-15)
    • no_show_rate ≥ 0.3 (-10)
    • 30d sem interação (-10)

History (append-only)

  • TRACKED_SCORES: engagement_score_30d, churn_risk_score, relationship_health_score → entry quando Δ ≥ 10.
  • Tags: entry em cada add/remove.
  • delta_kind: first_value, score_jump_up, score_jump_down, tag_added, tag_removed.

Performance (3758 contatos)

  • ~16 queries totais por refresh (paralelo-friendly).
  • Batch upsert via pg_insert.on_conflict_do_update.
  • Skip-on-no-change: ~70% das linhas pulam materialização.
  • ~2-5s por 5000 contatos.

9. Patterns (L3) — Causality Sub-Agent

Snapshots coletados:

  1. campaign_cohorts — por campanha → n contatos, deals_won, deals_lost, ltv, avg eng/churn/health.
  2. channel_analysis — por canal (YouTube, IG, Email, Ads) → similar.
  3. product_affinity — produtos comprados juntos.
  4. objection_distribution — categorias em deals won vs lost.
  5. appointment_patterns — no-show por weekday/hour.
  6. churn_signals — contatos com churn_risk alto + engagement queda.

Prompt do Claude (causality.py):

Recebe JSONs estruturados (nunca dados crus de pessoa). Pede "padrões com evidência estatística". Retorna array:

{
  "kind": "cohort_behavior|cross_channel_correlation|temporal|...",
  "scope_kind": "global|cohort|contact|campaign|product|segment|channel",
  "scope_id": "uuid-if-applicable",
  "title": "≤80 chars",
  "description_md": "2-4 linhas pt-BR com números",
  "severity": "info|warning|critical|opportunity",
  "confidence": 0..1,
  "sample_size": int,
  "evidence": {"metric": "...", "comparison": "62% vs 8%", "base": "n=42"}
}

Regras firmes:

  • confidence ≤ 0.3 se sample_size < 10.
  • Nunca inventar números.
  • Citar na descrição: base (n=X) e efeito (Y% vs Z%).

10. Brain Observation (L5)

Estrutura (planejado para cross-tenant via mandir-events, hoje só log estruturado):

  • advisor_slug — qual agente/conselheiro consultou intelligence.
  • conversation_id, message_id, contact_id — contexto.
  • trigger_kindcontact_pre_interaction, campaign_launch_eligibility, diary_engagement.
  • observed_facts (JSONB) — {contact_engagement: 75, churn_risk: 42, last_interaction_days: 3}.
  • patterns_used — IDs de patterns consultados.
  • decision_md — raciocínio em markdown.

Exemplos:

  • "Luciano cota 7 no vídeo Yoga" — contact_id=luciano, observed_facts={sentiment: "positive", engagement_topic: "yoga"}, trigger_kind="diary_engagement".
  • "Yoga no-show segunda-manhã 60%" — padrão global, scope_kind="global", observed_facts={no_show_bucket: "weekday_0_hour_09", rate: 0.60}.

11. Configuração

Env vars

VarPropósito
ANTHROPIC_API_KEYClaude (compartilhado com council/agents)

Settings flags (planejados — TODO)

  • INTELLIGENCE_LLM_ENABLED (master switch para sub-agentes LLM)
  • INTELLIGENCE_REFRESH_ENABLED (pause refresh em deploy)
  • INTELLIGENCE_CONTACT_ATTRIBUTE_FORCE_VERSION (bump formula)

12. Operações

Como rodar refresh ad-hoc

# Forçar refresh de tudo (ignora hash)
curl -X POST '/api/intelligence/contact-attributes/refresh?force=true'

# Refresh limit 100
curl -X POST '/api/intelligence/contact-attributes/refresh?limit=100'

Como descobrir patterns

curl -X POST '/api/intelligence/run/causality'
# Verifica /admin/intelligence/patterns
# Marca confirmed/invalidated

Troubleshooting

Sintoma: ContactAttribute desatualizado

Diagnóstico:

SELECT MAX(refreshed_at), COUNT(*) FROM contact_attribute;

Fix: verificar Beat refresh_contact_attributes rodando (docker logs mandir-suite-beat).

Sintoma: Padrão "óbvio" / inventado

Causa: Claude inventando sem evidence forte. Fix: verificar confidence e sample_size. Se baixo, marcar invalidated na UI.

Sintoma: Custo LLM crescendo

Causa: crisis_detection ou causality rodando muito. Fix: ajustar Beat schedule; usar model_tier=fast (Haiku) onde possível.


13. Métricas e observabilidade

Logs estruturados-chave

Logger keyQuando emiteCampos
intelligence.refresh.startBeat refresh começoutenant_id, limit, force
intelligence.refresh.doneRefresh terminouupdated, skipped_no_change, history_rows, duration_ms
intelligence.causality.discoveredPattern novotenant_id, kind, confidence, sample_size
intelligence.crisis.detectedCrisis insightseverity, contact_id
intelligence.churn.flaggedChurn altocontact_id, score, factors

14. Limitações e débitos técnicos conhecidos

#ItemImpactoPlano
1L4 (truth) não persistidoMid — regras derivadas só em runtimeFase futura
2event_trigger sub-agent não implementadoLowBacklog
3Embeddings em knowledge_entryMid — busca só ILIKEpgvector planejado
4Crisis detection sem fallback heurísticoMid — se LLM falha, sem alertAdicionar regex fallback
5Patterns sem expiry automáticoLow — stale precisa marcar manualJob futuro
6brain_observation cross-tenant não publicaMid — analytics agregada perdidaImplementar mandir-events
7causality costMid — 1 call Claude por discovery cycleCache snapshots; reduce frequency
8History sem TTLLow — contact_attribute_history cresceArchive > 90d futuro
9Segments materialization full-refreshMid — sem diff incrementalFase 2
10chat_query tool use sem cache de resultsLow — cada chamada repete toolsCache LRU futuro

15. Histórico relevante

  • 2026-05-13 (alembic 0101, commit c8ca39e2) — Sprint 2.A "Contact OS": provenance (formula_version, inputs_hash, confidence), explainability nativa (churn/health/at_risk), 4 tags novas (dormant, new_lead, objection_open, no_show_chronic), refresh v2 cruzando objections+price_inquiries+appointments, skip-on-no-change, history append-only, tool Council read_contact_attribute_history, endpoint /health, UI estendida. Validado em 3758 contatos.
  • 2026-05-13 (alembic 0095+0096) — Sprint 1.B+1.C: L1 contact_attribute, L3 intelligence_pattern, L5 brain_observation, sub-agent causality, módulo business (knowledge+products+quotes+objections+appointments+brain_config), 13 tools novas no Council. Telas /admin/intelligence/{contact-attributes,patterns,observations}.
  • 2026-05-13 (alembic 0094, commits 09aada4 + a3729da) — Sprint 1.A: módulo attribution (campaign + touchpoint + crm_contact.attribution_*). Áudio inbound vira contexto do Council. emit_event em council.intervention, diary, whatsapp delivered/read/reaction. UTM resolution on-create.

Apêndices

A. Catálogo completo de behavior tags

TagQuando aplica
high_engagementeng_30d ≥ 60
low_engagementeng_30d ≤ 10
at_risk_customeré cliente + eng_30d ≤ 5
dormant> 60d sem interação
new_lead< 14d desde criação
repeat_buyer≥ 3 compras
price_sensitivequote_to_purchase_ratio < 0.34 com ≥ 3 quotes
objection_open≥ 1 objeção sem resolução
no_show_chronicno_show_rate ≥ 0.3 com ≥ 3 appointments

B. Glossário

  • L0-L5: camadas do Brain Observatory (cru → atributo → insight → padrão → verdade → observação).
  • Provenance: rastreabilidade da computação (formula_version + inputs_hash + confidence).
  • Skip-on-no-change: se inputs_hash igual ao anterior, atualiza só refreshed_at (não escreve atributos novamente).
  • Sub-agent: unidade de processamento dentro de Intelligence (summary, anomaly, causality, etc.).
  • Pattern: descoberta persistente (vs Insight, que é pontual).
  • Behavior tag: marcador comportamental aplicado ao contact_attribute (universalmente reconhecido por agentes/conselheiros).