A medical student rotating through their 3rd-year clerkships might spend two weeks on cardiology, then move to nephrology, then four weeks on neurology (whenever I write about 3rd year, I have jarring flashbacks to my Gyn-Onc rotation). Internal medicine residents are expected to learn even faster, with far more responsibility, and in a single year a resident works through more distinct disease areas than most engineers work through codebases in a career. And yet despite the massive scope of material and the urgency to master it, we don’t simply hand them the guidelines and ask them to memorize decision trees and flowcharts.
Instead, every good attending intuitively helps their trainees build a general model for approaching the disease they’re treating or the diagnostic problem they’re working up. You build this framework inductively, guided by specific patients, whether from case studies in the first few years of med school or real examples on the wards. For example, you might manage a few patients with heart failure and then learn that there are evidence-based medical therapies to initiate, that those drugs have doses you’re trying to reach, and that some patients can’t tolerate them, but that there’s a defined thing you do when that happens. And then the next disease arrives, but the good thing is you aren’t starting from scratch because you’re following that same approach: what’s my target, how am I going to measure it, what are my tools, and what’s going to get in my way.
Then we bring in the next disease or problem and help the trainee draw the management or workup parallels. Depression after hypertension can be a little discomfiting at first, until you notice that a PHQ-9 score is partly playing the role the blood pressure cuff played, and that there is a compendium of medications to be used, and that you need to watch out for some med-specific side effects in both cases, whether by testing (e.g., ECG, HbA1c) or asking about symptoms (dry mouth, cough).
We teach this way, and not by rote memorization, for good reasons.
First, memorized decision trees don’t transfer at all. If you learn hypertension as a flowchart, then you’ve learned hypertension and nothing else, and you haven’t picked up anything that makes atrial fibrillation easier to learn the following month.
Decision trees are also brittle. Guidelines get revised, and a revision often doesn’t limit itself to one branch, so the tree gets rewired and whoever memorized the old one starts over.
But the problem with teaching by memorizing guidelines is even more insidious and becomes a medical liability. Memorized trees can’t be communicated. If your attending or the resident you’re passing off to asks you why you did something, you’re not going to hand them a flowchart path. You’ll bring them right back to the shared mental disease model in order to justify your diagnosis and plan. Guidelines might be useful for terminal decision points but they can’t anchor the discussion. And you certainly aren’t going to sway a patient being asked to take a fourth medication by pointing to the table in Section 5.3.1 of the ACC/AHA 2025 blood pressure guidelines.
Figure 1. One hypertension guideline, encoded two ways.
We set out to build an autonomous cardiologist
When Atman Health was founded in 2021, our goal was not simply to build a disease-management tool. We wanted to create an AI cardiologist (or, more ambitiously, an AI pan-specialist) who could handle every aspect of virtual patient care without a human in the loop, built with every modern technique available.
I had spent the last 15 years on the academic side at the interface of machine learning and clinical medicine. Random forests, hidden Markov models, SVMs, and gradient boosting over genetic and genomic data; convolutional networks on echocardiograms and ECGs; and, towards the end of my academic career, after the 2018 Google attention paper, transformer models across medical notes for diagnosis extraction. Although I cut my teeth on more objective data, I pushed into the text-model space because I recognized that medicine, for better or for worse, is inherently a field where much data is captured in natural language.
During this time, I gained a strong appreciation for the tools available, but also recognized they wouldn’t address the major problems I saw in medicine regarding cost and quality. Saving seconds on reading a scan will have essentially no impact on managing a complex patient. Risk models are a dime a dozen - whether they’re produced by logistic regression or 50-layer neural networks - and are hardly ever used. And none of this helps decide in 30 seconds or less whether to start an ACE inhibitor and at what dose, in a patient with Stage II hypertension whose potassium and creatinine ran high eight months ago but cannot get transportation for a repeat lab check, had an echocardiogram three years ago you can’t readily retrieve but she thinks showed something about her heart not doing something properly, and who already told you she hates taking pills.
As I’ve written about in the past, problems such as how to make optimal decisions in the face of missing data, how to choose starting doses and titration intervals, and how to overcome obstacles to care, all in a scalable manner, are not going to be solved by AI scribes and RAG models that output guidelines and voluminous passages on best practices. We’ve built and incorporated versions of both into our software, because they certainly have uses. But even though the market has decided this is what AI in medicine means, we haven’t found that to be the case.
So the question was never which modern neural network architecture to reach for. It was what you’d have to build for a machine to achieve autonomous complex care. That ended up being a very different solution.
An abstraction of chronic disease treatment
The obvious temptation when building an autonomous solution is to transcribe guidelines into branching logic. It kind of works for one disease at one point in time, and only from a testing standpoint. But it fails miserably when it comes to what we believed would be essential: portability to other diseases, revisions in guidelines, and, most importantly, helping develop the shared model that underlies human-human, human-patient, and eventually human-agent collaboration.
So instead we did something a little more ambitious: we based our software on an abstraction of treating chronic diseases. We deliberately took on eight diseases at once: depression, anxiety, hypercholesterolemia, hypertension, heart failure, COPD, type 2 diabetes, and rheumatoid arthritis. Conveniently, I was recertifying my Internal Medicine boards that year, so I was forced to move out of my cardiology comfort zone anyway. We picked four specialties on purpose, because a model that only works in cardiology isn’t particularly generalizable. As one might have guessed, the behavioral health programs were the most distant from cardiovascular programs in “disease space” since a depression score and a blood pressure cuff don’t have much in common.
Figure 2. Verbatim rows from the program definitions.
That work produced a much more modest set of reusable data objects and functions, organized around the concept of treatment programs. A treatment program has targets, and those targets have a variety of types, whether they’re device measurements, lab measurements, symptom quantification, or “medication dose targets” reflecting doses showing maximal benefit in clinical trials. Treatment interventions, usually medications, attain targets, but the choice of intervention depends heavily on patient characteristics, which were encoded as measurements and questionnaire data. These then impacted predicates that evaluated against them. Finally, the optimal progression of treatments represented rankings of (sometimes grouped) medications, where each medication-program combination itself had titration schedules, inclusion and exclusion criteria, efficacy and inefficacy criteria, tracked toxicity measures, and toxicity plans.
Today those fields cover 89 treatment programs across ten specialties, from nephrology to rheumatology to pulmonology, and the engine underneath hasn’t changed much since we wrote it against the original eight. We, of course, focus heavily on cardiology, which has 28 treatment programs.
Those fields look simpler than they are. Open one, and you’ll see why this took years instead of months.
Figure 3. The response to a side effect is composed, not selected. A decision tree’s leaf is a single instruction. Here the instruction is itself computed, which is why the same complaint gets a different answer in two different patients.
A toxicity isn’t just one value. Statin muscle problems come in multiple severities. And even some of those can come in two flavors: the kind that fades if you hold the dose steady (tachyphylaxis), and the kind that never does, a distinction that needs to be modeled correctly as it impacts how to handle side effects.
Switching medications also can be more nuanced. Moving somebody off an SSRI isn’t stopping one abruptly while starting another at its lowest dose; it’s a cross-taper, and the details of the cross-taper depend on what medication you’re transitioning them to. Each transition has a name and individualized characteristics, and the decision engine chooses among them, based on patient characteristics and preferences.
In fact, individual patient characteristics impact the entire set of decisions. Medications can be restricted to specific doses, titration schedules can be optimized by patient characteristics, and preferences can be captured as structured data. None of that is in a guideline, and it all determines whether the recommendation will work and whether it should be revisited in the future.
The clinical content lives in the values, and not in the branch structure.
Finally, one of the first problems we recognized, which carries a fascinating amount of complexity, is how to decide if the measurement value (lab, device, etc.) is recent enough to be used. I’ve always lived in medically dense and affluent areas where I never had a second thought about reordering tests. But repeat testing can be costly and inconvenient in many parts of the country, and seemingly trivial tasks like remeasuring potassium or creatinine aren’t straightforward. You’re often faced with the unenviable decision: you have a difficult-to-engage patient on the phone, and have a chance to make a substantial impact on blood pressure or heart failure outcomes, but your last values are 14 months old. What are you going to do?
And of course, who the patient is matters. What is their historic kidney function, what historic potassium spikes have they seen, what other medications are they on, how hard will it be to get a repeat measurement, and are they prone to dangerous arrhythmias? In these scenarios, clinicians decide what to do ad hoc, often non-reproducibly, and can’t describe their reasoning. No guideline provides guidance on this. Our approach is not to hard-code a number of days after which a number needs updating but to compute one. And then what to do when it’s not available depends, deterministically, on the functions that consume it.
Figure 4. How recent a potassium has to be isn’t a fixed number. It falls out of the kidneys, the drugs, where that person’s own potassium has already been, and whether their heart is prone to dangerous rhythms — and it changes again depending on whether you’re taking a history or watching for toxicity mid-titration. A denied symptom is evidence. A question nobody asked isn’t.
You can’t delegate and share risk with someone (or something) who reasons differently from you
The parallel between how we teach trainees and how we developed our software extends beyond ease of extending a model to new diseases. We don’t simply build a shared model with a trainee because it’s pedagogically elegant. We do it because it’s the only thing that makes efficient delegation and risk management possible.
This situation is exemplified when an attending signs off on a fellow’s plan (another set of emotional flashbacks, this time to cardiology fellowship at MGH, though much fonder memories). On an efficient afternoon rounds on the consult service, the fellow presents each patient for ninety seconds. The attending follows by asking a couple of questions and briefly speaking to and examining the patient. They then are willing to cosign a note describing a plan they personally didn’t formally reason through. This is only possible because the attending and fellow have aligned on a shared model. Often, trust from recognizing that alignment is established before the specific encounter and carries forward in all new settings.
Now replace the fellow with a system whose reasoning isn’t shared by the attending physician or perhaps is unknowable. We have a couple of choices, and both are undesirable. The attending can just start from scratch and build up the evidence for a decision on their own, in case no real delegation has occurred. Or they can take a leap of faith, and just sign without much faith that they truly agree with the basis of the decision, which is a malpractice disaster waiting to happen. Neither of those is a tenable path to shared liability.
And without delegation, there’s no scaling, and our system remains saddled with untenable costs, so this is not just an academic concern.
The generalizable disease model brings in some more perks.
Adding a new treatment program takes about a week, and it’s curation, not engineering. In most cases, we don’t have to touch the engine. Only data elements are updated.
A guideline revision requires a few hours of work. The 2026 dyslipidemia guideline, perhaps the most significant overhaul in 15 years, required a half day to incorporate.
A different new formulary, or for that matter a new country, is a different set of medication rankings. Formularies live in data fields separate from the underlying logic.
Patients can be motivated by accessible data elements. A user (including an agent) can describe the motivation for any recommendation: your SBP is averaging 152 against a target of 130; this is the optimal medication and starting dose given your kidney function; and here’s what we’d expect in two weeks.
An ISO 14971-type hazard analysis for regulatory submissions is a byproduct of the design. Every value can be sourced. Every predicate is a function you can run. Every recommendation has a test that passes or fails.
Diagnosis has no question order at all
We started by describing our treatment programs, because that’s the easier half of the equation. Diagnostic workup of an undifferentiated problem is even more ambitious. In this case, the difference between our approach and decision trees becomes even more obvious, because a decision tree for a diagnostic workup is hard-coding of which questions to ask and in what order.
In contrast, our Bayesian diagnostic engine doesn’t store any question order.
The approach starts with curating prevalence, stratified by age and sex, across 2,152 conditions, granular enough that they carry real diagnostic evidence and usually treatments. These evidence-condition pairs have likelihood ratios attached to them, curated per condition, and are derived from patient responses and tests, including labs, imaging, exam findings, and therapeutic maneuvers. As evidence accumulates, posterior probabilities shift, and individual diagnoses compete for supremacy.
If you’re not using a hard-coded decision tree, you need a data-driven, principled way to choose questions. In our case, the engine re-scores every remaining question against its posterior probability and asks whichever one is expected to reduce uncertainty the most. And then it does it again and again.
Figure 5. There is no question order stored anywhere in the system.
When deciding which conditions to consider, the system upweights urgent conditions, even if prevalence is low. Tests for our diagnostic engine focus on whether diagnosis X would have been recovered in simulations where a patient is playing the role of someone with X. Repeat this for N conditions, hundreds of times, simulating variations in patient persona, including anxiety, health literacy, and frustration. To avoid irritating patients with head-jerking topic changes, questions in the same symptom domain will get a small bonus so the engine asks a slightly less informative question, keeping it from lurching from chest to abdomen to sleep and back.
Within this schema, chest pain has been mapped to 145 conditions, and dyspnea to 197. With that breadth, narrowing to the most plausible set of conditions in ten to fifteen questions is feasible; it won’t be with a hard-coded list. But the principles for getting there can be driven by an engine that dynamically updates probabilities and prioritizes based on risk.
A quarter of a million curated clinical parameters underlie this endeavor: prevalence by age and sex (separating joint from conditional probabilities), positive and negative likelihood ratios, and probability-of-necessity values attributing symptoms to competing diagnoses. Most people believe that scale is impossible to manage, and until recently it would have been. Foundation models have made it tractable (see below).
Even more importantly, we’ve managed these patients throughout these past five years, and tens of thousands of encounters have fed back into determining which questions hold information, which criteria are ill-designed, and which recommendations a patient will simply refuse. Gaps in guidelines become all too apparent when you are forced to encode and systematize an entire field.
Test ordering runs on the same information-theoretic principle. As with questions, we prioritize tests by their anticipated impact. But unlike questions, which are mostly free (unless you count patient irritation as a cost, which we do), tests have costs. So our test-choosing strategy is data-driven, shaped by expected impact and value. Challenging for a human to do in most cases, other than using crude heuristics.
Symptom attribution asks whether it’s the drug or the disease
The abstraction shows up a third time in symptom attribution and triage. In this case, the goal is not to diagnose a new condition but to first attempt to ascribe a patient complaint to an existing likely cause.
For example, your patient reports swollen ankles. She’s on amlodipine, and we know (and the software knows) amlodipine causes exactly that. But she also has heart failure with preserved ejection fraction, and heart failure also causes exactly that. Those two hypotheses compete, but they carry different consequences, and myopic software or an agent that picks one naively has failed to address the root cause.
But of course that’s just one symptom and one disease. The universe of diseases is in the thousands, as is the universe of medications. Disease attribution runs as its own Bayesian chain over the patient’s confirmed conditions. The vocabulary underneath includes over a thousand symptom concepts and tens of thousands of curated symptom-drug and disease-drug associations. An intelligent engine handles timing and characteristics to recommend attribution.
Figure 6. Not three engines.
Guidelines are (part of) what we test against, not what we hard-code.
If you transcribe a guideline into branching code, then the guideline has become your source code. And there’s nothing independent left to test that code against, because the two are now one artifact. In that situation, when the ACC/AHA publishes revised guidelines, you rewrite the code.
But because our clinical content sits in values instead of branches, the guideline stays outside the engine entirely, as a set of tests the engine is evaluated against. When a case fails, the engine is what was wrong. And a new guideline is a new set of tests. The goal always has to be 100% concordance against guideline-based tests, unless, of course, guidelines themselves are logically incoherent (which, unfortunately, is not an uncommon finding).
Guidelines are just a small fraction of our test base. Exclusion criteria and inclusion criteria at an individual medication level, dealing with data missingness and non-recent data, addressing medication restrictions (including incorporating patient preferences), handling cross-tapers and tachyphylaxis correctly, discontinuing or adjusting drug doses in response to side effects: most of these are not listed in practice guidelines but are essential to safe and effective software.
Figure 7. The guideline as an oracle instead of as source code.
None of this was buildable three years ago
An abstraction like this, taking on what is effectively most of cardiology decision-making, needs an enormous amount of underlying curated clinical content to function. Prevalence for two thousand conditions. Sensitivities and specificities for every piece of evidence that impacts the likelihood of relevant disease conditions. Titration schedules, toxicity plans, inclusion and exclusion criteria, and dose targets across thousands of medications. And a ranking strategy for choosing medications, individualized to patients. That’s nearly a quarter of a million values, all of which must be defensible.
Hand-curating a quarter of a million clinical values has historically needed an institution’s effort and most of a decade. And, depressingly, these stalwart curators would watch it become obsolete in real time while they worked on it. Foundation models have transformed this undertaking. Their role is not to provide clinical judgment, a task they are unsuited for. A cardiologist (guess who?) still signs off on every meaningful value (and thankfully modern tools let that validation happen at scale). What they enabled is a dramatically lower cost of getting a working version in front of that cardiologist, at a rate that makes this effort a tractable product goal for a small venture-backed startup. Separately, they let us create that structured representation quickly enough that, from year two (2022 in our case), we could enrich and battle-test it by taking care of actual patients.
An autonomous cardiologist needs a clean division of labor between an LLM and a decision engine
The prevalent approach to introducing AI into clinical care has been to use foundation models to produce diagnostic and treatment recommendations. The results have been both impressive and yet concerning, underscoring the “jaggedness” of these models. They can outperform average physicians armed with conventional tools, but, as would be expected given how they’re trained, they struggle with quantitative parameter estimates or understanding dates and chronology; they can’t tell you exactly how they did what they did; they are sensitive to minor changes in prompts, and every now and then they make a catastrophic reasoning failure. Since I’ve spent tens of thousands of hours leaning on top foundation models for software and AI development and curation efforts over the past few years, I’m very aware of how great and how unpredictably terrible they are.
That brings me to the problem of entrusting them with autonomous decisions. If you don’t know how they will behave and you don’t know what’s behind their decisions, how can you trust them without a human in the loop? So right now, there’s always a human in the loop to address the cringe-worthy failures. And I suspect, unless we’re working in trivial situations, if an LLM is tasked with decision-making, there should always be a human in the loop. This is not to say that humans are uniformly great or even good at a lot of complex medical tasks. But a new paradigm of medicine with unpredictable, potentially catastrophic failures seems problematic to get behind.
However, if one can achieve a division of labor between a deterministic engine and a conversational LLM agent, you can overcome this exact problem. The engine’s decisions are computable functions over structured data, so you can enumerate them completely and test them directly against an extensive corpus. We currently have tens of thousands of tests of all flavors, including regression tests and partially and fully simulated patient-agent tests. But volume isn’t the point. Those tests aim at a formal ISO 14971 hazard register, and the hazards aren’t just about guideline non-adherence. They are focused on missing and stale data, abnormal values acted on or ignored, medication confusion, missed urgency, undertitration, and the boundaries where the system should decline to act at all. All in all, there are 61 current hazard categories, each linked to predicates that can trigger it, and some, like a hallucinated lab value that impacts a decision, are zero-tolerance release blockers. In this framing, the language model’s role is simply to extract from patient conversation and other unstructured data (prescription signatures, charts) what the engine needs. You can test this extraction ability separately from the deterministic logic underlying the decision-making engine.
Figure 8. The two failure modes come apart, so they can be measured apart.
This division of labor has a name, but we often hear it discussed in the context of foundation models competing in Math Olympiad competitions. It’s called neurosymbolic reasoning: a neural component and a symbolic one, each doing different jobs with a clean boundary. If we want to keep going with buzzy words, the symbolic half can also be seen as a world model of cardiology. Not an implicit one tangled up inside a set of weights, but an explicit model of how disease behaves that you can query and update.
The applicability of these terms suggests we’re much closer to where AI is headed than it may have seemed at first. There are a lot of hot takes these days on whether an explicit model of the world is needed to reason reliably, and we’ve put our money on the side that says it does. Enormous effort, including billion-dollar seed rounds, is going into training world models. In cardiology, you don’t need to wait for that, because medicine has spent the past 80 years measuring that world and publishing the results. Today, you can organize that initial world model into a structured form. Still a heroic task. But importantly, the structured form is the essential starting point for ongoing practice to make it better.
Our approach has also let us incorporate autonomy gradually, instead of imposing it opaquely in an all-or-nothing manner. The same engine and flow specifications underpin our provider tool, our consumer intake, the shadow agent that drafts a plan for a provider to approve, and the voice agent. This sharedness ensures that optimization in a provider’s use carries over to all other forms, as will any error fixes.
How the LLM-based conversational layer attaches to this is a different story, which I’ll write separately. But it should be clear that the risks are bounded to conversational extraction failures on the engine output, not on the unknowable results of LLMs pretending to be cardiologists.