Spaces:
Running
title: MedCodeRL - Medical Coding & Billing Compliance Environment
emoji: π₯
colorFrom: blue
colorTo: green
sdk: docker
pinned: false
app_port: 7680
base_path: /web
tags:
- openenv
MedCodeRL π₯
Medical Coding & Billing Compliance OpenEnv Environment
A realistic RL environment where AI agents must navigate the complex world of medical coding (ICD-10/CPT), billing compliance, and fraud detection. Built to the OpenEnv specification.
π― Why This Matters
- The US healthcare system loses $125B+ annually to incorrect medical coding
- Hospitals spend $80K+ per coder annually with 12β18 month training cycles
- Current LLMs fail at ICD-10/CPT coding because they lack hierarchical constraint understanding
- No existing OpenEnv environment covers this critical domain
Quick Start
from my_env import MedAction, MedCodeEnv
try:
env = MedCodeEnv.from_docker_image("medcoderl:latest")
result = env.reset()
print(f"Case: {result.observation.case_id}")
print(f"Note: {result.observation.clinical_note}")
action = MedAction(
diagnosis_codes=["J02.9"],
procedure_codes=["99213"],
decision="approve",
confidence=0.9,
reasoning="Acute pharyngitis with appropriate E&M coding for straightforward visit.",
risk_flags=[]
)
result = env.step(action)
print(f"Score: {result.reward}")
finally:
env.close()
π³ Building & Running with Docker
# Build from project root
docker build -t medcoderl .
# Run locally
docker run -p 7680:7680 medcoderl
# Verify it's running
curl http://localhost:7680/health
Deploying to Hugging Face Spaces
- Create a new Space on Hugging Face (Docker SDK):
# Via huggingface_hub CLI
huggingface-cli repo create medcoderl --type space --space-sdk docker
- Push your code:
git remote add hf https://huggingface.co/spaces/<your-username>/medcoderl
git push hf main
- Or use:
openenv push
βοΈ Environment Variables
The following variables must be set before running inference.py:
| Variable | Required | Description |
|---|---|---|
HF_TOKEN |
β | Your Hugging Face / API key (also accepts OPENAI_API_KEY) |
API_BASE_URL |
β | The API endpoint for the LLM (default: https://api.openai.com/v1) |
MODEL_NAME |
β | The model identifier to use for inference (default: gpt-4o-mini) |
CASES_PER_DIFFICULTY |
β | Number of cases per difficulty tier (default: 5) |
MAX_RUNTIME_SECONDS |
β | Timeout safety limit (default: 1100 β 18.3 min) |
π¬ Environment Details
Action Space (MedAction)
| Field | Type | Description |
|---|---|---|
diagnosis_codes |
list[str] (1β5) | ICD-10-CM codes (primary + secondary) |
procedure_codes |
list[str] (0β5) | CPT/HCPCS procedure codes |
decision |
approve / reject / review | Billing compliance decision |
confidence |
float (0.0β1.0) | Agent confidence in coding decision |
reasoning |
str (15β500 chars) | Clinical justification |
modifier_codes |
list[str] (0β3) | Optional CPT modifier codes |
risk_flags |
list[str] (0β5) | Compliance risk flags identified |
Observation Space (MedObservation)
| Field | Type | Description |
|---|---|---|
case_id |
str | Unique case identifier |
difficulty |
str | easy / medium / hard |
clinical_note |
str | Full clinical documentation |
symptoms |
list[str] | Reported symptoms |
treatments |
list[str] | Treatments administered |
insurance_type |
str | Medicare / Medicaid / Private / Uninsured |
prior_auth_required |
bool | Prior authorization needed |
treatment_cost |
str | low / medium / high |
patient_age |
int | Patient age |
patient_sex |
str | M / F |
provider_specialty |
str | Treating provider specialty |
visit_type |
str | inpatient / outpatient / emergency / telehealth |
comorbidities |
list[str] | Pre-existing conditions |
lab_results |
str / null | Relevant lab findings |
medications |
list[str] | Current medications |
Reward System
Grader Components (Deterministic, 0.0β1.0):
| Component | Weight | Description |
|---|---|---|
| Diagnosis accuracy (ICD-10) | 35% | Jaccard + partial prefix matching |
| Procedure accuracy (CPT) | 20% | Jaccard + partial prefix matching |
| Decision accuracy | 25% | Exact match (1.0), partial credit for "review" (0.2β0.3) |
| Reasoning quality | 10% | Length + medical terminology density |
| Risk flag identification | 5% | Jaccard similarity with expected flags |
| Confidence calibration | 5% |
Shaped Penalties (scaled by difficulty β easy Γ0.8, medium Γ1.0, hard Γ1.2):
| Penalty | Value | Trigger |
|---|---|---|
| Wrong approval | β0.25 | Approved a case that should be rejected |
| Wrong denial | β0.20 | Rejected a case that should be approved |
| Upcoding | β0.15 | Predicted >1 extra procedure codes |
| Missing primary code | β0.15 | Ground truth primary ICD-10 code not in prediction |
| Undercoding | β0.10 | <50% of expected diagnoses covered |
| Unnecessary procedure | β0.10 | Predicted procedures not in ground truth |
| Low confidence | β0.05 | Confidence < 0.2 |
Bonuses:
| Bonus | Value | Trigger |
|---|---|---|
| Perfect diagnosis | +0.05 | Diagnosis accuracy β₯ 0.99 |
| Good reasoning | +0.03 | Reasoning quality β₯ 0.80 |
| All risk flags | +0.05 | Risk identification β₯ 0.99 |
π Tasks (90 cases total)
π’ Easy (30 cases)
Straightforward clinical cases with single diagnoses and direct ICD-10/CPT mapping. Examples: viral pharyngitis, UTI, ankle sprain, routine wellness exam, vaccination, tension headache.
π‘ Medium (30 cases)
Multi-diagnosis cases with comorbidities, insurance considerations, and partial ambiguity. Examples: COPD with pneumonia, diabetic neuropathy, cardiac workup, RA flare, MS relapse, hip fracture.
π΄ Hard (30 cases)
Complex compliance dilemmas: upcoding, unbundling, fraud detection, medically unnecessary treatments, dangerous polypharmacy, ethical edge cases. Examples: Medicare fraud (cloned notes, unbundled labs), off-label immunotherapy, DKA in uninsured patient, advanced dementia with aggressive intervention requests.
π Running the Inference Script
export HF_TOKEN="your-key"
export API_BASE_URL="https://api.openai.com/v1"
export MODEL_NAME="gpt-4o-mini"
python inference.py
Structured Logging
The inference script emits structured stdout logs in [START], [STEP], [END] format as required by the OpenEnv evaluation pipeline:
[START] {"task_id": "easy", "model": "gpt-4o-mini", "num_cases": 5}
[STEP] {"task_id": "easy", "step": 1, "action": {...}, "reward": 0.72, "done": true, "info": {"case_id": "easy_001", "feedback": "..."}}
[STEP] {"task_id": "easy", "step": 2, "action": {...}, "reward": 0.65, "done": true, "info": {"case_id": "easy_002", "feedback": "..."}}
...
[END] {"task_id": "easy", "reward": 0.68, "num_cases": 5}
[START] {"task_id": "medium", "model": "gpt-4o-mini", "num_cases": 5}
...
[END] {"task_id": "medium", "reward": 0.52, "num_cases": 5}
[START] {"task_id": "hard", "model": "gpt-4o-mini", "num_cases": 5}
...
[END] {"task_id": "hard", "reward": 0.31, "num_cases": 5}
Expected Baseline Scores (gpt-4o-mini)
| Difficulty | Expected Avg | Score Range |
|---|---|---|
| Easy | ~0.70 | 0.55 β 0.85 |
| Medium | ~0.50 | 0.35 β 0.65 |
| Hard | ~0.30 | 0.15 β 0.45 |
| Overall | ~0.50 | 0.35 β 0.65 |
Development & Testing
Run comprehensive tests
python test_env.py
Runs 11 tests covering case loading, reset/step/state API, reward range, grader determinism, reward shaping, episode boundaries, and invalid action handling.
Run server locally
uvicorn server.app:app --reload --host 0.0.0.0 --port 7680
Direct environment testing
from server.my_env_environment import MyEnvironment
from models import MedAction
env = MyEnvironment()
obs = env.reset(task_id="easy")
action = MedAction(
diagnosis_codes=["J02.9"],
procedure_codes=["99213"],
decision="approve",
confidence=0.9,
reasoning="Acute pharyngitis with appropriate coding.",
risk_flags=[]
)
result = env.step(action)
print(f"Score: {result.reward}, Done: {result.done}")
Pre-submission validation
# Validate locally
./validate-submission.sh https://your-space.hf.space
# Or run openenv validate directly
openenv validate
Project Structure
medcoderl/
βββ __init__.py # Module exports
βββ README.md # This file
βββ openenv.yaml # OpenEnv manifest (full metadata)
βββ pyproject.toml # Dependencies
βββ Dockerfile # Root Dockerfile for HF Spaces
βββ client.py # MedCodeEnv client
βββ models.py # MedAction & MedObservation models
βββ inference.py # Baseline inference script (structured logging)
βββ test_env.py # Comprehensive environment tests (11 tests)
βββ validate-submission.sh # Pre-submission validator
βββ tasks/
β βββ easy.json # 30 easy clinical cases
β βββ medium.json # 30 medium clinical cases
β βββ hard.json # 30 hard clinical cases
βββ server/
βββ __init__.py # Server exports
βββ my_env_environment.py # Core env logic + grader + rewards
βββ app.py # FastAPI application
βββ Dockerfile # Alternative multi-stage Dockerfile
βββ requirements.txt # Server dependencies
β οΈ Disclaimer
This environment is a simulation for AI training and evaluation only. It does not use real patient data and should not be used for actual medical coding or billing. All clinical cases are synthetic.
License
MIT License