The summary has to carry every dose and I have no way to prove one did not fall out
We generate a short summary of a patient's current medication for the pharmacist screen. It's built off the fax and the record together and it runs on write, about 9k a day. The requirement is that every active drug and its dose appears in it. Not paraphrased into a category, not rolled up as ongoing antihypertensives. The drug and the number. The failure that matters is omission. A wrong dose looks wrong. A pharmacist reading 500mg where the fax says 50 stops, because 500 is not a strength that drug comes in. A drug that is simply not there reads as a clean summary of a shorter list, and there's nothing on the screen to say otherwise. It has happened twice. Once in June and once about three weeks ago. Both times the drug that dropped was on a continuation page, so the source text had it after a page break and a repeated header, and both times the rest of the summary was correct. Nobody was hurt. The second one reached the screen and the pharmacist had the fax open next to it and noticed, and thats luck, not a control. Where I get stuck is the checking. The obvious thing is to diff the drug names in the summary against the list going in. Two problems with that. One, the dose gets paraphrased. Source says BD, summary says twice daily, or q12h, or every 12 hours. Exact match fails on all of those so I match loosely, and loosely then passes 5mg where the source says 15mg, because the string is in there. two, not every drug going in should come out. held, discontinued, PRN and the ones somebody has typed in twice are all legitimately dropped, and a check that fires on every legitimate drop fires eight times a day and by week two nobody's reading it. we've been there with a different alert. what I want under here is a prompt whose output can be checked for omission by a machine. i dont need it to be pretty. i need a caller to be able to say every active row is carried, or name the row that isnt. summaries paint with the screen so I have maybe 200ms, and the batch that rebuilds them overnight kicks at 01:00.
Not run against a model yet
0 works · 1 fails
Times copied by users
Problem Instructions
A medication summary a machine can check for omission. Every active drug and its dose is either in the summary or named as dropped, and the caller can say which one is missing without a person reading the fax alongside the screen.
- •Every active row is either carried into the summary or listed as dropped. Held, discontinued, PRN and the ones typed in twice are legitimate drops and get listed as such.
- •The dose survives paraphrase for checking. BD, twice daily and q12h compare equal, and 5mg does not match a source row reading 15mg.
- •the check is a comparison the caller runs, not a second model call. summaries paint with the screen.
Response contract
Reply with one JSON object and nothing else. No preamble, no code fence, no trailing note.
{
"medications": [
{ "n": 1, "drug": "Bisoprolol fumarate", "dose": "2.5mg", "frequency": "OD", "status": "ACTIVE" }
],
"summary": "...",
"carried": [
{ "row": 1, "verdict": "CARRIED", "carrier": "Bisoprolol fumarate 2.5mg once daily", "dose_in_summary": "2.5mg", "freq_in_summary": "once daily", "notation": "SAME" }
],
"dropped": [ { "row": 4, "reason": "HELD" } ],
"omitted_rows": []
}
medications
One record per distinct medication entry, in the order the entries first appear in the source. Read the whole source: below a page break, below a repeated header, inside a running paragraph, and inside a note attached to the record.
Two lines stating the same drug, the same dose and the same frequency are ONE record, wherever they sit and however often they repeat. Record it once, at the position of its first appearance. The same drug at a different dose is a separate record.
n: 1-based, assigned in that order, and referenced by "carried", "dropped" and "omitted_rows".
drug: the drug name exactly as the source writes it, not normalised to a generic, a brand or a class.
dose: the dose and unit exactly as the source writes it, or the literal NO_DOSE_STATED when the source states none. Never inferred, never rounded, never widened into a range.
frequency: the frequency exactly as the source writes it, or the literal NO_FREQUENCY_STATED. Not expanded here.
status: exactly one of ACTIVE, HELD, DISCONTINUED, PRN, UNCLEAR.
ACTIVE: the source presents it as currently taken on a schedule.
HELD: paused, suspended, or on hold.
DISCONTINUED: stopped, ceased, crossed through, or printed under a heading that says it was stopped.
PRN: as required, as needed, when necessary.
UNCLEAR: the source lists it and does not say which of the four above applies.
Allergies, reactions, diagnoses and anything the source does not present as a medication entry are not records.
summary
Plain prose for the pharmacist screen. No row numbers, no square brackets, no bullets, no headings, no markers of any kind inside it.
Every ACTIVE row appears in it with its drug name, its dose and its frequency. No ACTIVE row is left out for length.
No entry whose status is not ACTIVE is carried into it: not its dose, and not a statement that the patient takes it. Where the same drug name also sits on an ACTIVE row, the summary names that drug once, carrying the ACTIVE row's dose only.
Dose here is copied character for character from "dose", with one exception: a dose the source wrote in grams is written in milligrams here. Nothing else is converted, rounded or respaced.
Frequency here is written out in English using this table and no other. OD is once daily. BD is twice daily. TDS is three times daily. QDS is four times daily. ON is at night. MANE is in the morning. A frequency not in the table is copied as written.
A row whose dose is NO_DOSE_STATED appears with its drug name and its frequency and says in words that no dose is documented.
carried
Exactly one record per ACTIVE row, in the same order as "medications", and no record for any other row.
row: the "n" of the medication row this record judges.
verdict: CARRIED when "summary" names the drug and its dose. CARRIED_NO_DOSE when that row's dose is NO_DOSE_STATED and "summary" names the drug and says no dose is documented. NOT_CARRIED otherwise, which is you reporting a defect in your own summary.
carrier: a substring of "summary" copied out of it character for character, holding the drug name and, unless the verdict is CARRIED_NO_DOSE, the dose. Null when the verdict is NOT_CARRIED. Two records never quote the same span.
dose_in_summary: the dose exactly as it is written inside "carrier". Null when the verdict is CARRIED_NO_DOSE or NOT_CARRIED.
freq_in_summary: the frequency exactly as it is written inside "summary" for this row. Null when the row has no stated frequency.
notation: SAME when "dose_in_summary" is character-identical to "dose". CONVERTED when it is the same quantity in a different unit, which happens only under the grams to milligrams rule. NONE when there is no dose to compare. DIFFERENT when the two are not the same quantity, which is a defect in your own summary.
dropped
Exactly one record per row whose status is not ACTIVE, in the same order as "medications". row: that row's "n". reason: that row's status.
omitted_rows
The "n" of every ACTIVE row whose carried record is NOT_CARRIED, ascending, and an empty array when every ACTIVE row was carried. This is the one field the caller reads to decide whether a dose fell out.🏆 Best Current Solution
Xander 🚀 | prompt systems has the most upvoted solution, at 5.