Skip to main content

A Python package for simulating patient interactions.

Project description

PatientSim-pkg


PyPI - Python Version PyPI Version Downloads DOI

An official Python package for simulating patient interactions, called PatientSim. By setting a patient persona and assigning it to the LLM agent, you can generate outcomes of interactions with a doctor. The patient persona consists of four elements, resulting in 37 unique combinations:

  • Personality: plain (default), verbose, pleasing, impatient, distrust, overanxious.
  • Language Proficiency: C (default), B, A (C means the highest level).
  • Medical History Recall Level: no_history (default), low, high.
  • Cognitive Confusion Level: normal (default), moderate, high.

The simulation scenarios also have two visit types:

  • Outpatient: outpatient
  • Emergency: emergency_department

 

Recent updates 📣

  • March 2026 (v1.0.4): Administration simulation will be deprecated in the future. Please use h-adminsim: pip install h-adminsim
  • March 2026 (v1.0.3): Minor improvements.
  • February 2026 (v1.0.2): Several improvements were made.
  • February 2026 (v1.0.1): Update citations.
  • February 2026 (v1.0.0): Added multi-condition patient agent prompts, enabled MIMIC-based data download, and simplified Google Cloud simulation setup.
  • October 2025 (v0.2.1): We have unified history format and improved simulation process.
  • September 2025 (v0.2.0): We have supported vLLM local model for the patient simulation.
  • September 2025 (v0.1.8): Fixed bugs and updated explanation about the simulation.
  • September 2025 (v0.1.7): Fixed typos of the prompts.
  • September 2025 (v0.1.6): Updated dependencies.
  • August 2025 (v0.1.5): Improved the outpatient simulation to be more realistic based on expert feedback.
  • August 2025 (v0.1.4): Added support for outpatient simulation and added exception handling for None-type responses from Gemini.
  • August 2025 (v0.1.3): Added support for emergency department simulation, Azure for GPT, and Vertex AI for the Gemini API.
  • August 2025 (v0.1.1): Added support for a doctor persona in the LLM agent for the emergency department.
  • August 2025 (v0.1.0): Initial release: Introduced a dedicated LLM agent for patients that allows customization of patient personas.

 

 

Installation 🛠️

pip install patientsim
import patientsim
print(patientsim.__version__)

 

 

Overview 📚

This repository is the official repository for the PyPI package.For the repository related to the paper and experiments, please refer to here.

 

 

Quick Starts 🚀

If you plan to run this simulation with real clinical data or other sensitive information, you must use Vertex AI (for Gemini) or Azure OpenAI (for GPT). When using Azure OpenAI, be sure to opt out of human review of the data to maintain compliance and ensure privacy protection.

[!NOTE] Before using the LLM API, you must provide the API key for each model directly or specify it in a .env file.

  • gemini-*: If you set the model to a Gemini LLM, you must have your own GCP API key in the .env file, with the name GOOGLE_API_KEY. The code will automatically communicate with GCP.
  • gpt-*: If you set the model to a GPT LLM, you must have your own OpenAI API key in the .env file, with the name OPENAI_API_KEY. The code will automatically use the OpenAI chat format.

[!NOTE] To use Vertex AI, you must complete the following setup steps:

  1. Select or create a Google Cloud project in the Google Cloud Console.
  2. Enable the Vertex AI API.
  3. Generate a Vertex AI Express Mode API key and set its value in the GENAI_API_KEY environment variable.

 

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 GPT API with Azure
AZURE_ENDPOINT="https://your-azure-openai-endpoint"

# For Gemini API without Vertex AI
GOOGLE_API_KEY="YOUR_GEMINI_API_KEY" 

# For Gemini API with Vertex AI
GOOGLE_PROJECT_ID="your-gcp-project-id"
GOOGLE_PROJECT_LOCATION="your-gcp-project-location"  # (e.g., us-central1)
GOOGLE_APPLICATION_CREDENTIALS="/path/to/google_credentials.json" # Path to GCP service account credentials (JSON file)

 

Agent Initialization

Patient Agent

  1. Default settings usage.
# Patient Agent (GPT)
from patientsim import PatientAgent

patient_agent = PatientAgent('gpt-5', 
                              visit_type='emergency_department',
                              random_seed=42,
                              random_sampling=False,
                              temperature=0,
                              api_key=OPENAI_API_KEY,
                              use_azure=False   # Set True if using Azure
                            )

# Patient Agent (Gemini)
patient_agent = PatientAgent('gemini-2.5-flash', 
                              visit_type='emergency_department',
                              random_seed=42,
                              random_sampling=False,
                              temperature=0,
                              api_key=GOOGLE_API_KEY,
                              use_vertex=False # Set True for use Vertex AI
                            )
                            
# Patient Agent (vLLM)
patient_agent = PatientAgent('meta-llama/Llama-3.3-70B-Instruct', 
                              visit_type='emergency_department',
                              random_seed=42,
                              random_sampling=False,
                              temperature=0,
                              use_vllm=True, # Set True for use vLLM API
                              vllm_endpoint=VLLM_ENDPOINT # Pass the vLLM server endpoint (e.g. http://localhost:PORT)
                            )

response = patient_agent(
    user_prompt="How can I help you?",
)

print(response)

# Example response:
# > I'm experiencing some concerning symptoms, but I can't recall any specific medical history.
# > You are playing the role of a kind and patient doctor...

 

  1. Apply custom persona.
from patientsim import PatientAgent

# Using a default system prompt
patient_agent = PatientAgent('gpt-5', 
                              visit_type='emergency_department',
                              personality='verbose',
                              recall_level='low',
                              confusion_level='moderate',
                              lang_proficiency_level='B',
                              age='45',
                              tobacco='Denies tobacco use',
                              allergies="Penicillins",
                              ...
                            )

# Using a custom system prompt
# You can pass additional keyword arguments required by your custom system prompt
patient_agent = PatientAgent('gpt-5', 
                              visit_type='outpatient',
                              personality='verbose',
                              recall_level='low',
                              confusion_level='moderate',
                              lang_proficiency_level='B',
                              system_prompt_path='my_system_prompt.txt',
                              additional_patient_conditions={"condition_1": "value_1", ...},
                              ...
                            )

Patient Persona Arguments (O: Applicable to outpatient simulation, E: Applicable to emergency department):

  • visit_type (str): emergency_department (default), outpatient
  • personality (str, OE): plain (default), verbose, pleasing, impatient, distrust, overanxious
  • recall_level (str, OE): no_history (default), low, high
  • confusion_level (str, OE): normal (default), moderate, high
  • lang_proficiency_level (str, OE): C (default), B, A (C means the highest level).
  • name (str, O): Patient's name. Default: "James Lee".
  • birth_date (str, O): Patient's birth_date. Default: random date between 1960-01-01 and 2000-12-31.
  • age (str, E): Patient's age. Default: random.randint(20, 80). The value is randomly generated and does not depend on the birth date.
  • gender (str, OE): Patient's gender. Default: random.choice(['male', 'female']).
  • telecom (str, O): Patient's phone number. Default: "N/A".
  • personal_id (str, O): Patient's personal identification number. Default: "N/A".
  • address (str, O): Patient's address. Default: "N/A".
  • race (str, E): Patient's race or ethnicity. Default: "N/A".
  • tobacco (str, E): Patient's tobacco use status (e.g., current, former, never). Default: "N/A".
  • alcohol (str, E): Patient's alcohol use status (e.g., current, former, never). Default: "N/A".
  • illicit_drug (str, E): Patient's illicit drug use status. Default: "N/A".
  • sexual_history (str, E): Patient's sexual history. Default: "N/A".
  • exercise (str, E): Patient's physical activity level or exercise habits. Default: "N/A".
  • marital_status (str, E): Patient's marital status (e.g., single, married, divorced). Default: "N/A".
  • children (str, E): Number of children or information about dependents. Default: "N/A".
  • living_situation (str, E): Patient's current living arrangement (e.g., alone, with family). Default: "N/A".
  • occupation (str, E): Patient's occupation or job information. Default: "N/A".
  • insurance (str, E): Patient's health insurance status or type. Default: "N/A".
  • allergies (str, OE): Known allergies of the patient (medication, food, environmental). Default: "N/A".
  • family_medical_history (str, OE): Relevant medical history of the patient's family. Default: "N/A".
  • medical_device (str, E): Any medical devices the patient uses (e.g., pacemaker, insulin pump). Default: "N/A".
  • medical_history (str, OE): Patient's past medical history (conditions, surgeries, hospitalizations). Default: "N/A".
  • present_illness_positive (str, E): Positive symptoms or findings for the current illness. Default: "N/A".
  • present_illness_negative (str, E): Negative symptoms or findings for the current illness. Default: "N/A".
  • chiefcomplaint (str, OE): Main reason the patient seeks medical attention. Default: "N/A".
  • pain (str, E): Description or severity of pain, if any. Default: "N/A".
  • medication (str, E): Current medications the patient is taking. Default: "N/A".
  • arrival_transport (str, E): How the patient arrived at the facility (e.g., ambulance, private vehicle). Default: "N/A".
  • disposition (str, E): Planned disposition after evaluation (e.g., discharge, admission). Default: "N/A".
  • diagnosis (str, OE): Diagnosed condition(s) for the patient. Default: "N/A".
  • department (str, O): Hospital department related to the patient’s chief complaint or diagnosis. Default: "N/A".

 

Doctor Agent

from patientsim import DoctorAgent

doctor_agent = DoctorAgent('gpt-5', use_azure=False)
doctor_agent = DoctorAgent('gemini-2.5-flash', use_vertex=False)
doctor_agent = DoctorAgent('meta-llama/Llama-3.3-70B-Instruct', use_vllm=True, vllm_endpoint="http://localhost:8000")
print(doctor_agent.system_prompt)

Doctor Agent Arguments (O: Applicable to outpatient simulation, E: Applicable to emergency department):

  • top_k_diagnosis (int, E): Number of diagnoses to predict. Default: 5.
  • age (str, E): Patient persona's age. Default: "N/A". he value is randomly generated and does not depend on the birth date.
  • gender (str, E): Patient persona's gender. Default: "N/A".
  • arrival_transport (str, E): Patient persona's arrival transport (e.g., ambulance, private vehicle). Default: "N/A".

 

Administraion Office Agent

from patientsim import AdminStaffAgent

admin_staff_agent = AdminStaffAgent('gpt-5', department_list=['gastroenterology', 'cardiology'], use_azure=False)
admin_staff_agent = AdminStaffAgent('gemini-2.5-flash', department_list=['gastroenterology', 'cardiology'], use_vertex=False)
admin_staff_agent = AdminStaffAgent('meta-llama/Llama-3.3-70B-Instruct', 
                                    department_list=['gastroenterology', 'cardiology'], 
                                    use_vllm=True, 
                                    vllm_endpoint="http://localhost:8000"
                                  )
print(admin_staff_agent.system_prompt)

 

Dialog Termination Checker Agent

The CheckerAgent is used to double-check if the dialog should be terminated, especially in edge cases where rule-based logic might fail.
Using CheckerAgent is useful for improving safety and consistency in conversations, but involves an additional LLM call, which may increase both latency and cost per interaction.

from patientsim import CheckerAgent

checker_agent = CheckerAgent('gpt-5', visit_type='emergency_department', use_azure=False)
checker_agent = CheckerAgent('gemini-2.5-flash', visit_type='emergency_department', use_vertex=False)
checker_agent = CheckerAgent('meta-llama/Llama-3.3-70B-Instruct', visit_type='emergency_department', vllm_endpoint="http://localhost:8000")
print(checker_agent.prompt_template)

 

Run Simulation

from patientsim.environment import OPSimulation, EDSimulation

# Emergency department
simulation_env = EDSimulation(patient_agent, doctor_agent)
dialogs = simulation_env.simulate()

# Emergency department with additional kwargs
# NOTE: You can also set other generation parameters beyond temperature and seed
patient_kwargs = {"reasoning_effort": "low"}
doctor_kwargs = {"reasoning_effort": "medium"}    
simulation_env = EDSimulation(patient_agent, doctor_agent, patient_kwargs, doctor_kwargs)
dialogs = simulation_env.simulate()

# Emergency department with checker agent
simulation_env = EDSimulation(patient_agent, doctor_agent, checker_agent)
dialogs = simulation_env.simulate()

# Outpatient
simulation_env = OPSimulation(patient_agent, admin_staff_agent)
dialogs = simulation_env.simulate()

# Outpatient with additional kwargs
# NOTE: You can also set other generation parameters beyond temperature and seed
patient_kwargs = {"reasoning_effort": "low"}
staff_kwargs = {"reasoning_effort": "medium"}    
simulation_env = OPSimulation(patient_agent, admin_staff_agent, patient_kwargs, staff_kwargs)
dialogs = simulation_env.simulate()

# Outpatient with checker agent
simulation_env = OPSimulation(patient_agent, admin_staff_agent, checker_agent)
dialogs = simulation_env.simulate()

# Example response:
# Example response:
# > Doctor   [0%]  : Hello, how can I help you?
# > Patient  [6%]  : I'm experiencing some concerning symptoms,
# > Doctor   [6%]  : I'm sorry to hear that you're experiencing difficulty. When dit this start?
# > Patient  [13%] : Three hours prior to my arrival.
# > ...

 

Download dataset

To set up the patient profile, you can use the MIMIC-ED patient profile following our paper, or use your own patient data.
Our dataset is available through PhysioNet: PatientSim Dataset

Prerequisites

Before downloading the dataset, you must:

  1. Be a credentialed user on PhysioNet
  2. Sign the Data Use Agreement (DUA) for our project: https://physionet.org/sign-dua/persona-patientsim/1.0.0/

For information on becoming a credentialed user, visit: https://physionet.org/credential-application/

Quick Setup

If you are a credentialed user, you can easily set up the dataset using the following code:

from patientsim.dataset import DatasetManager

# Option 1: Download only patient_profile.json (recommended for quick start)
manager = DatasetManager(save_path="./data")
manager.download(mode="profile")


# Option 2: Download entire dataset
manager = DatasetManager(save_path="./data")
manager.download(mode="all")

You will be prompted to enter your credentials:

Physionet Username: your_username
Physionet Password: ********

 

 

Citation

1. For emergency department simulation, please cite the following.

@inproceedings{
    kyung2025patientsim,
    title={PatientSim: A Persona-Driven Simulator for Realistic Doctor-Patient Interactions},
    author={Daeun Kyung and Hyunseung Chung and Seongsu Bae and Jiho Kim and Jae Ho Sohn and Taerim Kim and Soo Kyung Kim and Edward Choi},
    booktitle={The Thirty-ninth Annual Conference on Neural Information Processing Systems Datasets and Benchmarks Track},
    year={2025},
    url={https://openreview.net/forum?id=1THAjdP4QJ}
}

2. For outpatient simulation, please cite the following.

@misc{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},
      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

patientsim-1.0.4.tar.gz (69.3 kB view details)

Uploaded Source

Built Distribution

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

patientsim-1.0.4-py3-none-any.whl (82.7 kB view details)

Uploaded Python 3

File details

Details for the file patientsim-1.0.4.tar.gz.

File metadata

  • Download URL: patientsim-1.0.4.tar.gz
  • Upload date:
  • Size: 69.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.7

File hashes

Hashes for patientsim-1.0.4.tar.gz
Algorithm Hash digest
SHA256 503c091907589aa974c198a3d285c94b6fd9dc9fb47bf5e42e5f1d8c35fcb086
MD5 6ade92448c3300d6bfd25d343160ec13
BLAKE2b-256 4da258163e5f371edd2e32407f305166419614a6bb20fdefe89e5f684481e7a4

See more details on using hashes here.

File details

Details for the file patientsim-1.0.4-py3-none-any.whl.

File metadata

  • Download URL: patientsim-1.0.4-py3-none-any.whl
  • Upload date:
  • Size: 82.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.7

File hashes

Hashes for patientsim-1.0.4-py3-none-any.whl
Algorithm Hash digest
SHA256 1bb1b746bc6f0df3e6eaa4cc593741bd807e74deb6984a28ecab68e7765ec0df
MD5 e12085bb465df70261cb8acac48ea707
BLAKE2b-256 b696cdbc4fdfa98f230151687a6d1df8c9b3703dccb0989f5c2ddf3a9e14dd47

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