Spaces:
Sleeping
Sleeping
Tafazzul-Nadeeem commited on
Commit ·
e61e3e2
1
Parent(s): 9c4e3a6
Prescription feature done
Browse files- agents/__init__.py +2 -1
- agents/get_prescription_text_agent.py +31 -0
- agents/rag_decision_agent.py +1 -1
- app.py +44 -25
- faiss_index_store/index.faiss +0 -0
- faiss_index_store/index.pkl +0 -0
- prompts.py +17 -10
- ratelist_offers.docx +0 -0
- ratelist_offers.pdf +0 -0
agents/__init__.py
CHANGED
|
@@ -1,2 +1,3 @@
|
|
| 1 |
from .rag_decision_agent import rag_decision
|
| 2 |
-
from .rag_retrieval_agent import get_top_k
|
|
|
|
|
|
| 1 |
from .rag_decision_agent import rag_decision
|
| 2 |
+
from .rag_retrieval_agent import get_top_k
|
| 3 |
+
from .get_prescription_text_agent import get_prescription_text
|
agents/get_prescription_text_agent.py
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from openai import OpenAI
|
| 2 |
+
import os
|
| 3 |
+
import re
|
| 4 |
+
|
| 5 |
+
from prompts import prescription_text_user
|
| 6 |
+
|
| 7 |
+
def get_prescription_text(messages):
|
| 8 |
+
"""
|
| 9 |
+
Function to inference openai to get prescription text.
|
| 10 |
+
"""
|
| 11 |
+
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
|
| 12 |
+
prompt = prescription_text_user
|
| 13 |
+
cleaned_messages = [
|
| 14 |
+
{
|
| 15 |
+
"role": "system",
|
| 16 |
+
"content": [
|
| 17 |
+
{
|
| 18 |
+
"type": "text",
|
| 19 |
+
"text": prompt,
|
| 20 |
+
}
|
| 21 |
+
]
|
| 22 |
+
}
|
| 23 |
+
]
|
| 24 |
+
cleaned_messages.extend(messages)
|
| 25 |
+
# Make the API call to OpenAI
|
| 26 |
+
response = client.chat.completions.create(
|
| 27 |
+
model="gpt-4o-mini",
|
| 28 |
+
messages=cleaned_messages
|
| 29 |
+
)
|
| 30 |
+
prescription_text = response.choices[0].message.content.strip()
|
| 31 |
+
return prescription_text
|
agents/rag_decision_agent.py
CHANGED
|
@@ -9,7 +9,7 @@ def rag_decision(query):
|
|
| 9 |
"""
|
| 10 |
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
|
| 11 |
prompt = f"""
|
| 12 |
-
You are an agent of a Diagnostics Lab agentic
|
| 13 |
Your task is to determine whether the user's query requires Retrieval-Augmented
|
| 14 |
Generation (RAG) or not. Currently the system has access to information about
|
| 15 |
the following topics: Details and cost of Radiology Scans, Laboratory Tests, Health Packages,
|
|
|
|
| 9 |
"""
|
| 10 |
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
|
| 11 |
prompt = f"""
|
| 12 |
+
You are an agent of a Diagnostics Lab agentic AI Chatbot system.
|
| 13 |
Your task is to determine whether the user's query requires Retrieval-Augmented
|
| 14 |
Generation (RAG) or not. Currently the system has access to information about
|
| 15 |
the following topics: Details and cost of Radiology Scans, Laboratory Tests, Health Packages,
|
app.py
CHANGED
|
@@ -11,6 +11,7 @@ load_dotenv()
|
|
| 11 |
|
| 12 |
from agents import rag_decision
|
| 13 |
from agents import get_top_k
|
|
|
|
| 14 |
from prompts import bot_welcome_message, openai_opening_system_message, prescription_upload_message
|
| 15 |
|
| 16 |
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
|
|
@@ -36,6 +37,13 @@ with gr.Blocks() as demo:
|
|
| 36 |
temperature=0.7
|
| 37 |
)
|
| 38 |
return response.choices[0].message.content.strip()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 39 |
###########################################################################
|
| 40 |
def encode_image(image_path):
|
| 41 |
with open(image_path, "rb") as f:
|
|
@@ -51,18 +59,32 @@ with gr.Blocks() as demo:
|
|
| 51 |
return [{"role": "assistant", "content": bot_welcome_message}], None
|
| 52 |
|
| 53 |
def add_message(history, message):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
for x in message["files"]:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 55 |
history.append({"role": "user", "content": {"path": x}})
|
|
|
|
|
|
|
|
|
|
|
|
|
| 56 |
if message["text"] is not None:
|
| 57 |
history.append({"role": "user", "content": message["text"]})
|
|
|
|
| 58 |
return history, gr.MultimodalTextbox(value=None, interactive=False, file_count="multiple", placeholder="Enter message or upload file...")
|
| 59 |
|
| 60 |
def respond(history):
|
| 61 |
-
# print("history", history)
|
| 62 |
if len(history) == 2:
|
| 63 |
-
# print("Inside")
|
| 64 |
history.insert(0,{"role": "system", "content": openai_opening_system_message})
|
| 65 |
-
# print("history after insert", history)
|
| 66 |
messages = copy.deepcopy(history)
|
| 67 |
for i, msg in enumerate(messages):
|
| 68 |
if isinstance(msg["content"], str):
|
|
@@ -72,37 +94,36 @@ with gr.Blocks() as demo:
|
|
| 72 |
"text": msg["content"]
|
| 73 |
}]
|
| 74 |
if isinstance(msg["content"],tuple):
|
| 75 |
-
# print("inside tuple", msg["content"])
|
| 76 |
# If the content is a file path, encode it
|
| 77 |
-
file_path = msg["content"][0]
|
| 78 |
-
#
|
| 79 |
-
encoded_content = encode_image(file_path)
|
| 80 |
messages[i]["content"] = [{
|
| 81 |
-
"type": "
|
| 82 |
-
"
|
| 83 |
-
|
| 84 |
clean_messages = [] # OpenAI doesnot accept metadata or options in messages
|
| 85 |
for msg in messages:
|
| 86 |
-
try:
|
| 87 |
-
if msg["content"][0]["type"] == "image_url":
|
| 88 |
-
clean_messages.append({
|
| 89 |
-
"role": "user",
|
| 90 |
-
"content": [{
|
| 91 |
-
"type": "text",
|
| 92 |
-
"text": prescription_upload_message
|
| 93 |
-
}]})
|
| 94 |
-
except:
|
| 95 |
-
pass
|
| 96 |
clean_msg = {
|
| 97 |
"role": msg["role"],
|
| 98 |
"content": msg["content"]
|
| 99 |
}
|
| 100 |
-
clean_messages.append(clean_msg)
|
| 101 |
-
# print("First messages", messages[0])
|
| 102 |
|
| 103 |
########################### AGENTIC WORKFLOW ##########################
|
| 104 |
# Call Agent1- the RAG Decision Agent
|
| 105 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 106 |
|
| 107 |
if rag_decision == True:
|
| 108 |
#Call Agent2 - the RAG Retrieval Agent
|
|
@@ -120,12 +141,10 @@ with gr.Blocks() as demo:
|
|
| 120 |
response = agent3_llm_agent(clean_messages)
|
| 121 |
#######################################################################
|
| 122 |
|
| 123 |
-
# print("response:", response)
|
| 124 |
# history.append({"role": "assistant", "content": response})
|
| 125 |
history.append({"role": "assistant", "content": ""})
|
| 126 |
|
| 127 |
# return history
|
| 128 |
-
# print("history", history)
|
| 129 |
for character in response:
|
| 130 |
history[-1]['content'] += character
|
| 131 |
time.sleep(0.005)
|
|
|
|
| 11 |
|
| 12 |
from agents import rag_decision
|
| 13 |
from agents import get_top_k
|
| 14 |
+
from agents import get_prescription_text
|
| 15 |
from prompts import bot_welcome_message, openai_opening_system_message, prescription_upload_message
|
| 16 |
|
| 17 |
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
|
|
|
|
| 37 |
temperature=0.7
|
| 38 |
)
|
| 39 |
return response.choices[0].message.content.strip()
|
| 40 |
+
|
| 41 |
+
def agent4_get_prescription_text(messages):
|
| 42 |
+
"""
|
| 43 |
+
Function to inference openai to get prescription text.
|
| 44 |
+
"""
|
| 45 |
+
prescription_text = get_prescription_text(messages)
|
| 46 |
+
return prescription_text
|
| 47 |
###########################################################################
|
| 48 |
def encode_image(image_path):
|
| 49 |
with open(image_path, "rb") as f:
|
|
|
|
| 59 |
return [{"role": "assistant", "content": bot_welcome_message}], None
|
| 60 |
|
| 61 |
def add_message(history, message):
|
| 62 |
+
# Send the image to the agent4_get_prescription_text
|
| 63 |
+
messages = []
|
| 64 |
+
if message["text"] is not None:
|
| 65 |
+
messages.append({
|
| 66 |
+
"role": "user",
|
| 67 |
+
"content":[{"type": "text", "text": message["text"]}]
|
| 68 |
+
})
|
| 69 |
for x in message["files"]:
|
| 70 |
+
encoded_content = encode_image(x)
|
| 71 |
+
messages[0]["content"].append({
|
| 72 |
+
"type": "image_url",
|
| 73 |
+
"image_url": {"url": f"data:image/jpeg;base64,{encoded_content}"}
|
| 74 |
+
})
|
| 75 |
history.append({"role": "user", "content": {"path": x}})
|
| 76 |
+
# call agent4_get_prescription_text to get prescription text
|
| 77 |
+
prescription_text = "Extracted lab tests from prescription: \n" + agent4_get_prescription_text(messages)
|
| 78 |
+
history.append({"role": "system", "content": prescription_text})
|
| 79 |
+
|
| 80 |
if message["text"] is not None:
|
| 81 |
history.append({"role": "user", "content": message["text"]})
|
| 82 |
+
|
| 83 |
return history, gr.MultimodalTextbox(value=None, interactive=False, file_count="multiple", placeholder="Enter message or upload file...")
|
| 84 |
|
| 85 |
def respond(history):
|
|
|
|
| 86 |
if len(history) == 2:
|
|
|
|
| 87 |
history.insert(0,{"role": "system", "content": openai_opening_system_message})
|
|
|
|
| 88 |
messages = copy.deepcopy(history)
|
| 89 |
for i, msg in enumerate(messages):
|
| 90 |
if isinstance(msg["content"], str):
|
|
|
|
| 94 |
"text": msg["content"]
|
| 95 |
}]
|
| 96 |
if isinstance(msg["content"],tuple):
|
|
|
|
| 97 |
# If the content is a file path, encode it
|
| 98 |
+
# file_path = msg["content"][0]
|
| 99 |
+
# encoded_content = encode_image(file_path)
|
|
|
|
| 100 |
messages[i]["content"] = [{
|
| 101 |
+
"type": "text",
|
| 102 |
+
"text": "User Image"}]
|
|
|
|
| 103 |
clean_messages = [] # OpenAI doesnot accept metadata or options in messages
|
| 104 |
for msg in messages:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 105 |
clean_msg = {
|
| 106 |
"role": msg["role"],
|
| 107 |
"content": msg["content"]
|
| 108 |
}
|
| 109 |
+
clean_messages.append(clean_msg)
|
|
|
|
| 110 |
|
| 111 |
########################### AGENTIC WORKFLOW ##########################
|
| 112 |
# Call Agent1- the RAG Decision Agent
|
| 113 |
+
if clean_messages[-1]["role"] == "system" and "No prescription found" in clean_messages[-1]["content"]:
|
| 114 |
+
# If the last message is a system message with "No prescription found", skip RAG decision
|
| 115 |
+
rag_decision = False
|
| 116 |
+
elif clean_messages[-2]["role"] == "system" and "No prescription found" in clean_messages[-2]["content"]:
|
| 117 |
+
rag_decision = False
|
| 118 |
+
else:
|
| 119 |
+
rag_query = ""
|
| 120 |
+
# Get the last 10 messages in the format "role: <message>"
|
| 121 |
+
last_10 = clean_messages[-10:] if len(clean_messages) > 10 else clean_messages
|
| 122 |
+
rag_query = "\n".join(
|
| 123 |
+
f"{msg['role']}: {msg['content'][0]['text'] if isinstance(msg['content'], list) and msg['content'] and 'text' in msg['content'][0] else ''}"
|
| 124 |
+
for msg in last_10
|
| 125 |
+
)
|
| 126 |
+
rag_decision = agent1_rag_decision(rag_query)
|
| 127 |
|
| 128 |
if rag_decision == True:
|
| 129 |
#Call Agent2 - the RAG Retrieval Agent
|
|
|
|
| 141 |
response = agent3_llm_agent(clean_messages)
|
| 142 |
#######################################################################
|
| 143 |
|
|
|
|
| 144 |
# history.append({"role": "assistant", "content": response})
|
| 145 |
history.append({"role": "assistant", "content": ""})
|
| 146 |
|
| 147 |
# return history
|
|
|
|
| 148 |
for character in response:
|
| 149 |
history[-1]['content'] += character
|
| 150 |
time.sleep(0.005)
|
faiss_index_store/index.faiss
CHANGED
|
Binary files a/faiss_index_store/index.faiss and b/faiss_index_store/index.faiss differ
|
|
|
faiss_index_store/index.pkl
CHANGED
|
Binary files a/faiss_index_store/index.pkl and b/faiss_index_store/index.pkl differ
|
|
|
prompts.py
CHANGED
|
@@ -11,21 +11,28 @@ and may vary from the information provided here.
|
|
| 11 |
**Can I help you with anything?**
|
| 12 |
"""
|
| 13 |
openai_opening_system_message = """"You are a helpful assistant of a diagnostic
|
| 14 |
-
services business.
|
| 15 |
The system uses RAG to retrieve relevant information from a knowledge base.
|
| 16 |
You can also answer questions based on the information provided by the user.
|
|
|
|
|
|
|
|
|
|
| 17 |
Do not provide any medical advice or diagnosis.
|
| 18 |
"""
|
| 19 |
-
prescription_upload_message = """
|
| 20 |
-
Check if the image contains a prescription, if not, ask the user to upload a valid prescription
|
| 21 |
-
image or provide details about the tests they are interested in. Do not provide
|
| 22 |
-
information about any other image if the image is not a prescription. Just reply that "I am
|
| 23 |
-
only trained to assist with prescription images and the uploaded image does not seem
|
| 24 |
-
to be a prescription." Do not answer any question if the uploaded
|
| 25 |
-
image is not a prescription.
|
| 26 |
-
If the image contains a prescription, extract the tests advised by the doctor
|
| 27 |
-
and provide details about those tests like rates and offers. For the tests
|
| 28 |
which are not in your knowledge base, say, "Not in our lab".
|
| 29 |
At last, also ask the user if You missed any test.
|
| 30 |
Do not provide any medical advice or diagnosis.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
"""
|
|
|
|
| 11 |
**Can I help you with anything?**
|
| 12 |
"""
|
| 13 |
openai_opening_system_message = """"You are a helpful assistant of a diagnostic
|
| 14 |
+
services business in an agentic AI framework.
|
| 15 |
The system uses RAG to retrieve relevant information from a knowledge base.
|
| 16 |
You can also answer questions based on the information provided by the user.
|
| 17 |
+
If the user has uploaded an image and an agent has replied in the message that No prescription
|
| 18 |
+
found, then just reply "The image does not seem to that of a prescription, please
|
| 19 |
+
upload good quality staright images of prescription" and nothing else.
|
| 20 |
Do not provide any medical advice or diagnosis.
|
| 21 |
"""
|
| 22 |
+
prescription_upload_message = """For the tests
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
which are not in your knowledge base, say, "Not in our lab".
|
| 24 |
At last, also ask the user if You missed any test.
|
| 25 |
Do not provide any medical advice or diagnosis.
|
| 26 |
+
"""
|
| 27 |
+
|
| 28 |
+
prescription_text_user = f"""You are an agent of a Diagnostics Lab agentic AI
|
| 29 |
+
Chatbot system using RAG on a knowledge base. Your job is to extract the
|
| 30 |
+
lab tests advised by the doctor in the prescription image uploaded by the user.
|
| 31 |
+
The user has uploaded an image.
|
| 32 |
+
Check if the image contains a medical prescription, if not, just reply
|
| 33 |
+
"No prescription found". DO NOT provide any other information about the image
|
| 34 |
+
if the image is not a prescription.
|
| 35 |
+
If the image is a prescription, extract the tests advised by the doctor and
|
| 36 |
+
using your knowledge about those tests, enumerate those in the reply.
|
| 37 |
+
Do not reply anything else other than the tests advised by the doctor.
|
| 38 |
"""
|
ratelist_offers.docx
CHANGED
|
Binary files a/ratelist_offers.docx and b/ratelist_offers.docx differ
|
|
|
ratelist_offers.pdf
CHANGED
|
Binary files a/ratelist_offers.pdf and b/ratelist_offers.pdf differ
|
|
|