Inspiration
Medication errors during care transitions are one of the most common — and most preventable — sources of patient harm. Reconciling a patient's active orders against what they're actually taking, while simultaneously checking for drug interactions, renal-dose violations, and allergy conflicts, is tedious, error-prone work that pharmacists do under time pressure. We wanted to see how far a modern LLM-driven agent, plugged directly into a SMART-on-FHIR EHR via the A2A protocol, could go toward making that safety net automatic, fast, and composable with other clinical agents.
What it does
The Medication Reconciliation Agent is an A2A server that, given a patient's SHARP context (FHIR server URL, OAuth bearer token, patient ID), will:
Pull live clinical data — demographics, active MedicationRequests, patient-reported MedicationStatements, conditions, allergies, observations (vitals + labs), and encounters. Let an LLM orchestrator pick the right tools for this specific patient — e.g., skip renal dosing when there's no eGFR, skip interaction checks for a single med. Run a battery of safety checks: Orders-vs-reported reconciliation (RxNorm-aware) Renal dosing against curated eGFR-tier rules Drug-drug interactions (contraindicated / major / moderate) Allergy cross-reactivity (e.g., penicillin → cephalosporin) Fall back to live web search for drugs outside the curated rules or borderline-eGFR cases. Synthesize a severity-ranked (CRITICAL / HIGH / MODERATE / LOW) clinical narrative, returned as both human-readable markdown and a structured JSON artifact over A2A task events.
How we built it
A2A protocol via the a2a Python SDK — Starlette server, agent card at /.well-known/agent-card.json, JSON-RPC message/send handler with streaming task updates.
LLM orchestration with OpenAI gpt-4o-mini: one pass distils the FHIR context and selects tools, a second pass converts raw tool outputs into a ranked clinical narrative. Curated rule modules for renal dosing, drug interactions, and allergy cross-reactivity — small, auditable Python tables rather than a black box.
Web-search fallback using OpenAI's *-search-preview models, capped per request to keep cost and latency bounded
Challenges we ran into
FHIR data is messy. RxNorm codes are inconsistent across servers, eGFR can be reported under multiple LOINC variants, allergy category casing is unreliable — every tool needed defensive normalization. Avoiding alert fatigue. Naively surfacing every theoretical interaction drowns the real findings; tuning the severity gates so CRITICAL actually means CRITICAL took several iterations.
A2A task lifecycle. Pre-generated task_ids from upstream orchestrators tripped the SDK's TaskNotFoundError; we had to subclass the request handler.
Knowing when to trust the rules vs. the web. Borderline-eGFR cases and unknown drugs needed a clear policy for when to pay the latency/cost of web enrichment.
Getting the LLM to skip tools. The orchestrator prompt had to be explicit that omitting a tool is the right call when preconditions aren't met (single med → no interaction check).
Accomplishments that we're proud of
A genuinely agent-to-agent medication-safety service — any orchestrator that speaks A2A can drop it into a workflow.
Severity-ranked clinical narratives that read like a pharmacist's note, not a JSON dump.
Hybrid reasoning: deterministic curated rules for the cases we know, LLM web-search enrichment for the long tail.
Token-secured agent card and SHARP-context-driven auth — no hardcoded credentials. Containerized via Dockerfile — deployable as a standalone A2A microservice.
What we learned
What's next for Medication Reconcilation agent
Caching + provenance for web-search lookups so repeated patients don't re-incur cost and citations stay stable.
Evaluation suite with synthetic patient cases covering each severity tier, scored against pharmacist-reviewed gold answers.
Streaming partial results so the UI can render findings as each tool completes, not just at the end.
Plug into authoritative public drug databases & APIs — replace/augment the curated rules with live lookups against: RxNav / RxNorm API (NLM) for canonical drug normalization and ingredient resolution OpenFDA for adverse-event signals, recalls, and structured product labels DrugBank / DailyMed for monographs, indications, and full prescribing information NIH DDInter or ONC's drug-drug interaction lists for evidence-graded interaction data SIDER for side-effect frequencies MedlinePlus Connect for patient-friendly drug education links CDC / WHO ATC classifications for therapeutic-class reasoning
Built With
- langgraph
- python
- render
Log in or sign up for Devpost to join the conversation.