Skip to main content

A Python package for simulating hospital administrative tasks.

Project description

H-AdminSim


DOI PyPI Version Downloads

 


Recent updates 📣

  • v1.2.4—v1.2.6 (April 2026): Improved scheduling simulation for more realistic behavior.
    • Added option for more natural patient end phrases.
    • Enhanced preference rejection for more realistic simulation.
    • Improved scheduling simulation stability.
  • v1.2.3 (April 2026): Add support for custom department and disease-symptom data.
  • v1.2.1, v1.2.2 (April 2026): Update license to Apache License 2.0.
  • v1.2.0 (April 2026): Bug fixes and simulation improvements.
  • v1.1.0 (March 2026): Merge administrative simulation code from patientsim into h-adminsim.
  • v1.0.5 (March 2026): Minor improvements.
  • v1.0.4 (March 2026): Simulation improvements.
  • v1.0.3 (February 2026): Update error exception codes for observable traceback.
  • v1.0.2 (February 2026): Update dependencies for stable simulation.
  • v1.0.1 (February 2026): H-AdminSim now supports concurrent simulation and open-source tool calling.
  • v1.0.0 (February 2026): H-AdminSim package has been released.

 

 


Overview 📚

H-AdminSim is an official Python package for simulating interactions between hospital administrative staff and first-visit outpatients using LLM agents. It provides a standardized evaluation testbed for assessing LLM performance across key administrative tasks across multiple care levels (primary, secondary, and tertiary), with optional FHIR integration and support for heterogeneous deployment environments, allowing flexible simulation workflows tailored to diverse hospital systems.

Large hospitals often handle 10,000+ outpatient encounters per day, and prior reports indicate limited specialization among administrative staff despite high workload. H-AdminSim is designed to help address these challenges by offering a realistic, reproducible simulation environment that supports future hospital automation and LLM-assisted administrative workflows.

 

1. Care level-specific data synthesis

We provide configuration examples for simulating primary, secondary, and tertiary care settings. Each configuration reflects key characteristics of its hospital level:

  • Hospital time granularity: tertiary < secondary = primary (coarser in lower levels)
  • Number of departments: primary < secondary < tertiary
  • Number of physicians: primary < secondary < tertiary
  • Patient referral rate: primary < secondary < tertiary
  • Proportion of patients with preferred physician/date: primary < secondary = tertiary

You may also define your own conditions using a custom configuration file (e.g., data_synthesis.yaml)

 

2. Hospital Administration Simulation

2.1. Patient Intake Simulation

We extend the previously emergency department-focused PatientSim to enable realistic conversations between administrative staff and first-visit outpatients with diverse backgrounds.

  • Disease profile: One of 194 disease–symptom pairs across 9 internal-medicine departments (gastroenterology, cardiology, pulmonology, endocrinology/metabolism, nephrology, hematology/oncology, allergy, infectious diseases, rheumatology)
  • Medical referral status: Dialogue flow adapts based on whether the patient has a referral
  • Tasks: Department recommendation, information extraction, structured data construction

2.2. Appointment Scheduling Simulation

We simulate realistic scheduling interactions between administrative staff and patients, reflecting diverse scheduling behaviors and hospital-level constraints.

  • Time flow: Users can define the simulation period and starting point, enabling the agent to perform time-related tasks based on the progression of simulated time.
  • Patient preferences: ASAP (earliest slot), physician (specific physician requested), date (preferred date range start)
  • Random requests: cancellation, rescheduling
  • Tasks: New appointment scheduling, rescheduling, schdule cancellation

2.3. FHIR Integration

We provide optional support for integrating with FHIR, allowing the simulator to operate flexibly across heterogeneous hospital environments as long as FHIR-compatible data is available. For instructions on running a FHIR server, please refer to the FHIR Server Execution repository.

 

 


Quick Starts 🚀

1. Installation

pip install h_adminsim
import h_adminsim
print(h_adminsim.__version__)

 

2. Environment Variables

Before using the LLM API, you need to provide the API key (or the required environment variables for each model) either directly or in a .env file.

# For GPT API without Azure
OPENAI_API_KEY=${YOUR_OPENAI_KEY}

# For Gemini API
GOOGLE_API_KEY=${YOUR_GEMINI_API_KEY}

 

3. Simulation

from h_adminsim.pipeline import DataGenerator, Simulator
from h_adminsim.task.agent_task import OutpatientFirstIntake, OutpatientFirstScheduling

data_generator = DataGenerator()
data_generator.build(convert_to_fhir=True)
agent_data_dir = data_generator.save_dir / 'agent_data'
output_dir = data_generator.save_dir / 'simulation_results'

# Intake task
intake_task = OutpatientFirstIntake(
    patient_model='gpt-5-nano',
    admin_staff_model='gemini-2.5-flash',
)

# Scheduling task
scheduling_task = OutpatientFirstScheduling(
    patient_model='gpt-5-nano',
    admin_staff_model='gpt-5-mini',
)

# Simulation
simulator = Simulator(
    intake_task=intake_task,
    scheduling_task=scheduling_task,
)
simulator.run(
    simulation_data_path=agent_data_dir,
    output_dir=output_dir,
    resume=False,
    verbose=True
)

 

 


Components Details ⚙️

1. Data synthesis

from h_adminsim.pipeline import DataGenerator

# 1. Generator Initialization
# 1.1. Default usaage
data_generator = DataGenerator()    # Default: primary care
# data_generator = DataGenerator(care_level='secondary') # For secondary care
# data_generator = DataGenerator(care_level='tertiary')  # For tertiary care

# 1.2. You can synthesize data with your own configuration
data_generator = DataGenerator(config='data_config.yaml')


# 2. Synthesizing Data
# 2.1. Default usage
data_generator.build()

# 2.2. When you want the synthesized data returned along with its FHIR-converted version (optional)
data_generator.build(convert_to_fhir=True)

# 2.3. Using Custom Hospital Data
# (For the expected file format, see the examples below.)
data_generator.build(
    department_info_path="department_info.json",
    symptom_file_path="disease_symptom_pair.json",
)

# 2.3. When you want to upload the synthesized data to your own FHIR server (optional)
# Provide your FHIR server URL
data_generator.upload_to_fhir(
    fhir_data_dir=data_generator.save_dir / "fhir_data",
    fhir_url=${FHIR_URL},
)       
Configuration example for data synthesis
# Base
seed: 9999

# FHIR server url
fhir_url: http://localhost:8080/fhir    # Optional: set your FHIR server URL here

# Data configs
project: ./synthetic_data/
data_name: hospital_small    # Output path: ./synthetic_data/hospital_small/data
hospital_data:
    hospital_n: 10           # Number of hospitals to synthesize
    start_date:
        min: 2025-03-17      # ISO format: YYYY-MM-DD
        max: 2025-09-21      
    days: 7                  # Simulation period (in days)
    interval_hour: 0.25      # Time unit expressed in hours
    start_hour:              # Possible hospital opening hours
        min: 9
        max: 10
    end_hour:                # Possible hospital closing hours
        min: 18
        max: 19
    department_per_hospital:
        min: 7
        max: 9
    doctor_per_department:
        min: 1
        max: 1
    working_days:                   # Number of days each doctor works during the simulation period
        min: 3
        max: 4
    doctor_capacity_per_hour:
        min: 1
        max: 4
    doctor_has_schedule_prob: 0     # Probability that a doctor has at least one fixed schedule
    schedule_coverage_ratio:        # Proportion of fixed schedules relative to total working hours
        min: 0.4
        max: 0.6
    appointment_coverage_ratio:   # Proportion of appointments scheduled outside fixed schedules
        min: 0.2
        max: 0.5
    preference:
        type: ['asap', 'doctor', 'date']    # Types of patient scheduling preferences
        probs: [0.4, 0.4, 0.2]              # Probability distribution for each preference type
    symptom:
        type: ['simple', 'with_history']    # 'simple' = no referral; 'with_history' = referral case
        probs: [0.7, 0.3]                   # Probability distribution for symptom types
Custom data examples
  • department_info.json
{   
   "metadata": {
       "reference": "https://emergency.or.kr/bbs/general-notice/2513"
   },
   "specialty": {
       "internal medicine": {
           "code": "IM",
           "subspecialty": {
               "gastroenterology": {
                   "code": "IMGAS",
                   "field": [
                       "Hepatology",
                       "Pancreatobiliary Medicine",
                       "Inflammatory Bowel Disease"
                   ]
               },
               "cardiology": {
                   "code": "IMCAR",
                   "field": [
                       "Interventional Cardiology",
                       "Electrophysiology",
                       "Heart Failure and Transplantation"
                   ]
               }
           }
       
       }
   }
}
  • disease_symptom_pair.json

It is recommended that this file contains disease-symptom pairs corresponding to the subspecialties defined in department_info.json.

{
   "gastroenterology": [
       {
           "Acute cholecystitis": {
               "department": [
                   "gastroenterology"
               ],
               "symptom": [
                   "Sudden sharp pain in the upper right side of the abdomen that spreads towards the right shoulder",
                   "Tender abdomen",
                   "Worsening pain with deep breathing",
                   "Persistent pain",
                   "High temperature (fever)",
                   "Nausea and vomiting",
                   "Sweating",
                   "Loss of appetite",
                   "Yellowing of the skin and whites of the eyes (jaundice)",
                   "Bulge in the abdomen"
               ]
           }
       }
   ],
   "cardiology": [
       {
           "Abdominal aortic aneurysm": {
               "department": [
                   "cardiology"
               ],
               "symptom": [
                   "Pulsating feeling in the abdomen, usually near the belly button",
                   "Persistent back pain",
                   "Persistent abdominal pain",
                   "Sudden and severe pain in the abdomen (if ruptured)",
                   "Pain radiating down into the scrotum (in men, if ruptured)",
                   "Dizziness (if ruptured)",
                   "Sweaty and clammy skin (if ruptured)",
                   "Rapid heartbeat (tachycardia, if ruptured)",
                   "Shortness of breath (if ruptured)",
                   "Feeling faint (if ruptured)",
                   "Loss of consciousness (if ruptured)"
               ]
           }
       }
   ]
}

 

2. Task Initialization

2.1. Patient Intake

from h_adminsim import SupervisorAgent
from h_adminsim.task.agent_task import OutpatientFirstIntake

# 1. Patient Intake
# 1.1. Default usage (Staff-only)
intake_task = OutpatientFirstIntake(
    patient_model='gpt-5-nano',
    admin_staff_model='gpt-5-mini',
    intake_max_inference=5,  # Default: up to 5 rounds (10 turns) of dialogue
)
##############################################################

# 1.2. Role separation
# Staff: dialogue handling, Supervisor: data collection and structuring
supervisor_agent = SupervisorAgent(
    target_task='first_outpatient_intake',
    model='gemini-2.5-flash',
    api_key=${YOUR_API_KEY},  # You may set the API key here instead of using a .env file
)
intake_task = OutpatientFirstIntake(
    patient_model='gemini-2.5-flash',
    admin_staff_model='gpt-5',
    supervisor_agent=supervisor_agent,
    intake_max_inference=8,
)
##############################################################

# 1.3. Advanced usage: vLLM
supervisor_agent = SupervisorAgent(
    target_task='first_outpatient_intake',
    model='meta-llama/Llama-3.3-70B-Instruct',
    use_vllm=True,              # Use a vLLM-hosted model as the supervisor
    vllm_endpoint='http://0.0.0.0:8000',  # vLLM server endpoint
)
intake_task = OutpatientFirstIntake(
    patient_model='meta-llama/Llama-3.3-70B-Instruct',
    admin_staff_model='meta-llama/Llama-3.3-70B-Instruct',
    supervisor_agent=supervisor_agent,
    intake_max_inference=5,
    patient_vllm_endpoint='http://0.0.0.0:8000',
    admin_staff_vllm_endpoint='http://0.0.0.0:8000',
)
##############################################################

 

2.2. Appointment Scheduling

from h_adminsim.task.agent_task import OutpatientFirstScheduling

# 2. Appointment Scheduling
# 2.1. Default usage (Tool-calling with reasoning fallbacks)
scheduling_task = OutpatientFirstScheduling(
    patient_model='gpt-5-nano',
    admin_staff_model='gemini-2.5-flash',
    schedule_cancellation_prob=0.05,    # Cancellation event
    request_early_schedule_prob=0.1,    # Rescheduling event
    preference_rejection_prob = 0.3,        # Prob. of rejecting the first-priority scheduling preference
    preference_rejection_prob_decay = 0.5,  # Decay factor for the preference rejection prob.
    scheduling_max_inference=5,
    scheduling_strategy='tool_calling',
    fhir_integration=False,
)
##############################################################

# 2.2. LLM reasoning-based scheduling without tool-calling
scheduling_task = OutpatientFirstScheduling(
    patient_model='gpt-5-nano',
    admin_staff_model='gpt-5-mini',
    schedule_cancellation_prob=0.05,    # Cancellation event
    request_early_schedule_prob=0.1,    # Rescheduling event
    preference_rejection_prob = 0.3,        # Prob. of rejecting the first-priority scheduling preference
    preference_rejection_prob_decay = 0.5,  # Decay factor for the preference rejection prob.
    scheduling_max_inference=5,
    scheduling_strategy='reasoning',
    fhir_integration=False,
)
##############################################################

# 2.3. HIS upload via FHIR
scheduling_task = OutpatientFirstScheduling(
    patient_model='gpt-5-nano',
    admin_staff_model='gemini-2.5-flash',
    schedule_cancellation_prob=0.05,    # Cancellation event
    request_early_schedule_prob=0.1,    # Rescheduling event
    preference_rejection_prob = 0.3,        # Prob. of rejecting the first-priority scheduling preference
    preference_rejection_prob_decay = 0.5,  # Decay factor for the preference rejection prob.
    scheduling_max_inference=5,
    scheduling_strategy='tool_calling',
    fhir_integration=True,
)
##############################################################

# 2.4. Advanced usage: vLLM
scheduling_task = OutpatientFirstScheduling(
    patient_model='meta-llama/Llama-3.3-70B-Instruct',
    admin_staff_model='gpt-5-mini',
    schedule_cancellation_prob=0.05,    # Cancellation event
    request_early_schedule_prob=0.1,    # Rescheduling event
    preference_rejection_prob = 0.3,        # Prob. of rejecting the first-priority scheduling preference
    preference_rejection_prob_decay = 0.5,  # Decay factor for the preference rejection prob.
    scheduling_max_inference=5,
    scheduling_strategy='tool-calling',    # Currently, we do not support tool-calling from vLLM
    fhir_integration=False,
    patient_vllm_endpoint='http://0.0.0.0:8000',
)
##############################################################

 

3. Simulation

from h_adminsim.pipeline import Simulator

# 3. Simulator initialization
# 3.1. Default usage
simulator = Simulator(
    intake_task=intake_task,
    scheduling_task=scheduling_task,
    simulation_start_day_before=3,
    fhir_integration=False,      
    fhir_url=None,
    fhir_max_connection_retries=5,
    random_seed=9999,
)
##############################################################

# 3.2. FHIR integration 
# (If enabled, scheduling task must be initialized with `fhir_integration=True`)
simulator = Simulator(
    intake_task=intake_task,
    scheduling_task=scheduling_task,
    simulation_start_day_before=3,
    fhir_integration=True,
    fhir_url='http://localhost:8080/fhir',
    fhir_max_connection_retries=5,
    random_seed=9999,
)
##############################################################


# 3.3. Running a single task
# 3.3.1. Intake task only
simulator = Simulator(
    intake_task=intake_task,
    scheduling_task=None,
    simulation_start_day_before=3,
    fhir_integration=False,
    fhir_url=None,
    fhir_max_connection_retries=5,
    random_seed=9999,
)

# 3.3.2. Scheduling task only
simulator = Simulator(
    intake_task=None,
    scheduling_task=scheduling_task,
    simulation_start_day_before=3,
    fhir_integration=False,
    fhir_url=None,
    fhir_max_connection_retries=5,
    random_seed=9999,
)
##############################################################
# Run the initialized simulator
simulator.run(
    simulation_data_path='hospital_data/primary/agent_data',
    output_dir='hospital_data/primary/simulation_results',
    resume=False,   # If the simulation stopped unexpectedly, set resume=True with the same paths
    verbose=True,
)

 

 


License

This project is licensed under the Apache License 2.0.

 

 


Citation

For H-AdminSim and PatientSim outpatient simulation, please cite the following.

@inproceedings{lee2026hadminsimmultiagentsimulatorrealistic,
  title         = {H-AdminSim: A Multi-Agent Simulator for Realistic Hospital Administrative Workflows with FHIR Integration}, 
  author        = {Jun-Min Lee and Meong Hi Son and Edward Choi},
  booktitle     = {Proceedings of the Conference on Health, Inference, and Learning (CHIL)},
  year          = {2026},
  eprint        = {2602.05407},
  archivePrefix = {arXiv},
  primaryClass  = {cs.AI},
  url           = {https://arxiv.org/abs/2602.05407}, 
}

 

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

h_adminsim-1.2.6.tar.gz (1.7 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

h_adminsim-1.2.6-py3-none-any.whl (1.8 MB view details)

Uploaded Python 3

File details

Details for the file h_adminsim-1.2.6.tar.gz.

File metadata

  • Download URL: h_adminsim-1.2.6.tar.gz
  • Upload date:
  • Size: 1.7 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.7

File hashes

Hashes for h_adminsim-1.2.6.tar.gz
Algorithm Hash digest
SHA256 d08573fb167a25a21d121ebf8b5ca4e06f60f04cbbb1fb993050c2a033d3548f
MD5 ade414525e92c763a31f6581fa655199
BLAKE2b-256 3ebbac20c4b17a8263b322927cf77e316dfc4c6293993a86eb4295e905789ef0

See more details on using hashes here.

File details

Details for the file h_adminsim-1.2.6-py3-none-any.whl.

File metadata

  • Download URL: h_adminsim-1.2.6-py3-none-any.whl
  • Upload date:
  • Size: 1.8 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.7

File hashes

Hashes for h_adminsim-1.2.6-py3-none-any.whl
Algorithm Hash digest
SHA256 b741752ec9c3aa1251a0970011d04511211eb50f5062b98283bcc1b11df79f3e
MD5 e9d37256e4ca24ff686e5c3b1c79884b
BLAKE2b-256 a2e411b10e7f6084d37a64f811a110b38543fd72875e27b9cf0b9451c1dabb37

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page