Spaces:
Running
Running
| """ | |
| 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() | |