Agentes IA
Status: 🟡 Em fluxo (modo rascunho —
auto_respond=falsepor default) Code: backend/app/modules/agents UI: frontend/src/app/(admin)/[slug]/admin/agents Última revisão deste doc: 2026-05-13 por Felipe + Claude Dependências fortes: whatsapp + instagram (canais), council (recebe ações via bridge), business (brand_voice, knowledge, products), tenant_router
1. Identidade
O que faz (uma frase)
Provisiona, configura e executa agentes de IA externos (Hari, Clara, Aurora, Chandra, Dunning, etc.) que conversam com o cliente final via WhatsApp (DM + grupos), Instagram (DM + comentários) e email — sempre dentro do tom da marca, com escopo limitado e auditoria completa.
Por que existe (negócio)
Mandir tem duas IAs separadas (memória [[camadas_ia]]):
- Conselho = gerência (fala com Felipe, vê tudo).
- Agentes = operação (falam com cliente, escopo restrito).
Sem agentes externos, atendimento depende de Felipe online 24/7. Com agentes, Mais Consciente:
- Responde lead em <30s mesmo às 3h da manhã.
- Faz onboarding consistente (sem variar tom).
- Cobra inadimplente sem desgaste pessoal.
- Modera comunidade WhatsApp respeitando regras.
- Responde comentários públicos no Instagram com prudência.
Agentes são "papéis" personalizáveis — manager, vendedor, agendamento, suporte, conteúdo, dunning, community_moderator, onboarding, student_mirror, low_ticket_sales — cada tenant escolhe quais ativar.
Por que existe (técnico)
A separação Agentes/Conselho não pode ser código compartilhado porque:
- Escopo distinto — Conselho vê billing + intelligence; Agente vê só catálogo + brand_voice + histórico do contato.
- Riscos diferentes — Conselho pode propor ações (humano aprova); Agente envia em tempo real (precisa kill switch + fallback humano explícito).
- Multi-instância — agentes ficam vinculados a
whatsapp_provider_accountouinstagram_accountespecíficos. - Modos de roteamento —
agents_instance_modecontrola se DM cai pro Manager (orquestrador), agente dedicado, ou pool de time. - Auto-rollback de prompt drift — proposta de mudança de persona pode ser revertida automaticamente se score cair (Fase 10x — sub-feature avançada).
Como módulo dedicado:
- Slugs estáveis (agentes são nomes, não funções — memória [[agentes-nomes-nao-funcoes]]).
- Templates pré-configurados (9 templates: manager + 8 especialistas).
- Brain isolado com tools read-only restritas (sem
propose_actionque o Conselho tem). - Telemetria por run + scoring multi-axis (knowledge, welcoming, conversion, compliance).
Status atual
- 6 agentes seeded em prod no Mais Consciente (manager, onboarding, dunning, student_mirror, community_moderator, low_ticket_sales) — memória [[agentes-preenchidos-2026-05-13]]. Todos com
auto_respond=false(modo rascunho). - Hub.7 deployado (2026-05-13) — DM IG → agente em prod (commit
4db4beb, alembic 0108). Memória [[hub-7-instagram-dm-agente-deployed]]. - Hub.8 deployado (2026-05-13) — Comments IG → agente em prod (commit
d6af3dd, alembic 0110). Memória [[hub-8-ig-comments-agente-deployed]]. - Hub.7.1 deployado (2026-05-13) — Token IG cifrado (envelope AES-256-GCM por tenant) — memória [[hub-7-1-ig-token-encrypted]].
Próxima mudança planejada: ativação gradual de auto_respond=true por agente após validação humana. Fase 10x (auto-rollback de drift) também pendente de validação real.
2. Cases de uso reais
Case 1: Hari atende lead em DM no WhatsApp
Situação: Lead novo manda mensagem pro número Hari.
Fluxo:
- Webhook Evolution →
record_inbound→whatsapp.message.receivedevent. agents.tasks._dispatch_workerenfileira → abreworker_session(tenant_id)(NullPool isolada — fix loop-mismatch).orchestration.resolve_agent_for_instance(provider_account_id)→ consultaagents_instance_mode:- Se
mode=orchestrator→ Manager (Hari neste tenant). - Se
mode=dedicated→ agente fixo. - Se
mode=team→ Manager + pool hint.
- Se
- Cria
agents_run(status=queued, channel=whatsapp, intent=dm_respond). brain.respond_dm(channel=whatsapp)monta system prompt (persona + brand_voice + forbidden_topics + business_hours + regras absolutas).- Loop tool-use (max 6 iterações):
read_products,read_contact_objections,read_brain_config. - Texto final →
whatsapp.service.send_message→ outbound persiste. agents_run.status=completed, output_payload com text + tool_calls + tokens.
Impacto: Resposta em <30s, citando produto correto, no tom da marca.
Case 2: Hub.7 — Agente responde DM no Instagram
Situação: Seguidor manda DM no @maisconsciente.
Fluxo:
- Webhook IG
field=messages→ persist eminstagram_message. instagram.tasks._dispatch_worker→orchestration.resolve_agent_for_instance(instagram_account.id).brain.respond_dm(channel=instagram)— diferenças vs WhatsApp:- Aviso no system: resposta concisa, sem markdown pesado.
- Max 1500 tokens output.
- Histórico: últimas 20 msgs do
instagram_message(mesmo schema role: inbound→user, outbound→assistant).
- Token IG decifrado on-demand (
instagram_account.access_token_encryptedenvelope AES-256-GCM) — memória [[hub-7-1-ig-token-encrypted]]. - Envia via Graph API
/me/messages.
Impacto: Atendimento IG escalado sem usuário ter que sair do app.
Case 3: Hub.8 — Agente responde comentário público no Instagram
Situação: Seguidor comenta "qual o preço?" num post.
Fluxo:
- Webhook IG
field=comments→service.persist_inbound_comment(idempotente viaexternal_idunique). instagram.tasks._dispatch_comment_worker→orchestration.resolve_agent_for_post(media_id).brain.respond_comment— diferente de respond_dm:- SEM tools (risco de vazar dado privado em resposta pública).
- Prompt de segurança extra: "1-2 frases, sem markdown, se sensível → convide pro DM".
- Histórico: 5 comments anteriores do mesmo post como contexto.
- Max 400 tokens.
- Reply via Graph API
/{comment_id}/replies. - Persiste outbound + status=
replied.
Impacto: Comments públicos respondidos sem risco de vazamento; tom sempre conservador.
Case 4: Conselho propõe ação que vai pro Agente Clara
Situação: Conselheiro Commercial detecta lead MQL com score alto sem follow-up em 7d. Propõe mensagem.
Fluxo:
council.brainchama toolpropose_action→ criacouncil_action(intent=send_message, target_agent_slug=clara, requires_approval=true, status=proposed).- Felipe aprova na UI →
service.dispatch_approved_action→bridge.dispatch_to_agent. - Bridge cria
agents_run(input_payload={target_phone, content, crm_contact_id})com linkbridge_run_id(lógico, sem FK). agents.router._execute_dispatch:_decide_order(agent, target_email, target_phone, prefer_channel)→ ordem de canais.- Tenta whatsapp:
whatsapp.service.send_message(to_phone, content, account_id). - Se falha → tenta email.
agents_run.status=completed+ outcome reportado procouncil_action.outcome.
Impacto: Conselho "delega" ao agente certo, com audit trail completo (proposed_at → approved_at → dispatched_at → completed_at).
3. Oportunidades de negócio
- Marketplace de templates de agentes: hoje 9 templates hardcoded. Marketplace (community-driven) por vertical (e-commerce, infoprodutor, consultor solo, terapeuta, etc.) com revenue share.
- Tier "Sociedade": despacho automático sem aprovação humana para intents low-risk (templates pré-aprovados com kill switch global). Premium pricing.
- Voz (ElevenLabs):
agents_agent.config.voice_enabledprevisto mas não implementado. Áudio IA no WhatsApp = diferencial pra comunidades. - Multi-tenant agency: consultor vende "Hari pré-configurado pra clínicas" como pacote. Whitelabel agentes.
- Agentes verticais como produto SaaS standalone: "Mandir Onboarding" (apenas o template onboarding + canais + analytics) por preço menor que o Suite completo.
- Compliance brasileira: agentes com LGPD-aware (auto opt-out, anonimização). Diferencial em saúde/educação/financeiro.
- Drift detection como serviço: Fase 10x (auto-rollback) é única — vender "garantia de qualidade de IA" pra empresas que treinam agentes.
Riscos comerciais:
- Meta pode mudar política de bots no IG (já aconteceu em 2024 com restrições a auto-replies).
- Anthropic pricing — cada DM custa ~$0.005-0.05 dependendo de tools.
- Risco reputacional: agente respondendo besteira pra cliente é dor pública.
4. Arquitetura interna
Diagrama do fluxo principal — DM WhatsApp
Webhook WhatsApp → record_inbound → whatsapp.message.received event
↓
agents.tasks._dispatch_worker [Celery — worker_session NullPool]
↓
orchestration.resolve_agent_for_instance(provider_account_id)
├─ instance_mode=orchestrator → Manager
├─ instance_mode=dedicated → Agent específico
└─ instance_mode=team → Manager + pool hint
↓
INSERT agents_run(status=queued, channel=whatsapp, intent=dm_respond)
↓
brain.respond_dm(channel=whatsapp)
├─ load brand_voice, forbidden_topics, business_hours
├─ load histórico (últimas 20 msgs)
├─ build system prompt (persona + brand + regras)
├─ tool-use loop (max 6 iter):
│ read_products, read_contact_objections,
│ read_brain_config, read_contact_attributes, etc.
└─ texto final
↓
whatsapp.service.send_message → outbound
↓
UPDATE agents_run(status=completed, output_payload)
Diagrama do fluxo — Comment Instagram (Hub.8)
Webhook IG field=comments → persist_inbound_comment (idempotente)
↓
agents.tasks._dispatch_comment_worker
↓
orchestration.resolve_agent_for_post(media_id)
↓
brain.respond_comment (SEM tools, prompt seguro, max 400 tokens)
↓
service.reply_to_comment → POST /{comment_id}/replies
↓
persist outbound + status=replied
Arquivos do módulo
| Arquivo | Propósito |
|---|---|
models.py | 4 tabelas: AgentsAgent, AgentsRun, AgentsWhatsappPresence, AgentsInstanceMode |
tasks.py | 3 tasks Celery: dispatch_run, detect_drift (diário), calibrate_meta_judge (semanal) |
brain.py | respond_dm (com tools), respond_comment (sem tools, seguro) |
orchestration.py | resolve_agent_for_instance (DM), _for_thread (grupo WA), _for_post (comment IG) |
router.py | dispatch (sync), enqueue_dispatch (async), _execute_dispatch (canal multi-tentativa) |
routes.py | ~15 endpoints REST /api/agents/* |
service.py | get_or_create_manager, create_from_template, create_custom_agent |
whatsapp_presence.py | Presença em grupos WA (espelho da estrutura council_whatsapp_presence) |
templates.py | 9 templates pré-configurados |
drift.py | Auto-rollback de propostas Haiku |
calibration.py | Meta-judge drift detection |
crm_tools.py | Tools CRM: advance_stage, set_category, add_note, schedule_next_action, mark_won/lost |
scoring.py | Ponderação multi-axis (knowledge, welcoming, conversion, compliance) |
db.py | get_db_agents seta agents.tenant_id + whatsapp.tenant_id GUCs |
Tasks Celery
| Task | Schedule | Idempotência | Retry |
|---|---|---|---|
agents.dispatch_run | On-demand (enqueue_dispatch) | SELECT ... FOR UPDATE SKIP LOCKED em agents_run | max 3, countdown 60s |
agents.detect_drift | Beat diário | proposal status check, cooldown_hours | max 2, countdown 300s |
agents.calibrate_meta_judge | Beat semanal | upsert por (tenant, agent, week) | max 2, countdown 300s |
Todas usam worker_session (NullPool) — memória [[celery-asyncpg-loop-mismatch]].
Os 9 Templates Pré-Configurados
| Slug | Nome | Sugerido para |
|---|---|---|
manager | Gerente | Sempre criado (orquestrador, único por tenant — is_orchestrator=true) |
seller | Vendedor | sells_*products, offers_subscription |
scheduler | Agendador | offers_scheduled_service |
support | Suporte | sells_digital, offers_subscription |
content | Entrega de Conteúdos | sells_digital_products |
dunning | Cobrança | offers_subscription |
community_moderator | Moderador de Comunidade | hosts_events, offers_subscription |
onboarding | Boas-Vindas | sells_digital, offers_subscription, offers_service |
student_mirror | Espelho do Aluno | sells_digital, offers_subscription (jornada de 28 dias) |
low_ticket_sales | Vendas Low-Ticket | sells_digital, offers_subscription |
Importante: slug é nome do agente, não função. Mesmo slug mantém identidade no tempo (memória [[agentes-nomes-nao-funcoes]]).
5. Tabelas + relacionamentos
4 tabelas, prefixo agents_*. Sem FK física cross-módulo.
agents_agent
Definição de persona IA + canais habilitados.
| Coluna chave | Tipo | Notas |
|---|---|---|
tenant_id | UUID | idx |
slug | VARCHAR(64) | UNIQUE per tenant — nome do agente (estável) |
name | VARCHAR(120) | "Gerente", "Vendedor", "Espelho do Aluno" |
role | VARCHAR(120) | "Orquestrador", "Faz cotação e fecha venda" |
persona_prompt | TEXT | Instrução de sistema do agente |
channels | JSONB | {"whatsapp": true, "email": true, "ig_dm": false, "ig_comment": false} |
is_active | BOOL | Kill switch individual |
is_orchestrator | BOOL | Único por tenant (Manager) |
template_kind | VARCHAR | manager / seller / custom / etc. |
provider_account_id | UUID | Vínculo opcional com instância WA (Evolution/Meta) |
deleted_at | TIMESTAMP(tz) | Soft-delete |
Constraint: UNIQUE(tenant_id, slug).
agents_run
Execução de tarefa (DM, email, comment, etc.).
| Coluna chave | Tipo | Notas |
|---|---|---|
tenant_id | UUID | idx |
agent_id | UUID | FK CASCADE → agents_agent.id |
channel | VARCHAR(32) | whatsapp / email / ig_dm / ig_comment |
target | VARCHAR(255) | email, phone ou user_id |
intent | VARCHAR(64) | dm_respond / comment_respond / qualify_lead / followup |
status | VARCHAR(16) | queued / running / completed / failed / escalated_to_human |
input_payload | JSONB | {content, target_email, target_phone, target_name, crm_contact_id, account_id} |
output_payload | JSONB | {text, message_id, tool_calls, tokens_in, tokens_out} |
error_message | TEXT | Se status=failed |
started_at / completed_at | TIMESTAMP(tz) | Timing |
Índices: (tenant, status).
agents_whatsapp_presence
Presença de agente em grupo WhatsApp (mention-based).
Espelha council_whatsapp_presence mas pra agentes. Mesma estrutura: group_external_id, agent_slug, phone_number_e164, mention_token (@clara, @suporte), proactivity (silent/passive/active), min_caller_role, context_window_days, max_context_tokens.
agents_instance_mode
Roteamento de DM por instância WhatsApp.
| Coluna chave | Tipo | Notas |
|---|---|---|
provider_account_id | UUID | Não-nulo — qual instância |
mode | VARCHAR(16) | orchestrator (default) / dedicated / team |
dedicated_agent_id | UUID | Se mode=dedicated |
agent_pool | JSONB | Lista de slugs se mode=team — ex: ["vendedor", "suporte"] |
Constraint: UNIQUE(tenant_id, provider_account_id).
Relacionamentos cross-módulo
| Direção | Outro módulo | Como | Por quê |
|---|---|---|---|
| ↗ Lê | whatsapp | whatsapp_provider_account.id em agents_agent.provider_account_id | Vincula agente a instância |
| ↗ Lê | business | read_brain_config, read_products, read_knowledge (tools brain) | Brand voice + catálogo |
| ↗ Lê | crm | read_contact_360, read_contact_objections (tools brain) | Contexto do contato |
| ↗ Lê | intelligence | read_contact_attributes, read_patterns (tools brain) | Sinais de churn/health |
| ↘ Escreve | whatsapp | service.send_message em _execute_dispatch | Envio de mensagem |
| ↘ Escreve | instagram | service.send_dm, service.reply_to_comment | Hub.7 + Hub.8 |
| ↘ Escreve | email | service.send_transactional | Multi-canal |
| ↗ Escreve | council (via bridge) | council_action.bridge_run_id = agents_run.id (lógico) | Despacho aprovado pelo Conselho |
6. API / Endpoints
~15 endpoints sob /api/agents/*.
| Método | Rota | Auth | O que faz |
|---|---|---|---|
| GET | /_whoami | session | Debug: tenant_id + agent count |
| GET | /agents | session | Lista (filtro: archived) |
| POST | /agents | admin | Cria custom (do zero) |
| POST | /from-template | admin | Cria a partir de template |
| GET | /templates | session | Lista 9 templates + suggested_for capabilities |
| POST | /ensure-manager | admin | Cria/retorna Manager (idempotente) |
| POST | /dispatch | admin | Despacha mensagem (sync ou async) — principal |
| GET | /runs | session | Lista runs (filtros: agent, status) |
| GET | /ai-settings | session | Lê settings_identity.ai_auto_reply_enabled |
| PATCH | /ai-settings | admin | Modifica kill switch global |
| GET | /instance-modes | session | Lista modos por instância |
| PUT | /instance-modes | admin | Upsert (orchestrator/dedicated/team) |
| GET | /{slug}/account | session | Lê account binding |
| PATCH | /{slug}/account | admin | Altera vínculo de instância |
| Sub-rotas | /{slug}/{10x,policy,avaliacao,custo} | admin | Fase advanced (proposals, drift policy, scoring, cost) |
7. Brain — raciocínio LLM
respond_dm(db, tenant_id, agent, thread_id, contact_phone, channel, pool_hint, target_override)
Modelo: Claude Opus default (configurável via tenant_brain_config.default_council_model).
Tools disponíveis (12 read-only, subset do Conselho):
read_contact_attributes,read_attribution,read_contact_timelineread_patterns,read_knowledge,search_knowledgeread_products,read_contact_price_inquiries,read_contact_objectionsread_contact_appointments,read_brain_config,read_contact_360
Loop tool-use (MAX_TURNS=6):
- Iter 0: monta system prompt + histórico + user_message → call LLM.
- Stop_reason=tool_use → executa via
council_tools.execute_toolem paralelo. - Adiciona tool_results, próxima iter.
- Stop_reason=end_turn → texto final.
System prompt (_build_system):
agent.persona_prompt(base).-
## Voz da marca\n{brand_voice_md}(detenant_brain_config).
-
## NÃO fale sobre\n{forbidden_topics_md}.
-
## Horário de atendimento\n{business_hours JSON}.
- (se
pool_hint) +## Modo time\nVocê é o Gerente, pode mencionar: .... -
## Regras absolutas:
- Responda em pt-BR.
- Nunca invente preço, política ou data — consulte ferramentas.
- Se não sabe → "vou checar e acionar humano".
- Resposta concisa (1-3 parágrafos WA, 1-2 IG).
Max output: 1500 tokens (DM), 400 tokens (comment).
respond_comment(db, tenant_id, agent, comment_id, pool_hint)
Diferenças vs respond_dm:
- SEM tools — risco de vazamento de dado privado em resposta pública.
- Prompt segurança extra: "Nunca cite dados de outros clientes, preços não publicados, estratégia interna. Se pergunta exige privacidade → convide pro DM."
- 1-2 frases, sem markdown, sem emojis (exceto se brand_voice autorizar).
- Sem iterações — 1 turn só.
- Histórico: 5 comments anteriores do mesmo
media_idcomo contexto. - Empty string se não puder responder com segurança (não responde).
8. Eventos emitidos / consumidos
Consome
whatsapp.message.received→_dispatch_workerenfileira run.instagram.message.received(Hub.7) → idem.instagram.comment.received(Hub.8) →_dispatch_comment_worker.council.action.dispatched(via bridge) →_execute_dispatch.
Emite (planejado, ainda log estruturado)
agents.dispatch.startedagents.dispatch.completedagents.dispatch.failedagents.drift.detectedagents.drift.rolled_back
9. Configuração
Env vars
| Var | Propósito |
|---|---|
ANTHROPIC_API_KEY | Claude (compartilhado com council) |
MANDIR_CRYPTO_MASTER_KEY | Decryption do instagram_account.access_token_encrypted |
settings_identity flags
| Coluna | Default | Propósito |
|---|---|---|
ai_auto_reply_enabled | true | Kill switch global dos Agentes (não afeta Conselho — kill switches separados, mig 0111) |
Kill switches em cascata
- Global:
settings_identity.ai_auto_reply_enabled = false. - Por agente:
agents_agent.is_active = false. - Por presença em grupo:
agents_whatsapp_presence.is_active = false. - Por instância:
agents_instance_mode.mode(defaultorchestrator; sem agente = fallback). - Por thread WA:
whatsapp_thread.agent_paused_at NOT NULL. - Por conta IG:
instagram_account.agent_paused_at NOT NULL.
Config por agente (agents_agent.config JSONB — não cravado, planejado)
{
"tone": "direto" | "reflexivo" | "analítico",
"auto_respond": True | False, # quando false, IA gera mas NÃO envia
"model_tier": "fast" | "default" | "deep", # Haiku | Sonnet | Opus
"voice_enabled": True | False, # ElevenLabs (TBD)
"max_tokens_per_turn": 1500,
"schedule": {"weekdays": [1,2,3,4,5], "hours": [8, 22]},
}
10. Operações
Como criar agente novo
Via UI: /admin/agents/new → escolhe template → editar persona → salvar (cria agents_agent).
Via API: POST /api/agents/from-template {template_kind, slug, name?, customizations?}.
Como ativar despacho automático
- Verificar
settings_identity.ai_auto_reply_enabled = true(kill switch global). agents_agent.is_active = true.agents_agent.config.auto_respond = true(quando ainda for false, agente gera mas não envia).- Para grupo WA: criar
agents_whatsapp_presence(is_active=true, mention_token="@<slug>", min_caller_role). - Para DM: configurar
agents_instance_mode(mode=dedicated, dedicated_agent_id=<id>)ou deixarorchestrator(Manager decide).
Troubleshooting
Sintoma: Agente não responde DM
Diagnóstico em ordem:
settings_identity.ai_auto_reply_enabledestá true?agents_instance_modeexiste pra essa instância? (sem registro = fallback Manager).- Manager está ativo (
agents_agent.is_active)? - Verificar log:
docker logs mandir-suite-worker | grep agents.dispatch. - Loop-mismatch? (ver memória [[celery-asyncpg-loop-mismatch]] — se sim, conferir
worker_session).
Sintoma: Agente envia mensagem mas erro no IG
Causa: token expirado ou decryption falhou.
Fix: UI Hub.5 (Instagram) reconectar conta; verificar instagram_account.access_token_encrypted está populado.
Sintoma: respond_comment retorna empty string
Causa: Brain decidiu que pergunta exige privacidade. Comportamento esperado.
Verificação: Log agents.dispatch.skipped com reason="privacy_concern".
11. Métricas e observabilidade
Logs estruturados-chave
| Logger key | Quando emite | Campos |
|---|---|---|
agents.dispatch.start | run criada | tenant_id, agent_slug, channel, intent |
agents.dispatch.completed | run terminou OK | run_id, tokens_in, tokens_out, tool_calls_count |
agents.dispatch.failed | run falhou | run_id, error, error_class |
agents.brain.tool_call | tool invocado | agent_slug, tool_name, iter |
agents.drift.detected | proposta com drift | agent_slug, proposal_id, score_delta |
agents.drift.rolled_back | proposta revertida | agent_slug, proposal_id |
agents.calibration.discrepancy_high | meta-judge drift | agent_slug, discrepancy_rate |
Dashboards planejados
/admin/agents/{slug}/avaliacao— outcomes (score_knowledge, score_conversion, etc.) + drift/admin/agents/{slug}/custo— tokens × $/token, cost por mês
12. Limitações e débitos técnicos conhecidos
| # | Item | Impacto | Plano |
|---|---|---|---|
| 1 | auto_respond=false por default | High — agentes geram mas não enviam | Validação humana antes de ligar; Felipe ativa um por vez |
| 2 | Sem stateful memory entre runs | Mid — cada DM é stateless do ponto de vista do agente (contexto via thread histórico) | Fase futura: agents_run.context_carry_over |
| 3 | MAX_TURNS=6 | Low — defesa contra loops | OK |
| 4 | Voice (ElevenLabs) não implementado | Mid — voice_enabled previsto mas TBD | Roadmap |
| 5 | Sem fallback humano automático | Mid — se brain falha, run vira failed mas operador não é notificado | TODO: notification + assignment |
| 6 | Drift detection (Fase 10x) precisa validação | Mid — auto-rollback nunca foi acionado em prod real | Aguardar runs suficientes |
| 7 | Sem cost cap por agente | Mid — agente caro pode estourar budget | TODO: agents_agent.config.daily_budget_usd |
| 8 | agents_instance_mode.mode=team sem implementação completa | Low — pool hint passa pro Manager mas roteamento ativo TBD | Fase 2 |
| 9 | Sem A/B testing de personas | Low — proposta de melhoria existe (Fase 10x) mas só rollback | Roadmap |
| 10 | Webhook IG field=messages não testado em escala | Mid — Hub.7 deployado mas pouco tráfego real | Aguardar uso |
13. Histórico relevante
- 2026-05-13 (commit
8b7107e, mig0111_council_kill) — Kill switch dos Agentes (ai_auto_reply_enabled) separado do Conselho (council_enabled). Memória [[conselho-e-agentes-kill-switches-separados]]. - 2026-05-13 (commit
d6af3dd, mig0110_ig_comments) — Hub.8 deployado: comments IG → agente. - 2026-05-13 (commit
7e5a9c, mig0109_ig_token_envelope) — Hub.7.1: token IG cifrado em envelope AES-256-GCM. 3 contas backfilladas. - 2026-05-13 (commit
4db4beb, mig0108) — Hub.7 deployado: DM IG → agente. - 2026-05-13 — 6 agentes seeded em prod no Mais Consciente (modo rascunho).
- 2026-05-13 (commit
b536768) —_dispatch_workermigrado praworker_session(NullPool ad-hoc) — fix loop-mismatch.
Apêndices
A. Diferenças respond_dm vs respond_comment
| Aspecto | respond_dm | respond_comment |
|---|---|---|
| Tools | 12 read-only | Nenhuma |
| Iter max | 6 | 1 |
| Output max | 1500 tokens | 400 tokens |
| Markdown | Permitido | Proibido (IG não renderiza) |
| Privacidade | OK (DM privada) | Crítica (post público) |
| Histórico | Últimas 20 msgs da thread | 5 comments anteriores do post |
| Fallback | Texto curto pedindo dado | Empty string (não responde) |
B. Glossário
- Manager: o Gerente. Único por tenant (
is_orchestrator=true). Orquestra DMs em modoorchestratorouteam. - Pool hint: quando
mode=team, lista de slugs no system prompt do Manager pra ele "delegar mentalmente". - Drift: score de outcomes caindo após mudança de prompt.
- Auto-rollback: Fase 10x — se drift detectado dentro de janela, persona_prompt volta ao valor anterior.
- Meta-judge: Haiku que rotula outcomes (buying_signal, score_conversion). Calibração semanal compara com Sonnet.
- Bridge: interface contratual Conselho ↔ Agentes (ADR 0015).
council_action.bridge_run_id = agents_run.id(lógico, sem FK). - Instance mode:
orchestrator(Manager decide) /dedicated(1 agente fixo) /team(Manager + pool).