File size: 7,558 Bytes
1768992 7d20361 9474502 ad73f05 9474502 f819bed 7243c9b f819bed 7d20361 73bbdbf 7d20361 00f6446 7d20361 00f6446 7d20361 1768992 ad73f05 1768992 ad73f05 1768992 fbe315c 1768992 4d5bf0e 1768992 7243c9b 1768992 fbe315c 1768992 fbe315c 1768992 b0fb599 1768992 9474502 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 |
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() |