File size: 10,793 Bytes
bdb09c8 c6163b1 b9dbc6c bdb09c8 b9dbc6c bdb09c8 c6163b1 b9dbc6c c6163b1 b9dbc6c bdb09c8 b9dbc6c c6163b1 b9dbc6c c6163b1 b9dbc6c c6163b1 b9dbc6c c6163b1 b9dbc6c c6163b1 b9dbc6c bdb09c8 c6163b1 bdb09c8 b9dbc6c c6163b1 b9dbc6c c6163b1 b9dbc6c c6163b1 b9dbc6c c6163b1 b9dbc6c c6163b1 b9dbc6c c6163b1 b9dbc6c c6163b1 b9dbc6c c6163b1 b9dbc6c c6163b1 b9dbc6c c6163b1 b9dbc6c c6163b1 b9dbc6c c6163b1 b9dbc6c c6163b1 b9dbc6c c6163b1 b9dbc6c c6163b1 b9dbc6c bdb09c8 c6163b1 b9dbc6c c6163b1 b9dbc6c c6163b1 b9dbc6c c6163b1 b9dbc6c bdb09c8 c6163b1 b9dbc6c bdb09c8 c6163b1 b9dbc6c c6163b1 b9dbc6c c6163b1 b9dbc6c c6163b1 b9dbc6c c6163b1 b9dbc6c c6163b1 bdb09c8 |
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 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
import streamlit as st
import google.generativeai as genai
import os
# from PIL import Image # Removing image focus for this agentic text example
import io
from typing import Optional, Tuple, Any # For type hinting
# --- Configuration and Initialization ---
# Securely load API key (Prioritize Secrets, then Env Vars)
GEMINI_API_KEY = st.secrets.get("GEMINI_API_KEY", os.environ.get("GEMINI_API_KEY"))
# Configure Gemini Client
genai_client_configured = False
if GEMINI_API_KEY:
try:
genai.configure(api_key=GEMINI_API_KEY)
genai_client_configured = True
except Exception as e:
st.error(f"Fatal Error: Failed to configure Google Generative AI. Check API Key and permissions. Details: {e}")
st.stop()
else:
st.error("β οΈ Gemini API Key not found. Please configure `GEMINI_API_KEY` in Streamlit secrets or environment variables.")
st.stop()
# Initialize models (Using specific models for consistency)
# Using a potentially more powerful model like 1.5 Pro might be beneficial for complex reasoning
MODEL_NAME = 'gemini-1.5-pro-latest' # Or 'gemini-1.5-flash' if speed is critical
if genai_client_configured:
try:
model = genai.GenerativeModel(MODEL_NAME)
# vision_model = genai.GenerativeModel('gemini-pro-vision') # Keep commented unless adding image capability back
except Exception as e:
st.error(f"Fatal Error: Failed to initialize Gemini model ({MODEL_NAME}). Details: {e}")
st.stop()
else:
st.error("AI Model could not be initialized due to configuration issues.")
st.stop()
# --- Core Agentic AI Simulation Function ---
# This prompt instructs the LLM to simulate a structured, agent-like reasoning process
# focused on differential diagnosis support.
AGENTIC_ANALYSIS_PROMPT_TEMPLATE = """
**Simulated Clinical Reasoning Agent Task:**
**Role:** You are an AI assistant simulating an agentic clinical reasoning process to support a healthcare professional. Your goal is NOT to diagnose, but to structure information, generate possibilities, and suggest logical next steps based *strictly* on the provided information.
**Input Data:** You will receive unstructured clinical information (e.g., symptoms, history, basic findings). Assume this is the *only* information available unless stated otherwise.
**Simulated Agentic Steps (Perform these sequentially in your response):**
1. **Information Extraction & Structuring:**
* Identify and list the key patient demographics (age, sex, if provided).
* List the primary symptoms and signs presented.
* Summarize relevant medical history points.
* Note any explicitly mentioned negative findings (pertinent negatives).
2. **Differential Considerations Generation:**
* Based *only* on the structured information from Step 1, generate a list of **potential differential considerations** (possible conditions that *could* explain the findings).
* **Use cautious and probabilistic language:** "could be consistent with," "warrants consideration," "less likely but possible," "should be ruled out." **AVOID definitive statements.**
* Briefly state the primary rationale linking each consideration to the key findings.
3. **Information Gap Analysis:**
* Identify critical pieces of information typically needed for assessment that are missing from the input (e.g., specific lab results, imaging details, physical exam specifics, duration/onset details).
4. **Suggested Next Steps for Investigation (for the Clinician):**
* Propose logical next steps a **healthcare professional might consider** to narrow down the possibilities or gather missing information.
* Categorize suggestions (e.g., Further History Taking, Physical Examination Points, Laboratory Tests, Imaging Studies).
* Frame these as *suggestions* for the clinician's judgment (e.g., "Consider ordering...", "Assessment of X may be informative", "Further questioning about Y could clarify...").
5. **Mandatory Disclaimer:** Conclude with: "This AI-generated analysis is for informational support only. It is **NOT** a diagnosis and cannot replace the judgment of a qualified healthcare professional who must consider the full clinical context, conduct necessary examinations, and interpret investigations."
**Input Clinical Information:**
---
{text_input}
---
**Agentic Analysis:**
"""
def run_agentic_reasoning(text_input: str) -> Tuple[Optional[str], Optional[str]]:
"""
Simulates an agentic reasoning process on clinical text using the Gemini model.
Args:
text_input: The clinical information provided by the user.
Returns:
A tuple containing:
- The structured analysis text (str) if successful, None otherwise.
- An error message (str) if an error occurred, None otherwise.
"""
if not text_input or not text_input.strip():
return None, "Input text cannot be empty."
try:
prompt = AGENTIC_ANALYSIS_PROMPT_TEMPLATE.format(text_input=text_input)
# Consider adding safety settings if dealing with potentially sensitive outputs
# safety_settings = [...]
# response = model.generate_content(prompt, safety_settings=safety_settings)
response = model.generate_content(prompt)
# Check for blocked content or other issues
if response.parts:
return response.text, None
elif response.prompt_feedback.block_reason:
return None, f"Analysis blocked by safety filters: {response.prompt_feedback.block_reason.name}. Please review input for potentially harmful content or adjust safety settings if appropriate."
else:
# Handle cases where the response might be empty but not explicitly blocked
candidate = response.candidates[0] if response.candidates else None
if candidate and candidate.finish_reason != "STOP":
return None, f"Analysis stopped prematurely. Reason: {candidate.finish_reason.name}. The input might be too complex or ambiguous."
else:
return None, "Received an empty or unexpected response from the AI model. The model may not have been able to process the request."
except Exception as e:
st.error(f"Critical Error during AI Analysis: {e}", icon="π¨") # Log for debugging
# Provide a user-friendly error message
return None, f"An error occurred while communicating with the AI model. Please try again later or check the input. Details: {e}"
# --- Streamlit User Interface ---
def main():
st.set_page_config(
page_title="Agentic AI Clinical Reasoning Support",
layout="wide",
initial_sidebar_state="expanded"
)
# --- Header ---
st.title("π€ Agentic AI: Clinical Reasoning Support Tool")
st.caption(f"Powered by Google Gemini ({MODEL_NAME})")
st.markdown("---")
# --- CRITICAL DISCLAIMER ---
st.warning(
"""
**π΄ EXTREMELY IMPORTANT DISCLAIMER π΄**
* This tool **SIMULATES** an AI reasoning process. It **DOES NOT DIAGNOSE** diseases or provide medical advice.
* Outputs are based **SOLELY** on the text input and the AI's internal knowledge, which may be incomplete or contain inaccuracies. **It lacks real-world clinical context.**
* **NEVER** use this tool for actual patient diagnosis, treatment decisions, or clinical management. It is intended for **educational and conceptual purposes ONLY**, potentially aiding clinicians in organizing thoughts or exploring possibilities.
* **ALWAYS rely on the expertise and judgment of qualified healthcare professionals.**
* **PRIVACY ALERT:** Do **NOT** enter identifiable patient information (PHI) unless you comply with all legal and ethical requirements (e.g., HIPAA, GDPR, patient consent). You are responsible for the data you input.
""",
icon="β οΈ"
)
st.markdown("---")
# --- Input Area ---
st.header("Clinical Information Input")
st.markdown("Enter de-identified clinical information below (e.g., symptoms, brief history, key findings). The AI will attempt a structured analysis.")
text_input = st.text_area(
"Enter Clinical Data:",
height=300,
placeholder="Example: A 68-year-old male presents with sudden onset shortness of breath and pleuritic chest pain. History of recent long-haul flight. Vitals show tachycardia (HR 110) and mild hypoxia (SpO2 92% on room air). No significant cardiac history mentioned...",
key="clinical_text_input"
)
# --- Action Button ---
analyze_button = st.button("βΆοΈ Run Agentic Analysis", key="analyze_button", type="primary", help="Click to start the simulated reasoning process.")
st.markdown("---") # Separator before results
# --- Output Area ---
st.header("Analysis Results")
if analyze_button:
if text_input:
with st.spinner("π§ Simulating agentic reasoning... Please wait."):
analysis_result, error_message = run_agentic_reasoning(text_input)
if error_message:
st.error(f"Analysis Failed: {error_message}", icon="β")
elif analysis_result:
st.markdown("**Simulated Agent Analysis Output:**")
st.markdown(analysis_result) # Use markdown for better formatting
else:
st.error("An unexpected issue occurred. No analysis was returned.", icon="β")
else:
st.warning("Please enter clinical information in the text area above before analyzing.", icon="βοΈ")
else:
st.info("Analysis results will appear here after you enter information and click 'Run Agentic Analysis'.")
# --- Sidebar for Explanation/Prompt ---
st.sidebar.header("About This Tool")
st.sidebar.info(
"This application demonstrates how an AI model (Gemini) can be prompted to simulate "
"a structured, agent-like approach to analyzing clinical information. It focuses on "
"differential considerations and suggesting investigation pathways for **clinician review**."
)
with st.sidebar.expander("View the Agentic Prompt Structure"):
st.markdown(f"```plaintext\n{AGENTIC_ANALYSIS_PROMPT_TEMPLATE.split('---')[0]} ... [Input Text] ...\n```")
st.caption("The prompt guides the AI to break down the task into logical steps.")
st.sidebar.header("Ethical Considerations")
st.sidebar.error(
"**Crucial Reminder:** This AI is a tool, not a clinician. It has limitations and biases. "
"Clinical decisions require human expertise, empathy, and comprehensive patient assessment. "
"Misuse can lead to harm."
)
if __name__ == "__main__":
main() |