World’s largest virtual agentic engineering & quality conference

WHENAUG 19-21
WHEREVirtual · Global
Register Now
AITestingAutomation

Testing Non-Deterministic AI Outputs: A Practical Guide

Testing non-deterministic AI outputs without exact-match assertions: determinism knobs, four assertion types, pass-rate sample sizes, metamorphic relations.

Author

Prince Dewani

Author

Author

Srinivasan Sekar

Reviewer

Last Updated on: August 9, 2026

Testing non-deterministic AI outputs replaces equality assertions with JSON schema checks, semantic similarity thresholds, and pass rates measured across repeated runs. Thinking Machines Lab sampled 1,000 completions from Qwen3-235B at temperature 0 and still produced 80 unique answers.[1]

This guide covers why one prompt returns different answers, what temperature and seed actually control, the four assertion shapes that replace exact match, how many runs a pass rate needs, metamorphic relations, golden sets, cross-version regression, and agent validation before production release.

Key Takeaways

  • Batch-size variance: Inference servers group your request with other traffic, and that changing batch size alters floating-point reduction order, which is why identical prompts diverge even at temperature 0.
  • Seed is best-effort: OpenAI documents seeded requests as mostly deterministic and warns that a system fingerprint change can shift output, so never build a test that assumes byte-identical responses.
  • Four assertion shapes: Replace string equality with schema checks, invariant properties, semantic similarity scores, and rubric judging, and route each claim to the cheapest shape that can verify it.
  • Pass-rate sample size: An 18-of-20 pass rate carries an exact binomial interval of 68.3% to 98.8%, and catching a 95% to 85% drop takes 53 samples.
  • Metamorphic relations: Assert that paraphrasing an input leaves the extracted answer unchanged, which tests correctness without ever writing down an expected response.
  • Distribution regression: Store the per-scenario pass rate and score spread as the baseline, then fail a build when the new mean falls below that interval instead of when a single string changes.

Why Do AI Models Give Different Answers to the Same Prompt?

AI models give different answers to the same prompt because inference servers batch requests together, and the batch size changes the order in which floating-point values are summed inside the model. That reordering shifts token probabilities enough to flip a choice.

Thinking Machines Lab traced this behavior directly. Sampling 1,000 completions from Qwen3-235B at temperature 0 with a single fixed prompt produced 80 distinct completions, and the most common one appeared 78 times. The completions stayed identical until token 103, where 992 of them continued with "Queens, New York" and 8 continued with "New York City".[1]

Your prompt is identical on every run, but the other users' requests batched alongside it are not, so the source of variation sits outside your code and outside your control. Three separate sources stack:

  • Sampling randomness: Temperature and top-p draw the next token from a probability distribution, so wording and structure shift between runs even on a stable server.
  • Batch-size dependence: Reduction kernels for operations like RMSNorm and attention are not batch-invariant, so the same input under a different server load produces different logits.
  • Provider-side changes: Model weights and serving configuration change on the provider's schedule, which moves output without any deploy on your side.
Diagram of batch-size non-determinism showing one identical prompt sent three times landing in three server batches under light, medium and heavy load, where non-batch-invariant RMSNorm and attention reduction kernels sum floating-point values in a different order and produce different logits, so the completions stay identical until token 103 and then split into 992 continuing with Queens, New York and 8 continuing with New York City

Only the first source is yours to configure. A test suite written as though sampling is the whole problem will pass in development and fail under production load, because production is exactly where batch composition varies most.

Does Setting Temperature to 0 Make an LLM Deterministic?

No. Temperature 0 forces greedy decoding, so the model always takes the highest-probability token, but it leaves the batching and kernel behavior underneath untouched. Greedy decoding narrows variance without removing it, and a fixed seed adds nothing at temperature 0, because greedy decoding makes no sampling draw for the seed to control.

OpenAI states the position plainly in its API documentation: Chat Completions are "non-deterministic by default", and a seeded request returns output that is only "(mostly) deterministic".[2] The same documentation ties reproducibility to a system fingerprint that tracks model weights and infrastructure configuration, and it changes when the provider updates either.

The measured cost of assuming otherwise is large. Researchers at Penn State University and Comcast AI Technologies ran five models across eight benchmark tasks at temperature 0 with fixed seeds, and recorded accuracy variations up to 15% across runs, with a gap between best and worst possible performance reaching 70%.[3]

KnobWhat it controlsWhat it leaves untouched
Temperature 0Token selection becomes greedy, removing sampling randomness.Batch-size effects on logits, provider updates, tool-call ordering.
Fixed seedThe sampling draw when temperature is above 0.Everything at temperature 0, where no sampling draw happens.
Top-p and top-kThe size of the candidate token pool.Which candidate wins once the pool is set.
Pinned model versionSilent weight changes between releases.Serving infrastructure changes within the same version.

Set temperature to 0 and pin the model version anyway. Both narrow the distribution you have to test against.

Why Do Exact-Match Assertions Fail on AI Output?

Exact-match assertions fail because one question has many correct answers. "Paris", "Paris is the capital of France", and "The capital of France is Paris" are all correct, and a string equality check accepts exactly one of them. Each valid phrasing the model can produce lowers the odds that one expected string matches, so the suite decays as prompts evolve.

This is the test oracle problem. A conventional assertion needs an oracle, meaning a reliable way to decide whether a specific output is correct. Generative systems break that assumption because the correct output cannot be enumerated in advance, so a red test tells you the string changed and nothing about whether the behavior broke.

A script written for this article sent one prompt to gemini-2.5-pro 20 times at temperature 0 and compared each response against the first. The exact-match assertion passed 5 of the 20 runs, and the five distinct strings differed only in wording. Every response was a correct definition, so this run tested exact match on correct output only. The result covers one prompt, one model, and one provider.

Terminal output from nondet.mjs showing model gemini-2.5-pro, the prompt In one sentence what does a load balancer do, config temperature=0 topP=1 candidateCount=1, and 20 API calls made with 20 successful and 0 errors. Five unique output strings appear across the 20 runs with counts of 5, 5, 5, 4 and 1, differing only in wording such as multiple servers versus a group of backend servers and becomes overwhelmed versus is overwhelmed. Per-run status lists runs 1, 4, 14, 17 and 19 as exact=MATCH and the remaining 15 runs as exact=DIFF, with semantic=PASS on every run. The result block reads exact-match assertion against run 1 at 5 of 20 pass, and semantic assertion of 3 concepts at 20 of 20 pass

The failure is expensive in both directions. False failures train the team to rerun the suite until it passes, which destroys the signal. False passes are worse: an assertion that checks only for the substring "Paris" also passes on "Paris is not the capital of France".

Two rules follow. Assert on properties the answer must hold rather than on the text it happens to use, and keep every deterministic check that still applies. Response schema, status codes, latency bounds, required fields, and banned patterns are all still exactly assertable, and they should stay as strict as they were before the model arrived.

What Assertion Types Work for Testing Non-Deterministic AI Outputs?

Four assertion types work on non-deterministic AI output: structural checks on shape, invariant properties that must always hold, semantic similarity against a reference, and rubric scoring by a judge model. Each costs more than the one before it. Structural checks run locally with no model call, while rubric scoring adds an extra inference to every assertion.

Assertion typeWhat it verifiesWhere it breaks
StructuralValid JSON, required fields, enum membership, length and format bounds.Passes on well-formed output that is factually wrong.
InvariantRules that hold for every input, such as a refund never exceeding the order total.Only covers what you thought to forbid in advance.
Semantic similarityWhether the meaning matches a reference answer, scored by embedding distance.Scores negation and small factual edits as near-identical.
Rubric scoringSubjective dimensions like faithfulness, tone, and completeness.The judge is itself non-deterministic and carries its own biases.

Route each claim to the cheapest type that can actually verify it. Sending a JSON schema check to a judge model spends tokens and adds variance on a problem that a Pydantic model answers instantly and identically every time. Reserve rubric scoring for claims that genuinely need semantic judgment, and read LLM as a judge for the bias controls that keep those scores stable.

In the Reddit thread "You can't test the model, so I gave up and tested everything around it" on r/LLMDevs, the author replaced a hand-tuned instruction file with deterministic gates: a hook that typechecks every file write, and an allowlist that stops the agent before it pushes. The author closes by asking how to test the non-deterministic part itself.

How Many Runs Does It Take Before a Pass Rate Means Anything?

A pass rate needs enough runs that its confidence interval is narrower than the regression you want to catch. An 18-of-20 result looks like 90%, but its exact binomial interval at 95% confidence runs from 68.3% to 98.8%.[4] Precision improves with the square root of the run count, so doubling runs narrows that interval by far less than half.

That figure uses the exact binomial method, which the NIST Engineering Statistics Handbook specifies for proportions measured on small samples. A range that wide cannot separate a healthy suite from a badly degraded one, so a short gate reporting a high pass rate tells you almost nothing.

Bar chart of the width of the 95 percent Clopper-Pearson exact binomial confidence interval at a constant 90 percent observed pass rate, narrowing from 30.46 percentage points at 18 of 20 runs, to 20.87 percentage points at 36 of 40 runs, to 14.34 percentage points at 72 of 80 runs, with each doubling of runs narrowing the interval by 31.5 percent and then 31.3 percent instead of the 50 percent a halving would require

Small run counts also hide common defects. The same binomial model says a failure mode firing on 8% of requests survives a 5-run gate whenever all 5 runs pass, and 0.92 to the fifth power is 65.9%.[4] The defect clears the gate on roughly two attempts out of three, then reaches production as an intermittent complaint nobody can reproduce.

Work backwards from the regression size that matters to you. Applying the NIST sample-size formula for proportions at 95% confidence and 80% power, detecting a drop from a 95% baseline to 85% needs 53 samples.[5] Halve the difference you want to catch and the requirement roughly quadruples, which is the arithmetic that decides your suite size.

  • Smoke gate: Run 5 to 10 repetitions on a handful of critical scenarios for per-commit feedback, and accept that it catches only gross breakage.
  • Release gate: Run 55 or more scenarios once each before a release, which buys statistical power through breadth instead of repetition.
  • Stability probe: Repeat one scenario 100 times when you specifically need to measure variance for that prompt, such as after a model version change.

Breadth beats repetition for most suites. One hundred different scenarios run once exercises far more of the input space than one scenario run 100 times, and it costs the same in tokens. Repeat a single prompt only when the variance of that specific prompt is the thing under test.

In the Reddit thread "Verifying non-deterministic generative UI in CI" on r/LLMDevs, the author reported that generated interfaces change on every render, so pixel-diff tools fail. Their harness samples N generations, renders each in headless Chromium, and scores data fidelity, accessibility, and layout, then reports consistency as the standard deviation of those scores. The practical takeaway is that spread across runs is itself worth gating on.

Note

Note: Run your AI test suites across 3,000+ browser and OS combinations on TestMu AI. Try free!

What Is Metamorphic Testing, and When Does It Beat a Golden Set?

Metamorphic testing checks that a required relation holds between the outputs of two related inputs, so it needs no expected answer at all. It beats a golden set whenever the correct output cannot be written down in advance. The relation itself is the assertion, which is why it scales to inputs that have no reference answer.

A systematic survey by Zheng Zheng and colleagues describes the technique as oracle-alleviating, because it checks necessary relations among multiple related executions instead of relying on exact expected outputs.[6] Their worked example is sentiment analysis: replacing a word with a synonym, so "The movie is good" becomes "The movie is excellent", must not change the predicted label.

Metamorphic relations are the cheapest way to generate large numbers of valid test cases, because each one turns a single labeled input into an unlimited supply of derived checks. Four relations transfer directly to a retrieval or support application:

  • Paraphrase invariance: Rewording a question must not change the extracted fact, so "When does my plan renew?" and "What is my renewal date?" must return the same date.
  • Negation inversion: Negating the input must flip a classification label, which catches the exact failure that embedding similarity scores as a near-match.
  • Irrelevant-context invariance: Appending an unrelated sentence to the prompt must not change the answer, which exposes prompt-injection sensitivity and context dilution.
  • Order invariance: Shuffling retrieved documents or list items must not change the conclusion, which catches position bias in the retrieval layer.

The relations complement a golden set rather than replacing it. A golden set proves the system gets specific known cases right, and metamorphic relations prove it stays self-consistent across inputs nobody labeled, which is where regressions usually hide. For broader coverage of scoring methods, LLM evaluation maps the metric families these relations feed into.

How Do You Build a Golden Set for Testing Non-Deterministic AI Outputs?

A golden set is a fixed collection of inputs paired with human-approved acceptance criteria rather than exact expected strings. Start with 25 to 50 labeled cases, then grow the set from real production failures. Criteria do not catch a regression nobody anticipated, so the set only covers failure modes someone has already written down.

The design decision that makes a golden set survive is storing criteria instead of answers. An expected-string record breaks on the first harmless rewording, while a criteria record keeps working across model versions because it encodes what correctness means for that input.

  • Required facts: The specific values the answer must contain, such as a policy number or a cancellation deadline, checked by substring or extraction.
  • Forbidden claims: Statements the answer must never make, such as promising a refund the policy does not allow, checked by pattern or judge.
  • Structural requirements: Field presence, value ranges, and format rules that a schema validator can settle without a model.
  • Reference answer: One human-written correct response used only as the anchor for semantic similarity scoring, never as an equality target.
  • Provenance note: Where the case came from, because cases harvested from production incidents deserve stricter thresholds than synthetic ones.

Keep the set small enough to run often. Scaling past 100 cases before the thresholds are calibrated produces a suite that is expensive to run and still unable to say whether a change made things better. Every production failure that reaches a user should end its life as a new record in this file.

How Do You Catch Regressions When the Output Changes Every Run?

Compare distributions instead of single runs. Record the pass rate and score spread for every scenario on each build, then fail the pipeline when the new mean drops below the stored baseline interval. A build whose wording changed on every scenario but whose pass rate held has not regressed.

A single red response is not a regression signal on a system that samples from a distribution. The measurable signal is a shift in the distribution, and it takes two forms: the mean pass rate drops, or the spread widens while the mean holds steady.

The second form is the one teams miss. An unchanged average with a doubled standard deviation means the system now fails harder on the runs where it fails.

# Gate a build on the distribution, not on one response.
import statistics

BASELINE_PASS_RATE = 0.94
BASELINE_STDDEV = 0.06
MIN_RUNS = 30

def gate(scores, threshold=0.75):
    """scores: one similarity or rubric score per scenario run."""
    if len(scores) < MIN_RUNS:
        raise SystemExit(f"Need {MIN_RUNS} runs, got {len(scores)}")

    pass_rate = sum(s >= threshold for s in scores) / len(scores)
    spread = statistics.pstdev(scores)

    # Wilson-style margin: allow normal sampling noise, block real drops.
    margin = 1.96 * (BASELINE_PASS_RATE * (1 - BASELINE_PASS_RATE) / len(scores)) ** 0.5

    if pass_rate < BASELINE_PASS_RATE - margin:
        raise SystemExit(f"Pass rate {pass_rate:.2%} below baseline")
    if spread > BASELINE_STDDEV * 2:
        raise SystemExit(f"Score spread {spread:.3f} doubled; output destabilized")

    print(f"OK pass_rate={pass_rate:.2%} spread={spread:.3f}")

Store results per scenario rather than as one aggregate. An aggregate score hides the case where two scenarios improve while one collapses, and per-scenario history makes a regression traceable to the prompt that caused it. Re-baseline deliberately after a model upgrade, and record the old numbers so the comparison stays honest.

Sampling several responses and taking the majority answer also raises accuracy on reasoning tasks. Wang and colleagues reported that self-consistency, which samples diverse reasoning paths and selects the most consistent answer, improved GSM8K accuracy by 17.9%.[7] The same aggregation that stabilizes a test also stabilizes production behavior.

For the wider tooling picture, LLM testing covers the frameworks these gates plug into, and LLM test automation shows the pipeline wiring with code.

How Do You Validate a Non-Deterministic Agent Before It Ships?

Run the agent through many scenario variants, score each on fixed quality dimensions, and require a confidence level tied to scenario volume before approving the release. A verdict from 10 scenarios is not the same evidence as a verdict from 200.

Multi-turn agents make the sample-size problem worse. A five-turn conversation can score well on every individual response and still fail overall because the agent lost context between turns, so per-response scoring misses the defect entirely. Building that scenario volume by hand is where most teams stall, because writing 100 conversational variants and grading them consistently is slow manual work.

TestMu AI provides Agent Testing, which generates the scenarios and scores the transcripts against fixed dimensions:

  • Response Consistency: Measures information uniformity across repeated calls that run the same scenario, which is the direct measurement of the variance this guide is about.
  • Evaluation Confidence Scoring: Labels each metric High, Medium, or Low based on scenario volume, so a passing score from too few scenarios is marked as indicative rather than decisive.
  • Hallucination Detection: Flags responses that state information the agent's knowledge base and context do not support, scored per scenario and aggregated across the run.

Scenario generation produces 60 to 100 or more variants per workflow from uploaded documentation, and each runs as a full multi-turn conversation rather than a single exchange. You can follow the getting started with agent testing platform guide to connect an agent and read the go-live report.

Non-determinism shows up at every stage of a testing pipeline, not only at the model boundary. TestMu AI runs a set of purpose-built AI agents across those stages, including Agent Testing for conversational quality, an Auto Healing Agent for element drift, a Test Insights Agent for result analysis, and a Root Cause Analysis Agent for failure triage.

The metric definitions behind agent evaluation scores are set out in AI agent evaluation.

Validate Non-Deterministic Agent Behavior Before Release

Conclusion

Start by writing down the acceptance criteria for 25 scenarios your application must handle, then pick the cheapest assertion type that can verify each one. Set temperature to 0, pin the model version, and treat the remaining variance as a property to measure rather than a bug to eliminate.

Testing non-deterministic AI outputs comes down to one shift: the assertion moves from the response to the distribution behind it. Pass rates, tolerance bands, and metamorphic relations all answer the question a release actually turns on, which is whether behavior changed since the last build.

Teams planning a broader skills path can follow the AI roadmap for software testers, which places these techniques alongside the rest of the AI testing stack.

Test infrastructure that does not break, from TestMu AI

Author

...

Prince Dewani

Blogs: 15

  • Linkedin

Prince Dewani is a Community Contributor at TestMu AI specializing in AI agents, software testing, QA, and SEO. He is certified in Selenium, Cypress, Playwright, Appium, Automation Testing, and KaneAI, and presented academic research on AI agents at PBCON-01. At TestMu AI, he has also carried out extensive cross-browser research on the support of modern web technologies such as WebGPU, WebAssembly, WebXR, WebGL2 and other web technologies, validating their compatibility and feature parity across major browsers and rendering engines through rigorous hands-on testing. Prince has hands-on experience building AI agent workflows using Anthropic Claude, Google Antigravity, n8n, LangChain, and other agentic frameworks, and works regularly with MCP and A2A protocols. He shares his work with 5,500+ QA engineers, developers, DevOps experts, tech leaders, and AI agent practitioners on LinkedIn.

Reviewer

...

Srinivasan Sekar

Reviewer

  • Linkedin

Srinivasan Sekar is Director of Engineering at TestMu AI (formerly LambdaTest), where he leads engineering and open-source initiatives behind the Selenium and Appium automation grid and owns TestMu AI's MCP Server. A committer to Appium and a contributor to Selenium, WebdriverIO, Taiko, and AppiumTestDistribution, he brings over 15 years of experience in quality engineering and open-source technologies. He is the author of the Apress book 'The MCP Standard: A Developer's Guide to Building Universal AI Tools with the Model Context Protocol,' a Certified Kubernetes and Cloud Native Associate, and an international conference speaker. Before TestMu AI he spent over eight years at Thoughtworks as a Principal Consultant and Quality Architect. Srinivasan holds a B.Tech in Information Technology from Anna University.

Open in ChatGPT Icon

Open in ChatGPT

Open in Claude Icon

Open in Claude

Open in Perplexity Icon

Open in Perplexity

Open in Grok Icon

Open in Grok

Open in Gemini AI Icon

Open in Gemini AI

Copied to Clipboard!
...

3000+ Browsers. One Platform.

See exactly how your site performs everywhere.

Try it free
...

Write Tests in Plain English with KaneAI

Create, debug, and evolve tests using natural language.

Try for free
...
TestMu Conf 2026

World's largest virtual agentic engineering & quality conference

...

AUG 19-21, 2026

REGISTER NOW

Non-Deterministic AI Output Testing FAQs

Did you find this page helpful?

More Related Blogs

TestMu AI forEnterprise

Get access to solutions built on Enterprise
grade security, privacy, & compliance

  • Advanced access controls
  • Advanced data retention rules
  • Advanced Local Testing
  • Premium Support options
  • Early access to beta features
  • Private Slack Channel
  • Unlimited Manual Accessibility DevTools Tests