utils.ts 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. /**
  2. * Utility functions for the RAG system
  3. */
  4. /**
  5. * Calcula a similaridade de cosseno entre dois vetores
  6. *
  7. * Por que usar cosseno?
  8. * - É a métrica padrão para comparar embeddings
  9. * - Normaliza automaticamente (não depende do tamanho do vetor)
  10. * - Valores entre -1 e 1 são fáceis de interpretar
  11. *
  12. * Fórmula: cos(θ) = (A · B) / (||A|| × ||B||)
  13. *
  14. * @param vetorA - Primeiro vetor (ex: embedding da pergunta)
  15. * @param vetorB - Segundo vetor (ex: embedding do documento)
  16. * @returns Similaridade entre -1 e 1
  17. */
  18. export function calcularSimilaridadeCosseno(vetorA: number[], vetorB: number[]): number {
  19. // Validação: vetores devem ter o mesmo tamanho
  20. if (vetorA.length !== vetorB.length) {
  21. throw new Error('Vetores devem ter o mesmo tamanho');
  22. }
  23. // Passo 1: Calcular o produto escalar (A · B)
  24. // Multiplicamos cada elemento correspondente e somamos
  25. let produtoEscalar = 0;
  26. for (let i = 0; i < vetorA.length; i++) {
  27. produtoEscalar += (vetorA[i] ?? 0) * (vetorB[i] ?? 0);
  28. }
  29. // Passo 2: Calcular a magnitude de A (||A||)
  30. // Raiz quadrada da soma dos quadrados
  31. let magnitudeA = 0;
  32. for (let i = 0; i < vetorA.length; i++) {
  33. magnitudeA += (vetorA[i] ?? 0) * (vetorA[i] ?? 0);
  34. }
  35. magnitudeA = Math.sqrt(magnitudeA);
  36. // Passo 3: Calcular a magnitude de B (||B||)
  37. let magnitudeB = 0;
  38. for (let i = 0; i < vetorB.length; i++) {
  39. magnitudeB += (vetorB[i] ?? 0) * (vetorB[i] ?? 0);
  40. }
  41. magnitudeB = Math.sqrt(magnitudeB);
  42. // Passo 4: Calcular a similaridade
  43. // Dividimos o produto escalar pelo produto das magnitudes
  44. // Evitamos divisão por zero
  45. if (magnitudeA === 0 || magnitudeB === 0) {
  46. return 0;
  47. }
  48. return produtoEscalar / (magnitudeA * magnitudeB);
  49. }