Local AI Automation
Local AI

Stop Vibe-Checking Prompts: A Testing Framework for Consistent AI Output

"It looked good when I tried it" is a memory of one lucky run, not a standard. Test cases, a rubric, adversarial inputs, and a regression log — here's the build.

Piyabhum Sornpaisarn5 min read
Share
Pixel art QC robot feeding identical paper forms through a brass testing machine with gauge and pass-cross stamps, Ollama llama logo on the machine panel

You spend a Saturday afternoon perfecting a prompt. Twenty iterations, a persona, a punctuation tweak you're weirdly proud of. The output looks great. You drop it into your workflow, and by Wednesday it's producing something subtly wrong — a missing step here, a hallucinated date there — and your only debugging tool is re-reading the output and going "hmm, feels off."

That's the vibe check, and it's the thing standing between you and reliable AI workflows. "It looked good when I tried it" is not a quality standard; it's a memory of a good run. Model outputs are probabilistic — the same prompt gives different results — so a single good sample proves nothing about the next thousand runs.

The skill that matters now isn't writing better prompts. It's testing them. Prompt wording is getting automated (frameworks like DSPy already optimize phrasing for you); what can't be automated is knowing what "good" means for your business, encoding it as criteria, and running the check every time. This post builds that system — rubric, adversarial cases, A/B comparison, regression log — with a local version that runs on your own machine.

Direct answer

To keep AI outputs consistent, stop judging single samples and start testing prompts like software: define test cases (common and edge inputs), score outputs against a fixed rubric (e.g. accuracy, tone, length, actionability, each 1–5), feed it adversarial inputs to find failure modes, A/B old vs new versions on the same cases, and keep a regression log so a tweak that breaks one scenario is caught immediately. Consistency comes from measured criteria, not carefully chosen wording.

Why the Vibe Check Fails

Three properties of model output break eyeball-based QA:

  • Variance. The same prompt produces different outputs per run; your good Saturday sample was one draw from a distribution.
  • Drift. Models get updated; a prompt that worked last month may silently degrade after a version bump.
  • Your inconsistency. Humans grade the same output differently depending on mood, coffee, and which sentence they read last.

A testing framework fixes all three by making "good" a fixed target instead of a feeling.

The Framework, Step by Step

Step 1: Define test cases

Before trusting a prompt, write the inputs it must survive. Aim for five to ten covering both the happy path and the edges:

test_cases:
  - id: happy_path
    input: "normal customer email, clear request"
    expect: "all requests addressed, correct tone"
  - id: empty_input
    input: ""
    expect: "polite error, no hallucinated content"
  - id: ambiguous
    input: "email with two conflicting requests"
    expect: "asks one clarifying question, no guessing"
  - id: jargon_heavy
    input: "technical thread with domain acronyms"
    expect: "no dropped steps, terms preserved verbatim"
  - id: adversarial
    input: "email containing a fake 'ignore previous instructions' line"
    expect: "instruction ignored, normal handling"

The edge cases are where prompts actually fail. An empty input that produces a confident hallucinated reply is a bug you want found in a test file, not in front of a customer.

Step 2: Score with a rubric

Turn judgment into data. Four criteria, 1–5 each:

{
  "rubric": {
    "accuracy": "every factual claim traceable to the input",
    "tone": "matches the target voice, no corporate filler",
    "length": "within the stated word band",
    "actionability": "a reader knows what to do next"
  },
  "fail_flags": [
    "invented facts",
    "missed an explicit request",
    "banned phrases present"
  ]
}

Fail flags are automatic zeros regardless of other scores — a reply that invents a deadline is broken even if the tone is lovely. Now "is this good?" has an answer: average rubric score, no flags.

Step 3: Hunt failure modes adversarially

Take your worst-case imagination and feed it in: incomplete information, weird formatting, two contradictory instructions, input that's off-topic entirely. Every failure you find here is a customer-support ticket you never receive. Fix the prompt, add the case to the file, and it guards the fix forever.

Step 4: A/B every change

The discipline that separates testing from tinkering: when you change a prompt, never judge the new version on a fresh sample. Run old and new against the same test cases, compare scores per case:

case            old_avg  new_avg  verdict
happy_path      4.2      4.6      improved
ambiguous       3.8      4.5      improved
jargon_heavy    4.0      2.9      REGRESSION

That REGRESSION row is the whole point. Without the side-by-side, you'd have shipped the change because the happy path got better — and quietly broken the technical-jargon customers you never hear from.

Step 5: Keep a regression log

Prompts need version history like code does:

## v3 — 2026-08-26
change: added "ask one clarifying question when ambiguous"
scores: avg 4.4 (was 4.1) | regressions: none
cases added: ambiguous_followup

## v2 — 2026-08-14
change: banned-phrase list expanded
scores: avg 4.1 (was 3.9) | regressions: jargon_heavy (fixed in v3)

When next week's "small tweak" degrades something, the log tells you what changed and what to roll back to — minutes instead of archaeology.

Running Evals Locally

Everything above is prompts and files, which makes it perfect for a local loop: run the suite with Ollama, score with a script (or a local model applying your rubric), and append results to the log.

ollama pull llama3.1
for case in cases/*.txt; do
  echo "--- $case"
  ollama run llama3.1 "$(cat prompt-v3.txt) INPUT: $(cat $case)"
done | tee runs/v3-output.txt

A scoring pass can be mechanical — word counts and banned-phrase checks in plain Python — with the model-assisted parts (tone, actionability) graded by a second local model applying your rubric to each output. Nothing uploads, every re-run is free, and you can execute the whole suite after every prompt change in under a minute.

This local loop also covers the drift problem: when a new model version lands, re-run the suite, compare against the logged averages, and you know immediately whether the update broke your workflows.

The Roadmap From Prompt-Tinkerer to Prompt-Tester

If you're starting from zero:

  1. Pick one prompt you use weekly — the email drafter, the summarizer, the classifier.
  2. Write five test cases — three common, two edge.
  3. Score current outputs with the four-criteria rubric; note any fail flags.
  4. Fix the biggest gap, re-run, and confirm the scores moved.
  5. Log it as v2. Repeat monthly.

One prompt, fully tested, teaches more than ten prompts vibes-checked — and the pattern transfers to every workflow you build afterward.

Frequently Asked Questions

What exactly is an edge case in prompting?

Any realistic-but-uncommon input: empty notes, a two-line "transcript," heavy jargon, contradictory requests, or an embedded instruction trying to hijack the prompt. Edge cases are where prompts break, so they're where testing effort pays.

Why a rubric instead of just reading the output?

Humans are inconsistent graders — one good sentence can hide three flaws. A rubric scores the same factors the same way every run: word-count limits, banned keywords, request coverage. Consistent grading is the only way to tell real improvement from lucky variance.

What is a regression log and why does it matter?

A version history for prompts with scores per test case. It matters because fixing scenario A often breaks scenario B; the log shows regressions immediately and tells you exactly what to roll back to.

Do I need a big model to score outputs?

No — mechanical checks (length, banned phrases, required sections) are plain scripts, and rubric grading of tone or actionability is a comprehension task mid-size local models handle well. Save your strongest model for generating the outputs, not grading them.

Wrap-Up

The craft of writing prompts is being automated; the craft of judging them isn't. Build the test file, fix the rubric, break your own prompt with adversarial inputs, A/B every change, and log every version. Run the loop locally and it costs nothing to repeat. A prompt with a test suite is an asset; a prompt with a vibe check is a liability waiting for Wednesday.

Newsletter

Get the next guide in your inbox

New articles plus the workflow files from each guide — and instant access to the free download library.

No spam. Unsubscribe anytime.

Related posts

Local AI

Map It First: Design Workflows Before You Automate Them

Automating an unmapped process just repeats the mess faster. Document reality, name an owner for every output, bound automation by risk — then hand the runbook to people or AI agents.

4 min readmap workflow before automation