
Once a medical coding pipeline maps a clinical concept to an ICD-10-CM code, it is tempting to declare victory and celebrate but story does not end here
given a coding pipeline that generated the ICD code
Clinical concept
↓
Candidate retrieval
↓
LLM reasoning
↓
Validated ICD code
This is celebratory but It is also incomplete.
A hospital episode summmary rarely contains one diagnosis in isolation.
It contains active disease, chronic comorbidities, symptoms, historical conditions, ruled-out diagnoses, complications, procedures, and several diagnoses. All of these are correct but are not the final code of the episode.
Consider this simplified discharge summary:
DISCHARGE DIAGNOSES
1. Acute kidney injury secondary to dehydration.
2. Dehydration.
3. Chronic atrial fibrillation.
HOSPITAL COURSE
The patient was treated with IV fluids. Renal function improved.
Chronic atrial fibrillation remained rate controlled.
There was no evidence of acute myocardial infarction.
PAST MEDICAL HISTORY
Previous ischemic stroke.A concept-level pipeline may produce:
Acute kidney injury → N17.9
Dehydration → E86.0
Chronic atrial fibrillation → validated AF code
Acute myocardial infarction → RULED OUT
Previous stroke → HISTORYEvery concept have been interpreted correctly. However, the chain of questions have only just started.
-
Which diagnoses belong in the final episode?
-
Which one is principal?
-
Does the chronic atrial fibrillation meet the criteria for an additional diagnosis?
-
Are symptoms separately reportable?
-
Does one code need to be sequenced before another?
-
Do multiple diagnoses collapse into a combination code?
That is the difference between coding a diagnosis and coding an episode.
Quip: Finding the right code is like buying all the super ingredients in a restaurant. Episode coding is figuring out which ones actually belong in a given recipe.
The Paradigm shift
Up to this point, the pipeline has been asking:
“What does this documented condition map to?”
Episode coding asks something fundamentally different
“Given everything we now know about the admission, what should the final coded representation of the hospitalization look like?”
That distinction deserves its own architecture. Coders workflow looks something like
Discharge Summary
│
▼
Concept Extraction
│
▼
Concept Coding
│
▼
Validated Concept Decisions
│
▼
Episode Adjudication
┌────────────┼────────────┐
▼ ▼ ▼
Reportability Relationships Rules
│ │ │
└────────────┼────────────┘
▼
Principal Diagnosis
│
▼
Sequencing
│
▼
Final Episode CodesThe crucial part is that the episode layer does not silently recode the diagnosis from previous layers.
If the concept layer decided:
C1 → N17.9the episode layer should not converge to
Actually, I fancy N17.8 today.Its job is not to rewrite classification truth.
Its job is to determine whether C1 belongs in the final episode, and what role it plays.
Senior-engineer tip: When one stage answers “what is it?” and another answers “what do we do with it?”, keep those concerns separate. Otherwise debugging session leads to an archaeological expedition.
Step 1: Reportability comes after correctness
One of the common misconception is that a correctly coded concept becomes part of the final episode.
Consider:
Past medical history:
Essential hypertensionthe concept pipeline maps it to:
I10This means:
If this condition is being coded, then I10 code represents it
It does not yet answer:
Should it be reported for this hospitalization?
Those are independent deductions.
So make reportability an explicit decision in the pipeline
ConceptCodingDecision
↓
ReportabilityDecisionFor example:
Acute kidney injury
documented at discharge ✓
evaluated during stay ✓
treated ✓
→ REPORTABLECompare that with:
Hypertension
appears only in PMH
no medication adjustment
no monitoring mentioned
no effect on management
→ NOT_REPORTABLE / NEEDS_REVIEWThe system should converge on the evidence, not on the presence of a diagnosis.
Quip: A diagnosis appearing somewhere in the chart is not the same as it applying for permanent residency on the claim.
Step 2: Symptoms need their own adjudication
Suppose a patient presents with:
fever
cough
shortness of breathdischarge diagnosis is
Pneumococcal pneumoniaconcept extractor should still detect the symptoms. They are indeed useful But they should not become separately reported diagnosis.
The episode layer needs to ask whether the symptom is
independent ?
integral to a confirmed diagnosis ?
explained by a confirmed diagnosis ?
still clinically significant on its own ?This should be modelled as
SymptomConcept
↓
SymptomReportabilityEvaluator
↓
REPORTABLE
or
EXPLAINED_BY_CONFIRMED_DIAGNOSIS
or
INTEGRAL_TO_DIAGNOSIS
or
NEEDS_REVIEWA suitable approach is to combine all of the following
clinical relationships
evidence
retrieved guideline context
constrained reasoningand then make the system explain why a symptom was suppressed.
Pro tip: Suppression rules should be explainable. “Because this giant dictionary said so” is indeed an explanation, albeit a weak one.
Step 3: Clinical relationships matter, but they are not coding rules
The extraction layer may discover relationships like
Acute kidney injury
CAUSED_BY
Dehydration
or:
Postoperative wound infection
COMPLICATION_OF
AppendectomyThese relationships can influence
-
guideline retrieval
-
principal-diagnosis reasoning
-
combination-code analysis
-
complication logic
But they should not automatically dictate code order. This distinction is important.
A clinical edge:
AKI ── CAUSED_BY ──► Dehydrationmeans something about medicine.
A sequencing edge:
CODE_A ── MUST_PRECEDE ──► CODE_Bmeans something about classification rules.
These are not the same graph.
Quip: “A caused B” is medical relationship. “A must be printed before B” is bureaucracy. Both matter, but bureaucracy a little more
Step 4: Principal diagnosis needs its own reasoning stage
The principal diagnosis is not necessarily:
the first diagnosis in the note
nor:
the most severe diagnosis
nor:
the diagnosis with the highest LLM confidence
nor even:
the one that generated the largest billThe principal diagnosis determination needs to look at the circumstances of the admission and the condition established after study as chiefly responsible for that admission.
For our earlier example:
Acute kidney injury
Dehydration
Chronic atrial fibrillationThere may have evidence like:
poor oral intake
dizziness
weakness
abnormal renal function
AKI confirmed
AKI attributed to dehydration
IV fluids givenThe system should build structured principal-diagnosis candidates.
EPISODE_CANDIDATE_1
Diagnosis: Acute kidney injury
Admission relevance: strong
Established after study: yes
Treated: yes
Evidence: E1, E2, E3versus:
EPISODE_CANDIDATE_3
Diagnosis: Chronic atrial fibrillation
Admission relevance: weak
Established after study:
already known chronic condition
Treatment:
no specific intervention
Monitoring:
yesNow the reasoning task is far narrower. Instead of asking the LLM:
“What is the principal diagnosis?”
it gets three reportable candidates, admission evidence, clinical relationships , relevant official guideline context
and returns one of
EPISODE_CANDIDATE_1
EPISODE_CANDIDATE_2
EPISODE_CANDIDATE_3
ABSTAINNo arbitrary code ever gets generated the LLM stays grounded.
Pro tip: Principal diagnosis selection is an adjudication problem, not a popularity contest among diagnoses.
Step 5: The sequencing graph
This is where the architecture becomes pleasantly boring again.
Suppose final reportable diagnosis candidates are
A
B
C
Dand authoritative ICD instructions produce these dependencies:
A must come before B
B must come before C
A must come before D
Represented as:
A ─────► B ─────► C
│
└──────► DNow you have a directed sequencing constraint graph.
An edge means exactly one thing:
The source code must precede the target code.
It does not mean:
source caused target
source is principal
source is more severe
source has a lower ICD numberThis graph can be generated from things like:
CODE FIRST
USE ADDITIONAL CODE
etiology/manifestation instructions
other authoritative sequencing constraintsThat is valuable because code sequencing stops being an informal collection of procedural rules. It becomes a graph problem.
Quip: When coding rules start forming dependencies, reach for a DAG before reaching for another rule table.
Step 6: Combination codes complicate things further
Episode coding is not always
one concept = one code
Sometimes two documented concepts may be represented by a combination code. Other times multiple codes are still required. The important thing is not to let the LLM improvise here
A combination-code evaluator should use
Alphabetic Index
Tabular instructions
inclusion terms
clinical relationships
guideline contextand produce something like:
NO_COMBINATION
COMBINATION_ALREADY_RESOLVED
POTENTIAL_COMBINATION
SEPARATE_CODES_REQUIRED
NEEDS_REVIEWIf a potential combination code was never validated through the concept-level pipeline, It should rather return
NEEDS_REVIEW
instead of silently substituting a brand-new code.
Step 7: Validate the whole episode again
Even after all this while, run a final validator on the pipeline (always)
Validator should check:
every code exists
principal diagnosis is reportable
no ruled-out diagnosis leaked in
no history-only diagnosis leaked in
no duplicate final code exists
all sequencing constraints are satisfied
all guideline references exist
all emitted codes came from validated concept decisionsIf any unresolved issue remains then
NEEDS_REVIEWis a perfectly acceptable result. This is especially important in healthcare.
Quip: “Needs review” is not a failure state. It is what honesty looks like in a production system.
Step 8: Evaluation now needs multiple layers
Once episode coding exists, a single F1 score becomes even less informative. Metrics are needed at every layer
For concept coding
candidate Recall@K
exact code
accuracy f
amily-level accuracy
unsupported specificityFor episode coding
micro precision
micro recall
micro F1
exact episode-set match
For principal diagnosis:
principal diagnosis accuracy
principal abstention
rate principal
conflict rateFor safety
ruled-out
leakage history
rate sequencing violations
symptom overcodingAnd for debugging
EXTRACTION_ERROR
RETRIEVAL_ERROR
CONCEPT_REASONING_ERROR
REPORTABILITY_ERROR
PRINCIPAL_DIAGNOSIS_ERROR
SEQUENCING_ERROR
VALIDATION_ERRORThese telemetry matters.
If an expected code never crossed candidate retrieval then there is no need to blame the principal diagnosis reasoner.
Quip: Blaming the LLM for a retrieval miss is like blaming the waiter because the chicken never had tomatoes.
Stage 10 : Synthetic episodes become even more valuable here
Concept-level synthetic tests are useful. Episode-level tests are better.
Generate Synthetic cases containing
active diagnosis
secondary chronic diagnosis
ruled-out diagnosis
historical diagnosis
symptoms
causal relationshipand freeze:
expected active set
expected principal code
expected exclusionsNow the evaluation is not merely
Did you retrieve N17.9?It becomes:
Did you code the correct concepts?
Did you exclude the historical ones?
Did you exclude ruled-out disease?
Did you include the right additional diagnoses?
Did you choose the correct principal?
Did you satisfy sequencing rules?That gets much closer to the actual engineering problem.
Pro tip: Synthetic data is excellent at making your assumptions explicit. Real data is excellent at proving those assumptions were incomplete.
The bigger engineering lesson
At first glance, medical coding looks like an NLP problem, Then it looks like a retrieval problem, Then a classification problem , And by the time you reach episode coding, it starts becoming
workflow engine
+
knowledge retrieval
+
constraint solver
+
LLM adjudicatorThat is what a healthy evolution looks like
The closer we get to final coding truth, the more It becomes:
deterministic mechanics
explicit provenance
constraint graphs
structured decisions
safe abstentionover
"the model seemed confident"That is the real difference between a demo and an engineering system.
The LLM remains important, but it becomes one component among several.
Final thought
The first phase of medical coding asks
What code represents this diagnosis?
The episode phase tries to answer
Given everything that happened during this hospitalization, what should the final coded story of the episode be?
That second question is harder. It also happens to be where good architecture starts paying dividends.
Because once classification truth, clinical interpretation and sequencing responsibility are separated cleanly, the model no longer has to know everything.
It only has to be good at the part we actually want it to do.
Final quip: The goal is not to build an LLM that runs the coding department. The goal is to build a coding system smart enough to know which decisions should never be delegated to the LLM.
Final Output



