Repository navigation
Arquitetura Chatbot
Esta documentação descreve a arquitetura de um chatbot de Processamento de Linguagem Natural (PLN) projetado para traduzir perguntas de usuários em consultas SQL dinâmicas e seguras. A arquitetura é modular, promovendo a separação de responsabilidades em três camadas distintas:
-
Chatbot(Orquestração): A classe de fachada que gerencia o fluxo de ponta a ponta. Ela recebe a pergunta, delega o processamento para a camada de PLN e, em seguida, para a camada de acesso a dados, retornando a resposta final ao usuário. -
NlpEngine(Compreensão de Linguagem): O cérebro da operação. Esta camada é responsável por dissecar a pergunta do usuário em seus componentes lógicos: a intenção (o que o usuário quer saber) e as entidades (os filtros da consulta, como cidades, produtos ou clientes). -
crud_dados(Acesso a Dados): A camada responsável por interagir com o banco de dados. Ela constrói dinamicamente a consulta SQL com base nos componentes extraídos, executa-a de forma segura e formata os resultados em uma resposta clara e legível.
A NlpEngine utiliza um modelo híbrido, combinando aprendizado de máquina, regras e conhecimento de domínio para traduzir a linguagem humana em uma estrutura de dados acionável.
A tarefa mais crítica da NlpEngine é identificar a intenção do usuário com precisão. Para isso, o sistema utiliza uma abordagem híbrida que combina duas técnicas de PLN, garantindo uma compreensão que é ao mesmo tempo ampla e específica.
Pense no processo como dois analistas trabalhando em conjunto para interpretar a pergunta, cada um com uma especialidade diferente:
-
TfidfVectorizer(Léxico):-
Função: Este modelo é um especialista em estatística textual. Sua função é identificar quais palavras são matematicamente mais relevantes dentro do universo de perguntas que o chatbot conhece (o corpus em
perguntas.csv). -
Mecanismo: Ele calcula o score TF-IDF para cada palavra:
- TF (Term Frequency / Frequência do Termo): Mede quão frequente uma palavra é dentro de uma única pergunta. Uma palavra que aparece mais vezes em um documento é considerada mais importante para aquele documento.
- IDF (Inverse Document Frequency / Frequência Inversa do Documento): Mede quão rara uma palavra é em todo o conjunto de perguntas de exemplo. Palavras que aparecem em muitas perguntas (como "qual", "me", "diga") são consideradas "ruído" e recebem um score baixo. Palavras que aparecem em poucas perguntas (como "faturamento", "estoque") são consideradas distintivas e recebem um score alto.
- Resultado Prático: Ele transforma cada pergunta em um vetor numérico onde as posições de maior valor correspondem às palavras-chave mais distintivas. É extremamente eficaz para encontrar correspondências quando o usuário utiliza os termos técnicos exatos que o modelo aprendeu a reconhecer.
-
Função: Este modelo é um especialista em estatística textual. Sua função é identificar quais palavras são matematicamente mais relevantes dentro do universo de perguntas que o chatbot conhece (o corpus em
-
SentenceTransformer(Semântico):- Função: Este é um modelo de deep learning (baseado na arquitetura BERT) que vai além das palavras-chave para compreender o significado e o contexto da frase como um todo.
- Mecanismo: O modelo já foi pré-treinado em um volume massivo de textos da internet, aprendendo as relações sutis entre palavras e conceitos. Ele converte a pergunta inteira em um vetor numérico de alta dimensão (um embedding) que representa sua "posição" em um espaço de significados. Frases com sentidos similares, mesmo que usem palavras completamente diferentes, terão embeddings vetoriais muito próximos nesse espaço.
-
Resultado Prático: Ele permite que o chatbot entenda que "quanto nós ganhamos no total?" é semanticamente equivalente a "qual foi o faturamento geral?", algo que o
TfidfVectorizersozinho não conseguiria fazer.
O sistema combina os resultados de ambos para chegar a uma conclusão mais confiável.
-
Ao receber uma pergunta, o sistema calcula a similaridade dela com todas as perguntas de exemplo usando ambas as abordagens simultaneamente.
-
Ele então calcula um score final ponderado para cada possível intenção:
score_final = (score_similaridade_semantica * 0.7) + (score_similaridade_lexica * 0.3) -
A intenção com o maior
score_finalé escolhida. A ponderação de 70/30 privilegia a compreensão do significado geral (semântica), mas ainda dá peso suficiente para que palavras-chave importantes (léxico) possam influenciar o resultado final, criando um classificador robusto e flexível.
A extração de entidades (filtros) é realizada com a biblioteca spaCy e seu componente EntityRuler, que foi aprimorado com as seguintes estratégias:
Para garantir que o vocabulário do chatbot esteja sempre atualizado com o negócio, a NlpEngine carrega entidades diretamente do banco de dados durante sua inicialização:
-
Cidades e Produtos: Nomes únicos de cidades e produtos são buscados na base de dados (
domrock.vendas). - Tratamento de Acentos: Para cada entidade (ex: "São Paulo"), o sistema gera dois padrões de reconhecimento: um com a grafia original e outro sem acentos ("Sao Paulo"), garantindo a detecção independentemente da digitação do usuário.
- Sustentabilidade: Essa abordagem torna o sistema altamente sustentável. Novos produtos ou cidades adicionados ao banco de dados são automaticamente incorporados pelo chatbot na próxima inicialização, sem necessidade de alterar o código.
Além dos padrões dinâmicos, o pipeline inclui:
-
Regras de Prioridade: Para corrigir ambiguidades, regras explícitas foram criadas. Por exemplo, se uma pergunta contém "top" e "produto", a intenção é forçada para
TOP_PRODUTOS_VENDIDOSouTOP_PRODUTOS_ESTOQUE, sobrepondo-se ao modelo de IA e aumentando drasticamente a precisão para perguntas de ranking. -
Padrões Estáticos (Regex): Para entidades com formato previsível, como
PRODUTO_SKU(ex:FR-4567) eCLIENTE_ID(ex:cliente 12345). -
Fallback para Produtos Desconhecidos: Uma expressão regular (
re.search) tenta capturar nomes de produtos que não estão no banco de dados, procurando por padrões como "vendas de [produto]". -
Fallback do spaCy: Se nenhuma entidade de localização for encontrada, o sistema utiliza os modelos pré-treinados do spaCy (
LOC,GPE) como uma alternativa.
Este módulo constrói, executa e formata a resposta da consulta, com foco em segurança e resiliência.
O QUERY_CONFIG é um dicionário Python que serve como um "plano de execução" para cada intenção. Ele mapeia uma Intencao a todos os metadados necessários para construir a consulta: nome da tabela, função de agregação (SUM, COUNT), colunas, etc. Este design declarativo permite que novas consultas e funcionalidades sejam adicionadas com mínima alteração de código.
-
Segurança (Anti-SQL Injection): A segurança é a principal prioridade. Todas as consultas são construídas usando queries parametrizadas (passando valores como
%sna query e os parâmetros separadamente), o que previne completamente ataques de SQL Injection. -
Lógica de Retentativa para Acentos: Para lidar com inconsistências de acentuação entre a pergunta do usuário e os dados no banco, foi implementado um mecanismo de retentativa inteligente:
-
Primeira Tentativa: O sistema executa a consulta com o filtro extraído (ex:
zs_cidade = 'São Paulo'). -
Análise e Retentativa: Se a consulta não retorna resultados e continha filtros de texto, o sistema, em vez de falhar, gera uma segunda consulta automaticamente. Desta vez, ele aplica a função
unidecodeao valor do filtro (zs_cidade ILIKE 'Sao Paulo').
Essa abordagem de duas etapas resolve a grande maioria dos problemas de busca causados por acentuação.
-
Primeira Tentativa: O sistema executa a consulta com o filtro extraído (ex:
A formatação da resposta foi padronizada para sempre retornar uma lista de strings, garantindo consistência na apresentação:
-
Respostas de Ranking (TOP N): Gera um cabeçalho informativo e uma lista formatada dos resultados (
- Produto A: R$ 10.000,00). -
Respostas de Agregação: Constrói uma frase completa e clara (
O faturamento total para São Paulo é R$ 50.000,00.). - Respostas Vazias: Retorna uma mensagem amigável, sugerindo ao usuário verificar a grafia dos filtros.
A versão atual do chatbot é um assistente de dados robusto, preciso e flexível. Seus principais diferenciais são:
- Inteligência Aprimorada: A combinação do modelo híbrido de intenção com a extração de entidades via spaCy e padrões dinâmicos do banco de dados permite uma compreensão profunda e precisa da linguagem do usuário.
- Robustez e Resiliência: A lógica de retentativa para acentos e as regras de desambiguação tornam o sistema mais tolerante a erros de digitação e ambiguidades, melhorando a experiência do usuário.
-
Escalabilidade e Manutenibilidade: Ao carregar entidades do banco e usar o
QUERY_CONFIGde forma declarativa, o sistema pode ser expandido para cobrir novos domínios de dados com alterações mínimas no código-fonte, tornando-o altamente sustentável a longo prazo.