File size: 5,737 Bytes
e06d532
 
 
 
 
 
88e7d80
e06d532
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88e7d80
 
 
e06d532
88e7d80
 
 
 
 
 
 
 
 
 
 
 
e741e3b
88e7d80
 
 
 
 
e06d532
88e7d80
 
 
 
 
 
 
 
 
93d2c31
88e7d80
 
 
 
 
 
e06d532
88e7d80
 
e06d532
88e7d80
 
e06d532
88e7d80
 
 
 
 
e06d532
88e7d80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e06d532
88e7d80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e06d532
88e7d80
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import os
import streamlit as st
from langchain_community.vectorstores import Chroma
from langchain_community.embeddings import HuggingFaceBgeEmbeddings
from groq import Groq
from dotenv import load_dotenv
import requests

# Initialize Streamlit page configuration
st.set_page_config(page_title="Medical Knowledge Assistant", layout="wide")

# Add API key input in sidebar
with st.sidebar:
    st.header("API Key Configuration")
    api_key = st.text_input("Enter your Groq API Key:", type="password")
    if api_key:
        os.environ['GROQ_API_KEY'] = api_key
    else:
        # Try loading from .env file
        load_dotenv()
        api_key = os.getenv("GROQ_API_KEY")
        if api_key:
            st.success("API Key loaded from .env file")

# Check for API key before proceeding
if not api_key:
    st.warning("Please enter your Groq API key in the sidebar to continue.")
    st.stop()

# Initialize the app
st.title("Medical Knowledge Assistant")

# Google Drive file ID (use your own file ID)
file_id = '1lVlF8dYsNFPzrNGqn7jiJos7qX49jmi0'  # Replace with your Google Drive file ID
destination_path = '/tmp/Embedded_Med_books'  # Temporary location to store the vector store

# Function to download file from Google Drive
def download_from_drive(file_id, destination_path):
    """Download the vector store file from Google Drive."""
    url = f'https://drive.google.com/uc?export=download&id={file_id}'
    response = requests.get(url)
    if response.status_code == 200:
        with open(destination_path, 'wb') as f:
            f.write(response.content)
        return destination_path
    else:
        st.error("Failed to download the file from Google Drive.")
        return None

# Check if the vector store file exists, and download it if necessary
if not os.path.exists(destination_path):
    st.warning("Downloading the vector store from Google Drive...")
    download_from_drive(file_id, destination_path)
    st.success("Vector store downloaded successfully!")

# Set up embeddings
model_name = "BAAI/bge-large-en"
model_kwargs = {'device': 'cpu'}
encode_kwargs = {'normalize_embeddings': False}
embeddings = HuggingFaceBgeEmbeddings(
    model_name=model_name,
    model_kwargs=model_kwargs,
    encode_kwargs=encode_kwargs
)

# Load the vector store from the downloaded file
vector_store = Chroma(
    persist_directory=destination_path,
    embedding_function=embeddings
)
retriever = vector_store.as_retriever(search_kwargs={'k': 1})

# Initialize Groq client
client = Groq(api_key=api_key)

# Streamlit input
query = st.text_input("Enter your medical question here:")

def query_with_groq(query, retriever):
    try:
        # Retrieve relevant documents
        docs = retriever.get_relevant_documents(query)
        context = "\n".join([doc.page_content for doc in docs])

        # Call the Groq API with the query and context
        completion = client.chat.completions.create(
            model="llama3-70b-8192",
            messages=[
                {
                    "role": "system",
                    "content": (
                        "You are a knowledgeable medical assistant. For any medical term or disease, include comprehensive information covering: "
                        "definitions, types, historical background, major theories, known causes, and contributing risk factors. "
                        "Explain the genesis or theories on its origin, if applicable. Use a structured, thorough approach and keep language accessible. "
                        "provide symptoms, diagnosis, and treatment and post operative care , address all with indepth explanation , with specific details and step-by-step processes where relevant. "
                        "If the context does not adequately cover the user's question, respond with: 'I cannot provide an answer based on the available medical dataset.'"
                    )
                },
                {
                    "role": "system",
                    "content": (
                        "If the user asks for a medical explanation, ensure accuracy, don't include layman's terms if complex terms are used, "
                        "and organize responses in a structured way."
                    )
                },
                {
                    "role": "system",
                    "content": (
                        "When comparing two terms or conditions, provide a clear, concise, and structured comparison. Highlight key differences in their "
                        "definitions, symptoms, causes, diagnoses, and treatments with indepth explanation of each. If relevant, include any overlapping characteristics."
                    )
                },
                {
                    "role": "user",
                    "content": f"{context}\n\nQ: {query}\nA:"
                }
            ],
            temperature=0.7,
            max_tokens=3000,
            stream=True
        )

        # Create a placeholder for streaming response
        response_container = st.empty()
        response = ""
        
        # Stream the response
        for chunk in completion:
            if chunk.choices[0].delta.content:
                response += chunk.choices[0].delta.content
                response_container.markdown(response)
        
        return response
        
    except Exception as e:
        st.error(f"Error during query processing: {str(e)}")
        return None

if st.button("Get Answer"):
    if query:
        with st.spinner("Processing your query..."):
            answer = query_with_groq(query, retriever)
            if answer:
                st.success("Query processed successfully!")
    else:
        st.warning("Please enter a query.")