RAG / app.py
Arjun Singh
Changed chroma import
7d9b1aa
import os
from langchain_text_splitters import CharacterTextSplitter
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain.schema import HumanMessage
from langchain.document_loaders import UnstructuredFileLoader
#from langchain_community.document_loaders import UnstructuredFileLoader
from langchain_community.vectorstores import Chroma
from langchain_groq import ChatGroq
import gradio as gr
# Initialize ChromaDB and Groq API
DB_DIR = "chroma_db"
COLLECTION_NAME = "document_collection"
embedding_function = HuggingFaceEmbeddings()
GROQ_API_KEY = groq_api_key = os.environ.get("GROQ_API_KEY")
llm = ChatGroq(api_key=GROQ_API_KEY, model_name="llama-3.1-8b-instant")
# Keep track of current document ID
current_document_id = None
def load_and_split_document(file_path):
"""Loads a document and splits it into chunks."""
loader = UnstructuredFileLoader(file_path)
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=400, chunk_overlap=50)
chunks = text_splitter.split_documents(documents)
return chunks
def upload_and_process(file):
"""Processes uploaded file and stores it in ChromaDB."""
try:
global current_document_id
uploaded_file_path = file.name
# Generate a unique document ID (using filename in this case)
current_document_id = os.path.basename(uploaded_file_path)
# Load and split the document
chunks = load_and_split_document(uploaded_file_path)
# Add document ID as metadata to each chunk
for chunk in chunks:
chunk.metadata['document_id'] = current_document_id
# Get or create vector store
vector_store = Chroma(
persist_directory=DB_DIR,
embedding_function=embedding_function,
collection_name=COLLECTION_NAME
)
# Add new documents
vector_store.add_documents(chunks)
return f"Document successfully processed: {current_document_id}"
except Exception as e:
return f"Error processing document: {str(e)}"
def retrieve_and_generate_response(query):
"""Retrieves relevant text and uses Groq LLM to generate a response."""
try:
vector_store = Chroma(
persist_directory=DB_DIR,
embedding_function=embedding_function,
collection_name=COLLECTION_NAME
)
# Only search within the current document
if current_document_id:
filter_dict = {"document_id": current_document_id}
results = vector_store.similarity_search(
query,
k=2,
filter=filter_dict
)
else:
return "Please upload a document first."
retrieved_texts = [doc.page_content for doc in results]
context = "\n".join(retrieved_texts)
if not context:
return "No relevant content found in the current document."
messages = [
HumanMessage(content=f"Use the following context to answer the question:\n\n{context}\n\nQuestion: {query}")
]
response = llm.invoke(messages)
return response.content
except Exception as e:
return f"Error generating response: {str(e)}"
# Define the Gradio UI
with gr.Blocks() as demo:
gr.Markdown("# 🤖 RAG Chatbot with Groq & ChromaDB")
file_input = gr.File(label="Upload a PDF")
upload_button = gr.Button("Process Document")
upload_status = gr.Textbox(label="Upload Status", interactive=False)
query_input = gr.Textbox(label="Ask a Question")
response_output = gr.Textbox(label="Response", interactive=False)
chat_button = gr.Button("Get Answer")
upload_button.click(
upload_and_process,
inputs=[file_input],
outputs=[upload_status]
)
chat_button.click(
retrieve_and_generate_response, # Use the function directly
inputs=[query_input],
outputs=[response_output]
)
# Launch the Gradio app
demo.launch()