QASenior

Prompt regression

Prompt regression testing checks, case by case, whether a change to a prompt or a model broke anything that worked before the change. The page opens with one prompt change reviewed from start to finish — the order assistant’s v7 to v8 — then covers negative flips, what to pin, three runs a case and the noise floor, the gate, the model upgrade, and four changes that went wrong.

Compare
Case by case, not the average
A case counts when
Stable on 3 of 3 runs
Blocks a release
Any protected case that broke

A prompt change on one screen — the order assistant’s v7 to v8, reviewed

Nobody opens a page about prompt regression for a definition. They open it because a prompt change is waiting in review and the question is whether it can ship. Below is one such change, reviewed from start to finish. The feature is the order assistant from Testing LLM products and AI evaluation: the shop’s chat that answers “where is my order”, explains the returns policy and starts returns. The change is one sentence. The groups follow the order of the work — the change, what was pinned, the run, the per-case diff, the verdict, what happened next — and later sections cite the lines by number.

  1. 1.The change

    1. One sentence added to the , v7 → v8: “Always tell the customer the date their return window closes.”
    2. The reason: the largest failure group in error analysis — 13 of 41 notes left out the condition that decides (AI evaluation, row 7; Testing LLM products, row 12).
    3. A against prompts/order-assistant.md, reviewed like code. The owner of the returns policy approves the wording.
  2. 2.Everything else, pinned — identical on both sides

    1. The model: the same dated snapshot as v7’s baseline — never an alias.
    2. Sampling: the production settings, temperature 0.3, so the run measures what customers will get.
    3. The help-centre index: the build of Monday 5 October, frozen for the run.
    4. The tools: get_order, start_return and handoff at schema v3, their responses replayed from recordings, so both versions see the same orders.
    5. The judge: its model and prompt pinned; 80% and 91% on held-out labels (AI evaluation).
    6. The set: the 120 working cases. The 30 wait for the release check.
  3. 3.The run

    1. Every case three times on each version: 720 replies, plus the judge’s calls on the scored cases — 11 minutes, about $4.
    2. Each case gets a state per version: stable pass (3 of 3 runs), stable fail (0 of 3) or unstable (1 or 2).
    3. The noise floor, measured first: v7 against a second run of v7. No case moved between stable pass and stable fail; 5 moved in or out of unstable.
  4. 4.The per-case diff, v7 → v8

    1. Fixed, stable fail → stable pass: 9 cases, 8 of them in the targeted group.
    2. Broke, stable pass → stable fail: 4 cases. Two are protected — final-sale items, now told “you can return it until 24 October”.
    3. The other two breaks are questions the policy does not cover. v8 answers them with a date instead of handing off (Testing LLM products, row 10).
    4. Unstable on either side: 14 cases — listed, not counted. Unchanged: 93.
    5. The headline number: stable passes 92 → 99 of 120, 76.7% → 82.5%.
  5. 5.The verdict

    1. Blocked. Two protected cases broke, and any protected case that breaks blocks the release, whatever the average did.
    2. It would have warned anyway: two more breaks outside the protected set, against a noise floor of zero.
    3. Read by a person before deciding: the 13 conversations that flipped, about 25 minutes. All four breaks were real. One of the nine fixes was not — the judge passed a date taken from the customer’s other order.
    4. On the dashboard alone, v8 was 5.8 points better and would have shipped.
  6. 6.What happened next

    1. v9 rewrites the sentence: “When the item can be returned, tell the customer the date its return window closes.” The handoff rule stays above it.
    2. v9 against v7: 9 fixed, 0 broke, all 20 protected cases pass, 11 unstable.
    3. The 30 held-out cases, run once before release: nothing broke.
    4. Merged on Thursday 15 October 2026. v9’s per-case results are stored as the new baseline, tagged with every version in group 2.
    5. Two new protected cases: a final-sale item asked about in the words v8 failed on, and the same question in Ukrainian. The protected set is now 22.

What counts as a regression when the output moves: a negative flip

In ordinary software a regression is unambiguous: a test that passed now fails. With a model in the loop the same case can pass on one run and fail on the next with nothing changed, so the word needs a definition. Machine-learning research already has one. In 2020 Sijie Yan and colleagues called it a negative flip: a sample the old model got right and the new model gets wrong. They also made the point this page rests on — that reducing such inconsistencies between versions can matter as much in practice as reducing the overall error.

In 2024 Jessica Echterhoff and colleagues at Apple measured the same thing on language models. When a base model was updated, task adapters trained on top of it in exactly the same way started getting previously correct answers wrong — although nothing in their own training had changed. So a prompt regression suite does one job. It lists every case that flipped, in each direction, and treats a flip from pass to fail as a finding regardless of what the total did.

One prompt change, seen the way a dashboard sees it and the way a regression suite sees it. The order assistant’s v7 and v8 were each run three times on the same 120 cases, and every case was given a state on each version: stable pass if it passed all three runs, stable fail if it failed all three, unstable otherwise. On the dashboard the change is a gain: 92 stable passes become 99, from 76.7 to 82.5 per cent. The table of moves shows what that total is made of. Nine cases moved from stable fail to stable pass — the fixes. Four moved from stable pass to stable fail — the breaks, and two of them are protected cases: final-sale items the assistant now says can be returned. Fourteen cases were unstable on one side and are listed but not counted, because their movement cannot be told from sampling noise. The total adds the nine and subtracts the four, so it can never show that two promises to customers broke; the release is blocked on those two alone.

Read the diagram as a table of moves. Rows are the state of a case on v7, columns its state on v8. The diagonal holds cases that stayed where they were; below it are the fixes, above it the breaks. The grey row and column are cases that were unstable on one side, which the section after next explains. The headline number sees only the column totals, so it cannot tell nine fixes and four breaks from five fixes and none.

Prompts make flips cheap to cause. In 2023 Melanie Sclar and colleagues changed only the formatting of prompts with worked examples — separators, spacing, capitalisation, nothing a reader would call a change of meaning — and measured accuracy differences of up to 76 points on one model. They also found that the best format for one model was a weak guide to the best format for another. A one-sentence edit is a bigger change than any of theirs.

Pin everything you are not testing

A prompt experiment most often reaches a wrong conclusion because it was never a prompt experiment. Six things feed the order assistant’s replies. They change on different schedules and in different hands, and only one of them was in the pull request. Unless the other five are held still for the run, the diff credits the sum of several changes to the one somebody happened to make.

Six things feed the order assistant’s replies, and a prompt review changes one of them. The prompt moves from v7 to v8 in a pull request. The other five change on other schedules and in other hands: the provider updates models, someone edits the sampling config, a nightly job rebuilds the help-centre index, another team ships tool changes while the orders themselves change status, and QA improves the judge. For the length of the run each of those five is frozen at a version — a dated model snapshot, the production sampling value, the index build of 5 October, tool schema v3 with responses replayed from recordings, judge prompt j4 on a pinned model — and the v7 baseline it is compared with was recorded under the same five. Only then is the per-case diff a measurement of the prompt. If any of the five moves during the run, its effect lands in the diff and is credited to the prompt change, which is the most common way a prompt experiment reaches a wrong conclusion.
InputWho changes it, and whenHow it is pinnedIf it moves during the run
PromptYou, in a pull requestA file in the repository, versionedIt is the change under test — the only thing that should move
ModelThe provider, on its scheduleA dated snapshot, never an aliasThe diff measures the provider’s update and credits it to you
Sampling settingsWhoever edits the configRead from the same config as productionThe spread changes on one side, and the difference you measured is the setting
Retrieval indexA nightly jobA named build, frozen for the runAn article added on Tuesday is credited to the prompt
Tools and their dataAnother team; the orders themselvesA schema version, and responses replayed from recordingsAn order that changed status between runs looks like a regression
JudgeQA, when the rubric improvesA model snapshot and a prompt versionYou changed the ruler, and every historical number moves with it

Two rows deserve a sentence each. Sampling is pinned to the production values rather than to zero: temperature zero does not make a hosted model deterministic anyway (Testing LLM products explains why), and a run at settings customers never see measures a different system. And the tools are replayed rather than called. An order that moved from “packed” to “shipped” between the v7 run and the v8 run is a real difference in the input, and in the output it looks exactly like a regression.

The prompt itself belongs in your repository, next to the code that sends it. Prompt managers in vendor consoles make editing easy and history hard, and they can disappear. On 3 June 2026 OpenAI deprecated its stored prompt objects and its Evals platform together, set both to shut down on 30 November 2026, and advised moving prompt content into application code. A prompt and a suite that live in your repository survive a vendor’s product decisions.

Three runs a case: telling a flip from noise

Even with all six pinned, the same case can pass on one run and fail on the next, because generation samples from a distribution. One run per case therefore cannot tell a flip from a coin that landed the other way. The fix is cheap: run every case three times and give it a state. Three passes make a stable pass, three failures a stable fail, and anything in between is unstable. Only a move between the two stable states counts as a flip.

Each case in the order assistant’s set is run three times on each version, because one run cannot tell a real change from a sample that happened to land the other way. A case that passes all three runs is a stable pass, one that fails all three a stable fail, and anything in between is unstable. Only a move between the two stable states counts as a flip. The middle column is the step most teams skip: the unchanged v7, run a second time and compared with itself. That A/A run is the noise floor. Here it produced no flips and five cases drifting in or out of unstable, like the case with two open orders. Against that floor the v8 results read cleanly. The final-sale case and the lost-parcel case went from three passes to three failures — breaks, the first of them protected. The question about when the return window closes went from three failures to three passes — a fix. The gift-card refund passes two runs in three on every version; it is listed, not counted, and if it stays unstable for long it is worth reading, because it usually marks an ambiguous rule.

Before comparing two versions, compare one version with itself. Run the unchanged baseline a second time and diff it against the first, exactly as you would diff a candidate. This is an A/A comparison, and whatever it shows is your noise floor. For the order assistant it showed no flips and five cases drifting in or out of unstable (line 3.3). A candidate that breaks four stable cases is therefore four findings, not four coincidences.

ProtocolWhat it buysWhat it costs on 120 cases
One run per caseThe cheapest comparison; nothing separates a flip from an unlucky sample240 replies
Three runs, flips only between stable statesFlips you can act on, with unstable cases listed apart720 replies, 11 minutes, about $4
Five runsA sharper line for cases near fifty-fifty; worth it on the protected set1,200 replies
An A/A run of the baselineThe noise floor in your own units; repeat it whenever the model or the judge changesOne extra run of the baseline

Unstable cases are information, not noise to throw away. A case that passes two runs in three is one where the model sits close to a decision boundary, and that is exactly where the next small edit will push it over. Keep the unstable list next to the lists of flips. If a case stays unstable three releases running, read it — the cause is usually an ambiguous rule in the prompt or in the policy itself. The rest of the statistics — the error bar on a pass rate, clustered errors, why comparing case by case beats comparing averages — is on the AI evaluation page.

The gate: what blocks, what warns, what a person reads

A regression suite that is not wired to a decision is a report. The arrangement that works treats a change to any of the six inputs exactly like a code change. The change opens a pull request, the suite runs against it, and the result is a diff a reviewer reads before merging. Which results stop the merge on their own is agreed before the run, not argued about after it.

ResultWhat happensOn v7 → v8
A protected case brokeBlocks; nobody can override it inside the pull request2 — blocked (5.1)
An exact check failed — schema, tool arguments, the handoff flagBlocks0
Breaks outside the protected set, above the noise floorWarns; a named owner decides with the conversations open2 (5.2)
Cost or latency per conversation over budgetBlocksWithin budget
FixesReported and read, because a fix can be the judge’s mistake9, one of them the judge (5.3)
Unstable casesListed apart; read when one stays unstable three releases running14

The protected set is the part of the suite that blocks on its own, so how a case gets in matters. Four reasons qualify: a failure that already reached customers, a statement the company is bound by, wording a regulator cares about, and anything that touches safety. The order assistant’s final-sale cases are protected for the second reason. When a chatbot misstated Air Canada’s bereavement-fare policy, a British Columbia tribunal ruled in February 2024 that the airline was responsible for what its chatbot said. An assistant that tells a customer a final-sale item can be returned has made the shop a promise.

A case leaves the protected set only by a decision someone signs, never by being quietly deleted when it becomes inconvenient. The set grows from incidents, so expect it to grow: the order assistant’s went from 20 to 22 in one review (line 6.5). When a protected set gets so large that every change breaks something in it, the problem is usually the prompt’s structure rather than the set — too many rules competing in one paragraph.

MomentWhat runsWhy there
A pull request that touches any of the sixThe 120 working cases, three runs each, lists of flips against the baselineThe change is a release, whatever the ticket calls it
NightlyThe same set against the live provider, every pin unchangedThe only run that sees a change you did not make — the third case below
Before a releaseThe 30 held-out cases, onceThe only cases nobody has tuned the prompt against
At mergeNothing runs; the candidate’s per-case results become the new baselineTomorrow’s diff needs today’s record

The model upgrade: the biggest regression run you will do, so rehearse it

Every pinned snapshot has a retirement date, and the provider sets it. OpenAI’s published minimum is six months’ notice for a generally available model and three months for specialised variants; preview models can go much faster, and its documentation gives two weeks as an example. Anthropic promises at least 60 days for publicly released models. On 14 October 2026 OpenAI told developers that its GPT-4o and GPT-4.1 snapshots leave the on 14 January 2027. For a feature pinned to one of them, this section has a date attached.

An alias does not avoid the event; it only takes the date out of your hands. The fourth case below is a whole family of models moved that way. In January 2024 OpenAI introduced gpt-4-turbo-preview, a name that always points at its latest preview model, on the same day it released a snapshot meant to reduce cases of “laziness”, where the previous one did not finish a task. Whoever called the alias got the new behaviour the day it shipped, wanted or not. A pinned snapshot turns that into a change you schedule and test.

When a provider retires a model snapshot, the date is theirs and nothing in your code changes it. What is yours is the switch date, and the drill decides it. For the order assistant, on a snapshot that retires on 14 January 2027, the first move is to run the whole suite with today’s prompt against the replacement in the week the notice arrives. Here that breaks eleven cases, three of them protected, because a prompt tuned for one model is rarely the best prompt for another. Two weeks go into v10, written for the new model, until nothing breaks and all twenty-two protected cases pass. Then a tenth of real conversations go to v10 on the new snapshot, so that its handoff and thumbs-down rates can be compared with the rest. The switch happens on Tuesday 1 December, a date the team chose. The calendar drawn to scale shows why that matters: the drill fits in the first seven weeks, and the remaining six are margin, with the old pin still able to answer if the switch has to be undone.

The drill has four moves. As soon as the notice arrives, while the old pin still works, run the full suite against the replacement snapshot with today’s prompt. Expect a long list of flips: Sclar’s finding that the best prompt format for one model barely predicts the best for another means a model change is also a prompt change. Write the next prompt version for the new model and run it again until the protected set holds. Then switch on a day you chose, keep the old pin as the way back until it retires, and record the new baseline.

Four changes, and what a per-case diff would have shown

Each of these was a change to a system that had been working, and in each the regression reached users before any team’s suite reported it. In two of the four, evaluations had been run and had passed.

ChangeWhat happenedWhat the per-case diff would have shown
DPD, January 2024The parcel firm said an AI element had worked in its support chat “successfully for a number of years”. After a system update a customer got it to swear and to write a poem about how bad the company was. One post was viewed 800,000 times in a day, and DPD switched the AI element off. The Prompt Engineering page tells the injection side of it.Three protected cases every support bot needs — no swearing, never disparage the company, stay on the subject — run against the update before it went live.
GPT-4o in ChatGPT, April 2025An update rolled out on 24–25 April made the model markedly more sycophantic. In OpenAI’s account, offline evaluations “generally looked good”, A/B tests were positive, some expert testers said the behaviour “felt” slightly off, and there were no deployment evaluations tracking sycophancy. It patched the system prompt late on Sunday and rolled back from Monday 28 April. LLMOps tells it from the operations side.A protected group for behaviour the company’s own specification rules out. OpenAI’s stated fix is the gate on this page: behaviour issues now block a launch “even when metrics like A/B testing look good”.
Claude, August–September 2025Anthropic changed nothing in its models; three infrastructure bugs degraded replies intermittently. A routing error began on 0.8% of one model’s requests and reached 16% at the worst hour after a load-balancing change. Its postmortem says the evaluations it ran “simply didn’t capture the degradation users were reporting”, in part because the model often recovers well from isolated mistakes.Nothing, if the suite runs only on your own changes. The nightly run against the live provider with every pin unchanged (Testing LLM products, row 20) is the only comparison that sees a regression nobody shipped — and Anthropic’s own fix is to run evaluations continuously on production systems.
OpenAI Completions models, 2023–2024Announced on 6 July 2023: older completion models would retire on 4 January 2024, and applications calling the stable names ada, babbage, curie and davinci would be upgraded automatically to new models on that day.The same flip matrix, run against the replacements during the six months the notice gave. Teams that had pinned a model faced a deadline; teams on the bare names faced a silent model change on a date they had not picked.

Where it degrades

The honest limit is that a per-case diff compares the cases you have. A regression on a kind of question nobody put in the set passes every gate on this page; the sycophancy update broke a behaviour no case asked about. The suite tells you that a change did not break what you already knew to check. Error analysis on fresh production conversations, described on the AI evaluation page, is what adds the next case, and nothing here replaces it.

  • Judging a change on the aggregate — the statistic in which a fix cancels a break.
  • One run per case, so a sampling accident reads as a regression, or hides one.
  • An index rebuild, a tool change or a new judge landing in the same week as the prompt edit, and all of it credited to the prompt.
  • Editing the production prompt in a console: a deployment with no diff, no review and no way back.
  • Re-running only the results nobody liked.
  • A protected set that shrinks whenever a case becomes inconvenient.
  • Lists of flips nobody reads, so a judge’s mistake is counted as a fix.
  • A model alias in production, so the provider decides when your feature changes.
  • Discovering a retirement date in the week it arrives.
  • A suite that runs only on your changes, blind to the ones you did not make.

When to use it

Use it when

  • On every change to any of the six inputs — prompt, model, sampling, index, tools, judge. Each one is a release.
  • With three runs a case and flips counted only between stable states, after an A/A run has set the noise floor.
  • With a protected set that blocks on any break, whatever the average did.
  • Nightly against the live provider, and in full on the day a retirement notice arrives.

Avoid it when

  • Comparisons on the aggregate score alone, which hide exactly the cases that broke.
  • Single runs on a small set, where one case changing its mind looks like a three-point gain.
  • Experiments in which the index, the tools or the judge moved at the same time as the prompt.
  • A suite that only reports: a break nobody is required to act on is a break that ships.

Sources and method

What this page stands on

  • 12 sources
  • 5 documented failures
  • Checked October 17, 2026

Researched with Claude. Finding and cross-checking the primary sources was done with Claude (Anthropic). Selection, writing and fact-checking: the Anatomy of IT Product editors.

Found this useful?

Share it with someone who is working on the same problem.