import streamlit as st import os os.environ['TOKENIZERS_PARALLELISM'] = 'false' os.environ['HF_HOME'] = '/app/huggingface_cache' os.environ['TRANSFORMERS_CACHE'] = '/app/huggingface_cache/transformers' os.environ['SENTENCE_TRANSFORMERS_HOME'] = '/app/huggingface_cache/sentence_transformers' if not os.path.exists('/app/huggingface_cache'): os.makedirs('/app/huggingface_cache', exist_ok=True) import langchain from dotenv import load_dotenv from pinecone import Pinecone from langchain_pinecone import PineconeVectorStore from langchain_community.embeddings import SentenceTransformerEmbeddings from langchain_groq import ChatGroq from langchain_core.prompts import ChatPromptTemplate from langchain_core.runnables import RunnablePassthrough, RunnableLambda from langchain_core.output_parsers import StrOutputParser from langchain.retrievers import ContextualCompressionRetriever from langchain.retrievers.document_compressors import CohereRerank try: print("Step 1: Loading environment variables...") load_dotenv() PINECONE_API_KEY = os.getenv('PINECONE_API_KEY') GROQ_API_KEY = os.getenv('GROQ_API_KEY') COHERE_API_KEY = os.getenv('COHERE_API_KEY') INDEX_NAME = "rag-chatbot" print("Step 1: SUCCESS") st.set_page_config(page_title="Advanced RAG Chatbot", page_icon="🚀", layout="wide") st.markdown(""" """, unsafe_allow_html=True) @st.cache_resource def initialize_services(): print("Step 2: Entering initialize_services function...") if not all([PINECONE_API_KEY, GROQ_API_KEY, COHERE_API_KEY]): raise ValueError("An API key is missing!") embeddings = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2") pinecone = Pinecone(api_key=PINECONE_API_KEY) host = "https://rag-chatbot-sg8t88c.svc.aped-4627-b74a.pinecone.io" index = pinecone.Index(host=host) vectorstore = PineconeVectorStore(index=index, embedding=embeddings) base_retriever = vectorstore.as_retriever(search_kwargs={'k': 10}) compressor = CohereRerank(cohere_api_key=COHERE_API_KEY, top_n=3, model="rerank-english-v3.0") reranking_retriever = ContextualCompressionRetriever(base_compressor=compressor, base_retriever=base_retriever) llm = ChatGroq(temperature=0.1, model_name="llama3-70b-8192", api_key=GROQ_API_KEY) print("Step 2: All services initialized successfully.") return reranking_retriever, llm print("Step 3: Calling initialize_services...") retriever, llm = initialize_services() print("Step 3: SUCCESS, services are loaded.") # --- RAG CHAIN print("Step 4: Defining RAG chain...") system_prompt = """You are a helpful AI assistant that answers questions based ONLY on the provided context. Your answer should be concise and directly address the question. After your answer, list the numbers of the sources you used, like this: [1][2]. Do not make up information. If the answer is not in the context, say "I cannot answer this based on the provided documents." Context (Sources are numbered starting from 1): {context} """ prompt_template = ChatPromptTemplate.from_messages([ ("system", system_prompt), ("human", "{question}") ]) def format_docs_with_numbers(docs): numbered_docs = [] MAX_DOC_LENGTH = 1200 # Adjusted max length for i, doc in enumerate(docs): content = doc.page_content if len(content) > MAX_DOC_LENGTH: content = content[:MAX_DOC_LENGTH] + "..." numbered_docs.append(f"Source [{i+1}]:\n{content}") return "\n\n".join(numbered_docs) rag_chain = ( {"context": retriever | RunnableLambda(format_docs_with_numbers), "question": RunnablePassthrough()} | prompt_template | llm | StrOutputParser() ) print("Step 4: SUCCESS") # --- Streamlit Chat UI st.title("💬 Document Chatbot Interface") if "messages" not in st.session_state: st.session_state.messages = [{"role": "assistant", "content": "Hello! I'm ready to answer questions about your documents.", "sources": []}] st.markdown('