Build with it · Intermediate
Knowing If It Works
Draft, open for academic review
The least glamorous skill in applied AI, and the one that decides whether your thing actually works.
Your progress here is recorded once you pass the Shipping It exam.
The film · 16 min
The least glamorous skill in applied AI, and the one that decides whether your thing actually works.
101 MB · captions in English · nothing downloads until you press play
Read the transcript
Shipped on a feeling
Most AI features are shipped on a feeling. Nobody finds out how often the thing fails until the customers do. A small team in Lagos built a WhatsApp assistant to pull delivery addresses out of messages. They tested it on twelve messages they wrote themselves, and all twelve came back right. In its first week it handled three thousand real messages and got one in five wrong, because customers write addresses like opposite the blue mosque, after the second speed bump. The model did not fail. There was no measurement. This course is the other path: a labelled set built by hand, a metric that matches the decision, an honest test of whether a difference is real, a judge you have measured, and a shipped system kept honest after the model changes under you.
1. What counts as evidence
A result has four parts
A result is a number, on a fixed set, next to a comparison, with enough version detail to reproduce it. Anything else is an anecdote. The set need not be large. A hundred real examples, labelled by hand, is an afternoon of work and settles most arguments. But be honest about what a hundred can see. The interval is about plus or minus ten points: enough to see a fifteen-point change, nowhere near enough for a three-point one. Halving that interval costs four times the items. And before you label anything, write down the decision the number has to serve and the failure you will not accept. Write them afterwards and every number looks like agreement.
Count the flips, not the totals
Here is the idea that rescues small sets. When you compare two prompts you run the same items through both, and that pairing carries information. Forget the totals and look at the four cells. Items both prompts passed tell you nothing about the difference, and items both failed tell you nothing either. Only the flips matter. Here the old prompt scored eighty-two and the new one eighty-eight. On the naive reading, six points sits inside a plus or minus eight interval and is noise. But only one item regressed and seven improved, and that lopsided split is a real result on a hundred items. This is why the harness must record every item, not just the score.
2. Metrics that mean something
Accuracy rewards doing nothing
Every yes-or-no classifier produces four outcomes, and every metric is arithmetic on those four cells. A content filter runs over a thousand posts, sixty of them harmful. It flags eighty: forty-eight genuinely harmful, thirty-two false alarms, and twelve harmful posts slip through. Precision is forty-eight out of eighty, sixty per cent. Recall is forty-eight out of sixty, eighty per cent. Accuracy is ninety-five point six, which sounds excellent. Now consider a filter that flags nothing at all. Its accuracy is ninety-four per cent, because fine posts are so common. A system that does nothing scores within two points of the working one. Whenever somebody quotes accuracy on a rare event, ask for the base rate.
The threshold is a price, not a parameter
The threshold is not a setting inside the model. It is a price you put on the two kinds of mistake. Suppose a false alarm costs a reviewer five minutes and a miss costs two hours of damage. At a threshold of point three you get a hundred and fifty-three false alarms and three misses per thousand posts, about eleven hundred minutes of cost. At point eight, four false alarms and twenty-six misses, over three thousand minutes. The low threshold wins by a wide margin. Change the ratio between those two costs and the winner moves, which is exactly the argument worth having with the people who own the product.
Four numbers for a retrieval system
A retrieval-augmented system does two separable things. It finds passages, then writes an answer from them. One answer-correctness figure fuses both, so a drop from seventy-one to sixty-two tells you nothing about where to look. Split it into four. Retrieval: was the supporting passage in the context, at the number of passages you really pass in. Groundedness: is every claim supported by those passages, checked one claim per call with a quote required. Relevance: did it answer the question asked. And abstention: on the twenty questions your corpus cannot answer, did it say so. That last set is the one almost nobody builds, and it is where the confident invented answers live.
3. Deciding whether a difference is real
Ask what chance alone would produce
Two systems, scored on the same two hundred items, and system B is five points ahead. Is that real. Instead of reaching for a named test, ask what pure chance would have produced. Take each item's difference and flip its sign at random, which is the same as swapping which system you called A. Compute the gap. Do that ten thousand times. The spread of those gaps is what chance alone produces, and for two hundred items it runs about two points either way. Count how many shuffles beat your observed five points. Here it is about one and a half per cent, and that share is the p-value. One loop, no table, no normality assumption.
Size the set before you run it
Ask the question in the other direction. Not what can two hundred items conclude, but what is the smallest difference I would act on, and how many items does seeing it require. For a system passing about eighty per cent of the time, a ten-point gap needs about two hundred and fifty-six items per group. Five points needs just over a thousand. Two and a half points needs four thousand. Halve the effect and the count quadruples. Pairing changes everything, because only the items where the two systems disagree carry the comparison. About sixty-eight of those flips settle a five-point question, which, if fifteen per cent of items flip, is about four hundred and fifty items instead of two thousand.
4. The systems you will actually be handed
Stages multiply
A document pipeline usually has three stages: classify the page, read the text and layout, extract the fields. Each looks respectable on its own: ninety-seven per cent, ninety-five, ninety-four. Multiply them and you get eighty-seven, so thirteen documents in a hundred go wrong, and the customer only ever meets that last number. Measure every stage, because that is where the fix lives, and always report the end-to-end figure beside them, because that is the promise. Documents also carry checks that need no labels. Line items should sum to the subtotal, and subtotal plus tax should equal the total. When the arithmetic fails, something was misread, and that check runs on live traffic for free.
Score the session, not the turn
Every task shape has one failure its evaluation exists to catch. For a summariser it is the fact that was left out, because no similarity metric can see an omission. For generated code it is running it in a sandbox against tests it has never seen. For a multi-turn assistant it is this. A customer asks in Hindi for a refund on order A eight eight nine one. At turn two the assistant looks up A eight eight one nine instead, and nobody notices. Turns three to eight are all correct about the wrong order. Per-turn scoring records eight failures. Session scoring records one, first wrong at turn two, and that distribution of first wrong turns is the most useful diagnostic there is.
5. Automating judgement
Free checks first
There are three tiers of checking, four orders of magnitude apart in cost. Deterministic code runs in microseconds, costs nothing, and gives the same answer every time. A model judge takes about a second and a fraction of a penny. A human takes minutes and real money, and is the only tier that can settle a genuinely new question. Run them from the bottom up and let each tier filter for the one above. Does the output parse. Is every required field present. Is every quoted span really a substring of the source. A judge asked about an output that is not valid JSON has spent a call to learn what one line of code knew for free.
The judge needs judging
A model can read four thousand outputs a week for a few dollars, and you will end up using one. It fails in ways that produce plausible numbers rather than errors. Position bias: in pairwise comparisons the judge favours one slot, so run every pair both ways. Length bias: longer, more structured answers score higher regardless of content. Self-preference: a model rates its own family more kindly, so judge with a different provider. Scale compression: ask for a mark out of ten and you get sevens forever. Then the step almost everyone skips. Run the judge on fifty items two people labelled by hand. If it agrees ninety-two per cent of the time, use it. At seventy-one, it is an opinion with a decimal point.
Three times in five has not passed
When the output is a sequence of actions, score the final state and record the trajectory for diagnosis. Then run every task several times, because agents branch and one run tells you almost nothing. Here are forty tasks, each run five times. The mean pass rate is about seventy-seven per cent, which is the number in the announcement. Twenty-two tasks passed every time, and that is the number a business can rely on. Eleven passed three or four times out of five. Those have not passed, and reporting them as if they had is how agent demos become production incidents. Count cost and steps as part of the result, because hitting the step limit looks identical to ordinary failure.
6. Evaluation in the working loop
Eighty-four to eighty-four, and fourteen verdicts moved
A prompt is code with no type system. Every edit is a refactor with unknown blast radius, so run the tests on every change. But the report that matters is not the score. This run printed eighty-four per cent, the previous run printed eighty-four, and a team moves on. Look at the cells. Seven items newly pass, seven newly fail, and the total holds perfectly still. By tag, landmark-only addresses fell from sixty-one per cent to forty-four while street addresses rose from ninety-two to ninety-nine. That is a trade, and the aggregate hid it. Print the flips, and commit the actual outputs for a handful of items, so a prompt change shows up as a diff a reviewer catches in one second.
Read fifty failures
When the number is disappointing, read fifty failures, and write the cause in your own words before you categorise anything. Then label each cause as data, retrieval, prompt, model, label or product. A team extracting receipts had spent a fortnight comparing three prompt variants. When they read their failures, twenty-two of fifty were multi-page receipts where only the first page had been uploaded, a client bug. Eleven were dates read month first when written day first, a prompt fix. Eight were genuinely illegible photographs. Only five of the fifty were the model's. Most failures are not prompt problems, and the only way to learn that is to read them.
7. Evidence other people can act on
When the model is right and the product still fails
A support assistant measures ninety per cent correct on a careful set. In production, forty-one per cent of the people who start a question end up with their problem solved. Nothing is wrong with the measurement. Six per cent abandoned before a response arrived. Of the rest, eighty-five per cent got a correct answer. But only fifty-eight per cent acted on it, and the largest drop in the funnel is right there, between correct and acted on. That is a writing and interface problem: the answer was three hundred words, or had no next step, or showed no source, and no prompt work would have found it. Measure the funnel from attempt to resolved outcome, and watch five people use the thing.
Error rate and harm are different quantities
Two systems. One has a twenty per cent error rate, but the error is obvious, the user notices at once, and it is undone with a repeated request. The other has a point one per cent error rate, but the error is invisible, the user cannot verify it, acting on it is irreversible, and it lands on the people least able to appeal. Averaging over items treats these the same. So rank failures by severity, reversibility and whether the person can tell they were harmed, and write test cases for each. The same discipline applies when you buy a model: decide on your own three hundred items and on cost per successful task, because a cheaper model that needs two attempts costs more per task that came out right.
8. Living with it
The tail is what your users feel
Latency for a generative system is right-skewed by construction, because time scales with output length and output length has a long tail. So report p50, p95 and p99, never the mean, which describes nobody. And users make more than one call. If a session involves ten calls, the chance of meeting at least one call slower than the ninety-fifth percentile is forty per cent. A thirty-step agent meets one seventy-nine per cent of the time. That is why an improvement to p99 can matter more than one to p50. Print quality, latency and cost in the same row on every run, and pin the model to a dated id, so a forced upgrade is an afternoon with a frozen set rather than a crisis.
One average, three systems
A system at eighty-six per cent is not eighty-six per cent for everybody. Here it is ninety-one for English, which is most of the traffic, eighty-four for Hindi, and sixty-eight for Bengali. That is not one system with a quality problem. It is three systems, one of which was never evaluated. A per-slice floor of eighty fails this release while the average passes it, and a floor cannot be met by improving the group already doing well. Slice by language, region, device and channel, which you already record. When a system decides about people, the fairness definitions conflict mathematically, so choose one, state it, and report the others.
A small permanent tax
Evaluation is not a phase you complete. It is a small permanent tax: an hour a week keeping the set current, a job in CI, a chart somebody glances at, and one page written whenever a result travels without you, carrying the set, the interval, the slices, the cost, what was not measured, and the decision it supports. Every incident becomes a minimised test item with its origin recorded. Teams that pay the tax ship confidently and recover from surprises in an afternoon. Teams that do not spend the same hours finding out from customers. Match the effort to the consequences of failure, and ask again which tier you are in every time a prototype goes in front of customers.
8 modules. 76 lessons.
What counts as evidence
10 lessons · 1 h 25
You will be able toTurn a vague claim that a feature works into a fixed, labelled, held-out set with a stated agreement figure and a named baseline, and say what size of difference a set that size can and cannot detect.
- 1.1A demo is not a measurement
- 1.2The decision the number has to serve
- 1.3A hundred examples, made by hand
- 1.4Where the examples come from
- 1.5Writing a labelling guide two people can agree on
- 1.6How much your labellers actually agree
- 1.7Test cases you generate, and what they cannot tell you
- 1.8Two sets, and the ways they get contaminated
- 1.9The number above it and the number below it
- 1.10How wrong your number probably is
An illustrative case, built from documented patternsFifteen questions and a batch starting Monday
Vidyarthi Classes has 1,400 students across three batches and a doubt-solving problem that every coaching centre has: between nine at night and seven in the morning, nobody answers. The founder, Rakesh, had been paying two junior teachers to sit on the WhatsApp doubt groups until midnight, and they were leaving.
Over the summer a former student, now in his second year at an engineering college, built a doubt-solver on top of a hosted language model. You send a photo or a typed question, it replies with a worked solution. Rakesh tried it himself. He typed fifteen questions from the printed module on kinematics and rotational motion, read the answers, and all fifteen were right. Two were better explained than the printed solutions. He wanted it in every group by Monday, when the new batch started, because a competitor two streets away had started advertising “24x7 AI doubt support”.
The head of physics, Mrs Iyer, had been teaching for twenty-two years and did not trust it. Not on principle: she had read three of the fifteen answers and thought they were fine. Her objection was that she had no idea what the other few thousand answers would look like. “The questions you typed are from our own module. Our students do not send those. They send a blurry photo of a question from a random book, with half the diagram cut off, and they write ‘sir why not option C’.”
Rakesh’s position was that fifteen for fifteen was evidence, and that the cost of waiting was real. Every night the tool was not live was a night the competitor’s advertisement was true and his was not. He estimated that three days of building a proper test would cost him the launch date, and that a fortnight of “it works, we tried it” was worth more than a number.
Mrs Iyer’s position was that fifteen for fifteen told them almost nothing. If the true failure rate were one in four, fifteen clean passes would still happen often enough that nobody should be surprised. She also pointed out that Rakesh was the worst possible reader of the outputs, because he knew what the answer should be and filled in the gaps as he read. And she had a specific fear: a solver that confidently gives a wrong numerical answer to a student at 1 a.m., who then goes into the test believing it.
The two of them agreed on one thing, which was that the argument was going in circles. So they wrote down what a decision would actually require.
The decision was not “launch or not”. It was whether the tool answered students directly in the groups, or whether it drafted an answer that a junior teacher approved in the morning. Mrs Iyer wanted a threshold: on a hundred real doubts from last year’s groups, the tool had to give a correct final answer on at least 85, and for numericals the answer had to be correct to the printed solution. The unacceptable failure was a confident wrong numerical answer: she wanted that scored separately, and she wanted a single occurrence in a hundred to fail the run.
Building the set was the cost. The doubt groups from last year were still on two teachers’ phones. Pulling a hundred real doubts, stratified so that photographed questions, typed questions, conceptual doubts and numericals were all represented, would take a day. Labelling them took two teachers, and the labels had to agree with each other, which meant a labelling guide and a check that the two teachers actually applied it the same way. Three days, two senior teachers, at the busiest time of the year.
Rakesh’s counter-offer was to launch in one batch on Monday and “watch it closely”. Mrs Iyer’s counter-offer was that watching it closely was what he had just done with fifteen questions.
What would you have decided, and what would you have measured first?
How it played out
They built the set. It took two and a half days, not three. A hundred and twenty real doubts came off last year’s phones: 55 typed conceptual questions, 40 photographed numericals, 15 that were really a student asking why their own working was wrong, and 10 that were off-topic or abusive and should have been declined.
Before labelling the rest, the two teachers independently labelled the same twenty. They disagreed on seven. Not one of the seven was about physics. They were about what counted as “correct”: one teacher accepted an answer with the right number and a wrong intermediate step, the other did not. They wrote the ruling down (the final answer and the method both have to be right for a numerical; for a conceptual doubt, the answer has to address the misconception the student actually has). On the next twenty they disagreed on two.
The result: 71% overall. On typed conceptual questions, 89%. On photographed numericals, 38%, mostly because the photographs were poor and the model solved a slightly different question from the one in the picture. Two answers out of 120 were confident wrong numericals with no hedge at all. That failed Mrs Iyer’s gate on its own.
They did not launch it in the groups. They launched the drafting version: the tool answered typed conceptual doubts directly, tagged as AI-generated, and everything containing a photograph or a number went to the morning queue with the draft attached. The junior teachers’ evening shift went from four hours to about ninety minutes. Rakesh kept the 120 items as a frozen set and the failed photographs went into a separate folder that became the first thing they tested when the model was upgraded three months later.
Worth arguing about
Rakesh had fifteen correct answers out of fifteen. Why did that not settle whether the tool was ready?
One answer
Fifteen passes puts only a loose upper bound on the failure rate: a system failing a quarter of the time would still produce fifteen clean passes fairly often. The sample was also not representative, since the questions came from the centre’s own printed module rather than from what students actually send, and the reader was the person least able to spot a plausible wrong answer. A result needs a number on a fixed, representative set, next to a comparison.
The two teachers disagreed on seven of the first twenty labels, and none of the disagreements were about physics. What does that tell you, and what should happen next?
One answer
It tells you the criterion was not yet defined, not that the teachers were careless. Disagreement clustered on what counted as correct, so the fix was a written ruling in the labelling guide and a fresh twenty to check agreement had improved. Until two people can label the same items the same way, no model can be scored against the label and no judge could later automate it.
The overall pass rate was 71%, below the 85% threshold, yet the centre shipped something. Was that a violation of the pre-registered decision?
One answer
No. The decision written in advance was between answering students directly and drafting for teacher approval; the threshold governed the first option. The per-slice results showed conceptual doubts passed comfortably while photographed numericals did not, and the two confident wrong numericals failed the separately scored gate. Shipping the drafting mode, with direct answers only on the slice that cleared, is exactly what the three-line decision file was written to permit.
Test yourself6 questions on this module
A team writes twelve test messages, runs them through a new address extractor, and all twelve come back right. What does that result allow them to conclude?
The course insists that the ship-or-hold threshold be written down before any result is seen. What is the mechanism it is guarding against?
Refund requests are 1% of traffic but, after stratified sampling, 12% of the evaluation set. How should a headline pass rate be quoted?
Two labellers agree on 95 of 100 posts, but only 2% of posts are harmful, and Cohen’s kappa comes out near zero. What is the right reading?
A team generates 500 Devanagari test inputs from templates and the system passes 96% of them. Which claim does that result support?
After twenty rounds of prompt tuning, the development set scores 91% and the rarely-run test set scores 76%. What is the most likely explanation?
Metrics that mean something
10 lessons · 1 h 29
You will be able toChoose a metric that matches the decision at hand, set a threshold from a real confusion matrix or a precision-recall curve, say whether a model’s 0.8 means anything about probability, and separate a retrieval failure from a generation failure in a system that does both.
- 2.1What to measure when the output is prose
- 2.2Precision and recall, worked on real numbers
- 2.3When an item has several right answers
- 2.4What a curve says, and what its one number leaves out
- 2.5Moving the threshold is a business decision
- 2.6Making a 0.8 mean eighty per cent
- 2.7When the output is a quantity
- 2.8Scoring a ranked list
- 2.9Three questions, not one, for a retrieval system
- 2.10Public benchmarks, and what they are for
An illustrative case, built from documented patternsThe nurse who can read 250 messages a day
The hospital’s outpatient department had started taking symptom messages on WhatsApp during the pandemic and never stopped. By 2026 it received about 2,000 messages a week: a photo of a rash, “my father has had fever for three days”, a question about a prescription, a request to change an appointment. One nurse, Sunita, triaged them between her other duties and could realistically read about 250 in a working day.
A vendor offered a classifier. Each message got a score between 0 and 1 for “needs same-day clinical attention”, and the vendor’s deck said the model had an AUC of 0.91 on their evaluation set and an accuracy of 95%. The medical superintendent, Dr Pawar, was interested, and the hospital’s one IT person, Prakash, was asked to make it work.
Prakash did the thing this course spends a module on. He took 500 messages from the previous two months, had Sunita and a junior doctor label each one as urgent or not, and found that 6% were genuinely urgent. Then he ran the vendor’s model over them and swept the threshold.
At the default of 0.5, the model flagged 90 of the 500. Of those, 21 were really urgent, so precision was 23%. It missed 9 of the 30 urgent messages, so recall was 70%. Scaled up to a week’s traffic of 2,000, that is 360 flagged messages, which Sunita could read, and roughly 36 urgent messages missed every week.
At 0.3, the model flagged 150 of the 500 and caught 28 of the 30 urgent ones. Recall 93%. But 150 of 500 is 30% of traffic, which is 600 flagged messages a week for a nurse who can read 250. The queue would be two and a half days behind by Wednesday, and an urgent message at the back of a queue is a missed message with extra steps.
At 0.8, the model flagged 24 and caught 16. Precision 67%, recall 53%. Almost half the urgent messages would go unflagged.
The vendor’s accuracy figure was true and useless. A model that flagged nothing would score 94% accuracy on this data, because 94% of messages are not urgent.
Dr Pawar wanted the highest recall available. A missed urgent message was, in his words, the only failure that could end up in a newspaper. Sunita pointed out that the highest recall available would bury her, and that a flag she could not get to was worth nothing. Prakash had a third concern that neither of them had raised: the model’s scores did not mean what they said. When he bucketed the 500 messages by score, the ones scored between 0.8 and 0.9 were urgent about half the time, not 85% of the time. The vendor’s threshold advice, which assumed the score was a probability, was built on sand.
The decision had two parts. Where to put the line, given that every position traded a missed patient against a queue the nurse could not clear. And whether to trust a single line at all.
There was a budget question underneath it. The hospital could not hire a second nurse for this. It could, possibly, get a junior doctor to spend forty-five minutes a day on the queue. Forty-five minutes was perhaps another 80 messages.
How would you set the threshold, and what would you tell Dr Pawar about the 95% accuracy in the vendor’s deck?
How it played out
They did not choose a line. They chose a band. Messages scoring above 0.85 triggered an automatic call-back from the desk, without waiting for Sunita. Messages below 0.15 got an automatic reply with the appointment link and the emergency number, and were still visible in a low-priority list. Everything in between went to Sunita’s queue.
Prakash tuned the band edges on the 500 labelled messages until the middle came to about 220 messages a week at last month’s volume, which was under Sunita’s capacity with room for a bad week. At those settings the combined system caught 27 of the 30 urgent messages in the labelled set: 24 through the middle band and 3 through the automatic call-back. Two of the three misses were messages that did not look urgent to either human labeller until the second reading, which is an argument for a better labelling guide rather than a better model.
He calibrated the scores before setting the band, with a logistic fit on the 500 labels, so that the 0.85 edge meant something close to what it said. And he wrote the cost ratio down: a false alarm cost about two minutes of Sunita’s time; a miss they valued at four hours. The number was made up, but making it up in a document meant that when Dr Pawar later wanted to widen the band, the argument was about the ratio and not about feelings.
The 95% accuracy figure went into a one-page note to the superintendent with the base rate written next to it, and the phrase “a model that flags nothing scores 94% on our data” underlined. The vendor’s model stayed. The vendor’s threshold advice did not.
Worth arguing about
The vendor reported 95% accuracy. Why was Prakash right to treat that as almost no information?
One answer
Only 6% of messages were urgent, so a model that flagged nothing would score 94% accuracy on the hospital’s own data. Under class imbalance accuracy mostly measures the ability to say no. The numbers that describe the decision are precision and recall at a specific threshold, read together with the base rate.
Recall of 93% at a threshold of 0.3 sounds like the safest choice for patients. Why was it not?
One answer
At 0.3 the model flagged 30% of traffic, about 600 messages a week for a nurse who could read 250. A flag nobody reaches is a miss with a delay attached. The real constraint was the review queue’s capacity, so the honest metric was urgent messages caught per nurse-hour, and a band with automatic handling at both ends spent Sunita’s attention where the model was genuinely unsure.
Prakash calibrated the scores before setting the band. What would have gone wrong if he had skipped that step?
One answer
The band edges were chosen as if 0.85 meant an 85% chance of urgency, but the raw scores in that bucket were urgent only about half the time. Uncalibrated scores make any threshold reasoning built on expected cost wrong, even though calibration changes no rankings. A one-parameter logistic fit on a few hundred labelled points made the band edges mean what the team thought they meant.
Test yourself6 questions on this module
A content filter flags 80 of 1,000 posts. Of the flagged posts, 48 are truly harmful, and 60 posts in total are harmful. What are precision and recall?
On that same set, a filter that flags nothing at all scores 94% accuracy. Why does accuracy reward doing nothing?
A moderation queue can absorb about 200 items a day. Which threshold design does the course recommend?
A classifier has ROC-AUC 0.86 and an expected calibration error of 0.15. After Platt scaling on a held-out slice, what changes?
Why does the course prefer WAPE over MAPE for scoring a demand forecast?
A retrieval-augmented assistant answers 62% of questions correctly. On the same questions, recall@5 is 0.55. Where does the course say to look first?
Deciding whether a difference is real
9 lessons · 1 h 19
You will be able toDecide whether an observed difference between two systems is larger than the noise in your set, compute an interval for any metric you can calculate using the bootstrap, and state in advance how many items the comparison needs to detect the effect you would act on.
- 3.1Asking what pure chance would have produced
- 3.2What a p-value is, and the four things it is not
- 3.3Sizing the set before you run it
- 3.4The bootstrap, and the three places it lies
- 3.5Five hundred rows, forty users
- 3.6Twenty slices and one guaranteed surprise
- 3.7Watching the dashboard until it says yes
- 3.8Getting more signal from the items you already have
- 3.9Better in every group and worse overall
An illustrative case, built from documented patternsEighty-seven beats eighty-two, or does it
Kavitha runs an export business with her brother that makes knitted childrenswear for four buyers in Germany and the Netherlands. The buyers write long emails in English and occasionally German: order changes, delivery dates, fabric specifications, complaints. The production supervisor reads Tamil. For years Kavitha translated by hand, in the evenings.
Her brother Arun, who handles the accounts and is the closer thing to a technical person, built a prompt that turned each email into a Tamil summary with a fixed structure: what changed, the new deadline, the quantities, anything the supervisor must act on today. It worked well enough that Kavitha stopped translating. Then a shipment went out with the old collar specification, because the summary had dropped one sentence from a German email, and the buyer deducted 4% from the invoice.
Arun rewrote the prompt. He also, at Kavitha’s insistence, built a test set: a hundred real emails from the last two years, each with a hand-written Tamil summary and a short list of facts that had to be present. He ran the old prompt and the new prompt over all hundred. Old prompt, 82 correct. New prompt, 87.
Arun wanted to switch. Five points was five points, and the new prompt had been written specifically to stop the collar problem. Kavitha, who had spent an afternoon reading the module on error bars that her nephew had sent her, said that on a hundred items five points was inside the noise and asked him to prove it.
The argument had a shape worth pausing on. Arun’s cost of not switching was real: every week the old prompt ran was a week with the known failure in it. Kavitha’s cost of switching was also real: the summaries were now the only thing the supervisor read, and if the new prompt had regressed on something else, deadlines for instance, nobody would notice until a container was late.
Arun’s first move was one the course warns about. He re-ran the new prompt twice more, at the default temperature, and got 85 and 89. He proposed averaging the best two. Kavitha said that was the same as running until it looked good. She was right, and he knew it.
So he did the paired thing. Instead of comparing 82 against 87 he listed which items had changed verdict. Both prompts got 79 items right and 10 items wrong. On the remaining 11, the old prompt was right and the new one wrong on 3, and the old prompt was wrong and the new one right on 8. The difference in the totals was 5, which is 8 minus 3.
The rule of thumb from the course says the difference is worth believing when the absolute gap between the two flip counts exceeds twice the square root of their sum. Twice the square root of eleven is about 6.6. The gap was 5. Not conclusive. Close, but not conclusive, and a hundred items was what they had.
Arun’s suggestion was to add fifty more emails and re-run. Kavitha’s suggestion was to first look at the three items the new prompt had broken.
All three were deadline items. In each, the German email gave a date in the form 14.03., and the new prompt, which now insisted on quoting the changed specification verbatim, had summarised the specification beautifully and rendered the date as 3 April. The eight improvements were all specification items, which is what the rewrite had been for.
So the honest summary was not “the new prompt is five points better”. It was “the new prompt fixes specifications and breaks German dates, and on this set we cannot tell whether the net effect is positive”.
What should they ship, and how many more emails, if any, should they label?
How it played out
They shipped neither prompt as it stood. Arun added two lines to the new prompt naming the German date convention, and added a deterministic check to the harness: any date in a summary had to be a date that also appeared in the email after normalisation, or the item failed regardless of the rest. That check found one more item in the old prompt’s results that nobody had noticed.
With the date fix, the new prompt scored 90 on the same hundred items. The paired count was now 1 regression against 9 improvements, a gap of 8 against a threshold of about 6.3, which was a result. Arun ran the set three times at temperature zero to see the run-to-run spread, which was two points, and wrote all of it in the shared spreadsheet: the score, the flip counts, the spread, and the one regression by name.
Kavitha still asked for the fifty extra emails, but for a different reason. The hundred contained only nine German emails, and the three regressions had all been in that slice. She wanted to know how the prompt behaved on German dates specifically, and nine items could not tell her. They labelled thirty more German emails over two evenings. The new prompt got 27 of 30. That number, on that slice, was the one that made her comfortable.
The frozen hundred stayed frozen. The thirty German emails became a second, named set. And the deterministic date check ran on every summary in production from then on, which is how they caught the next problem, four months later, before the supervisor did.
Worth arguing about
Arun re-ran the new prompt until he had three scores and proposed averaging the best two. What is wrong with that, and what should he have done with the three runs?
One answer
Choosing the best runs after seeing them is optional stopping in miniature: it converts a controlled error rate into an uncontrolled one and biases the reported effect upwards. The three runs were still useful, as a measure of run-to-run spread. Reporting the mean and the spread across all runs, and noting that a gap smaller than the spread cannot be detected however many items are added, is the honest use of them.
The totals differed by five points, yet the paired analysis said the result was not conclusive. Why does counting flips give a different answer from comparing totals?
One answer
Items both prompts got right or both got wrong carry no information about the difference between them. Only the discordant items do, and here there were eleven, split eight to three. Twice the square root of eleven is about 6.6, and the gap of five falls short. Pairing is more sensitive than comparing two totals, but it still needs enough discordant items, and a hundred items produced only eleven.
Kavitha asked for thirty more German emails rather than fifty more of everything. What made that the better use of two evenings of labelling?
One answer
All three regressions were in a slice of nine items, which could not resolve anything about German dates. Fifty random emails would have added perhaps four or five German ones. Spending the labelling budget on the slice where the question actually lived, and keeping it as a separately named set rather than mixing it into the frozen hundred, answered the specific question without breaking comparability of the original set.
Test yourself6 questions on this module
An evaluation set’s items come from 40 customers, about twelve rows each. In a permutation test comparing two systems on it, what should be shuffled?
A team tries 100 prompt changes in a quarter. About 10 genuinely help. Tests run at the 5% level with roughly 50% power. About what share of the quarter’s significant wins are noise?
Detecting a five-point gap between two systems passing around 80% needs roughly 1,000 items per group. Detecting a 2.5-point gap needs about how many?
Why is a bootstrap interval for p99 latency computed from 200 requests misleading?
A fortnight-long online experiment is checked every morning and stopped the first day p drops below 0.05. Even when the effect is real, what happens to the reported effect size?
A new model scores higher than the old one in Hindi (72 against 68) and in English (91 against 89), yet lower overall (75.8 against 78.5). Why?
The systems you will actually be handed
10 lessons · 1 h 32
You will be able toDesign a defensible evaluation for a summariser, a translator, a code generator, a structured extractor, a multi-turn assistant, a ranking system, a vision or speech model, a document pipeline or a tabular model, and name the specific failure mode each design exists to catch.
- 4.1Summaries: what was invented, and what was left out
- 4.2Translation, and the languages nobody measures
- 4.3Code: run it, in a box, against tests it has not seen
- 4.4Structured extraction, where normalisation is most of the work
- 4.5Multi-turn: score the session, not the turn
- 4.6Ranking systems, where the labels are clicks and the clicks are biased
- 4.7Images: the background the model is actually reading
- 4.8Speech: word error rate, and the words that matter
- 4.9Documents: stages that multiply, and checks that need no labels
- 4.10Tables, cross-validation, and the leak that gives you 0.99
An illustrative case, built from documented patternsNinety-eight per cent of the fields, sixty-one per cent of the forms
The Thrissur District Co-operative Bank processes about 9,000 small loan applications in the eight weeks before Onam: gold loans, two-wheeler loans, festival advances. Each application is a bundle of paper: the form itself, an identity document, an address proof, and for salaried applicants a salary slip. Clerks in 34 branches type the fields into the core banking system by hand, and the backlog in the last fortnight of the season is the single biggest complaint the bank receives.
A vendor demonstrated a document pipeline: photograph the bundle, and the system classifies each page, reads it, and fills the form fields automatically. The demonstration was on the vendor’s own sample of forty documents and reported 98% field accuracy. The general manager wanted it in the branches by the first week of August. The head of operations, Mr Menon, had one question, which was how many applications would come through with every field right, because a form with one wrong field still has to be handled by a person, and if the person has to check every field to find the wrong one, the pipeline has saved nothing.
The vendor did not have that number. Neither did anybody else.
The bank’s IT officer, Deepa, was given the job of finding out, with a constraint: three weeks before the season, and every week of measurement was a week less of rollout. The vendor offered their sample set, already labelled, and the argument for using it was speed. Deepa’s argument against was that the vendor’s forty documents were flat scans of clean forms. The bank’s intake was a branch clerk’s phone camera, at an angle, under a tube light, with a rubber stamp over the date and, in the gold-loan forms, a thumbprint where a signature should be.
The decision in front of Mr Menon was whether to accept the vendor’s measurement and roll out with a clerk checking a sample, or to spend a week building a set from real intake and measuring the things the vendor had not.
Deepa’s proposal was specific. Take 150 application bundles from last season, photographed the way clerks actually photograph them, from six branches including two rural ones. Label the fields by hand, which she estimated at two clerks for three days. Then measure three separate numbers, not one: whether the output was valid at all, the accuracy of each field, and the proportion of whole applications with every required field correct. And measure each stage of the pipeline separately, because the vendor’s system did three things in sequence, page classification, text extraction, and field extraction, and a wrong page classification made every downstream number meaningless for that bundle.
She also wanted to know how many distinct salary-slip layouts the 150 bundles contained, because if most of them came from three large employers the score would describe three templates and not the world.
The cost of Deepa’s week was a week. The cost of skipping it was that the bank would learn the whole-record number in the second week of the season, from the clerks, in the branches with the longest queues.
What would you have measured, and what would you have done if the whole-record number came back well below the field number?
How it played out
Mr Menon gave her the week. The results on 150 real bundles: schema-valid output on 97% of bundles; page classification correct on 96%; per-field accuracy, after normalising dates and amounts, 93% on average, with the applicant’s name at 98% and the employer’s address at 81%. Whole-record accuracy, every required field correct, was 61%.
The salary slips came from 19 distinct layouts, of which three, all large employers in Kochi, accounted for 70% of the slips. On those three templates the field accuracy was 97%. On the other sixteen it was 84%.
The number that changed the rollout was not the model’s. Thirty-one of the 150 bundles had at least one page that was simply unreadable: motion blur, or the bottom third of the form cut off by the frame. Nothing downstream could fix that. Deepa’s recommendation was a capture screen in the branch app that detected blur and edge cut-off and asked the clerk to retake, before any of the vendor’s pipeline ran. It took the vendor four days to add and it raised the whole-record figure to 74% on a re-photographed subset, more than any change to the extraction model.
The bank rolled out with a review queue: bundles where any field’s confidence fell below a threshold went to a clerk, with the extracted value shown beside a crop of the source region, so that checking took seconds rather than a re-read. And Deepa added the checks that needed no labels at all: the loan amount on the form had to match the amount on the sanction sheet, the date of birth had to make the applicant at least eighteen, and identity numbers had to pass their checksum. Those ran on every bundle in production, and their failure rate became the number on the operations dashboard for the season.
Worth arguing about
The vendor reported 98% field accuracy and the bank measured 61% whole-record accuracy on real intake. Both were true. How do the two numbers relate, and which one governs the product?
One answer
Whole-record accuracy is roughly the product of per-field accuracies across the required fields, so twelve fields at 97% each give around 69% of records entirely correct. The bank’s fields were also less accurate on phone photographs than on clean scans. The whole-record figure governs the product wherever a person does not review every form, because a record with one wrong field still needs a person, and finding the wrong field costs nearly as much as typing the form.
Why did Deepa insist on counting distinct salary-slip layouts, and what did the answer change?
One answer
Document sets are dominated by a few templates, so a score on 150 slips where three employers supply 70% of them is mostly a score on three layouts. Grouping by template showed 97% on the common three and 84% on the other sixteen, which is the number that predicts how a new employer’s slip will fare. Nineteen layouts gave nineteen independent observations of layout handling, not 150.
The largest improvement came from a blur check on the capture screen rather than from the extraction model. What general lesson about document pipelines does that illustrate?
One answer
A pipeline’s accuracy is the product of its stages, and the first stage was the photograph. Thirty-one of 150 bundles were unreadable before any model ran, and no downstream change could recover them. Measuring each stage separately located the loss where it lived; building the set from real intake rather than clean scans is what made the loss visible at all.
Test yourself6 questions on this module
A summariser’s claim support rate is 96%, but about half of its summaries contain at least one unsupported claim. Which figure should lead the report?
A coding tool shows a developer exactly one suggestion, to accept or reject. Which number describes it?
In structured extraction, which failure has a free detector that runs on live traffic with no gold label at all?
An assistant misunderstands at turn two of a ten-turn session and every later reply is built on the misunderstanding. What does the course say to record?
Forty photographs of the same object, taken in one session, are split at random between training and test, and the classifier reports 96%. What is the likely problem?
A churn model reports an AUC of 0.99 in cross-validation. What does the course say to do first?
Automating judgement
10 lessons · 1 h 31
You will be able toBuild a layered automatic check with cheap deterministic assertions underneath a rubric-driven model judge, state the agreement figure that licenses trusting the judge’s numbers, and control the position bias, self-preference and cost that judging brings with it.
- 5.1LLM-as-judge, and where it misleads you
- 5.2Turning a quality you can feel into rules a machine can apply
- 5.3Gold answers, and asking whether two answers agree
- 5.4Proving the judge agrees with you, and re-proving it
- 5.5Turning pairwise wins into a ranking you can defend
- 5.6The checks that cost nothing and catch most of it
- 5.7Checking an answer against the passages it was given
- 5.8What judging costs, and how to pay a tenth of it
- 5.9Testing what happens when somebody tries
- 5.10When the output is a sequence of actions
An illustrative case, built from documented patternsThe judge that gave everything an eight
Padhai Labs sells an essay-practice product to CBSE schools. A student writes an essay on the app, and an AI tutor returns feedback: what worked, three things to improve, and a corrected paragraph. Teachers liked it, sales were growing, and the product team wanted to ship changes to the feedback prompt every fortnight.
Reading the feedback by hand did not scale. Two thousand essays a week came through, and the product lead, Nikhil, wanted a number he could watch. So the team built a judge: a second model prompt that read the essay and the feedback and returned a score out of ten for “feedback quality”, with a sentence of reasoning. The average across a week was 8.4. Nikhil put it on the dashboard.
A new feedback prompt was written that produced longer, more structured feedback with headings and a summary line. On the judge, it scored 8.9 against the old prompt’s 8.4. Nikhil wanted to ship it on Monday.
The evaluation engineer, Meera, said the judge had never been checked against a human and that until it had, 8.9 versus 8.4 was one model’s opinion of another model’s prose. She asked for a week to calibrate it: sixty essays with feedback, labelled independently by two English teachers on the staff, and the judge’s verdicts compared against theirs.
Nikhil’s objection was cost and time. Two teachers for five hours each was a real expense, the teachers had classes, and a week’s delay on a prompt that scored half a point higher looked like process for its own sake. “If the judge says it’s better and it reads better, what are we waiting for?”
Meera’s answer was that it read longer, and she did not know whether it read better, and neither did he. She also had a specific worry. The judge scored on a 1-to-10 scale, and she had noticed that almost every score was a 7, 8 or 9. A scale where everything lands in the same three numbers carries almost no information, and a model asked to compare two pieces of feedback tends to prefer the longer, more structured one whatever its content.
The decision was whether to ship the new prompt on the judge’s say-so, or to spend the teachers’ ten hours first.
Meera also pointed out that the judge and the feedback generator were the same model family, and that models tend to prefer their own family’s prose. That was one more reason to doubt the half point, and one more thing a calibration set would settle.
There was a second question underneath, which Meera raised and Nikhil initially waved away: what the score was for. Nobody could say what a move from 8.4 to 8.9 meant in terms of a student’s writing. What the teachers actually cared about, when asked, was three specific things. Did the feedback misstate what the student had written? Did it correct a sentence that was already correct? Did the three suggestions address the essay’s actual weaknesses rather than generic advice? Each of those is a yes-or-no question about an observable thing, and none of them is a 1-to-10.
What would you have done with the judge, and would you have shipped the new prompt on Monday?
How it played out
The teachers got their ten hours. Sixty essays, labelled blind by both, with a written ruling for each of the nine disagreements. Meera then ran the existing 1-to-10 judge over the same sixty and compared.
Overall agreement, counting a judge score of 7 or above as “acceptable”, was 86%. That looked fine and told her nothing. Of the twelve items the teachers had marked as containing a factual misstatement about the student’s essay, the judge had scored nine of them 8 or above. Its recall on the failure the teachers cared most about was 25%.
She rebuilt the judge as three binary rules, one per call, each requiring a quoted span before the verdict: does the feedback state something about the essay that the essay does not contain; does it correct a sentence that was already correct; does each suggestion refer to a specific sentence or paragraph. The quoted spans were checked by code to be genuine substrings of the essay or the feedback, which caught the judge inventing evidence twice in sixty items. Recall on misstatements rose to 83% and the kappa against the teachers was 0.74, which she wrote at the top of the rubric file with the date.
Then she ran the old prompt and the new prompt through the new judge, on the same essays, with each pairwise comparison made in both orders. The new prompt’s feedback was 60% longer. Its misstatement rate was the same as the old prompt’s. Its suggestions were specific slightly less often, because the extra length was mostly a generic paragraph about structure. The pairwise judge preferred it, and disagreed with itself on 22% of pairs when the order was swapped.
The new prompt did not ship on Monday. Word count and language checks moved into deterministic code. The 1-to-10 score came off the dashboard and was replaced by the three rule pass rates, and the sixty labelled essays became a calibration set that was re-run every month and whenever the judge model changed.
Worth arguing about
The judge agreed with the teachers on 86% of items. Why did Meera treat that as no evidence that the judge was usable?
One answer
Most feedback is acceptable, so a judge that says acceptable nearly always agrees with humans nearly always. The number that mattered was recall on the rare class the teachers cared about, misstatements about the essay, and there the judge caught three of twelve. Per-class recall on a stratified calibration set is the measurement; overall agreement under imbalance is the same trap as accuracy on a rare event.
The new prompt scored 8.9 against 8.4 on the original judge and was preferred in pairwise comparison. What does the 22% self-disagreement on swapped orders say about that preference?
One answer
When the judge contradicts itself on 22% of pairs depending only on which answer it saw first, no win margin under about 22 points can be distinguished from position bias. Combined with the new feedback being 60% longer, the preference is better explained by length and structure than by quality, which is why the team measured misstatements and specificity separately from preference.
Why did requiring the judge to quote a span before giving a verdict, and checking that span by code, improve the measurement?
One answer
A verdict given first is a commitment the model then justifies; evidence given first conditions the verdict on it. Checking that each quoted span is a real substring is free and deterministic, and it caught the judge fabricating evidence twice in sixty items, a failure that would otherwise have been invisible and counted as a confident judgement.
Test yourself6 questions on this module
A pairwise judge is run on every pair in both orders and contradicts itself on 25% of pairs. What follows?
Why does the course ask a judge to check six rubric rules in six separate calls rather than all six in one?
A system scores 93% against a set of reference answers. Before concluding anything, the course says to audit fifty disagreements. Why?
You have every pairwise comparison between six systems in a file. Why fit a Bradley-Terry model rather than compute Elo ratings?
In the judging cascade, why do deterministic checks run before any judge call?
An agent task passes on three of five runs. How should it be reported?
Evaluation in the working loop
9 lessons · 1 h 18
You will be able toRun evaluation as part of development: a harness in CI that survives a stochastic model, logging complete enough to diagnose a failure you did not reproduce, a structured error-analysis session that names causes rather than symptoms, and a staged release with a metric that can stop it.
- 6.1The harness, and why you should build the small one first
- 6.2An evaluation that runs on every change without going red at random
- 6.3Recording enough to diagnose a failure you did not see happen
- 6.4Regression testing a prompt
- 6.5Reading fifty failures
- 6.6A/B testing a feature honestly
- 6.7Getting evidence from live traffic without exposing users
- 6.8The signals users give you without being asked
- 6.9Sampling live traffic, and keeping reviewers honest
An illustrative case, built from documented patternsThe gate that went red on a README
Netra Support runs the WhatsApp assistant for a regional broadband company with about 300,000 subscribers. The assistant answers billing questions, books technician visits and explains plan changes, and it hands over to a human agent when it cannot. The team of six had done the early work properly: a 200-item eval set from real chats, a rubric, a judge, and a CI job that ran the set on every pull request and failed the build if the pass rate fell below 85%.
Within a month the gate was a joke. The model was stochastic, so the score moved two or three points between identical runs. A pull request that changed only the README went red. A developer added an automatic retry. Another raised the threshold to 83. By the time the founder, Sameer, noticed, the job had been marked “allow failure” and nobody had looked at its output for three weeks.
Then a customer was told the wrong window for a refund, twice, and posted the screenshots.
Two things were in front of the team at the same time. The first was what to do about the gate. The engineering lead, Farah, wanted a week to restructure it into tiers: deterministic checks that blocked, a small core set that blocked only when the drop exceeded a band derived from the measured run-to-run spread, and the full set nightly and non-blocking. Items that flipped between runs would be quarantined rather than retried. Sameer’s view was that a week of the lead engineer’s time on test infrastructure, in the fortnight after a public incident, was a week not spent on the incident.
The second was the A/B test. A rewritten reply prompt had been in a 50/50 experiment for four days of a planned fourteen, with resolution-without-handover as the primary metric and a pre-registered minimum effect of three points. On day four it was six points ahead with a p-value of 0.03. Sameer wanted to ship it that afternoon, partly because it would be something positive to say publicly. Farah said the p-value assumed one look at the end and that a daily-checked fortnight ran a false-positive rate nearer a quarter than a twentieth. Sameer said he did not care about the statistics if the customers were happier.
Farah did one more thing before the argument reached a decision. She and a colleague took fifty failed items from the last full run and read them, writing one line each about why, before assigning any category. Twenty-one of the fifty were the assistant quoting a refund window that had been correct until the company changed its policy in June; the knowledge base article had been updated, the retrieval index had not. Eleven were the eval set’s expected answer being wrong for the same reason. Nine were the assistant answering in English when the customer had written in Telugu. Six were genuine model failures on the prompt. Three were miscellaneous.
So the incident had not been a prompt problem, and the A/B was comparing two prompts on top of a stale index.
What would you ship, what would you fix first, and what would you do with the day-four result?
How it played out
They fixed the index. The June policy change had been indexed into a separate namespace nobody was retrieving from; the fix was a configuration line and a re-index, done that evening. The eleven stale expected answers in the eval set were corrected, with a note in the set’s changelog and a policy version attached to every refund item, so that the next policy change would fail the run loudly instead of silently penalising the right answer.
The A/B ran to its fourteenth day. With the index fixed underneath both arms, the rewritten prompt’s advantage settled at 1.8 points, below the three-point threshold they had written down before starting. It did not ship. Sameer, to his credit, said in the retrospective that the day-four number would have shipped a prompt that did nothing and let the index stay broken for another fortnight.
The gate got its week, but in the second fortnight. Deterministic checks became the only hard block: schema, the language of the reply matching the language of the customer, no refund window mentioned unless it appeared in the retrieved policy text, citations resolving. The core set of 150 items blocked only when the pass rate fell more than three standard deviations of the measured run-to-run spread below a rolling baseline. Nine items that had flipped in the last month went to quarantine, and reading them found two rubric ambiguities. The nightly full run posted a diff of which items changed verdict, not a score, and the Telugu failures became a named slice with its own floor.
Worth arguing about
The team had retries and a raised threshold on the CI gate before anyone decided to. Why does a fixed threshold on a stochastic eval fail in that specific way?
One answer
A stochastic model gives different scores on identical code, so a fixed line is crossed by noise, and every red build on an unrelated change teaches the team to route around the gate. Retrying a failing item until it passes is optional stopping inside CI. The fix is to block only on deterministic checks and on a band sized from the measured run-to-run spread, and to quarantine items that genuinely flip rather than retry them.
On day four the experiment was six points ahead at p = 0.03. Why was Farah right that this did not justify shipping, and what did the final result show?
One answer
The p-value was computed as if the team would look once, at the fixed horizon. Looking daily and stopping at the first crossing raises the false-positive rate several-fold and biases the reported effect upwards, because you stop at a high point. Run to the horizon, and with the stale index fixed under both arms, the advantage was 1.8 points, below the pre-registered three-point threshold.
Error analysis showed only six of fifty failures were the model’s. How did reading the failures change what the team worked on, compared with what the CI score alone would have told them?
One answer
The score said the assistant was worse; it could not say why. Reading fifty failures and writing the cause before categorising showed 21 retrieval failures from a stale index, 11 wrong expected answers in the set, and 9 language mismatches, none of which a prompt change addresses. The fix was a configuration line and a re-index, done in an evening, and a deterministic language check that now blocks merges.
Test yourself6 questions on this module
Two runs of the same harness disagree by six points and nobody can say why. Which missing record does the course single out as the most confusing cause?
An item in the CI core set flips verdict twice in one week. What does the course prescribe?
Which field does the tracing lesson call the single most valuable in a trace, and the one most often missing?
A prompt edit leaves the eval score at 84% before and 84% after. What can hide behind an unchanged total?
In error analysis, why write the cause of each failure in your own words before assigning it a category?
In shadow mode, what must be enforced structurally in the tool layer rather than by convention?
Evidence other people can act on
9 lessons · 1 h 20
You will be able toAssemble an evaluation record a stranger can audit (documented set, per-group results, stated limitations, reproducible run) interrogate a supplier’s claims with a set of your own, and say clearly where a quality judgement is contested rather than merely unmeasured.
- 7.1The document that travels with the system
- 7.2Buying a model you will depend on
- 7.3Why the builder’s own numbers are weak evidence
- 7.4What the emerging rules ask for, and what they do not settle
- 7.5Measuring the worst case, not the average one
- 7.6Measuring the human in the loop
- 7.7Testing whether the system gives away what it was given
- 7.8When the model is right and the product still fails
- 7.9When people disagree about what good means
An illustrative case, built from documented patternsThe card said ninety-six per cent
The department administers a post-matric scholarship that receives about 400,000 applications a year. Each application carries income and caste certificates, and a share of them are flagged for re-verification by a district clerk before payment. Historically the flagging was done by rule and by hand, it took three months, and students missed a semester’s fees waiting.
A vendor proposed a system that read each application and produced a flag, “needs document re-check”, with a confidence score. The proposal came with a system card: 96% accuracy on the vendor’s evaluation set, an ISO management-system certificate, and a line saying that every flagged application would be reviewed by a human before any action.
The joint secretary in charge, Mrs Rathore, was under pressure to sign. The scheme opened in six weeks, the vendor was ready, and the accuracy figure had already been quoted in a briefing to the minister. Her deputy, Anand, had two objections and a proposal.
The first objection was that 96% was measured by the vendor, on a set the vendor built, with a metric the vendor chose. Nothing on the card said what the set contained, how many items, what the base rate of genuinely problematic applications was, or whether the figure held for applications in Urdu, which were about a fifth of the total in three districts.
The second was the human review line. Anand had visited the district office in Bahraich. The clerks would receive flagged applications in a list of forty and approve them with one button. Nobody had measured how many wrong flags a clerk actually caught in that interface, and Anand’s guess, from watching for an hour, was very few.
His proposal was to spend three of the six weeks measuring. Take 300 applications from last year, stratified by district and by language, whose outcomes were known: which ones had genuinely needed re-checking. Run the vendor’s system over them and compute precision and recall per slice, with intervals. Then, separately, seed a small number of known-wrong flags into a test queue and measure how many the clerks caught, telling the clerks in writing that seeded cases existed and that the results would size the system and never be used against an individual.
Mrs Rathore’s cost was straightforward. Three weeks of a six-week runway, the clerks’ time, and the political embarrassment of a minister’s number being revised downwards in public. The vendor pointed out, accurately, that their certification covered their process and that no department had previously asked for anything of the kind.
Anand’s cost, if the measurement was skipped, was that the first anybody would know about a per-language gap would be when Urdu-medium students in three districts were flagged at twice the rate of everyone else, and the minister’s office found out from a newspaper.
There was also the question of what the confidence score meant. The vendor’s interface sorted the queue by it, so clerks would see the highest-scoring applications first, and nobody had checked whether an application scored 0.9 was actually more likely to need a re-check than one scored 0.6. If the score was decoration, the queue order was too.
Should she sign, measure, or both, and what would she need to see before the scheme opened?
How it played out
She did both. The contract was signed with a clause that made go-live conditional on the department’s own measurement, which the vendor accepted once it was clear the alternative was no contract.
On the department’s 300 applications, overall accuracy was 89%, and because only 11% of applications had genuinely needed re-checking, a system that flagged nothing would have scored 89% too. The numbers that mattered were recall of 71% on the applications that needed a re-check and a false-flag rate of 6% on the ones that did not. For the Urdu-medium slice, recall was 74% and the false-flag rate was 14%, more than double. The confidence scores were uncalibrated: applications scored above 0.9 needed a re-check about 60% of the time.
The seeded-error test was the finding that changed the design. Twenty known-wrong flags went into a queue of 400 across two district offices. The clerks caught seven. A 96% system with a 35% catch rate lets through more wrong flags than the department had been letting through by hand.
The system card was rewritten by the department, with the vendor’s cooperation: every claim carried its set, its sample size and its interval, the Urdu figure was printed separately, and the out-of-scope section said plainly that the system had not been evaluated on applications with handwritten certificates. The interface changed more than the model did: batch approval was removed, each flag was shown beside the specific certificate field that triggered it, and a per-language floor was written into the contract, with the Urdu slice to be re-measured monthly on a fresh sample. The vendor’s contract gained a version-pinning clause and ninety days’ notice of any model change.
The scheme opened on time. The minister’s briefing was corrected before the opening, which was uncomfortable for a day and not for longer.
Worth arguing about
The vendor’s 96% and the department’s 89% were both honest measurements. What made the department’s number the one to act on?
One answer
The builder chooses the set, the metric and what to report, and stops when the number is good; that is selection, not fraud, and it inflates the figure in a direction nobody can quantify. The department’s set was drawn from its own applications, stratified by district and language, with known outcomes and a stated base rate, so its precision and recall described the decision the department actually had to make.
Why was the seeded-error test necessary, given that the card already promised human review of every flag?
One answer
A statement that a human reviews every decision is a claim about a workflow, not an outcome. The miss rate cannot be computed from ordinary traffic because nobody knows which flags were wrong. Injecting known-wrong flags at a low rate, with the clerks told in advance and the results never used against an individual, gave a real catch rate of 35%, and showed that a one-click batch approval interface was not oversight.
The department kept the vendor. What changed in the deployment that made a 71%-recall system acceptable, and what would you still want to see measured?
One answer
The changes were to detectability and reversibility rather than to the model: each flag shown beside the triggering field so a clerk could verify in seconds, batch approval removed, a per-language floor with monthly re-measurement, and a rewritten card whose claims carried their measurements. Still to measure: the end-to-end pipeline figure after model and clerk together, calibration of the confidence scores per slice, and whether the Urdu gap closes with more representative examples or reflects something in the labels themselves.
Test yourself6 questions on this module
What is the rule that separates a system card from a brochure?
Model B costs half as much per token as model A, needs two attempts per task, and returns malformed output on 8% of calls. How should the two be compared?
A supplier says its model was independently verified. Which question decides whether that was an audit or a review?
Which axis of a failure mode does the harm lesson say dominates the others and is most often left out?
How do you obtain a real miss rate for a human review step?
According to the privacy lesson, where does the commonest real cross-tenant leak come from?
Living with it
9 lessons · 1 h 18
You will be able toKeep a shipped system honest over time: monitor for drift, measure the tail of cost and latency rather than the mean, measure quality separately for each group of users, convert incidents into permanent test items, and report a result with its uncertainty stated.
- 8.1Cost, latency, and the model that changed under you
- 8.2The tail is what your users feel
- 8.3Watching a system you can no longer test
- 8.4The system that trains on its own output
- 8.5Refreshing a set without breaking every comparison
- 8.6Fairness as arithmetic, and the choice you cannot avoid
- 8.7Turning a complaint into a permanent test
- 8.8Writing the result down
- 8.9How much of this to actually do
An illustrative case, built from documented patternsSixty days’ notice and a set from January
PaisaSathi runs a lending app with about two million users and a support assistant that answers questions about EMI dates, statements, KYC status and repayment. The assistant had been stable for most of a year. The team had done the early work: a frozen eval set of 300 items sampled in January, a calibrated judge, a canary set of twenty items run hourly, and a pinned model version in a config file.
In the first week of September two things arrived within days of each other. The model provider sent a deprecation notice: the pinned version would be withdrawn in sixty days, and the recommended replacement was a newer model under a rolling alias. And the head of support, Priya, reported that complaints tagged “assistant unhelpful” had risen by 40% over six weeks, with nothing deployed on the assistant in that time.
The engineering lead, Rohan, had three candidate explanations and no evidence for any of them. The provider might have changed something under the pinned version despite the pin. The users might have changed. Or nothing had changed and the complaint tag was being used differently.
The decision that could not wait was what to do about the deprecation. The product manager wanted to switch to the new alias immediately: the provider’s announcement described it as better on every benchmark, the deprecation was going to force the move anyway, and moving now might fix the complaints. Rohan wanted to hold the pinned version, run the frozen set against both models, read the per-item diff by slice, re-tune the prompt for the new model, and then canary. He estimated four working days. The cost of his four days was four more days of rising complaints if the model was the cause. The cost of switching immediately was that whatever the new model did differently, nobody would know until users did.
The canary set answered the first question in an hour. Its twenty items had produced byte-identical outputs for eleven weeks. The pinned model had not changed. Whatever was driving the complaints, it was not the provider.
So Rohan looked at the inputs. He bucketed August’s traffic and the January eval set on language, intent and input length, and computed the total variation distance between the two mixes. It was 0.27. In January, Marathi-language messages had been 4% of traffic; in August they were 19%, following a marketing campaign in Maharashtra’s tier-two cities. The eval set contained twelve Marathi items. The assistant’s pass rate on those twelve was 58%, which nobody had looked at because twelve items in a slice of 300 barely moved the headline.
That reframed both problems. The complaints were most likely a mix shift onto a slice the assistant handled badly and the set could not see. And the deprecation decision now had a specific question attached: was the new model better or worse in Marathi, and at what latency and cost?
The frozen set was the only asset that could answer it, and it was stale. Refreshing it would break comparability with every number the team had reported since January. Not refreshing it meant deciding a model migration on a set that no longer resembled the users.
What order would you do things in, and what would you report to Priya?
How it played out
Rohan did not refresh the frozen set. He drew a second set, 200 items from August’s traffic, stratified to the current mix, labelled over two days by two support agents. Both sets were run against both models, and the report carried all four numbers.
On the January set, the new model scored 84% against the old model’s 81%. On the August set, 79% against 76%. The three-point gap held on both, which was reassuring, but the slice table was the finding. In Marathi the new model scored 71% against 58%. Its refusal rate on borderline-but-legitimate Hinglish messages, the kind that mention loans and stress in the same sentence, was 9% against 2%. And its p95 latency was 5.1 seconds against 2.3.
The prompt was re-tuned for the new model over two days, mainly by removing formatting instructions the old model had needed, and the refusal rate on the Hinglish slice came down to 4%. A per-request token cap and a five-second timeout, counted as failures in every quality metric, brought p95 to 3.4 seconds. Then a 5% canary for two business days, with refusal rate and escalation rate as guardrails, and a full ramp over the following week.
The set policy was written down for the first time. The January set stayed frozen as the historical yardstick. The August set became the headline set, versioned and dated, with both reported for one cycle so the six-point difference between them was published as a fact about the sets rather than mistaken for a regression. Incident-derived items were capped at a third. The monthly divergence check became a scheduled job, and Marathi got its own floor.
Priya’s report said three things: the model had not changed; the users had, and the assistant had been weak for the new users all along; and the migration improved the weakest slice by thirteen points, with the interval stated.
Worth arguing about
The canary set had produced identical outputs for eleven weeks. What did that establish, and what would the team have concluded without it?
One answer
Twenty fixed items run hourly with stored outputs showed the pinned model had not changed, which eliminated the provider as the cause of rising complaints in an hour. Without it, the team would most likely have blamed the provider, switched models under pressure, and never looked at the inputs, where the real change was.
Rohan drew a new set rather than refreshing the frozen one, and reported both. Why does a silent refresh do damage, and what did reporting both buy?
One answer
Changing a set changes the number, and a number that moved because the set moved looks exactly like a quality change. Keeping January frozen preserved every historical comparison, and running both models on both sets let the three-point migration gain be separated from the six-point difference between the sets. Publishing the gap between sets turned it from a phantom regression into a stated fact.
The migration decision was made on a slice table rather than on the headline. What in the table would have been invisible in a single number, and how did it change what shipped?
One answer
The headline said the new model was three points better. The slices showed a thirteen-point gain in Marathi, a refusal rate that had more than quadrupled on a sensitive Hinglish slice, and a p95 latency that had doubled. Each drove a different action: the Marathi gain justified the move, the refusal rate was fixed by re-tuning the prompt, and the latency was bounded with a token cap and a timeout counted as failure, before any user saw the new model.
Test yourself6 questions on this module
Why does the course insist on reporting p95 latency rather than the mean?
Refusal rate moves from 2% to 9% overnight with no deployment on your side. What is the most likely cause?
Generated summaries start being saved into the help centre that the retriever indexes. What happens to the groundedness metric?
A refreshed evaluation set scores 81% on a system that scored 87% on the old set. What does the course say to do?
Two groups have different base rates for the outcome a classifier predicts. Which statement about fairness definitions is correct?
After two years, 60% of an evaluation set is made of items added from incidents. What is the problem, and the fix?
What this course is
Most AI features are shipped on a feeling. Someone tries eight examples, the outputs read well, and the thing goes live. And nobody finds out how often it fails until customers do. This course is about the other path: building a small evaluation set by hand, deciding what to measure when the output is prose, using a model as a judge without being lied to by it, catching regressions when you edit a prompt, running an honest A/B, and holding cost and latency in the same frame as quality. It ends with the situation every team eventually hits: the model changed under you, complaints went up, and you need an answer by tomorrow.
Who wrote it
Founder and series editor: Dr Mustafa Mun. Written by AI models to a written standard. Exam keys checked blind by a second model: 3,665 of 3,666 agreed. Academic review invited.
More in Build with it
- Python, from Zero, for AIFrom your first line of code to your first API call.
- Building with AIFrom your first API call to a feature you can trust
- Agents and AutomationWhat an agent actually is, and when you should build a script instead.
- Shipping ItGet what you built in front of real people, and keep it alive.
- Building Apps with AIBuild working software before you can write it, without fooling yourself.
- Data, SQL and Getting to the AnswerMost AI problems turn out to be data problems. This is where you learn to ask a database a question and defend the answer.
- Context EngineeringThe window is a budget. Learn to spend it.
