09. Drug Interaction Checking
Drug-drug interactions (DDIs) represent a well-defined, high-stakes clinical decision support use case. Checking a medication list against known interaction databases prevents adverse drug events. Local LLMs can augment database lookups by identifying potential interactions that structured databases miss.
The challenge: interaction checking must be reliable. Missing an interaction causes patient harm; flagging non-interactions creates alert fatigue. Local models work well for augmenting structured databases rather than replacing them.
# drug_interaction_checker.py
from dataclasses import dataclass
from typing import List, Optional, Dict
from enum import Enum
class InteractionSeverity(Enum):
CONTRAINDICATED = "contraindicated"
SEVERE = "severe"
MODERATE = "moderate"
MINOR = "minor"
@dataclass
class DrugInteraction:
drug_a: str
drug_b: str
severity: InteractionSeverity
mechanism: str
clinical_effect: str
recommendation: str
class LocalDrugInteractionChecker:
"""Check drug interactions using local database plus LLM augmentation."""
# Common interaction database entries
KNOWN_INTERACTIONS = {
("warfarin", "aspirin"): {
"severity": InteractionSeverity.SEVERE,
"mechanism": "Pharmacodynamic",
"effect": "Increased bleeding risk",
"recommendation": "Avoid combination unless clinically necessary"
},
("lisinopril", "potassium"): {
"severity": InteractionSeverity.MODERATE,
"mechanism": "Pharmacodynamic",
"effect": "Hyperkalemia risk",
"recommendation": "Monitor potassium levels"
},
# ... additional entries
}
def __init__(self, ollama_client, interaction_db_path: Optional[str] = None):
self.ollama = ollama_client
self.interaction_db = self._load_interaction_db(interaction_db_path)
def check_interactions(self, medication_list: List[Dict]) -> List[DrugInteraction]:
"""Check all pairs in medication list for interactions."""
found_interactions = []
# Check database for known interactions
for i, med_a in enumerate(medication_list):
for med_b in medication_list[i+1:]:
# Database lookup
db_interaction = self._db_lookup(
med_a["name"].lower(),
med_b["name"].lower()
)
if db_interaction:
found_interactions.append(db_interaction)
else:
# LLM-based detection for unknown interactions
llm_interaction = self._llm_check(med_a, med_b)
if llm_interaction:
found_interactions.append(llm_interaction)
return found_interactions
def _db_lookup(self, drug_a: str, drug_b: str) -> Optional[DrugInteraction]:
"""Check internal interaction database."""
key = tuple(sorted([drug_a, drug_b]))
if key in self.KNOWN_INTERACTIONS:
data = self.KNOWN_INTERACTIONS[key]
return DrugInteraction(
drug_a=drug_a,
drug_b=drug_b,
severity=data["severity"],
mechanism=data["mechanism"],
clinical_effect=data["effect"],
recommendation=data["recommendation"]
)
return None
def _llm_check(self, med_a: Dict, med_b: Dict) -> Optional[DrugInteraction]:
"""Use LLM to detect potential interactions not in database."""
prompt = f"""Analyze potential drug interaction between:
Drug A: {med_a.get('name')} {med_a.get('dosage', '')} {med_a.get('frequency', '')}
Drug B: {med_b.get('name')} {med_b.get('dosage', '')} {med_b.get('frequency', '')}
Consider:
- CYP450 interactions
- Additive/synergistic effects
- Absorption interactions
- Mechanism of action conflicts
If interaction exists, return JSON:
{{"severity": "severe/moderate/minor", "mechanism": "...", "effect": "...", "recommendation": "..."}}
If no significant interaction, return: {{"none": true}}"""
response = self.ollama.generate(prompt)
try:
data = json.loads(response)
if data.get("none"):
return None
return DrugInteraction(
drug_a=med_a["name"],
drug_b=med_b["name"],
severity=InteractionSeverity[data["severity"].upper()],
mechanism=data["mechanism"],
clinical_effect=data["effect"],
recommendation=data["recommendation"]
)
except:
return None
def _load_interaction_db(self, path: Optional[str]) -> Dict:
"""Load additional interaction data from file."""
if not path:
return {}
# Load from JSON/YAML file
return {}
The LLM augmentation catches novel interactions, but introduces uncertainty. Flag interactions from LLM analysis differently than database matches—clinicians need to know which recommendations come from validated sources.
Create a test medication list with ten drugs including two known interactions and two unknown combinations. Run the checker and evaluate both detection accuracy and false positive rate.