Skip to content

Latest commit

Β 

History

10 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ’Š RxSafe β€” Prescription Validation Environment

Train AI agents to catch dangerous prescriptions before they reach patients.

OpenEnv


Why This Matters

Medication errors harm 1.5 million people per year in the US alone. Pharmacists manually review every prescription for dosage safety, drug interactions, allergy conflicts, and contraindications β€” a critical but error-prone process under time pressure.

RxSafe creates a standardized RL environment where AI agents learn to perform this validation. The agent must investigate patient records (multi-step) and identify safety issues before approving, modifying, or rejecting a prescription.

This directly maps to a future product: an AI clinical pharmacist assistant that catches dangerous prescriptions in real-time.


Environment Design

Multi-Step Investigation

Unlike single-step classify-and-done environments, RxSafe requires the agent to actively investigate before making a decision:

reset() β†’ Agent sees prescription (drug, dose, patient name/age)
   ↓
step(request_info: "allergies")   β†’ Reveals patient allergies
step(request_info: "medications") β†’ Reveals current medications  
step(request_info: "conditions")  β†’ Reveals medical conditions
   ↓
step(submit: findings + recommendation) β†’ Graded by environment

Skipping investigation means missing critical safety issues. Thorough investigation is part of the score.

Action Space

Field Type Description
action_type "request_info" or "submit" Investigation vs. final answer
info_requested string allergies, medications, conditions, full_profile
dosage_safe bool Is the dose within safe limits?
interactions_found list[str] Drug pairs, e.g. ["warfarin-aspirin"]
allergy_conflicts list[str] e.g. ["penicillin-amoxicillin"]
contraindications_found list[str] e.g. ["kidney_disease-metformin"]
recommendation string approve, modify, or reject
reasoning string Clinical reasoning (hard task)

Observation Space

Field Type Description
prescription_id string Unique ID
patient_name string Patient name
patient_age int Patient age
drug_name string Prescribed drug
drug_dose string Dose amount
drug_frequency string How often
steps_remaining int Steps left in episode
known_allergies list or null Revealed after request
current_medications list or null Revealed after request
medical_conditions list or null Revealed after request
feedback string Grading feedback (after submit)
score_breakdown dict Per-component scores
issues_found_correctly list What agent caught
issues_missed list What agent failed to catch

Tasks

Task 1: dosage_check (Easy)

Check if the prescribed dosage is within safe daily maximum.

  • Max steps: 2
  • Scenarios: 6 (overdose detection: ibuprofen/tramadol/simvastatin, safe prescriptions: metformin/lisinopril/ciprofloxacin)
  • Scoring: dosage Γ— 0.50 + recommendation Γ— 0.50
  • Example: Ibuprofen 2400mg TID = 7200mg/day (max safe: 3200mg) β†’ modify

Task 2: interaction_check (Medium)

Check dosage + drug-drug interactions + allergy conflicts.

  • Max steps: 4 (investigate, then submit)
  • Scenarios: 8 (warfarin+aspirin, SSRI+tramadol, penicillin allergy, NSAID allergy, simvastatin+amiodarone, and more)
  • Scoring: dosage Γ— 0.20 + interactions Γ— 0.30 + allergies Γ— 0.25 + recommendation Γ— 0.25
  • Example: Patient on sertraline prescribed tramadol β†’ serotonin syndrome risk β†’ reject

Task 3: full_validation (Hard)

Complete multi-step prescription validation with investigation scoring.

  • Max steps: 6 (investigate all sources, then submit)
  • Scenarios: 8 (complex multi-issue cases with contraindications, cross-allergies, and cascading interactions)
  • Scoring: dosage Γ— 0.15 + interactions Γ— 0.20 + allergies Γ— 0.15 + contraindications Γ— 0.15 + recommendation Γ— 0.20 + investigation Γ— 0.15
  • Example: Patient with myasthenia gravis prescribed ciprofloxacin while on warfarin β†’ interaction + contraindication β†’ reject

Reward Design

Partial Progress Signals

  • Investigation rewards: +0.05 per info request (encourages thorough investigation)
  • Interaction recall: Partial credit for finding some but not all interactions
  • Priority adjacency: modify vs reject both indicate "something wrong" β†’ 0.6 partial credit
  • False positive penalty: Small penalty for reporting non-existent issues (-0.1 per false positive)
  • Critical miss penalty: Approving a dangerous prescription scores 0.0 on recommendation

Deterministic Grading

All scenarios have predetermined correct answers based on a curated drug interaction database with 12 drugs and their known interactions, allergy classes, and contraindicated conditions.

Score Diversity

The grader produces varied scores across episodes β€” never constant. Tested across all scenarios with multiple answer combinations.


Drug Database

13 drugs with realistic interaction profiles:

Drug Class Key Interactions
Warfarin Anticoagulant aspirin, ibuprofen, cipro (bleeding risk)
Aspirin NSAID/antiplatelet warfarin, methotrexate, heparin
Ibuprofen NSAID warfarin, lisinopril, methotrexate, lithium
Metformin Antidiabetic Contraindicated in severe kidney disease
Lisinopril ACE inhibitor potassium, spironolactone, NSAIDs
Amoxicillin Penicillin antibiotic Cross-allergy with penicillin class
Ciprofloxacin Fluoroquinolone warfarin, theophylline (seizure risk)
Simvastatin Statin amiodarone, erythromycin (rhabdomyolysis)
Sertraline SSRI tramadol (serotonin syndrome β€” fatal)
Tramadol Opioid SSRIs (serotonin syndrome β€” fatal)
Methotrexate Immunosuppressant NSAIDs (toxicity), many others
Digoxin Cardiac glycoside amiodarone, verapamil (toxicity)
Amiodarone Antiarrhythmic digoxin, simvastatin, warfarin (toxicity)

Setup & Usage

Quick Start

# Install dependencies
pip install -r requirements.txt

# Run locally
export ENABLE_WEB_INTERFACE=true
uvicorn server.app:app --host 0.0.0.0 --port 8000

# Validate local packaging
openenv validate

# Run lightweight regression checks
python3 -m unittest discover -s tests -v

# Open web UI (available when ENABLE_WEB_INTERFACE=true)
open http://localhost:8000/web

Docker

docker build -t rx-safe-env .
docker run -p 8000:8000 rx-safe-env

Run Inference

export HF_TOKEN="your_hugging_face_token"
export LOCAL_IMAGE_NAME="rx-safe-env"
python3 inference.py

API Examples

# Reset with medium task
curl -X POST http://localhost:8000/reset \
  -H "Content-Type: application/json" \
  -d '{"task": "interaction_check", "seed": 42}'

# Request patient allergies
curl -X POST http://localhost:8000/step \
  -H "Content-Type: application/json" \
  -d '{"action": {"action_type": "request_info", "info_requested": "allergies"}}'

# Submit validation
curl -X POST http://localhost:8000/step \
  -H "Content-Type: application/json" \
  -d '{"action": {"action_type": "submit", "dosage_safe": true, "interactions_found": ["warfarin-aspirin"], "allergy_conflicts": [], "recommendation": "reject"}}'

Baseline Scores

Before submission, replace the placeholder values below with exact scores from a real run of python3 inference.py.

Recommended baseline run:

export HF_TOKEN="your_hugging_face_token"
export API_BASE_URL="https://router.huggingface.co/v1"
export MODEL_NAME="Qwen/Qwen2.5-72B-Instruct"
export LOCAL_IMAGE_NAME="rx-safe-env"
python3 inference.py

If you are evaluating against a deployed Hugging Face Space instead of a local Docker image:

export ENV_URL="https://YOUR_SPACE_URL.hf.space"
python3 inference.py

Record the score from the final [END] line for each task:

Task Difficulty Measured Score Reproducibility Notes
dosage_check Easy 1.00 5-seed average via HF Space, Qwen/Qwen2.5-72B-Instruct
interaction_check Medium 0.65 5-seed average via HF Space, Qwen/Qwen2.5-72B-Instruct
full_validation Hard 0.48 5-seed average via HF Space, Qwen/Qwen2.5-72B-Instruct

Project Structure

rx-safe-env/
β”œβ”€β”€ server/
β”‚   β”œβ”€β”€ __init__.py
β”‚   └── app.py               ← Canonical OpenEnv server entrypoint
β”œβ”€β”€ rx_safe/
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ models.py            ← Drug database, scenarios, Pydantic types
β”‚   β”œβ”€β”€ client.py             ← HTTP client
β”‚   └── server/
β”‚       β”œβ”€β”€ __init__.py
β”‚       β”œβ”€β”€ app.py            ← Compatibility shim to the root server
β”‚       └── environment.py    ← Core RL environment logic
β”œβ”€β”€ tests/
β”‚   └── test_environment.py   ← 18-test regression suite
β”œβ”€β”€ Dockerfile
β”œβ”€β”€ inference.py              ← Mandatory inference script (5-seed multi-task)
β”œβ”€β”€ openenv.yaml              ← OpenEnv manifest
β”œβ”€β”€ pyproject.toml
β”œβ”€β”€ requirements.txt
└── README.md

OpenEnv Spec Compliance

  • βœ… Typed Pydantic models (Action, Observation, State)
  • βœ… step() / reset() / state() API
  • βœ… openenv.yaml with metadata
  • βœ… 3 tasks: easy β†’ medium β†’ hard
  • βœ… Graders return scores in [0.0, 1.0]
  • βœ… Multi-step trajectories with investigation
  • βœ… Partial rewards (not binary)
  • βœ… Deterministic, reproducible grading with seed support
  • βœ… Working Dockerfile
  • βœ… Baseline inference script with [START]/[STEP]/[END] format
  • βœ… Runs on vcpu=2, memory=8gb (no GPU needed)

License

MIT

About

Real-world OpenEnv benchmark for prescription safety validation with graded easy, medium, and hard clinical review tasks

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages