AI Adoption GuideHealthcareIntake
Medication reconciliation agent
NLP cross-references patient-reported medications against pharmacy and EHR records, then flags discrepancies and contraindications for clinical review.
Healthcare processAccessIntakeAssessDiagnoseTreatDischargeBillFollowup
By Don, DoneThat’s AI coach · updated
Dual-cite every discrepancy or write nothing
A medication reconciliation agent is doing its job when the only non-empty output is a discrepancy that cites both sides: the patient-reported line and the pharmacy or EHR line. If the lists already agree, that field stays empty. The agent does not invent a medication that neither source named. A clinician still reconciles.
The flag is evidence for review, not a replacement medication list. After intake, the active medications are whatever the clinician signs.
Patient-reported names often arrive through automated anamnesis collection or spoken intake. Pharmacy fills and EHR orders typically live in platforms such as Epic or Oracle Health. Ambient documentation tools such as Nabla may capture what the patient said. Drug knowledge bases such as FDB are used to normalize names and to attach contraindication labels. Treat those vendors as classes of record and knowledge sources, not as a ranked feature list. The comparison rule does not change with which class supplied a given line.
Load the reported list beside pharmacy and EHR lines
Start with two loads, not one blended table.
Load the patient-reported list as captured: name or description, strength, dose, frequency, route, and any "I stopped this" or "I take this sometimes" wording. Keep that original phrasing on the line you will cite. Do not rewrite "water pill" into a generic before comparison, or you will cite a sentence the patient never said.
Load pharmacy claims or fills and the EHR medication list, including active, recently discontinued, and pending rows, as separate citeable lines even if you display them together. A fill and an order can disagree. The agent still has to attach each claim to a real row.
Name the pharmacy window you loaded. A fill outside that window is not a line you can cite. Do not treat history you did not load as proof that pharmacy lacks a drug.
Reported OTC and herbal items still need a sourced counterpart or an explicit sourced-side absence. Cite the reported line and that pharmacy and EHR do not contain the product. Do not replace the OTC with a prescription analog the patient never named.
Normalize only enough to compare: ingredient, salt when named, strength, frequency. Use a knowledge base in the FDB class to map brand and generic names and to attach contraindication labels after two real lines exist. Normalization is not a license to add a drug.
Then walk reported lines against sourced lines.
When a reported line and a pharmacy or EHR line describe the same regimen, that pair is a match. Do not emit a discrepancy for that pair.
When they differ on a material fact (one side only, different dose, different salt, different frequency, reported active versus sourced discontinued), emit one discrepancy that cites both strings. Dual cite means the patient-reported text and the pharmacy or EHR text both appear. "Patient did not mention warfarin" is not a dual cite unless the pharmacy or EHR warfarin line is included. "Pharmacy has no lisinopril" is not a dual cite unless the patient-reported lisinopril line is included.
If you raise a contraindication, attach it to those same cites plus the knowledge-base rule. Do not raise a contraindication against a drug that exists only in the model's guess.
Matches stay empty; only mismatches become flags
If every reported line has a sourced counterpart with the same regimen, and every sourced active line appears on the reported list, leave the discrepancy output empty. Empty is the correct quality result. Do not fill the field with concordance prose unless local policy requires a recorded negative. Empty stays empty if the lists match.
The following is one illustrative comparison, not a case study and not a measured result.
A patient reports "metoprolol 50 once a day" and "atorvastatin 20 at night." Pharmacy fills show metoprolol succinate 50 mg daily and atorvastatin 20 mg daily. The EHR active list matches those fills. Neither source lists a third drug. The agent writes nothing in the discrepancy field. The clinician still reviews both lines and signs.
Change one fact. Pharmacy shows metoprolol tartrate 25 mg twice daily. The patient still said "metoprolol 50 once a day." The EHR still lists metoprolol succinate 50 mg daily. The agent quotes the patient-reported line and the pharmacy tartrate line. If the template allows another sourced cite, add the EHR succinate line. Do not add carvedilol, a nameless "beta blocker" product, or a dose nobody documented. The clinician chooses salt and schedule, whether to call the pharmacy, and whether the EHR order is stale.
That is the working sequence: load both lists, flag only dual-cited mismatches, leave matches empty, and hand the packet to a human.
Refuse one-cite flags, invented drugs, and flags used as the list
Three failure modes show up in intake. All three corrupt the medication list if they pass unchallenged.
One-cite medication. The model writes "possible missing apixaban" because the EHR has an old order, but the flag does not include that EHR line and does not record that the reported list has no apixaban row. A pharmacist cannot check it. Require the sourced line that exists and the reported-side evidence: a verbatim reported row or an explicit "not on the reported list" note tied to that sourced line. A one-cite highlight can live in a scratch note. It is not a discrepancy under the quality rule.
Invented drug. Mapping a patient's "cholesterol pill" to an atorvastatin 20 mg row that pharmacy and EHR both already list is comparison, and a matching pair stays empty. Invention is writing a product neither list named, or adding a second statin, an NSAID, or an antibiotic from comorbidity text. If the only evidence is a problem list or narrative, send it to prior record ingestion and summarization. Do not mint a current medication row from the summary.
Flag treated as the list. Discrepancy text gets copied into active medications, or a downstream check uses flags as the truth for real-time drug interaction monitoring. Interaction checking needs the signed list, not the exception log. A flag that the patient reported 50 mg daily and pharmacy filled 25 mg twice daily authorizes neither dose. Until a clinician reconciles, there is no reconciled list.
Keep discrepancies as append-only evidence and the medication list as a separate object the clinician edits. If Epic, Oracle Health, or another EHR only exposes one field, put agent output in a review comment or workqueue item, not in the coded medication list.
Intake ends at the signed list; later steps use that list
This page is intake: a cited comparison before the visit proceeds on a wrong list. Discharge compares the hospital list with what the patient will take at home. That step is discharge medication reconciliation. Do not reuse an intake discrepancy as the discharge rec.
Contraindication labels from a knowledge base belong on a dual-cited flag when the drug and the conflicting condition or pair are both in the record. Checking new orders after sign-off is real-time drug interaction monitoring, not another intake NLP pass.
Prior notes, scanned recs, and outside PDFs can explain why two current lists disagree. Summarize them. Do not let a summary replace a missing cite. A scanned page that names a drug absent from both the patient report and the current pharmacy or EHR list is a lead for the clinician, not a current medication.
Pharmacist test: for every non-empty discrepancy, can you point to the patient-reported line and the pharmacy or EHR line? If either pointer is missing, send it back. If the lists match, the field is blank. If a drug appears that nobody reported and no pharmacy or EHR row contains, delete it. Then the clinician reconciles.
Is this worth automating for you?
Whether this pays back depends on how much time it takes your team today. Most teams estimate that from memory, and the estimate is usually wrong in one direction or the other.
DoneThat reconstructs where the time actually went, with no timers to forget, so you can measure the baseline before committing to a project and check the gain afterward.
Measure the baseline first