Spaces:
Sleeping
Sleeping
| # utils | |
| from langchain_chroma import Chroma | |
| from langchain_nomic.embeddings import NomicEmbeddings | |
| from langchain_core.documents import Document | |
| from langchain.retrievers.document_compressors import CohereRerank | |
| #from langchain_core import CohereRerank | |
| #from langchain_cohere import CohereRerank | |
| from langchain.retrievers import ContextualCompressionRetriever | |
| from langchain.retrievers import EnsembleRetriever | |
| from langchain.retrievers import BM25Retriever | |
| from langchain_groq import ChatGroq | |
| from dotenv import load_dotenv | |
| from langchain_core.prompts import ChatPromptTemplate | |
| from langchain_core.runnables import Runnable, RunnableMap | |
| from langchain.schema import BaseRetriever | |
| from qdrant_client import models | |
| from langchain_huggingface.embeddings import HuggingFaceEmbeddings | |
| load_dotenv() | |
| import os | |
| LANGCHAIN_API_KEY = os.getenv('LANGCHAIN_API_KEY') | |
| #Retriever | |
| def get_retriever(n_docs=5): # renamed function | |
| vector_database_path = "db" | |
| embedding_model = NomicEmbeddings(model="nomic-embed-text-v1.5", inference_mode="local") | |
| vectorstore = Chroma(collection_name="chromadb3", | |
| persist_directory=vector_database_path, | |
| embedding_function=embedding_model) | |
| vs_retriever = vectorstore.as_retriever(k=n_docs) | |
| # Get documents from vector store | |
| try: | |
| store_data = vectorstore.get() | |
| texts = store_data['documents'] | |
| metadatas = store_data['metadatas'] | |
| if not texts: # If no documents found | |
| print("Warning: No documents found in vector store. Using vector retriever only.") | |
| return vs_retriever | |
| # Create documents with explicit IDs | |
| documents = [] | |
| for i, (text, metadata) in enumerate(zip(texts, metadatas)): | |
| doc = Document( | |
| page_content=text, | |
| metadata=metadata if metadata else {}, | |
| id_=str(i) # Add explicit ID | |
| ) | |
| documents.append(doc) | |
| # Create BM25 retriever with explicit document handling | |
| keyword_retriever = BM25Retriever.from_texts( | |
| texts=[doc.page_content for doc in documents], | |
| metadatas=[doc.metadata for doc in documents], | |
| ids=[doc.id_ for doc in documents] | |
| ) | |
| keyword_retriever.k = n_docs | |
| ensemble_retriever = EnsembleRetriever( | |
| retrievers=[vs_retriever, keyword_retriever], | |
| weights=[0.5, 0.5] | |
| ) | |
| compressor = CohereRerank(model="rerank-english-v3.0") | |
| compression_retriever = ContextualCompressionRetriever( | |
| base_compressor=compressor, | |
| base_retriever=ensemble_retriever | |
| ) | |
| return compression_retriever | |
| except Exception as e: | |
| print(f"Warning: Error creating combined retriever ({str(e)}). Using vector retriever only.") | |
| return vs_retriever | |
| #Retriever prompt | |
| rag_prompt = """You are a medical chatbot designed to answer health-related questions. | |
| The questions you will receive will primarily focus on medical topics and patient care. | |
| Here is the context to use to answer the question: | |
| {context} | |
| Think carefully about the above context. | |
| Now, review the user question: | |
| {input} | |
| Provide an answer to this question using only the above context. | |
| Answer:""" | |
| # Post-processing | |
| def format_docs(docs): | |
| return "\n\n".join(doc.page_content for doc in docs) | |
| #RAG chain | |
| def get_expression_chain(retriever: BaseRetriever, model_name="llama-3.1-70b-versatile", temp=0 ) -> Runnable: | |
| """Return a chain defined primarily in LangChain Expression Language""" | |
| def retrieve_context(input_text): | |
| # Use the retriever to fetch relevant documents | |
| docs = retriever.get_relevant_documents(input_text) | |
| return format_docs(docs) | |
| ingress = RunnableMap( | |
| { | |
| "input": lambda x: x["input"], | |
| "context": lambda x: retrieve_context(x["input"]), | |
| } | |
| ) | |
| prompt = ChatPromptTemplate.from_messages( | |
| [ | |
| ( | |
| "system", | |
| rag_prompt | |
| ) | |
| ] | |
| ) | |
| llm = ChatGroq(model=model_name,api_key="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", temperature=temp) | |
| chain = ingress | prompt | llm | |
| return chain | |
| embedding_model = NomicEmbeddings(model="nomic-embed-text-v1.5", inference_mode="local") | |
| #embedding_model = HuggingFaceEmbeddings(model_name="sentence-transformers/all-mpnet-base-v2") | |
| #Generate embeddings for a given text | |
| def get_embeddings(text): | |
| return embedding_model.embed([text], task_type='search_document')[0] | |
| # Create or connect to a Qdrant collection | |
| def create_qdrant_collection(client, collection_name): | |
| if collection_name not in client.get_collections().collections: | |
| client.create_collection( | |
| collection_name=collection_name, | |
| vectors_config=models.VectorParams(size=768, distance=models.Distance.COSINE) | |
| ) |