|
|
import os |
|
|
import shutil |
|
|
import gradio as gr |
|
|
from typing import List |
|
|
from llama_index.core import SimpleDirectoryReader, StorageContext, VectorStoreIndex |
|
|
from llama_index.core.node_parser import SentenceSplitter |
|
|
from llama_index.embeddings.huggingface import HuggingFaceEmbedding |
|
|
from llama_index.vector_stores.chroma import ChromaVectorStore |
|
|
from llama_index.llms.groq import Groq |
|
|
from llama_index.core.memory import ChatSummaryMemoryBuffer |
|
|
import chromadb |
|
|
from tempfile import TemporaryDirectory |
|
|
from PyPDF2 import PdfReader |
|
|
|
|
|
|
|
|
class ChromaEmbeddingWrapper: |
|
|
def __init__(self, model_name: str): |
|
|
self.model = HuggingFaceEmbedding(model_name=model_name) |
|
|
|
|
|
def __call__(self, input: List[str]) -> List[List[float]]: |
|
|
return self.model.embed_documents(input) |
|
|
|
|
|
|
|
|
embed_model = HuggingFaceEmbedding(model_name='intfloat/multilingual-e5-large') |
|
|
embed_model_chroma = ChromaEmbeddingWrapper(model_name='intfloat/multilingual-e5-large') |
|
|
|
|
|
|
|
|
chroma_client = chromadb.PersistentClient(path='./chroma_db') |
|
|
collection_name = 'documentos_serenatto' |
|
|
chroma_collection = chroma_client.get_or_create_collection( |
|
|
name=collection_name, |
|
|
embedding_function=embed_model_chroma |
|
|
) |
|
|
|
|
|
vector_store = ChromaVectorStore(chroma_collection=chroma_collection) |
|
|
storage_context = StorageContext.from_defaults(vector_store=vector_store) |
|
|
|
|
|
|
|
|
Groq_api = os.environ.get("GROQ_API_KEY") |
|
|
llms = Groq(model='llama3-70b-8192', api_key='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') |
|
|
|
|
|
|
|
|
document_index = None |
|
|
chat_engine = None |
|
|
|
|
|
|
|
|
|
|
|
def process_pdf(file): |
|
|
global document_index, chat_engine |
|
|
|
|
|
try: |
|
|
with TemporaryDirectory() as tmpdir: |
|
|
pdf_path = os.path.join(tmpdir, "upload.pdf") |
|
|
shutil.copy(file.name, pdf_path) |
|
|
|
|
|
text = "" |
|
|
reader = PdfReader(pdf_path) |
|
|
for page in reader.pages: |
|
|
text += page.extract_text() or "" |
|
|
|
|
|
with open(os.path.join(tmpdir, "temp.txt"), "w", encoding="utf-8") as f: |
|
|
f.write(text) |
|
|
|
|
|
documentos = SimpleDirectoryReader(input_dir=tmpdir) |
|
|
docs = documentos.load_data() |
|
|
|
|
|
node_parser = SentenceSplitter(chunk_size=1200) |
|
|
nodes = node_parser.get_nodes_from_documents(docs, show_progress=True) |
|
|
|
|
|
document_index = VectorStoreIndex(nodes, storage_context=storage_context, embed_model=embed_model) |
|
|
|
|
|
memory = ChatSummaryMemoryBuffer(llm=llms, token_limit=256) |
|
|
|
|
|
chat_engine = document_index.as_chat_engine( |
|
|
chat_mode='context', |
|
|
llm=llms, |
|
|
memory=memory, |
|
|
system_prompt='''Voce é especialista em cafes da loja Serenatto, uma loja online que vende graos de cafe |
|
|
torrados, sua funçao é tirar duvidas de forma simpatica e natural sobre os graos disponiveis.''' |
|
|
) |
|
|
|
|
|
return "PDF carregado com sucesso! Agora você pode conversar com o bot." |
|
|
|
|
|
except Exception as e: |
|
|
return f"Erro ao processar PDF: {e}" |
|
|
|
|
|
|
|
|
def converse_com_bot(message, chat_history): |
|
|
global chat_engine |
|
|
|
|
|
if chat_engine is None: |
|
|
return "Por favor, envie um PDF primeiro.", chat_history |
|
|
|
|
|
response = chat_engine.chat(message) |
|
|
|
|
|
if chat_history is None: |
|
|
chat_history = [] |
|
|
|
|
|
chat_history.append({"role": "user", "content": message}) |
|
|
chat_history.append({"role": "assistant", "content": response.response}) |
|
|
|
|
|
return "", chat_history |
|
|
|
|
|
|
|
|
def resetar_chat(): |
|
|
global chat_engine |
|
|
if chat_engine: |
|
|
chat_engine.reset() |
|
|
return [] |
|
|
|
|
|
|
|
|
with gr.Blocks() as app: |
|
|
gr.Markdown("# Chatbot da Serenatto - Especialista em Cafés") |
|
|
|
|
|
with gr.Row(): |
|
|
upload = gr.File(label="📄 Envie seu PDF") |
|
|
upload_button = gr.Button("Carregar PDF") |
|
|
|
|
|
output_status = gr.Textbox(label="Status", interactive=False) |
|
|
|
|
|
chatbot = gr.Chatbot(label="Conversa", type="messages") |
|
|
msg = gr.Textbox(label='Digite a sua mensagem') |
|
|
limpar = gr.Button('Limpar') |
|
|
|
|
|
upload_button.click(process_pdf, inputs=upload, outputs=output_status).then( |
|
|
resetar_chat, None, chatbot |
|
|
) |
|
|
msg.submit(converse_com_bot, [msg, chatbot], [msg, chatbot]) |
|
|
limpar.click(resetar_chat, None, chatbot, queue=False) |
|
|
|
|
|
app.launch(debug=True) |