Agent Skillsmaziyarpanahi/openmed › coding-hcc-risk-adjustment

coding-hcc-risk-adjustment

GitHub

将OpenMed提取的慢性病映射至CMS-HCC V28类别,估算RAF分数并检查MEAT文档支持。用于发现潜在HCC、代码映射及风险评估,为编码员提供决策支持而非自动编码。

skills/coding-hcc-risk-adjustment/SKILL.md maziyarpanahi/openmed

Trigger Scenarios

用户希望从病历中发现可风险调整的诊断或疑似未记录的HCC 需要将ICD-10-CM代码映射到V28 HCC类别并应用层级规则 需要为患者或群体估算或复核RAF分数 需要检查特定诊断在文档中是否有MEAT(监测、评估、处理)支持

Install

npx skills add maziyarpanahi/openmed --skill coding-hcc-risk-adjustment -g -y
More Options

Use without installing

npx skills use maziyarpanahi/openmed@coding-hcc-risk-adjustment

指定 Agent (Claude Code)

npx skills add maziyarpanahi/openmed --skill coding-hcc-risk-adjustment -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": "coding-hcc-risk-adjustment",
    "license": "Apache-2.0",
    "metadata": {
        "pairs": "after",
        "project": "OpenMed",
        "version": "1.0",
        "category": "terminology-coding"
    },
    "description": "Maps chronic conditions extracted by OpenMed to CMS-HCC V28 risk-adjustment categories and estimates a RAF (Risk Adjustment Factor) score as decision support. Use when the user wants to surface risk-adjustable diagnoses from notes, map ICD-10-CM codes to HCC categories, estimate or reconcile a patient\/panel RAF, find suspected-but-undocumented HCCs, or check MEAT documentation support. Trigger keywords: HCC, CMS-HCC, V28, RAF score, risk adjustment, Medicare Advantage, hierarchical condition category, MEAT, recapture, suspect HCC, RADV. Pairs after OpenMed NER + ICD-10 coding: consume Disease\/Pathology entities from openmed.analyze_text, code them (see coding-icd10), then roll up to HCCs. CMS-HCC mappings and weights are public from CMS. This is a coding-support aid for human review, never autonomous risk-adjustment coding."
}

Mapping conditions to CMS-HCC V28 and estimating RAF

Surface and risk-adjust the chronic conditions OpenMed extracts by mapping them to CMS-HCC categories (the V28 model, phasing in for payment years 2024–2026) and estimating a RAF (Risk Adjustment Factor) score. CMS pays Medicare Advantage plans based on RAF, so accurate, documented capture of chronic disease matters — and much of that signal lives in the narrative note, exactly what OpenMed reads.

This is decision support for coders/clinicians, not autonomous coding. The output is "candidate HCCs + estimated RAF + the documentation that supports (or fails to support) each one," for human validation.

CMS-HCC crosswalks (ICD-10-CM → HCC) and the category coefficients are public — CMS publishes them annually. Nothing restricted is bundled.

When to use

  • You want to find risk-adjustable diagnoses mentioned in a note that may not be on the coded problem list ("suspect HCCs" / recapture).
  • You need to map ICD-10-CM codes to V28 HCCs and apply the hierarchy.
  • You want an estimated RAF for a patient or panel for review.
  • You need to check whether a diagnosis has MEAT support (Monitored, Evaluated, Assessed, Treated) in the documentation.

Pairs with coding-icd10 (you need ICD-10-CM codes first) and may consume mapping-to-snomed output upstream.

Quick start (public CMS crosswalk + coefficients)

CMS publishes the V28 ICD-10-CM→HCC mapping and the model coefficients. Load them locally (public files) and apply the model:

import csv

# 1) ICD-10-CM -> HCC (V28) crosswalk from the CMS Risk Adjustment files.
icd_to_hcc = {}                       # "E1122" -> "HCC38" (Diabetes w/ complication)
with open("cms_hcc_v28_icd_map.csv") as fh:
    for row in csv.DictReader(fh):
        icd_to_hcc[row["icd10cm"].replace(".", "")] = row["hcc_v28"]

# 2) HCC -> RAF coefficient for the relevant model segment (e.g. CNA community).
hcc_weight = {}                       # "HCC38" -> 0.166 (illustrative)
with open("cms_hcc_v28_coefficients.csv") as fh:
    for row in csv.DictReader(fh):
        hcc_weight[row["hcc"]] = float(row["coefficient"])

# 3) Apply the HCC hierarchy: a more severe HCC in a family suppresses milder
#    ones (e.g. acute MI suppresses angina). Load the hierarchy from CMS.
hierarchy = {                         # parent HCC -> HCCs it zeroes out
    # "HCC37": {"HCC38"},  # illustrative; use the official V28 hierarchy file
}

def apply_hierarchy(hccs: set[str]) -> set[str]:
    kept = set(hccs)
    for parent in hccs:
        kept -= hierarchy.get(parent, set())
    return kept

def estimate_raf(icd_codes: list[str], demo_factor: float = 0.0) -> dict:
    hccs = {icd_to_hcc[c] for c in icd_codes if c in icd_to_hcc}
    hccs = apply_hierarchy(hccs)
    disease_raf = sum(hcc_weight.get(h, 0.0) for h in hccs)
    return {"hccs": sorted(hccs),
            "disease_raf": round(disease_raf, 3),
            "estimated_raf": round(disease_raf + demo_factor, 3)}

The demo_factor (age/sex, dual/disability, institutional status) comes from the CMS demographic tables — add it for a full RAF; omit for the disease component.

Workflow

  1. Extract condition spans with OpenMed (Disease/Pathology/Oncology models).
  2. Code each to ICD-10-CM (see coding-icd10) — HCCs key off ICD-10-CM.
  3. Map ICD-10-CM → V28 HCC via the CMS crosswalk.
  4. Apply the hierarchy so only the most severe HCC in each family counts.
  5. Sum coefficients for the correct model segment + add the demographic factor to estimate RAF.
  6. Attach MEAT evidence: for each candidate HCC, cite the note text that Monitors/Evaluates/Assesses/Treats the condition. No MEAT → flag as "unsupported / needs clinician confirmation," not a captured HCC.
  7. Emit candidate HCCs + estimated RAF + supporting offsets for human review.

Hand-off from OpenMed

openmed.analyze_text(..., output_format="dict") returns entities, each a dict with text, label, confidence, start, end. Use the offsets to pull MEAT evidence sentences:

import openmed

note = ("Problem list: type 2 diabetes with diabetic nephropathy; COPD. "
        "Plan: continue metformin, ordered HbA1c, refer nephrology.")
result = openmed.analyze_text(
    note,
    model_name="disease_detection_superclinical",   # Disease category
    output_format="dict",
)

DX_LABELS = {"DISEASE", "CONDITION", "PATHOLOGY"}
suspects = []
for ent in result["entities"]:
    if ent["label"] in DX_LABELS:
        # 1) code to ICD-10-CM (coding-icd10) -> e.g. "E1122"
        icd = map_to_icd10cm(ent["text"])           # your coding step
        hcc = icd_to_hcc.get(icd)
        if hcc:
            # MEAT: capture the sentence around the span for the reviewer
            sent = note[max(0, ent["start"] - 60): ent["end"] + 80]
            suspects.append({"condition": ent["text"], "icd10cm": icd,
                             "hcc": hcc, "span": (ent["start"], ent["end"]),
                             "meat_context": sent})

raf = estimate_raf([s["icd10cm"] for s in suspects])
print(raf, suspects)        # candidates + estimate, for coder validation

Carry OpenMed's start/end offsets so every suspect HCC links to the exact documentation; this is what makes the suggestion auditable for RADV. Store codes, HCCs, and offsets — not the raw note.

Edge cases & gotchas

  • Decision support, never autonomous coding. Risk-adjustment coding is audited (CMS RADV) and has direct payment and compliance consequences. Output suspects with evidence for a certified coder/clinician; never submit HCCs automatically.
  • MEAT is required. A diagnosis merely mentioned (e.g. in history) without being Monitored/Evaluated/Assessed/Treated in the encounter generally cannot be captured. Always attach MEAT evidence and flag bare mentions as unsupported.
  • V28 dropped ~2,000 codes. The V28 transition removed many ICD-10-CM codes from HCC mapping (notably diabetes-without-complication, some vascular and inflammatory codes). A code that mapped under V24 may map to nothing under V28 — use the V28 crosswalk, not V24, and don't assume continuity.
  • Hierarchy suppression. Within a disease family only the most severe HCC counts; summing all of them inflates RAF. Apply the official V28 hierarchy.
  • Model segment matters. Coefficients differ by segment (community vs institutional, aged vs disabled, new enrollee). Use the right segment's table or the RAF is wrong.
  • Negation/uncertainty. "No evidence of CHF" or "rule out malignancy" must not become captured HCCs. Resolve assertion/negation in OpenMed before mapping.
  • Annual model updates. CMS revises the model and weights yearly and is blending V24/V28 across payment years 2024–2026; pin and record which model version and payment year your estimate used.
  • Licensing. CMS-HCC crosswalks/coefficients and ICD-10-CM are public. Do not bundle restricted vocabularies (CPT, SNOMED, UMLS) to support this — keep those user-supplied and out-of-process.
  • Local-first. OpenMed NER runs on-device; HCC mapping uses local CMS tables. No PHI needs to leave the process at all.

Standards & references

Version History

  • f213557 Current 2026-07-23 00:43

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-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-clinical-entities/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
0afa910e
Indexed
2026-07-23 00:43

ホーム - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-07-29 13:12
浙ICP备14020137号-1 $お客様$