""" MSC Marketing Chatbot com RAG Assistente inteligente com busca semântica na base de conhecimento. """ import os import json import gradio as gr import numpy as np from sentence_transformers import SentenceTransformer import faiss from huggingface_hub import hf_hub_download # Configuração MODEL_NAME = "intfloat/multilingual-e5-base" DATASET_REPO = "Finish-him/msc-embeddings" TOP_K = 5 # Variáveis globais model = None index = None metadata = None def load_rag_components(): """Carrega modelo, índice e metadata.""" global model, index, metadata print("🔄 Carregando componentes RAG...") # Carregar modelo de embeddings print(" 📦 Carregando modelo de embeddings...") model = SentenceTransformer(MODEL_NAME) # Baixar arquivos do dataset print(" 📥 Baixando índice FAISS...") try: index_path = hf_hub_download( repo_id=DATASET_REPO, filename="rag_data/msc_faiss.index", repo_type="dataset" ) index = faiss.read_index(index_path) print(f" ✓ Índice carregado: {index.ntotal} vetores") except Exception as e: print(f" ⚠️ Erro ao carregar índice: {e}") # Criar índice vazio se não existir index = faiss.IndexFlatIP(768) print(" 📥 Baixando metadata...") try: metadata_path = hf_hub_download( repo_id=DATASET_REPO, filename="rag_data/msc_metadata.json", repo_type="dataset" ) with open(metadata_path, 'r', encoding='utf-8') as f: metadata = json.load(f) print(f" ✓ Metadata carregado: {len(metadata)} documentos") except Exception as e: print(f" ⚠️ Erro ao carregar metadata: {e}") metadata = [] print("✅ Componentes RAG carregados!") def search_knowledge_base(query: str, top_k: int = TOP_K) -> list: """Busca documentos relevantes na base de conhecimento.""" if model is None or index is None or index.ntotal == 0: return [] # Formato E5 para query query_text = f"query: {query}" query_embedding = model.encode([query_text], normalize_embeddings=True) # Buscar no índice scores, indices = index.search(query_embedding.astype('float32'), min(top_k, index.ntotal)) results = [] for score, idx in zip(scores[0], indices[0]): if idx < len(metadata): doc = metadata[idx] results.append({ "score": float(score), "title": doc.get("title", "Documento MSC"), "domain": doc.get("domain", "general"), "text": doc.get("full_text", doc.get("text", "")) }) return results def format_context(results: list) -> str: """Formata os resultados da busca como contexto.""" if not results: return "" context_parts = [] for i, doc in enumerate(results, 1): context_parts.append(f"[Documento {i}] {doc['title']}\n{doc['text'][:800]}") return "\n\n---\n\n".join(context_parts) def generate_response(query: str, context: str) -> str: """Gera resposta baseada no contexto.""" if not context: return f"""Olá! Sou o assistente da MSC Marketing. Recebi sua pergunta: "{query}" Infelizmente, não encontrei informações específicas na base de conhecimento sobre esse tema. **O que posso ajudar:** - Estratégias de SEO e Marketing Digital - Informações sobre serviços da MSC - Dúvidas sobre projetos e processos - Suporte técnico básico Visite https://mscmarketing.group para mais informações.""" response = f"""**Sua pergunta:** {query} **Baseado na documentação da MSC Marketing:** {context[:2000]} --- *Esta resposta foi gerada com base na documentação oficial da MSC Marketing.* *Para mais informações, visite https://mscmarketing.group*""" return response def chat(message: str, history: list) -> str: """Processa mensagem do chat com RAG.""" if not message.strip(): return "Por favor, digite uma mensagem." # Buscar contexto relevante results = search_knowledge_base(message, TOP_K) context = format_context(results) # Gerar resposta response = generate_response(message, context) return response def search_api(query: str, top_k: int = 5) -> dict: """API endpoint para busca semântica.""" results = search_knowledge_base(query, top_k) return { "query": query, "results": results, "count": len(results) } # Carregar componentes ao iniciar load_rag_components() # Interface Gradio with gr.Blocks( title="MSC Marketing Assistant", theme=gr.themes.Soft() ) as demo: gr.Markdown(""" # 🤖 MSC Marketing Assistant **Assistente inteligente com RAG (Retrieval-Augmented Generation)** Este chatbot utiliza busca semântica na base de conhecimento da MSC Marketing para fornecer respostas precisas e contextualizadas. --- """) with gr.Tab("💬 Chat"): chatbot = gr.ChatInterface( chat, examples=[ "O que é SEO multilíngue?", "Como funciona marketing digital?", "Quais são os serviços da MSC Marketing?", "O que é a MSC Academy?", "Como otimizar um site para SEO?" ], cache_examples=False ) with gr.Tab("🔍 Busca Semântica"): gr.Markdown("### Busque diretamente na base de conhecimento") with gr.Row(): search_input = gr.Textbox( label="Sua busca", placeholder="Digite sua busca...", scale=4 ) search_k = gr.Slider(1, 10, value=5, step=1, label="Resultados", scale=1) search_btn = gr.Button("🔍 Buscar", variant="primary") search_output = gr.JSON(label="Resultados") search_btn.click( search_api, inputs=[search_input, search_k], outputs=search_output ) with gr.Tab("📊 Status"): gr.Markdown(f""" ### Status do Sistema | Componente | Status | |------------|--------| | Modelo de Embeddings | `{MODEL_NAME}` | | Vetores no Índice | `{index.ntotal if index else 0}` | | Documentos | `{len(metadata) if metadata else 0}` | | Dataset | `{DATASET_REPO}` | ### Endpoints de API Este Space expõe endpoints para integração com N8N e outros sistemas: - **Chat:** `/api/predict` (POST) - **Busca:** `/api/search` (POST) ### Links - [MSC Marketing](https://mscmarketing.group) - [Dataset Knowledge Base](https://huggingface.co/datasets/Finish-him/msc-knowledge-base) - [Dataset Q&A](https://huggingface.co/datasets/Finish-him/msc-qa-pairs) - [Dataset Embeddings](https://huggingface.co/datasets/Finish-him/msc-embeddings) """) gr.Markdown(""" --- **MSC Marketing** | Assistente de IA com RAG | Powered by Hugging Face """) if __name__ == "__main__": demo.launch()