# Generating Synthetic Surrogates

Replace detected PHI with realistic, type-matched fake values in OpenMed so clinical...

- Repository: https://github.com/maziyarpanahi/openmed (5755 stars)
- Category: Writing
- License: Apache-2.0
- Last updated: 2026-10-31
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add maziyarpanahi/openmed --skill generating-synthetic-surrogates -g -a claude-code -y`
Codex: `npx skills add maziyarpanahi/openmed --skill generating-synthetic-surrogates -g -a codex -y`
Cursor: `npx skills add maziyarpanahi/openmed --skill generating-synthetic-surrogates -g -a cursor -y`
Gemini CLI: `npx skills add maziyarpanahi/openmed --skill generating-synthetic-surrogates -g -a gemini-cli -y`
Claude Code plugin marketplace: `/plugin marketplace add maziyarpanahi/openmed`

## Description

Replace detected PHI with realistic, type-matched fake values in OpenMed so clinical notes stay readable and parseable instead of full of [REDACTED] markers. Use when the user wants surrogate names, MRNs, addresses, or dates rather than opaque masks, needs consistent fake identities across a document, must keep notes natural for downstream NLP, or wants to register a custom surrogate generator or provider. Covers deidentify(method=\"replace\", consistent=True, seed=..., locale=...), register_label_generator, register_clinical_provider, and Anonymizer/AnonymizerConfig. Pairs with OpenMed deidentifying-clinical-text and configuring-privacy-policies.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# Generating synthetic surrogates

`method="replace"` swaps each detected identifier for a **realistic, type-matched
fake**, `John Doe` becomes `Mark Lee`, a phone becomes a plausible phone, a date
becomes a plausible date. Unlike opaque `[REDACTED]`/`[NAME]` masks, surrogate
text reads naturally and stays parseable by downstream NLP, while still
containing no real PHI. OpenMed generates surrogates on-device via Faker-backed
providers keyed to each canonical label.

## When to use this skill

Use surrogates when the de-identified text must remain **readable or machine-
parseable**: training data for clinical NLP, demos, QA, or notes a human still
needs to skim. If you only need the identifiers gone and don't care about
readability, plain `method="mask"` is simpler and more obviously redacted.

## Quick start

```python
import openmed

note = (
    "Patient John Doe (MRN 1234567) saw Dr. John Doe's colleague on 2024-03-02. "
    "Reach John Doe at 617-555-0142."
)

result = openmed.deidentify(
    note,
    method="replace",
    consistent=True,     # every "John Doe" -> the SAME surrogate within this call
    seed=42,             # reproducible across runs
    locale="en_US",      # shapes the fakes; defaults from lang via LANG_TO_LOCALE
)
print(result.deidentified_text)
# Patient Mark Lee (MRN 8830127) saw Dr. Mark Lee's colleague on 2024-07-18. ...
```

`consistent=True` is what makes the output coherent: the three mentions of
"John Doe" collapse to one fake identity instead of three different ones, so the
note still makes sense. `seed=` makes that mapping reproducible run to run.

## Surrogates vs opaque redaction

The rest: https://github.com/maziyarpanahi/openmed/blob/HEAD/skills/generating-synthetic-surrogates/SKILL.md
