Readback
Source code on GitHub (opens in a new tab)

Prescription intake that proves it did not mishear

High recognizer certainty does not protect against two medicines that sound alike.

The mechanism and the business case

A recognizer can be certain and wrong: for example, the caller says hydromorphone and it returns morphine at certainty 1.00. Readback asks which of the listed names was meant whenever a drug name falls in a look-alike pair published by ISMP, and a yes does not answer it, however confident the recognizer was. It writes nothing a validator or the caller has not proved.

  • Who pays: a pharmacy or telepharmacy service, per verified order. That is our hypothesis, not yet validated with buyers.
  • Who gets the order: the pharmacist, with every value's spoken words, timecodes and proof attached, before anything is dispensed.

The 14-second replay

One synthesised call runs through the shipped gate twice. Both columns read the drug name back; they differ by one flag, the pair rule, and only the column with the rule on needs a spoken name as the answer.

Ground truth for this replay

The caller said
hydromorphone
The recognizer heard
morphinecertainty 1.00

Both drugs exist, both pass a catalogue lookup, and both are opioid pain medicines dosed differently, which is why a swap between them is dangerous.

0.0/13.6 s

Session open on short-lived tokens, patient already named; the drug comes next

session clock 5.0s / 18.6s

Pair rule onshipped

Will ask which of the two names was meant, and wait for a name

Pair rule offcomparison only

Will read morphine back and take a yes

Pair rule on

The shipped policy. The drug name sits in a published pair, so the read-back names both drugs and only a spoken name answers it. A yes does not.

What the agent will say

morphine and hydromorphone are on a published confused-drug-names list. Which: morphine, M-O-R, or hydromorphone, H-Y-D? Answer with a name.

decided by the same gate function, reason code E_LASA_HIT

What the caller will answer

“Hydromorphone.”

read as E_CALLER_NAMED_LASA_PARTNER

What entered the order

Nothing until a name is said

The agent will ask which of the two drugs was meant, and wait for a name.

Pair rule off

The same policy with one flag changed: the pair check is off. The drug name is still read back, because the shipped policy reads back every drug name, and a yes confirms it.

What the agent will say

Confirming the drug name: morphine. Correct?

decided by the same gate function, reason code E_READ_BACK_REQUIRED

What the caller will answer

“Yes.”

read as C_CALLER_AFFIRMED

What entered the order

morphine 2 mg/mL injection, intravenous will enter after a yes

The agent will read the heard name back and accept a yes.

Playing without sound, because browsers only allow sound after a click. Press play to hear it.

Show how this was decidedThe field card: what proves the value, the recognizer’s certainty and the spoken words with their timecodes

The gate has not been asked anything yet

Every proposed value passes through one decision function before it can enter the order. Its verdict, and the reason code behind it, appears here as it happens.

Drug nameCriticalattempt 1

morphine

heard as "Morphine"

Not yet decided by the gateLook-alike paircatalogue

Recognizer heard

“Morphine”

0:06.80–0:07.62

Recorded as

morphine

What proves this value

Independently verified

ndc_catalog

product.txt lookup: proprietary_name or nonproprietary_name exact match

morphine sulfate is present in the built catalogue as a nonproprietary name

matchedColumn
nonproprietary_name
saltStripped
morphine sulfate

Proved by existence in the built NDC catalogue. There is no check digit here.

What the recognizer claims about itself

Recognizer said, of itself1.00 on its least certain word

field threshold 0.95 marked on the track

This name is on a published look-alike list, so this number will not decide it. The gate has not decided yet.

Proof decides first; the recognizer's own certainty comes second.

The spoken words this value came from

computed in the browser from the STT socket, so it is client-supplied

span 6800-7620 msturn 21 wordsmean 1.00

Transcript as shown to the operator: “Morphine two milligrams IV every four hours as needed.” (formatted turn)

What the pair rule catches, and what it costs

The replay is one call. Measured over 20 seeded pair mishearings, each answered by a reflex yes, the two columns end the same way every time.

Pair rule offwrong drug written
20/20
Pair rule onwrong drug written
0/20

npx tsx scripts/measure/ab-gate.ts n = 20, text candidates

Pair rule on, cost of its questionlonger than a plain read-back, per name it asks about
9.4 s
About 11.8 s against 2.5 s, at the desktop synthesiser's rate; the agent's own voice has not been timed. The coverage run put it to 21 of 59 correctly heard names.
npx tsx scripts/measure/coverage-matrix.ts n = 59 plain, 21 contrastive, synthesised speech

More of the demonstration

Sentences to try on a live call, a guided tour, one-button scenarios on the shipped gate, the keyterms A/B and recorded audio.

Say these three things

On the live call, these three sentences show the three ways a value is proved or stopped. The outcome and reason code beside each one come from the shipped gate function, run on this page.

SayWhat the gate doesWhy
“Lisinopril, ten milligrams, one tablet by mouth once daily, thirty tablets.”RE-ASKE_READ_BACK_REQUIREDEach value is read back once. Say yes and it is written; the order commits when every critical field is proved.
“Hydromorphone, two milligrams.”RE-ASKE_LASA_HITAsked again even if the recognizer is certain, naming every drug the published list pairs with it. Answer with the name; a yes does not confirm it.
“Prescriber NPI one two three four five six seven eight nine zero.”REFUSEDE_VALIDATOR_CHECKSUMRefused by arithmetic before anyone reads it back, then asked for digit by digit.
For judges: replay and evidence | Readback