Spaces:
Sleeping
Sleeping
| import os | |
| import yaml | |
| import gradio as gr # Importe o Gradio | |
| from langchain_huggingface import ChatHuggingFace | |
| from langchain_huggingface.llms.huggingface_endpoint import HuggingFaceEndpoint | |
| from langchain_community.vectorstores import FAISS | |
| from langchain.chains import RetrievalQA | |
| from langchain_huggingface.embeddings import HuggingFaceEmbeddings | |
| from langchain.prompts import PromptTemplate | |
| from langchain_community.document_loaders import WebBaseLoader | |
| from langchain_text_splitters import CharacterTextSplitter | |
| from langchain_community.vectorstores import FAISS | |
| from langchain_huggingface import HuggingFaceEmbeddings | |
| from dotenv import load_dotenv | |
| import os | |
| import logging | |
| logging.getLogger("langchain.text_splitter").setLevel(logging.ERROR) | |
| import warnings | |
| warnings.filterwarnings("ignore") | |
| from langchain_community.document_loaders import RecursiveUrlLoader | |
| import yaml | |
| # #----------- local paths ----------- | |
| CACHE_FOLDER = "./model/" | |
| LOCAL_FOLDER = "./model/" | |
| VS_BASE = "./vector_store/vs_base" | |
| os.makedirs(CACHE_FOLDER, exist_ok=True) | |
| os.makedirs(LOCAL_FOLDER, exist_ok=True) | |
| os.makedirs(VS_BASE, exist_ok=True) | |
| # --- CONFIGURAÇÕES DE MODELOS --- | |
| # LLM_MODEL = 'google/gemma-3-4b-it' | |
| LLM_MODEL = 'google/gemma-3-12b-it' | |
| EMBEDDING_MODEL = "sentence-transformers/all-MiniLM-L6-v2" | |
| # ------------ criando vs ----------------- | |
| ## knowledge base offline | |
| url_list = [ | |
| "https://www.infinitepay.io", | |
| "https://www.infinitepay.io/maquininha", | |
| "https://www.infinitepay.io/maquininha-celular", | |
| "https://www.infinitepay.io/tap-to-pay", | |
| "https://www.infinitepay.io/pdv", | |
| "https://www.infinitepay.io/receba-na-hora", | |
| "https://www.infinitepay.io/gestao-de-cobranca", | |
| "https://www.infinitepay.io/gestao-de-cobranca-2", | |
| "https://www.infinitepay.io/link-de-pagamento", | |
| "https://www.infinitepay.io/loja-online", | |
| "https://www.infinitepay.io/boleto", | |
| "https://www.infinitepay.io/conta-digital", | |
| "https://www.infinitepay.io/conta-pj", | |
| "https://www.infinitepay.io/pix", | |
| "https://www.infinitepay.io/pix-parcelado", | |
| "https://www.infinitepay.io/emprestimo", | |
| "https://www.infinitepay.io/cartao", | |
| "https://www.infinitepay.io/rendimento", | |
| 'https://www.infinitepay.io/taxas', | |
| 'https://www.cloudwalk.io/', | |
| 'https://www.cloudwalk.io/#our-mission', | |
| 'https://www.cloudwalk.io/#our-pillars', | |
| 'https://www.cloudwalk.io/#our-products', | |
| ] | |
| # Carregue o conteúdo da página web como documentos LangChain | |
| loader = WebBaseLoader(web_paths=url_list) | |
| docs = loader.load() | |
| #print(f"Total de páginas carregadas: {len(docs)}") | |
| text_splitter = CharacterTextSplitter(chunk_size=1500, chunk_overlap=100) | |
| split_docs = text_splitter.split_documents(docs) | |
| embeddings = HuggingFaceEmbeddings(model_name=EMBEDDING_MODEL) | |
| vector_store = FAISS.from_documents(split_docs, embeddings) | |
| os.makedirs(VS_BASE, exist_ok=True) | |
| vector_store.save_local(VS_BASE) | |
| print(f"vs_base salva em {VS_BASE}") | |
| # --- CONFIGURAÇÃO HF --- | |
| HF_TOKEN = os.getenv("HF_TOKEN") # Use os.getenv para ler a variável de ambiente | |
| if not HF_TOKEN: | |
| raise ValueError("HF_TOKEN não encontrado. Por favor, defina-o nos segredos do Hugging Face Space.") | |
| os.environ["HF_HUB_USER_AGENT"] = "CloudWalk_Chatbot" | |
| # --- 1. Inicializa o LLM Hugging Face --- | |
| llm = HuggingFaceEndpoint( | |
| repo_id=LLM_MODEL, | |
| task="text-generation", | |
| max_new_tokens=1024, | |
| do_sample=False, | |
| repetition_penalty=1.03, | |
| huggingfacehub_api_token=HF_TOKEN, | |
| ) | |
| chat_model = ChatHuggingFace(llm=llm) | |
| # --- 2. Inicializa os embeddings --- | |
| embeddings = HuggingFaceEmbeddings(model_name=EMBEDDING_MODEL) | |
| # --- 3. Carregando a vector store FAISS salva localmente --- | |
| vector_store_path = './vector_store/vs_base/' | |
| try: | |
| faiss_store = FAISS.load_local(vector_store_path, embeddings, allow_dangerous_deserialization=True) | |
| except Exception as e: | |
| print(f"Erro ao carregar a vector store FAISS: {e}") | |
| print("Verifique se o caminho está correto e se o arquivo não está corrompido.") | |
| exit() | |
| # --- 4. Retriever a partir da vector store (usando similarity como exemplo) --- | |
| retriever = faiss_store.as_retriever(search_type="similarity", search_kwargs={"k": 10}) | |
| # retriever = faiss_store.as_retriever( | |
| # search_type="mmr", | |
| # search_kwargs={"k": 5, "fetch_k": 20, "lambda_mult": 0.7} | |
| # ) | |
| # --- 5. PromptTemplate personalizado --- | |
| custom_prompt_template = """ | |
| You are a useful chatbot for customer service. | |
| If you don't know the answer, just say that you don't know, don't try to make up an answer. | |
| ALWAYS RESPONDE IN THE SAME LANGUAGE AS THE INPUT. | |
| Use the following pieces of context to answer the user's question. | |
| {context} | |
| Question: {question} | |
| Helpful Answer:""" | |
| # Crie um objeto PromptTemplate a partir da string | |
| QA_CHAIN_PROMPT = PromptTemplate.from_template(custom_prompt_template) | |
| # --- 6. Cria uma cadeia de QA que usa o retriever e o modelo --- | |
| qa_chain = RetrievalQA.from_chain_type( | |
| llm=chat_model, | |
| chain_type="stuff", | |
| retriever=retriever, | |
| return_source_documents=True, | |
| chain_type_kwargs={"prompt": QA_CHAIN_PROMPT} | |
| ) | |
| # --- 7. Função principal para a interface do Gradio --- | |
| def chat_response(question: str, history: list): # `history` é um parâmetro obrigatório para gr.ChatInterface | |
| """ | |
| Gera a resposta do chatbot usando o modelo de QA e formata para exibição no Gradio. | |
| Args: | |
| question (str): A pergunta do usuário. | |
| history (list): Histórico de conversas (não usado diretamente aqui, mas necessário para a interface). | |
| Returns: | |
| str: A resposta formatada do chatbot, incluindo as fontes. | |
| """ | |
| print(f"Recebida pergunta: '{question}'") # Para debug no console | |
| try: | |
| result = qa_chain.invoke({"query": question}) | |
| answer = result["result"] | |
| sources = result.get("source_documents", []) | |
| response_text = f"**Resposta:** {answer}\n\n" | |
| if sources: | |
| response_text += "**Saiba mais em:**\n" | |
| unique_sources = set() | |
| source_list_for_printing = [] | |
| for doc in sources: | |
| source_name = doc.metadata.get('source', 'Fonte desconhecida') | |
| if source_name not in unique_sources: | |
| unique_sources.add(source_name) | |
| source_list_for_printing.append(source_name) | |
| for i, source_name in enumerate(source_list_for_printing): | |
| response_text += f"- {i+1}. '{source_name}'\n" | |
| else: | |
| response_text += "Nenhuma fonte específica foi utilizada para esta resposta.\n" | |
| return response_text | |
| except Exception as e: | |
| error_message = f"Ocorreu um erro ao processar sua pergunta: {e}. Por favor, tente novamente." | |
| print(error_message) # Para debug no console | |
| return error_message | |
| # --- 8. Criação da Interface Gradio --- | |
| if __name__ == "__main__": | |
| print("Iniciando a interface Gradio...") | |
| demo = gr.ChatInterface( | |
| type="messages", | |
| fn=chat_response, # A função que processa a pergunta e retorna a resposta | |
| title="CloudWalk Chatbot", | |
| description="Olá! Estou aqui para responder suas dúvidas.", | |
| submit_btn="Enviar Pergunta", | |
| examples=[ | |
| #["What product and services InfinitePay offer ?"], | |
| #['What are the fees for the card machine?'], | |
| #['How can I order one card machine?'], | |
| ["Quais serviços a infinite pay oferece?"], | |
| ["Quais as taxas da maquininha?"], | |
| ["Como pedir uma maquininha?"], | |
| ], | |
| chatbot=gr.Chatbot(type="messages") | |
| ) | |
| demo.launch() |