/** * Módulo RAG (Retrieval-Augmented Generation) * * Este módulo integra a busca por documentos similares com a geração de respostas * Ele importa as funções da pasta rag e as adapta para uso na API */ // URL da nova API de embeddings const EMBEDDINGS_API_URL = process.env.EMBEDDINGS_API_URL || 'http://localhost:3402/api/embeddings'; console.log(`[API::rag.ts]Usando EMBEDDINGS_API_URL: ${EMBEDDINGS_API_URL}`); /** * Interface para os resultados da busca */ interface ResultadoBusca { nome: string; conteudo: string; similaridade: number; } /** * Interface para o resultado da busca com contexto */ interface ResultadoBuscaComContexto { contexto: string; resultados: ResultadoBusca[]; } /** * Interface para a resposta da API de embeddings */ interface ApiEmbeddingsResponse { contexto: string; resultados: Array<{ documento: { nome: string; caminho: string; conteudo: string; tamanho: number; embedding: number[]; }; similaridade: number; }>; } /** * Interface para a requisição da API de embeddings */ interface ApiEmbeddingsRequest { prompt: string; topK: number; limiarSimilaridade: number; } /** * Chama a API de embeddings para buscar documentos similares */ async function chamarApiEmbeddings( prompt: string, topK: number = 2, limiarSimilaridade: number = 0.3 ): Promise { console.log('Chamando API de embeddings...'); try { const requestBody: ApiEmbeddingsRequest = { prompt, topK, limiarSimilaridade }; const response = await fetch(EMBEDDINGS_API_URL, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(requestBody) }); if (!response.ok) { throw new Error(`API de embeddings retornou status ${response.status}`); } const data = await response.json() as ApiEmbeddingsResponse; return data; } catch (erro) { console.error('Erro ao chamar API de embeddings:', erro); throw new Error('Falha na comunicação com a API de embeddings'); } } /** * Busca documentos similares no banco de dados * * Esta função é otimizada para uso na API: * - Logs menos verbosos (para produção) * - Retorna dados simplificados * - Usa a nova API de embeddings * * @param pergunta - A pergunta do usuário * @param topK - Quantos documentos retornar (padrão: 2) * @param limiarSimilaridade - Similaridade mínima (padrão: 0.3) * @returns Objeto com contexto formatado e array com os documentos mais similares */ async function buscarContexto( pergunta: string, topK: number = 2, limiarSimilaridade: number = 0.3 ): Promise { try { // Chama a API de embeddings const respostaApi = await chamarApiEmbeddings(pergunta, topK, limiarSimilaridade); // Mapeia os resultados para o formato esperado const resultados: ResultadoBusca[] = respostaApi.resultados.map(resultado => ({ nome: resultado.documento.nome, conteudo: resultado.documento.conteudo, similaridade: resultado.similaridade })); return { contexto: respostaApi.contexto, resultados }; } catch (erro) { console.error('Erro ao buscar contexto:', erro); // Em caso de erro, retorna objeto vazio return { contexto: '', resultados: [] }; } } /** * Monta um prompt enriquecido com contexto RAG * * Esta é a função principal que integra tudo: * 1. Busca documentos relevantes usando a nova API * 2. Retorna o contexto formatado da API * * Por que usar a API? * - Centraliza a lógica de busca e formatação * - Reduz código duplicado * - Melhora a manutenibilidade * * @param pergunta - A pergunta do usuário * @param topK - Quantos documentos usar (padrão: 2) * @param limiarSimilaridade - Similaridade mínima (padrão: 0.3) * @returns Prompt formatado com contexto */ async function montarPromptComRAG( pergunta: string, topK: number = 2, limiarSimilaridade: number = 0.3 ): Promise { try { // Chama a API de embeddings const respostaApi = await chamarApiEmbeddings(pergunta, topK, limiarSimilaridade); // Retorna o contexto formatado diretamente da API return respostaApi.contexto; } catch (erro) { console.error('Erro ao montar prompt com RAG:', erro); // Em caso de erro, retorna apenas a pergunta return pergunta; } } // Exporta as funções para serem usadas na API export { buscarContexto, montarPromptComRAG, type ResultadoBusca, type ResultadoBuscaComContexto };