LUIS_DOMINGUES.exe
VOLTAR_PARA_BLOG
SEARCH_ALGORITHM.txt

Algoritmo de busca

[ 16 de Abril, 2025 ]

Algumas semanas atrás, eu estava testando o chatbot da nossa plataforma e reparei em um detalhe curioso: mesmo quando a pergunta era parecida com um problema já cadastrado, o resultado retornado era… diferente do esperado. Inicialmente, os resultados de buscas retornavam soluções priorizando os problemas e as tags. Mas ainda assim, era uma busca que poderia conter falhas. Afinal, os logs indicavam que a correspondência de palavras-chave foi reconhecida corretamente, e a pontuação estava sendo calculada com os pesos ajustados. Os valores pareciam coerentes, não havendo necessidade de ajustes. Posteriormente, notei que algumas buscas não retornavam resultados desejados, exigindo maior refinamento.

"E como você pensou nisso?"

O chatbot utiliza a função CalculateSimilarity, que normaliza os textos (remove acentos, stopwords etc.), tokeniza a query e os problemas do banco de dados, e compara os tokens, calculando a similaridade baseada na proporção de palavras coincidentes.

Mas existe um problema: o método não considera a importância das palavras na base. Algumas palavras podem ter mais peso que outras, e nossa aplicação estava tratando todas igualmente.

> O que melhorar?

Cheguei a três melhorias principais no cálculo:

  1. 1.
    Maior peso para tags e categorias: se uma palavra da query estiver presente nesses campos, ela valerá mais pontos.
  2. 2.
    Filtro por frequência: palavras muito comuns (como "o", "de", "com") não devem ter tanto peso.
  3. 3.
    Similaridade mínima: resultados com uma pontuação muito baixa (ex: 10%) devem ser descartados.
"Ok, mas como você aplicou isso no código?"

Atualizei a função CalculateSimilarity com a seguinte lógica:

                            
                                foreach (var token in inputTokens)
                                {
                                    if (problemTokens.Contains(token)) matches++;
                                    if (tagTokens.Contains(token)) tagMatches++;
                                }
                                
                                double score = ((matches * 1.0) + (tagMatches * 1.5)) / inputTokens.Count;
                            
                        

Esse código faz com que as palavras que aparecem nas tags ganhem um peso 1.5x maior que as do problema principal, e a similaridade agora reflete melhor os tópicos principais.

Também criei uma lista de stopwords para ignorar palavras irrelevantes, e apliquei um limite mínimo de similaridade. Assim, garantimos que só resultados realmente relevantes sejam exibidos.

> E quanto à performance?

Mesmo com a busca refinada, percebi que ainda dava para melhorar o tempo de resposta. A solução: cache com Redis.

process.txt

Sem cache, o fluxo era assim:

  1. 1.
    Usuário envia pergunta ao chatbot.
  2. 2.
    A API consulta o banco de dados.
  3. 3.
    SQL Server processa e retorna os dados.
  4. 4.
    API responde ao usuário.

Esse processo, com muitos acessos simultâneos, poderia sobrecarregar o banco. A solução foi usar o Redis para armazenar as respostas frequentes e evitar consultas desnecessárias.

Agora, a API verifica primeiro no Redis. Se a resposta estiver no cache, ela é retornada imediatamente. Caso contrário, busca no banco, salva no Redis e responde.

O resultado? Menos chamadas ao banco, respostas em milissegundos e maior escalabilidade sem comprometer o desempenho.

END_OF_FILE # # #