Rag_Chatbot / app.py
Areesh123's picture
Upload 2 files
b7b4342 verified
Raw
History Blame Contribute Delete
3.64 kB
import os
import fitz # PyMuPDF
import gradio as gr
import requests
from dotenv import load_dotenv
from sentence_transformers import SentenceTransformer, util
# Load environment variables
load_dotenv()
GROQ_API_KEY = os.getenv("GROQ_API_KEY")
GROQ_API_URL = "https://api.groq.com/openai/v1/chat/completions"
MODEL_NAME = "llama3-8b-8192"
# Load sentence-transformer model
embed_model = SentenceTransformer('all-MiniLM-L6-v2')
SYSTEM_PROMPT = """
You are a helpful AI assistant that answers questions using provided PDF documents.
Always base your answers on the context and include page numbers when possible.
"""
# Extract text from PDF with page numbers
def extract_text_with_pages(file):
doc = fitz.open(file.name)
chunks = []
for page_num in range(len(doc)):
page = doc.load_page(page_num)
text = page.get_text()
if text.strip():
chunks.append({"text": text.strip(), "page": page_num + 1})
return chunks
# Chunking (simple, per page)
def prepare_embeddings(chunks):
texts = [chunk["text"] for chunk in chunks]
embeddings = embed_model.encode(texts, convert_to_tensor=True)
return embeddings
# Retrieve top chunks
def retrieve_top_chunks(query, chunks, embeddings, top_k=3):
query_embedding = embed_model.encode(query, convert_to_tensor=True)
hits = util.semantic_search(query_embedding, embeddings, top_k=top_k)[0]
results = []
for hit in hits:
matched_chunk = chunks[hit["corpus_id"]]
results.append(f"[Page {matched_chunk['page']}]: {matched_chunk['text']}")
return results
# Query GROQ LLM
def query_groq(question, context, chat_history):
messages = [{"role": "system", "content": SYSTEM_PROMPT}]
for user, bot in chat_history:
messages.append({"role": "user", "content": user})
messages.append({"role": "assistant", "content": bot})
messages.append({"role": "user", "content": f"Context:\n{context}\n\nQuestion: {question}"})
headers = {
"Authorization": f"Bearer {GROQ_API_KEY}",
"Content-Type": "application/json"
}
response = requests.post(GROQ_API_URL, headers=headers, json={
"model": MODEL_NAME,
"messages": messages,
"temperature": 0.7
})
if response.status_code == 200:
return response.json()["choices"][0]["message"]["content"]
else:
return f"Error {response.status_code}: {response.text}"
# Full RAG pipeline
def rag_chatbot(files, question, history):
all_chunks = []
for file in files:
all_chunks.extend(extract_text_with_pages(file))
embeddings = prepare_embeddings(all_chunks)
top_chunks = retrieve_top_chunks(question, all_chunks, embeddings)
context = "\n\n".join(top_chunks)
response = query_groq(question, context, history)
history.append((question, response))
return "", history
# Gradio Interface
with gr.Blocks() as demo:
gr.Markdown("## 📄 RAG PDF Chatbot (Groq + SentenceTransformers)")
gr.Markdown("Upload PDFs and ask questions. The assistant will use document context and show page numbers in answers.")
pdf_files = gr.File(file_types=[".pdf"], file_count="multiple", label="Upload your PDF files")
question = gr.Textbox(label="Ask a question about the documents")
chatbot = gr.Chatbot()
clear_btn = gr.Button("Clear Chat")
state = gr.State([])
question.submit(rag_chatbot, [pdf_files, question, state], [question, chatbot])
clear_btn.click(lambda: ([], []), None, [chatbot, state])
demo.launch()