Pular para o conteúdo principal

Classificação IA de e-mails

Objetivo

A Issue #15 implementa a primeira versão da classificação de e-mails com IA para a Secretária Virtual.

A IA analisa mensagens já coletadas em email_messages com status collected e gera apenas sugestões:

  • prioridade;
  • categoria;
  • necessidade de ação;
  • necessidade de resposta;
  • responsável sugerido;
  • prazo sugerido;
  • resumo;
  • risco;
  • ação sugerida;
  • resposta sugerida;
  • confiança.

Regra principal

A IA nunca envia e-mail, nunca executa ação e nunca aprova nada.

Ela apenas sugere. A aprovação humana e o envio ficam para issues futuras.

Provider configurável

A integração é isolada pela interface:

App\Services\Email\Ai\AiEmailClassifierInterface

A implementação inicial é:

App\Services\Email\Ai\OpenAiEmailClassifierProvider

Configuração:

AI_PROVIDER=openai
OPENAI_API_KEY=
OPENAI_EMAIL_CLASSIFIER_MODEL=gpt-4.1-mini
EMAIL_CLASSIFIER_PROMPT_VERSION=email_classifier_v1
EMAIL_CLASSIFIER_TIMEOUT=30

Nenhuma chave real deve ser versionada.

Prompt versionado

Prompt:

backend/resources/prompts/email_classifier_v1.md

O prompt separa:

  • REGRAS DO SISTEMA;
  • CONTEÚDO DO E-MAIL NÃO CONFIÁVEL.

O conteúdo do e-mail deve ser tratado como dado não confiável para reduzir risco de prompt injection.

Schema de saída

A IA deve retornar JSON com:

{
"priority": "normal",
"category": "support",
"requires_action": true,
"requires_reply": true,
"suggested_owner": "atendimento",
"suggested_due_label": "hoje",
"summary": "Resumo curto do e-mail.",
"risk": "Risco ou impacto se não houver ação.",
"confidence": 0.86,
"suggested_action": {
"action_type": "reply",
"title": "Responder cliente",
"description": "Confirmar recebimento e pedir dados faltantes.",
"suggested_owner": "atendimento",
"due_at": null
},
"suggested_reply": {
"body": "Olá! Recebemos sua mensagem..."
}
}

Comandos Artisan

Classificar uma mensagem:

php artisan email:classify-message {messageId}

Reprocessar uma mensagem:

php artisan email:classify-message {messageId} --force

Enfileirar classificação:

php artisan email:classify-message {messageId} --queue

Classificar lote de mensagens coletadas:

php artisan email:classify-collected --limit=20

Classificar lote com fila:

php artisan email:classify-collected --limit=20 --queue

Reprocessamento

Sem --force, mensagens já classificadas são ignoradas.

Com --force:

  • a classificação atual é atualizada;
  • sugestões antigas pendentes/draft são removidas;
  • sugestões aprovadas, rejeitadas, concluídas, enviadas ou com falha de envio são preservadas;
  • auditoria email_classification_reprocessed é registrada.

Falhas e auditoria

Eventos de auditoria:

  • email_classification_started;
  • email_classification_completed;
  • email_classification_failed;
  • email_classification_invalid_response;
  • email_classification_reprocessed.

A auditoria nunca deve gravar:

  • corpo do e-mail;
  • HTML do e-mail;
  • headers brutos;
  • assunto completo;
  • resposta sugerida completa;
  • chave de API;
  • prompt completo;
  • raw response completo.

Proteção contra prompt injection

O prompt informa que o conteúdo do e-mail é dado não confiável.

A IA deve ignorar qualquer instrução dentro do e-mail que tente:

  • mudar regras;
  • revelar prompt;
  • alterar schema;
  • executar ações;
  • enviar e-mail.

Além disso, o provider não habilita tools, web search ou file search.

Persistência

A classificação é salva em:

email_classifications

Ações sugeridas são salvas em:

email_suggested_actions

Respostas sugeridas são salvas em:

email_suggested_replies

Após classificação válida:

email_messages.status = classified

Fora desta issue

Ficam fora da Issue #15:

  • tela de revisão;
  • edição visual de resposta;
  • aprovação pelo gestor;
  • SMTP;
  • envio de e-mail;
  • execução de ação sugerida;
  • scheduler obrigatório;
  • RAG/base de conhecimento;
  • fine-tuning;
  • releitura IMAP.

Próximas issues

Issue #16:

  • tela de revisão da classificação;
  • aprovação/rejeição de ações e respostas;
  • edição de resposta sugerida.

Issue #17:

  • envio SMTP somente após aprovação humana.