Non-determinism is the design problem nobody plans for
Ask a model the same question twice and you get two different answers. Most AI products are built as if that isn’t true, and it quietly breaks them.
Here’s an experiment worth running before you ship anything on top of a model: send it the exact same prompt ten times and read the ten answers side by side. They won’t match. Sometimes the difference is cosmetic: a reordered list, a synonym. Sometimes it’s substantive: a different recommendation, a fact present in one and absent in the next. This is not a bug you can file. It’s the nature of the thing. And an enormous amount of AI product design is quietly built on the assumption that it isn’t.
We inherited our instincts from deterministic software, where the same input yields the same output, always, and a test that passes once passes forever. Models don’t work like that. The same input yields a distribution of outputs, and where in that distribution any single call lands is not something you control.
Why this breaks products
The failure isn’t dramatic. It’s a slow erosion of trust, and it shows up in specific places:
- Demos that don’t reproduce. The magic run you showed the customer doesn’t happen on their first try, and now you look worse than if you’d never demoed.
- “Fixes” that were luck. You tweak a prompt, the bad output goes away, you ship. But it went away because you rolled the dice again, not because you fixed anything. It’s back next week.
- Evals that lie. You test a change once, it looks better, you conclude it is better. One sample of a distribution tells you almost nothing about the distribution.
Treating a single model call as ground truth is like judging a weighted die by one roll. You didn’t measure the die. You measured one throw.
Designing for a distribution instead
The teams that build reliable things on unreliable models share a habit: they stop pretending each call is deterministic and design around the spread.
- Sample, don’t trust. For anything that matters, call more than once and reconcile: take the majority, the highest-confidence, or a synthesized answer. One shot is a guess; several is a measurement.
- Evaluate on distributions. Run a change across many samples and compare the rates (how often it’s right, how often it fails), not a single before/after. A change that helps the average can still be worse where it counts.
- Constrain the output, not the vibes. Where correctness is binary, force structure (schemas, validators, retries on malformed results) so the variance you can’t remove at least can’t reach the user as garbage.
- Show your uncertainty honestly. When the model genuinely isn’t sure, a product that says so beats one that fabricates confidence and gets caught.
None of this makes the model deterministic. That’s the point. You’re not trying to. You’re building a reliable system out of an unreliable component, the way engineers have always built reliable systems out of unreliable parts. The mistake is designing as if the part were reliable, discovering it isn’t in production, and calling the model dumb. It isn’t dumb. It’s non-deterministic, and you built as if it weren’t.
I lead growth at a SaaS startup: inbound, outbound, and the software underneath both. Before that I ran growth at CleverX and built a content agency that worked with brands like Disney+ Hotstar and LG. I’m an AI nerd who lives inside LLMs and builds the tools most GTM teams still wait a quarter for.