Agent Skillsmaziyarpanahi/openmed › extracting-clinical-entities

extracting-clinical-entities

GitHub

对医疗文本执行临床实体识别,提取疾病、药物等实体及置信度。支持多种输出格式,可配置阈值与分组,适用于隐私优先管道中的实体抽取阶段。

skills/extracting-clinical-entities/SKILL.md maziyarpanahi/openmed

Trigger Scenarios

从病历中提取疾病、药物或基因等生物医学实体 需要带字符偏移和置信度的结构化NER结果 希望将结果保存为JSON、HTML或CSV格式

Install

npx skills add maziyarpanahi/openmed --skill extracting-clinical-entities -g -y
More Options

Use without installing

npx skills use maziyarpanahi/openmed@extracting-clinical-entities

指定 Agent (Claude Code)

npx skills add maziyarpanahi/openmed --skill extracting-clinical-entities -a claude-code -g -y

安装 repo 全部 skill

npx skills add maziyarpanahi/openmed --all -g -y

预览 repo 内 skill

npx skills add maziyarpanahi/openmed --list

SKILL.md

Frontmatter
{
    "name": "extracting-clinical-entities",
    "license": "Apache-2.0",
    "metadata": {
        "pairs": "adjacent",
        "project": "OpenMed",
        "version": "1.0",
        "category": "openmed-core"
    },
    "description": "Run clinical and biomedical named-entity recognition on medical text with OpenMed's analyze_text. Use when the user wants to extract diseases, drugs, anatomy, genes, or other biomedical entities from notes; needs NER output as dict\/json\/html\/csv; wants to filter by confidence, group entities, toggle sentence detection, or save spans to JSONL; or wants the openmed analyze CLI. Pairs with loading-openmed-models and choosing-openmed-models, and runs after deidentifying-clinical-text in a privacy-first pipeline."
}

Extracting Clinical Entities

openmed.analyze_text runs a token-classification model over medical text and returns structured entities with character offsets and confidence scores. It runs on-device after a one-time model download.

When to use

  • Pull diseases, medications, anatomy, genes, proteins, etc. out of clinical text.
  • You need exact character spans (start/end) plus confidence per entity.
  • You want output as objects, JSON, an HTML highlight view, or CSV.
  • You are building the "extract entities" stage of a clinical NLP pipeline.

To choose a model, see choosing-openmed-models. To load it once and reuse it, see loading-openmed-models. In a PHI workflow, de-identify first (see deidentifying-clinical-text), then run NER on the redacted text.

Install

pip install "openmed[hf]"

Quick start

import openmed

note = (
    "Patient prescribed 500 mg metformin for type 2 diabetes mellitus. "
    "Reports intermittent chest pain; ruled out myocardial infarction."
)

result = openmed.analyze_text(
    note,
    model_name="disease_detection_superclinical",  # registry key, HF id, or local path
    output_format="dict",                           # dict | json | html | csv
    confidence_threshold=0.5,
)

for ent in result.entities:
    print(f"{ent.label:12} {ent.text!r:40} {ent.confidence:.2f} [{ent.start}:{ent.end}]")

With output_format="dict" you get a PredictionResult. The fields you use most:

result.text          # the original input text
result.entities      # list of entity objects
result.model_name    # which model produced these
ent.text             # the surface string
ent.label            # entity type, e.g. "DISEASE"
ent.confidence       # model score in [0, 1]   (NOTE: .confidence, not .score)
ent.start / ent.end  # character offsets into result.text

Output formats

analyze_text(...) returns different types depending on output_format:

output_format Return type Use for
"dict" (default) PredictionResult object Programmatic access via .entities.
"json" str (JSON) Logging, APIs, writing to disk.
"html" str (HTML) A highlighted preview of the note.
"csv" str (CSV) Spreadsheet / quick review.
import openmed

note = "Started atorvastatin 40 mg; history of myocardial infarction."

json_str = openmed.analyze_text(note, output_format="json")
html_str = openmed.analyze_text(note, output_format="html")   # render in a browser
csv_str  = openmed.analyze_text(note, output_format="csv")

Key parameters

openmed.analyze_text(
    text,
    model_name="disease_detection_superclinical",
    output_format="dict",
    confidence_threshold=0.5,    # drop entities below this score; None keeps all
    aggregation_strategy="simple",  # HF subword aggregation; None for raw tokens
    group_entities=False,        # merge adjacent same-label spans into one
    include_confidence=True,     # include scores in formatted output
    sentence_detection=True,     # pySBD sentence splitting (better long-doc spans)
    sentence_language="en",
    loader=None,                 # pass a reused ModelLoader (see loading skill)
)
  • confidence_threshold — the most useful knob. Use the model's recommended_confidence (from get_model_info) as a starting point.
  • group_entities=True — merges "type", "2", "diabetes" fragments into a single "type 2 diabetes" span. Turn on for cleaner output.
  • sentence_detection=True (default) — splits long notes into sentences before inference for more accurate offsets and to respect model max length. Requires pySBD; if unavailable it silently falls back to whole-text inference.

Save results to JSONL

One line per note keeps offsets and labels for downstream grounding or eval:

import json
import openmed

notes = [
    "Type 2 diabetes managed with metformin.",
    "Acute myocardial infarction; started aspirin and atorvastatin.",
]

with open("entities.jsonl", "w", encoding="utf-8") as fh:
    for i, note in enumerate(notes):
        result = openmed.analyze_text(note, output_format="dict")
        fh.write(json.dumps({
            "doc_id": i,
            "text": result.text,
            "model": result.model_name,
            "entities": [
                {"label": e.label, "text": e.text,
                 "start": e.start, "end": e.end,
                 "confidence": round(e.confidence, 4)}
                for e in result.entities
            ],
        }) + "\n")

Store offsets and labels, not extra copies of free text, in PHI contexts.

CLI

openmed analyze --text "Type 2 diabetes managed with metformin." \
  --model disease_detection_superclinical \
  --format json \
  --threshold 0.5 \
  --group

# Or analyze a file:
openmed analyze --input-file note.txt --model disease_detection_superclinical -o csv

Flags: --text/-t, --input-file/-f, --model/-m, --format/-o (dict|json|html|csv), --threshold/-c, --group, --no-confidence, --sentence-detection/--no-sentence-detection.

Hand-off to / from OpenMed

  • From loading-openmed-models: pass your reused loader= so a batch loads weights once.

  • From deidentifying-clinical-text: run NER on result.deidentified_text, not raw PHI:

    deid = openmed.deidentify(raw_note, method="mask", policy="hipaa_safe_harbor")
    ner  = openmed.analyze_text(deid.deidentified_text, output_format="dict")
    
  • To terminology grounding (out-of-process): map ent.text/ent.label to RxNorm / LOINC / SNOMED using the user's own licensed service — OpenMed does not bundle restricted terminologies.

  • To batch processing: for large corpora use openmed.process_batch(...) / BatchProcessor (see processing utilities) with a shared loader.

Edge cases & gotchas

  • Attribute is .confidence, not .score. Entity objects extend EntityPrediction (text, label, confidence, start, end).
  • Right model for the labels. A Disease model won't emit oncology staging or gene labels — pick the category in choosing-openmed-models and check entity_types.
  • Offsets index result.text. Slice the original string with start:end; the surface form in ent.text is whitespace-trimmed.
  • Long documents: keep sentence_detection=True so chunks respect the model's max length (get_model_max_length); disabling it can truncate long notes.
  • NER assists, it does not diagnose. Treat output as decision support; surface a disclaimer for any clinical-facing use.
  • No raw PHI in logs. Log labels, offsets, and hashes — never patient text.

Standards & references

Version History

  • f213557 Current 2026-07-23 00:44

Same Skill Collection

skills/building-with-openmed/SKILL.md
skills/loading-openmed-models/SKILL.md
skills/annotating-variants/SKILL.md
skills/assembling-fhir-bundles/SKILL.md
skills/auditing-deid-leakage/SKILL.md
skills/auditing-deidentification-runs/SKILL.md
skills/auditing-part11-trails/SKILL.md
skills/auditing-safe-harbor-checklist/SKILL.md
skills/auditing-subgroup-fairness/SKILL.md
skills/authoring-model-cards/SKILL.md
skills/batch-processing-clinical-text/SKILL.md
skills/benchmarking-clinical-ner/SKILL.md
skills/bridging-presidio-and-spacy/SKILL.md
skills/building-gold-corpus/SKILL.md
skills/building-patient-timelines/SKILL.md
skills/checking-hipaa-compliance/SKILL.md
skills/choosing-openmed-models/SKILL.md
skills/coding-hcc-risk-adjustment/SKILL.md
skills/coding-icd10/SKILL.md
skills/computing-ecqms/SKILL.md
skills/configuring-privacy-policies/SKILL.md
skills/defining-cohort-phenotypes/SKILL.md
skills/deidentifying-clinical-text/SKILL.md
skills/deidentifying-multilingual-text/SKILL.md
skills/deploying-openmed-mcp/SKILL.md
skills/detecting-pv-signals/SKILL.md
skills/enforcing-nophi-logging/SKILL.md
skills/etl-to-omop-cdm/SKILL.md
skills/evaluating-with-leakage-gates/SKILL.md
skills/exporting-bulk-fhir/SKILL.md
skills/exporting-to-fhir/SKILL.md
skills/extracting-dicom-metadata/SKILL.md
skills/extracting-lab-tables/SKILL.md
skills/extracting-pii-entities/SKILL.md
skills/extracting-sdoh/SKILL.md
skills/fetching-fhir-resources/SKILL.md
skills/gating-deid-leakage/SKILL.md
skills/generating-synthea-data/SKILL.md
skills/generating-synthetic-surrogates/SKILL.md
skills/ingesting-clinical-documents/SKILL.md
skills/linking-umls-concepts/SKILL.md
skills/mapping-loinc/SKILL.md
skills/mapping-to-snomed/SKILL.md
skills/mining-pubmed-literature/SKILL.md
skills/normalizing-rxnorm/SKILL.md
skills/parsing-ccda-documents/SKILL.md
skills/parsing-hl7v2-messages/SKILL.md
skills/parsing-lab-values/SKILL.md
skills/parsing-trial-eligibility/SKILL.md

Metadata

Files
0
Version
f213557
Hash
59394e84
Indexed
2026-07-23 00:44

Accueil - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-07-30 05:46
浙ICP备14020137号-1 $Carte des visiteurs$