Pular para conteúdo

SENTIMENT - Análise de Sentimento

O que é este Node?

O SENTIMENT é o node responsável por analisar o sentimento emocional de textos automaticamente, classificando mensagens como positivas, negativas ou neutras com nível de confiança.

Por que este Node existe?

Identificar o sentimento do cliente é crucial para oferecer atendimento adequado. O SENTIMENT existe para:

  1. Detectar insatisfação: Identificar clientes frustrados antes que o problema escale
  2. Priorizar atendimento: Redirecionar casos negativos para atendimento humano imediato
  3. Medir satisfação: Quantificar o sentimento dos clientes em tempo real
  4. Personalizar respostas: Adaptar tom da conversa baseado no humor do cliente
  5. Análise de feedback: Processar reviews, comentários e avaliações automaticamente

Como funciona internamente?

Quando o SENTIMENT é executado, o sistema:

  1. Recebe o texto a ser analisado (de variável ou parâmetro direto)
  2. Processa o conteúdo buscando palavras e padrões indicadores de sentimento
  3. Classifica o sentimento em três categorias: positive, negative ou neutral
  4. Calcula confiança (0 a 1) baseado na quantidade de indicadores encontrados
  5. Gera score numérico (positivo = +0.6 a +1.0, negativo = -0.6 a -1.0, neutro = 0)
  6. Retorna resultado com sentiment, confidence e score para uso em decisões

Código interno (ai-processing-executor.service.ts:123-164):

private async executeSentiment(parameters: any, context: any): Promise<any> {
  const { text, language } = parameters;

  this.logger.log(`😊 SENTIMENT - Analyzing sentiment for text: "${text?.substring(0, 50)}..."`);

  if (!text) {
    throw new Error('Text is required for sentiment analysis');
  }

  // Simple sentiment analysis simulation
  const positiveWords = ['bom', 'ótimo', 'excelente', 'feliz', 'amor', 'good', 'great', 'excellent', 'happy', 'love'];
  const negativeWords = ['ruim', 'péssimo', 'triste', 'ódio', 'problema', 'bad', 'terrible', 'sad', 'hate', 'problem'];

  const lowerText = text.toLowerCase();
  const positiveCount = positiveWords.filter(word => lowerText.includes(word)).length;
  const negativeCount = negativeWords.filter(word => lowerText.includes(word)).length;

  let sentiment, confidence;
  if (positiveCount > negativeCount) {
    sentiment = 'positive';
    confidence = Math.min(0.9, 0.6 + (positiveCount - negativeCount) * 0.1);
  } else if (negativeCount > positiveCount) {
    sentiment = 'negative';
    confidence = Math.min(0.9, 0.6 + (negativeCount - positiveCount) * 0.1);
  } else {
    sentiment = 'neutral';
    confidence = 0.5;
  }

  return {
    success: true,
    action: 'sentiment_analyzed',
    text: text,
    language: language || 'auto',
    result: {
      sentiment: sentiment,
      confidence: confidence,
      score: sentiment === 'positive' ? confidence : sentiment === 'negative' ? -confidence : 0
    },
    timestamp: new Date().toISOString()
  };
}

Quando você DEVE usar este Node?

Use SENTIMENT sempre que precisar entender a emoção do cliente:

Casos de uso

  1. Triagem de suporte: "Identificar clientes frustrados e priorizar atendimento"
  2. Análise de reviews: "Classificar avaliações de produtos automaticamente"
  3. Feedback pós-compra: "Medir satisfação após entrega"
  4. Roteamento inteligente: "Enviar clientes insatisfeitos para supervisor"
  5. Pesquisa de opinião: "Analisar respostas abertas em pesquisas"
  6. Monitoramento de redes sociais: "Detectar menções negativas da marca"
  7. Quality assurance: "Avaliar qualidade do atendimento por sentimento"

Quando NÃO usar SENTIMENT

  • Análise de dados estruturados: Use VALIDATOR para validação de dados
  • Extração de informações: Use ENTITY para extrair emails, telefones, etc.
  • Classificação customizada: Use CONDITION com regras específicas

Parâmetros Detalhados

text (string, obrigatório)

O que é: O texto que será analisado para identificar o sentimento. Pode ser uma variável (ex: {{mensagem_cliente}}) ou texto fixo para teste.

Flow completo para testar:

{
  "name": "Teste SENTIMENT - Text Fixo",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "sentiment_1",
      "type": "sentiment",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Analisar Sentimento Positivo",
        "parameters": {
          "text": "Adorei o produto! Qualidade excelente e entrega rápida. Muito feliz com a compra!"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Mostrar Resultado",
        "parameters": {
          "message": "Sentimento: {{sentiment_result.sentiment}}\nConfiança: {{sentiment_result.confidence}}\nScore: {{sentiment_result.score}}"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 700, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "sentiment_1" },
    { "source": "sentiment_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Teste: Execute e veja resultado "positive" com alta confiança!

text com variável (string, obrigatório)

O que é: Analisar texto capturado do usuário usando variáveis.

Flow completo para testar:

{
  "name": "Teste SENTIMENT - Text com Variável",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "input_1",
      "type": "input",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Pedir Feedback",
        "parameters": {
          "message": "Como foi sua experiência com nosso produto?",
          "variable": "feedback_cliente"
        }
      }
    },
    {
      "id": "sentiment_1",
      "type": "sentiment",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Analisar Feedback",
        "parameters": {
          "text": "{{feedback_cliente}}"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Agradecer",
        "parameters": {
          "message": "Obrigado pelo feedback! Detectamos sentimento: {{sentiment_result.sentiment}}"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 900, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "input_1" },
    { "source": "input_1", "target": "sentiment_1" },
    { "source": "sentiment_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Teste: Digite "Péssimo atendimento, muito insatisfeito!" e veja resultado "negative".

language (string, opcional)

O que é: Idioma do texto a ser analisado. Melhora a precisão ao especificar o idioma correto.

Padrão: "auto" (detecção automática)

Valores aceitos: "pt-BR", "en", "es", "auto"

Flow completo para testar:

{
  "name": "Teste SENTIMENT - Language PT-BR",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "sentiment_1",
      "type": "sentiment",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Analisar em Português",
        "parameters": {
          "text": "Que produto maravilhoso! Superou minhas expectativas.",
          "language": "pt-BR"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Mostrar",
        "parameters": {
          "message": "Idioma: {{sentiment_result.language}}\nSentimento: {{sentiment_result.sentiment}}"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 700, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "sentiment_1" },
    { "source": "sentiment_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Teste: Veja análise otimizada para português brasileiro!

Parâmetros

Campo Tipo Obrigatório Descrição
text string Sim Texto a ser analisado (aceita variáveis como {{var}})
language string Não Idioma do texto: pt-BR, en, es, auto (padrão: auto)

Exemplo 1: Triagem de Atendimento por Sentimento

Objetivo: Redirecionar clientes insatisfeitos para atendimento humano prioritário

JSON para Importar

{
  "name": "SENTIMENT - Triagem Inteligente",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Saudação",
        "parameters": {
          "message": "Olá! Estou aqui para ajudar. Como posso auxiliá-lo hoje?"
        }
      }
    },
    {
      "id": "input_1",
      "type": "input",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Capturar Problema",
        "parameters": {
          "message": "Por favor, descreva seu problema ou dúvida:",
          "variable": "descricao_problema"
        }
      }
    },
    {
      "id": "sentiment_1",
      "type": "sentiment",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Analisar Sentimento",
        "parameters": {
          "text": "{{descricao_problema}}",
          "language": "pt-BR"
        }
      }
    },
    {
      "id": "condition_1",
      "type": "condition",
      "position": { "x": 900, "y": 100 },
      "data": {
        "label": "Cliente Insatisfeito?",
        "parameters": {
          "conditions": [
            {
              "variable": "sentiment_result.sentiment",
              "operator": "equals",
              "value": "negative"
            }
          ],
          "logic": "AND"
        }
      }
    },
    {
      "id": "message_2",
      "type": "message",
      "position": { "x": 1100, "y": 50 },
      "data": {
        "label": "Priorizar Atendimento",
        "parameters": {
          "message": "Entendo sua frustração. Vou conectá-lo com um especialista agora! Por favor aguarde."
        }
      }
    },
    {
      "id": "message_3",
      "type": "message",
      "position": { "x": 1100, "y": 150 },
      "data": {
        "label": "Atendimento Normal",
        "parameters": {
          "message": "Obrigado! Vou analisar sua solicitação e retorno em breve."
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1300, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "message_1" },
    { "source": "message_1", "target": "input_1" },
    { "source": "input_1", "target": "sentiment_1" },
    { "source": "sentiment_1", "target": "condition_1" },
    { "source": "condition_1", "target": "message_2", "label": "true" },
    { "source": "condition_1", "target": "message_3", "label": "false" },
    { "source": "message_2", "target": "end_1" },
    { "source": "message_3", "target": "end_1" }
  ]
}

Saída esperada:

Sistema: Olá! Estou aqui para ajudar. Como posso auxiliá-lo hoje?
Sistema: Por favor, descreva seu problema ou dúvida:
Usuário: Que absurdo! Meu pedido está atrasado há 2 semanas e ninguém responde!
Sistema: Entendo sua frustração. Vou conectá-lo com um especialista agora! Por favor aguarde.

Exemplo 2: Classificação de Reviews de Produto

Objetivo: Analisar avaliações de produtos e separar por sentimento

JSON para Importar

{
  "name": "SENTIMENT - Análise de Reviews",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Solicitar Review",
        "parameters": {
          "message": "Obrigado pela sua compra! Gostaríamos de saber sua opinião sobre o produto."
        }
      }
    },
    {
      "id": "input_1",
      "type": "input",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Capturar Avaliação",
        "parameters": {
          "message": "Como foi sua experiência com o produto?",
          "variable": "avaliacao_produto"
        }
      }
    },
    {
      "id": "sentiment_1",
      "type": "sentiment",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Analisar Review",
        "parameters": {
          "text": "{{avaliacao_produto}}",
          "language": "pt-BR"
        }
      }
    },
    {
      "id": "switch_1",
      "type": "switch",
      "position": { "x": 900, "y": 100 },
      "data": {
        "label": "Classificar Sentimento",
        "parameters": {
          "variable": "sentiment_result.sentiment",
          "cases": [
            { "value": "positive", "target": "message_positive" },
            { "value": "negative", "target": "message_negative" },
            { "value": "neutral", "target": "message_neutral" }
          ]
        }
      }
    },
    {
      "id": "message_positive",
      "type": "message",
      "position": { "x": 1100, "y": 50 },
      "data": {
        "label": "Resposta Positiva",
        "parameters": {
          "message": "Que ótimo saber que você amou! Obrigado pela avaliação positiva."
        }
      }
    },
    {
      "id": "message_negative",
      "type": "message",
      "position": { "x": 1100, "y": 150 },
      "data": {
        "label": "Resposta Negativa",
        "parameters": {
          "message": "Lamentamos sua insatisfação. Nossa equipe entrará em contato para resolver."
        }
      }
    },
    {
      "id": "message_neutral",
      "type": "message",
      "position": { "x": 1100, "y": 250 },
      "data": {
        "label": "Resposta Neutra",
        "parameters": {
          "message": "Obrigado pelo feedback! Como podemos melhorar sua experiência?"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1300, "y": 150 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "message_1" },
    { "source": "message_1", "target": "input_1" },
    { "source": "input_1", "target": "sentiment_1" },
    { "source": "sentiment_1", "target": "switch_1" },
    { "source": "switch_1", "target": "message_positive" },
    { "source": "switch_1", "target": "message_negative" },
    { "source": "switch_1", "target": "message_neutral" },
    { "source": "message_positive", "target": "end_1" },
    { "source": "message_negative", "target": "end_1" },
    { "source": "message_neutral", "target": "end_1" }
  ]
}

Saída esperada:

Sistema: Obrigado pela sua compra! Gostaríamos de saber sua opinião sobre o produto.
Sistema: Como foi sua experiência com o produto?
Usuário: Produto excelente! Qualidade ótima e chegou rápido. Muito feliz!
Sistema: Que ótimo saber que você amou! Obrigado pela avaliação positiva.

Exemplo 3: Roteamento de Tickets de Suporte

Objetivo: Rotear tickets baseado no sentimento para filas apropriadas (urgente vs normal)

JSON para Importar

{
  "name": "SENTIMENT - Roteamento de Tickets",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Boas-vindas",
        "parameters": {
          "message": "Bem-vindo ao suporte! Vamos abrir um ticket para você."
        }
      }
    },
    {
      "id": "input_1",
      "type": "input",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Assunto",
        "parameters": {
          "message": "Qual o assunto do seu chamado?",
          "variable": "assunto"
        }
      }
    },
    {
      "id": "input_2",
      "type": "input",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Descrição",
        "parameters": {
          "message": "Por favor, descreva o problema em detalhes:",
          "variable": "descricao"
        }
      }
    },
    {
      "id": "sentiment_1",
      "type": "sentiment",
      "position": { "x": 900, "y": 100 },
      "data": {
        "label": "Analisar Urgência",
        "parameters": {
          "text": "{{descricao}}",
          "language": "pt-BR"
        }
      }
    },
    {
      "id": "condition_1",
      "type": "condition",
      "position": { "x": 1100, "y": 100 },
      "data": {
        "label": "É Urgente?",
        "parameters": {
          "conditions": [
            {
              "variable": "sentiment_result.sentiment",
              "operator": "equals",
              "value": "negative"
            },
            {
              "variable": "sentiment_result.confidence",
              "operator": "greater_than",
              "value": 0.7
            }
          ],
          "logic": "AND"
        }
      }
    },
    {
      "id": "variable_1",
      "type": "variable",
      "position": { "x": 1300, "y": 50 },
      "data": {
        "label": "Fila Urgente",
        "parameters": {
          "variable": "fila_atendimento",
          "value": "URGENTE - Prioridade Alta"
        }
      }
    },
    {
      "id": "variable_2",
      "type": "variable",
      "position": { "x": 1300, "y": 150 },
      "data": {
        "label": "Fila Normal",
        "parameters": {
          "variable": "fila_atendimento",
          "value": "NORMAL - Prioridade Padrão"
        }
      }
    },
    {
      "id": "message_2",
      "type": "message",
      "position": { "x": 1500, "y": 100 },
      "data": {
        "label": "Confirmação Ticket",
        "parameters": {
          "message": "Ticket #12345 criado!\n\nAssunto: {{assunto}}\nFila: {{fila_atendimento}}\nSentimento detectado: {{sentiment_result.sentiment}}\n\nAguarde contato da equipe."
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1700, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "message_1" },
    { "source": "message_1", "target": "input_1" },
    { "source": "input_1", "target": "input_2" },
    { "source": "input_2", "target": "sentiment_1" },
    { "source": "sentiment_1", "target": "condition_1" },
    { "source": "condition_1", "target": "variable_1", "label": "true" },
    { "source": "condition_1", "target": "variable_2", "label": "false" },
    { "source": "variable_1", "target": "message_2" },
    { "source": "variable_2", "target": "message_2" },
    { "source": "message_2", "target": "end_1" }
  ]
}

Saída esperada:

Sistema: Bem-vindo ao suporte! Vamos abrir um ticket para você.
Sistema: Qual o assunto do seu chamado?
Usuário: Problema com cobrança duplicada
Sistema: Por favor, descreva o problema em detalhes:
Usuário: Fui cobrado duas vezes pelo mesmo pedido! Isso é um absurdo, preciso de reembolso urgente!
Sistema: Ticket #12345 criado!

Assunto: Problema com cobrança duplicada
Fila: URGENTE - Prioridade Alta
Sentimento detectado: negative

Aguarde contato da equipe.

Resposta do Node

{
  "success": true,
  "action": "sentiment_analyzed",
  "text": "Adorei o produto! Qualidade excelente.",
  "language": "pt-BR",
  "result": {
    "sentiment": "positive",
    "confidence": 0.8,
    "score": 0.8
  },
  "timestamp": "2025-01-15T10:30:00.000Z"
}

Valores de Sentiment

Sentiment Significado Score Range
positive Sentimento positivo/satisfação +0.6 a +1.0
negative Sentimento negativo/insatisfação -0.6 a -1.0
neutral Sentimento neutro/sem emoção clara 0

Níveis de Confiança

Confidence Interpretação
0.9 - 1.0 Altíssima confiança - sentimento muito evidente
0.7 - 0.89 Alta confiança - sentimento claro
0.6 - 0.69 Confiança média - sentimento presente
0.5 Baixa confiança - sentimento neutro ou ambíguo

Boas Práticas

SIM:

  • Sempre combine SENTIMENT com CONDITION para decisões
  • Use alta confidence (>0.7) para ações críticas (escalação, prioridade)
  • Especifique language quando souber o idioma do texto
  • Analise sentiment logo após capturar feedback do cliente
  • Salve resultado em variáveis para uso posterior

NÃO:

  • Não tome decisões críticas apenas em sentiment com baixa confiança (<0.6)
  • Não analise textos muito curtos (< 10 caracteres) - pouco conteúdo
  • Não use SENTIMENT para validação de formato de dados
  • Não ignore o campo confidence ao tomar decisões

Dicas

💡 Priorização inteligente: Combine sentiment === "negative" AND confidence > 0.7 para identificar casos realmente urgentes

💡 Análise de reviews: Use SENTIMENT + SWITCH para criar respostas personalizadas por sentimento

💡 Medir satisfação: Conte quantos clientes são positive vs negative para KPIs

💡 Detecção precoce: Analise primeiro contato do cliente para identificar insatisfação antes que escale

💡 Multi-idioma: O sistema detecta palavras em PT-BR e EN automaticamente quando language="auto"

💡 Textos longos: Quanto mais texto, melhor a precisão da análise

Palavras Indicadoras

Positivas (PT-BR)

bom, ótimo, excelente, feliz, amor, perfeito, maravilhoso, satisfeito, recomendo, adorei

Negativas (PT-BR)

ruim, péssimo, triste, ódio, problema, horrível, insatisfeito, nunca mais, decepcionado, frustrado

Positivas (EN)

good, great, excellent, happy, love, perfect, wonderful, satisfied, recommend, amazing

Negativas (EN)

bad, terrible, sad, hate, problem, horrible, disappointed, never again, frustrated, awful

Próximo Node

ENTITY - Extrair entidades (email, telefone, CPF, nomes) → AI - Processamento avançado com IA → CONDITION - Decisões baseadas em sentimento → SWITCH - Roteamento por tipo de sentimento