AI medical bill review: what the model can and cannot do
Every accuracy problem we hit building an automated medical bill review engine was fixed the same way: by taking work away from the AI. Four times we found a failure, and four times the fix was to hand that job to deterministic code or to a paid service and leave the model with less. What is left for the model is reading messy language, and nothing that produces a number.
An AI company is not supposed to tell this story. It is what happened, and it is the reason the output is defensible.
Can AI review medical bills for a legal case?
Yes, for part of the work. A language model can read messy language: it can tell a bill from a treatment note, match provider names and propose duplicates. It should not produce any dollar figure. In our engine, code computes every amount and a person signs the result.
The rest of this article is the evidence for that split: four failures, each fixed by giving the model less to do. For the manual process this replaces, see how long medical bill review takes to prepare.
Why does an AI model invent a number on a medical bill?
When the figure it is asked for is illegible, cut off or absent, a language model can return a plausible amount instead of nothing. It gives no sign that it is unsure, so an invented amount arrives with the same confidence as a correct one.
It happened to us, and not randomly. It happened when the model was pushed into a corner: the figure was illegible, or cut off, or simply absent from the page it had been given. Rather than return nothing, it returned something plausible. A dollar amount that looked exactly like the other dollar amounts on that bill, and that no provider had ever charged. We did not count it as a rate. We designed it out.
This is the specific failure that makes a language model unsuitable for the last mile of this work. It has no reliable signal for its own unreliability. The reasoning behind that behavior, and why it is a property of the technology rather than a bug in one model, is the subject of why we are called System 2.
In litigation, that number ends up in a damages figure an expert signs. There is no version of this where that is an acceptable failure rate, so the response was not to prompt around it. It was to stop asking the model for numbers.
Round one: why is OCR separate from the model?
Reading a scan is an optical problem before it is a reasoning problem. We first handed the PDF to the model and asked it to read the bills. It did not work, so the reading moved to a dedicated cloud OCR service that returns the text and the position of every word.
Scanned medical bills are hostile input. They are faxed, photocopied, rotated, stamped, and stacked on top of each other in one file. Columns do not line up. A paid amount and a billed amount sit inches apart in a grid the scan has partly destroyed. A model asked to read that and reason about it at the same time does neither well.
The model no longer sees the image. It sees a clean spatial grid with blank cells preserved, which is what stops a paid amount from sliding into an empty neighboring column.
What does better OCR cost?
Better OCR is a cost we choose to pay rather than cut. We have not published a cost ratio, so this article makes no claim about its size. What it can show is why: OCR is the input to everything downstream, and a cheaper read moves the cost to a person checking a row.
A read that garbles one digit in a CPT code does not save money. It moves the cost to a person checking a row, or to an expert defending a number that was never on the bill. That is the tradeoff worth stating plainly rather than optimizing quietly.
Round two: who turns the text into rows?
Deterministic code, wherever the document has a structure it recognizes. With clean text available, the model originally turned it into rows. Now code does that wherever it can, and the model handles the remainder, which is the part that does not fit a known shape.
The split is by confidence, not by preference. Code reading a known structure is reproducible: it returns the same answer every time, and when it is wrong it is wrong in a way you can find once and fix forever. Where the document does not fit a known shape, the model reads it, and the result carries the model’s own confidence rating, which is a screen rather than a guarantee. Below the bar, the value does not become an answer. It becomes something the reviewer is asked to confirm.
The distinction that matters is not which one is smarter. A deterministic error is a bug and a model error is a coin flip. You can eliminate the first. You can only ever reduce the second.
Round three: why does no dollar figure come from the model?
Every amount in the output is computed by a formula, not checked by one. The model is never asked what a number should be, because it can be wrong and has no way to tell you. Opposing counsel can reproduce a formula. They cannot reproduce a model’s guess. The model may read a printed amount off a page that fits no known shape, and a reading below the confidence bar goes to the reviewer. It is never asked to compute or supply an amount.
The fee schedule lookups, the bilateral uplift, the multiple procedure reduction, the daily caps, the totals: all of it is arithmetic over values that came from a source page, run in code. You can look up the underlying Medicare fee schedule figures yourself in our free Medicare rate lookup.
Plenty of people in this field would call that overcautious, and in a lower-stakes domain they would be right. Here the output is an exhibit. Someone signs it, an opposing expert reads it looking for exactly one thing to break, and a single invented figure discredits the rest of a correct analysis. The asymmetry is not close, so the rule is absolute rather than a matter of judgment.
Round four: what happens to a duplicate the engine is not sure about?
An uncertain duplicate stays. The same service is often billed more than once: a provider’s HCFA, the insurer’s EOB, a ledger and a lien can all describe one office visit, and adding them up triple-counts the damages. So the engine merges only what it can prove and keeps everything else as highlighted rows.
An early instinct is to have the model decide which lines are duplicates and remove them. We do not do that, and the reason is the same principle that governs the assembly step: a deleted charge is invisible, and an extra one is not.
A duplicate the engine can prove collapses to one charge. Everything it cannot prove stays in the workbook as two rows, highlighted, so the reviewer can see at a glance which lines are possible duplicates and remove one in a few seconds. That is a few seconds of work in exchange for never silently erasing a real charge.
The check works in the other direction too. In one case the engine proposed two genuinely separate charges as one duplicate. The reviewer kept both. The matching rules are in duplicate charges in a medical bill review.
What does the engine assert, and what does it ask?
The output has two tiers. What the engine asserts is everything it can produce deterministically or verify. What it asks lives on a checklist tab in the same workbook. Anything uncertain goes in the second tier and is never promoted into an answer to make the output look cleaner.
That is the design idea underneath all four rounds, and the one worth stealing. It is why the assertions can be trusted. Not because the system is incapable of being unsure, but because being unsure has somewhere else to go. A pipeline with only one tier has to resolve every ambiguity into a confident value, and a confident wrong value is the failure that costs an expert her credibility.
What does a person still check, and how long does it take?
On a large case a person spends under an hour. That is from my own experience; we have not timed it. That time goes on a mix of flagged rows: possible duplicates, provider names and page classification. It is real review, not a rubber stamp. If you were hoping for a system that hands back a finished number nobody has to look at, this is not that.
We would rather say so before you start than after.
What does the model still do?
The model reads messy language, the part it does better than any rule we could write. It decides that a page is a bill rather than a treatment note, recognizes that two differently spelled provider names are the same practice, and proposes that two lines from different documents describe one service.
Those are judgments about meaning, and code is bad at them. What the model does not do is decide what anything costs. It reads. The arithmetic belongs to code, and the signature belongs to a person.
Frequently asked questions
Can AI extract medical billing data accurately?
AI reads messy documents well and should not be trusted to produce the numbers. In our engine a language model classifies pages, resolves provider names and proposes duplicate groups, while every dollar figure is computed by deterministic code from values traced to a source page. The reason is that a model has no reliable signal for its own uncertainty, so a fabricated amount arrives looking exactly like a correct one.
Why not just send the PDF to an AI model?
Scanned medical bills are faxed, rotated, stamped and stacked, and reading them is an optical problem before it is a reasoning problem. Asking one model to do both at once produces worse results than separating them. A dedicated OCR service returns text plus the position of every word, and the model then works on a clean spatial grid rather than a damaged image.
How do you stop an AI from hallucinating a number on a medical bill?
Do not ask it for numbers. Every amount in our output is produced by a formula over values extracted from a source page, and the model is never in the arithmetic path. Where a value cannot be read with confidence, it is not filled in with a guess. It goes on a checklist for the reviewer to confirm.
What happens to duplicate charges the system is not sure about?
Uncertain duplicates are kept, not removed. Both lines stay in the workbook and are highlighted so the reviewer can see the possible duplicate and delete one in seconds. Deleting a real charge is invisible and unrecoverable, while an extra row costs a few seconds, so the system is built to make the second mistake rather than the first.
Can AI replace a medical bill reviewer?
Not entirely. In our engine AI and code take over the reading and the arithmetic, but a person still confirms the flagged rows and signs the result. On a large case that review takes under an hour, by my own experience rather than a timed measure, spent on a mix of possible duplicates, provider names and page classification.
Burak Tamac spent eight years as a senior paralegal at a New Jersey personal-injury firm preparing PIP arbitration files, and three of those years building the billing analyses behind medical billing expert reports. He now builds document-processing systems for law firms and expert practices at S2Reason. He holds a Ph.D. in political science and is an adjunct professor at Montclair State University. The engine described here is Desk.