07. Medical Coding Assistance
Medical coding translates clinical documentation into standardized codes for billing, epidemiology, and quality measurement. ICD-10-CM codes describe diagnoses; CPT codes describe procedures; HCPCS codes cover supplies and equipment. Accurate coding requires clinical knowledge, coding guidelines, and payer-specific rules.
Local LLMs assist coding by suggesting codes based on clinical documentation. The model reads the note and proposes relevant codes; coders review and select final codes. This reduces search time and improves consistency when the model learns an organization's coding preferences.
# medical_coder.py
from dataclasses import dataclass
from typing import List, Optional
import json
@dataclass
class CodingSuggestion:
code: str
code_type: str # ICD-10, CPT, HCPCS
description: str
confidence: float
reasoning: str
class MedicalCodeAssistance:
"""Suggest medical codes based on clinical documentation."""
ICD10_SYSTEM = "ICD-10-CM"
CPT_SYSTEM = "CPT"
def __init__(self, ollama_client):
self.ollama = ollama_client
def suggest_codes(self, clinical_text: str,
code_type: str = "all") -> List[CodingSuggestion]:
"""Suggest medical codes from clinical documentation."""
if code_type == "all":
prompt = self._build_universal_coding_prompt(clinical_text)
elif code_type.upper() == "ICD":
prompt = self._build_diagnosis_coding_prompt(clinical_text)
elif code_type.upper() == "CPT":
prompt = self._build_procedure_coding_prompt(clinical_text)
else:
raise ValueError(f"Unknown code type: {code_type}")
response = self.ollama.generate(prompt)
return self._parse_coding_response(response)
def _build_diagnosis_coding_prompt(self, text: str) -> str:
return f"""Analyze this clinical documentation and suggest ICD-10-CM codes.
For each code, provide:
1. The code (e.g., J06.9)
2. A brief description
3. Confidence level (high/medium/low)
4. Why this code applies
Only suggest codes that are explicitly supported by the documentation.
Do not suggest codes for unmentioned conditions.
Documentation:
{text}
Output as JSON array:
[{{"code": "...", "description": "...", "confidence": "...", "reasoning": "..."}}]"""
def _build_procedure_coding_prompt(self, text: str) -> str:
return f"""Analyze this clinical documentation and suggest CPT codes.
For each code, provide:
1. The code (e.g., 99213)
2. A brief description
3. Confidence level (high/medium/low)
4. Why this code applies
Only suggest codes for procedures explicitly documented.
Documentation:
{text}
Output as JSON array:"""
def _build_universal_coding_prompt(self, text: str) -> str:
return f"""Analyze this clinical documentation and suggest relevant medical codes.
Include ICD-10-CM for diagnoses and CPT for procedures.
Documentation:
{text}
Output as JSON with 'diagnoses' and 'procedures' arrays:"""
def _parse_coding_response(self, response: str) -> List[CodingSuggestion]:
try:
data = json.loads(response)
suggestions = []
# Handle both flat arrays and nested objects
if isinstance(data, list):
for item in data:
suggestions.append(self._create_suggestion(item))
elif isinstance(data, dict):
for category in ["diagnoses", "procedures"]:
if category in data:
for item in data[category]:
suggestions.append(self._create_suggestion(item))
return suggestions
except json.JSONDecodeError:
return []
def _create_suggestion(self, item: dict) -> CodingSuggestion:
return CodingSuggestion(
code=item.get("code", ""),
code_type=item.get("code_type", "ICD-10"),
description=item.get("description", ""),
confidence=self._parse_confidence(item.get("confidence", "medium")),
reasoning=item.get("reasoning", "")
)
def _parse_confidence(self, conf: str) -> float:
mapping = {"high": 0.9, "medium": 0.7, "low": 0.5}
return mapping.get(conf.lower(), 0.5)
def suggest_code_sequence(self, diagnoses: List[CodingSuggestion],
procedures: List[CodingSuggestion]) -> dict:
"""Determine proper code sequencing per coding guidelines."""
prompt = f"""Based on coding guidelines, determine the proper sequence for these codes.
Primary diagnosis should be the reason for the encounter.
Identify any hierarchical condition categories (CCs/MCCs) for inpatient coding.
Diagnoses: {diagnoses}
Procedures: {procedures}
Return JSON with 'primary_diagnosis', 'secondary_diagnoses', 'procedure_sequence'."""
response = self.ollama.generate(prompt)
return json.loads(response)
The model's coding suggestions depend heavily on training data quality. Medical coding has region-specific rules and annual updates that general-purpose models miss. Regular evaluation against gold-standard coded records identifies knowledge gaps.
Take ten clinical notes with known correct codes. Run them through the coder and compare suggestions against correct codes. Calculate suggestion accuracy and identify common error patterns.