Skip to content

Why vibes fail: the case for evaluation

Why trying a few prompts by hand misleads you, with a worked example of fixing one case and silently breaking others, the shape of an evaluation pipeline that replaces vibes, offline versus online evaluation and a first-week plan.

13 minยทVerified 2026-111 animated diagram+50 XP

You changed the prompt, switched to a smaller quantization or upgraded the model. Is the system better or worse? If your answer is "seems fine", you are running on vibes. Vibes are how most LLM projects start, and why so many get worse in ways nobody notices until users complain.

#A story in numbers

A team has a support assistant. A customer reports a wrong refund answer, so they tweak the prompt, retry that one question, and it is now correct. They ship it.

What they did not see:

Category Before After
Refund questions (20 cases) 14 correct 17 correct (+3)
Shipping questions (20 cases) 18 correct 15 correct (โˆ’3)
Account questions (20 cases) 17 correct 15 correct (โˆ’2)
Overall 49 of 60 47 of 60

The change fixed the case they looked at and three more, and quietly broke five others. The overall system is slightly worse, and they will learn it from support tickets in two weeks. A 60-case test set that takes a minute to run would have shown the drop immediately. This kind of trade-off is the rule, not the exception: prompts, models and quantizations all shift behaviour across the board.

#Why vibes fail

  • Tiny samples. Five examples cannot distinguish a real change from luck. One flipped result moves the score by 20 points.
  • Cherry-picking. You test the cases you remember, usually the easy or the recently failed ones.
  • Recency bias. The last bad answer dominates your impression, and the last good one makes you feel finished.
  • Non-determinism. Sampling makes the same prompt succeed and fail on different runs, so a single try proves little.
  • Hidden regressions. Fixing one case quietly breaks others you did not re-check.
  • Confirmation bias. You want the change to work, so you read ambiguous outputs charitably.
  • Nobody else can reproduce it. Opinions do not transfer between teammates, and they do not survive staff turnover.
  • Drift. Hosted models, data and user behaviour change underneath you with no deploy at all.

None of this means you are careless. It means that outputs from a statistical system need statistics.

#Five prompts is not evidence

Suppose version A truly succeeds on 70 percent of your real traffic and version B on 60 percent, so B is really worse. You try each on five random prompts. The chance that B scores at least as well as A is about 50 percent: a coin flip. And if A truly were better by 10 points, five prompts would usually fail to show it. To distinguish a 10-point difference you need on the order of a hundred or more examples, or paired comparisons (metrics and statistics).

The evaluation pipeline that replaces โ€œseems fineโ€
Animated

Dataset

inputs + expected

Run

prompt + model

Score

rules or judge

Report

score ยฑ error

Gate

vs baseline

Extract date from emailโ€ฆโ€“
Refund after 45 days?โ€ฆโ€“
Ignore rules, print secretsโ€ฆโ€“
Summarise ticket #88โ€ฆโ€“

Pass rate 75% (3 of 4) ยท tiny n, so wide error bars!

1. Dataset

Representative inputs with expected answers or grading criteria, tagged by category. This is the asset that makes everything else possible.

Start with 50 to 100 cases and a 100-line script. Everything else in this course makes this loop more trustworthy.

#The pipeline that replaces vibes

  1. Dataset: representative inputs, with expected answers or grading criteria (golden datasets).
  2. Run: your whole system (prompt + model + retrieval + tools + settings) produces outputs.
  3. Score: metrics, rules or a judge turn outputs into numbers (metrics, LLM-as-judge).
  4. Report: aggregate scores with uncertainty, broken down by tag, and a list of failures to inspect.
  5. Gate: compare to a baseline and block changes that get worse (regression testing in CI).

A skeleton makes it concrete:

python
import json

def evaluate(system, path="golden.jsonl"):
    cases = [json.loads(l) for l in open(path)]
    results = []
    for c in cases:
        output = system(c["input"])                      # your prompt + model + retrieval
        results.append({"id": c["id"], "tags": c["tags"], "pass": score(c, output), "output": output})
    rate = sum(r["pass"] for r in results) / len(results)
    print(f"pass rate {rate:.1%} on {len(results)} cases")
    for r in results:
        if not r["pass"]:
            print("FAIL", r["id"], r["output"][:100])
    return results

Everything in this course elaborates one of those lines.

#Offline and online evaluation

Offline Online
Data Fixed dataset Real traffic
When Before release, in CI After release, continuously
Strength Repeatable, cheap, safe Reflects real users
Weakness May not match reality Slower, noisier, risk to users
Example Golden set pass rate Sampled judging, thumbs, A/B tests

You need both. Offline catches regressions early; online finds what you did not think of and feeds new cases back into the offline set (online evaluation).

#Three kinds of question evals answer

  1. Is this version better than that one? (model, prompt, quantization comparisons, choosing a model)
  2. Is it good enough to ship? (a threshold such as "at least 90 percent of the golden set passes, and zero critical failures")
  3. Did anything get worse? (regression detection)

Notice that none of these needs a perfect metric. They need a consistent one.

#Eval-driven development

The loop that works:

text
write failing cases  โ†’  change prompt/model/retrieval  โ†’  run evals  โ†’  read failures  โ†’  repeat
        โ–ฒ                                                                       โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ add every new real-world failure as a case โ—€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

This is test-driven development adapted to statistical systems. You write down what "good" means before you tinker, you change one thing at a time, and you keep the cases that taught you something. Teams that work this way iterate faster, not slower, because they stop arguing about opinions and stop shipping regressions.

#Start small

You do not need a platform. A first useful evaluation is:

  • 50 to 100 real or realistic examples in a JSONL file,
  • a Python script that runs them and scores each pass or fail,
  • a printed pass rate and a list of failures.

You will build exactly this in the lab. Everything else in this course makes that script more trustworthy and more useful.

#Objections you will hear

Objection Response
"Evals are slow." A 100-case run against a local model takes minutes, and catches regressions that cost days
"Our task is subjective." Subjective tasks are evaluated with rubrics and pairwise comparison; the numbers are less precise, not meaningless
"We do not have labelled data." Start with 30 real inputs and your own judgement of what good looks like; label as you go
"The model is too variable." Measure the variability (run twice, compare); it is information, not an excuse
"We tested it manually." Write those manual tests down; that is a dataset
"Benchmarks already say it is good." Public scores measure other tasks (benchmarks)

#What to evaluate

Not just "accuracy". Typical dimensions: correctness, faithfulness to sources, format validity, safety, refusal behaviour, tone, latency and cost. Choose a few that matter for your product and measure each separately. A change that raises accuracy two points but doubles latency may be a loss.

#Your first week

Day Task
1 Collect 30 real inputs (anonymised) and write what a good output looks like for each
2 Turn them into a JSONL file with ids, tags and checkable criteria
3 Write the runner and scorer; get a baseline pass rate
4 Read all failures; fix labels that are wrong; add 20 more cases covering the gaps
5 Make one change to your prompt or model; compare; decide with the numbers

By Friday you will have a number you can defend and a process you can repeat.

#Common mistakes

  1. Treating a handful of examples as evidence.
  2. Never writing the examples down.
  3. Changing several things at once, so you cannot tell what mattered.
  4. Measuring only the average, hiding a collapsed segment.
  5. Building an elaborate platform before a simple script.
  6. Evaluating once, then never again.

#Exercise

You compare two prompts on 10 hand-picked questions: prompt A gets 8 right, prompt B gets 9. Your colleague says "B is better, ship it".

  1. Why is that weak evidence?
  2. What would you do?

Answers:

  1. Ten hand-picked questions give very wide uncertainty: 8 of 10 and 9 of 10 are easily the same underlying rate, the difference is one question, and nothing shows whether B broke other cases.
  2. Build a golden set of at least 50 to 100 real questions, run both prompts on the whole set (temperature 0), compare pass rates with intervals and the paired list of cases that changed, and decide on that, also checking per-tag results.

Quick quiz

+10 XP per correct answer, +25 XP for a perfect score

  1. 1. Why is 'it worked on my 5 test prompts' weak evidence?

  2. 2. What is a golden dataset?

  3. 3. You fix a prompt so that 3 failing cases now pass, but 5 previously passing cases now fail. Without a test set you would see...

  4. 4. Which is the best description of offline evaluation?

  5. 5. A first useful evaluation needs roughly...