A call to the model times out. The wrapper does what every wrapper has done for twenty years. It calls again. The second answer comes back and goes downstream. The log shows one attempt and one success.
The first answer existed. It was different. Nobody will ever see it. The retry overwrote it, and the log keeps only what succeeded.
Across the hall, someone writes a test. The summary should contain the word “database.” It passes Monday. Tuesday the summary says “DB.” The test gets loosened to accept both. Wednesday it says “the data layer.” Thursday the test is gone.
The Contract Nobody Signed
Neither of those is a model problem. The model did its job both times. The plumbing around it did its job too. The two jobs were written for different worlds. The wrapper was written for a database that returns the same row every time. The model was built to return the most likely next word.
Every piece of software built before this year runs on one assumption. Same input, same output. Nobody wrote it down because nobody had to. Retries assume it. Tests assume it. Caches assume it. Audits assume it. The SLA clock assumes it. The runbook assumes it. The person on call assumes it.
Retry was built to answer the same question twice.
Drop one component into that system that doesn’t honor the assumption, and nothing breaks loudly. The retry still retries. The test still runs. The cache still caches. Each one just stops meaning what it used to mean. A passing test means it passed once. A cache hit means you are serving an answer the model might not give today. A retry means a second roll.
Rediscovery, One Pipe at a Time
Teams are finding this out the way teams find things out. One ticket at a time.
The test suite goes first. Someone notices the model tests are flaky, and the word flaky is doing a lot of work. Temperature gets set to zero. That helps until the vendor ships a new version and the same prompt returns a different shape.
The cache goes next. Someone asks why two users got two different answers to the same question, and someone else explains that one of them hit the cache. Both answers were fine. The ticket stays open anyway. Fine was never the standard. Same was.
Then the audit. A customer asks what the system told them on the 14th and why. The log has the output. Nobody can replicate the output. The replication step in the runbook was written for software that reproduces.
Each team patches the pipe in front of them. Eval suites. Confirmation steps. Pinned model versions. Run it three times and take the majority. Three guesses and a show of hands. It all gets filed under AI reliability. None of it is about the model. The model is doing exactly what it did on day one. It is the old contract getting rewritten by hand, one clause at a time, by people who did not know they were lawyers.
The Person on Call
The SRE gets paged at two in the morning. The alert says a model response failed validation. She does what she was trained to do. She pulls the input and runs it again.
It passes.
She has a runbook. Step one is to reproduce the failure. There is no step for “the failure is not reproducible and that is normal.” She closes the page as transient. Transient is the word the runbook uses for things it wasn’t built to explain. The same alert fires Thursday.
Where the Contract Still Holds
Most teams reach for the fix: make the model behave. Lock the version. Zero the temperature. Constrain the output. Some of that is worth doing. None of it restores the contract. A smaller range of answers is still a range. Retry still rolls inside it.
The other fix is quieter. Keep the model out of the places that need the same answer twice.
Most of a system never needed a model. Linking records. Matching keys. Checking a date against a window. All of that is deterministic and should stay deterministic. The model gets a small job at the end, after the facts are already connected, where a different phrasing of the same answer is harmless. The contract holds everywhere it matters. The model lives in the one place the contract was never required.
That is a design choice. It is not an AI choice. It is the same choice an engineer makes when deciding which part of the system gets to be slow. The slow part goes where nobody is waiting on it. The part that changes its mind goes where nobody needs it to match.
The wrapper is still calling again.