Lesson 25 of 30
Trying a prompt a few times and eyeballing whether it looks right isn't an evaluation — it's a demo. Non-deterministic systems need a systematic, repeatable eval to actually know whether a change made things better or worse.
12 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
Question 1 of 3
A developer tries a new prompt three times, likes the results, and ships it. Why isn't this a real evaluation of the change?
Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
"I tried it a few times and it looked good" feels like validation, but it isn't one — it's a handful of anecdotes against a system that can behave differently on the exact same input from one call to the next. A change that looks fine on the three prompts you happened to try can still be quietly worse on the hundred prompt shapes you didn't try, and there's no way to know which without actually checking.
An eval (evaluation) is what checking systematically looks like: a fixed, repeatable set of test cases run against the system, each scored against some standard, so a change to a prompt, model, or pipeline can be compared against a baseline instead of judged by feel. Two common ways to score each case:
Running the same fixed set of cases after every meaningful change is what turns "I think this prompt change helped" into "this prompt change improved the eval score from X to Y on the same 40 cases as before" — a claim that's actually checkable.
// Rough sketch of an eval run — not this app's actual test harness
type EvalCase = { input: string; expectedContains?: string[] };
const cases: EvalCase[] = [
{ input: "Explain useState", expectedContains: ["closure", "re-render"] },
{ input: "Explain useEffect cleanup", expectedContains: ["unmount", "dependency"] },
// ...a fixed set, run identically before and after a prompt change
];
async function runEval(systemPrompt: string) {
let passed = 0;
for (const c of cases) {
const output = await callModel(systemPrompt, c.input);
const ok = c.expectedContains?.every((kw) => output.includes(kw)) ?? true;
if (ok) passed++;
// For open-ended cases with no fixed keyword to check for,
// an LLM-as-judge call would grade `output` against stated criteria instead.
}
return passed / cases.length;
}
Run this same set of cases against the current prompt and a candidate change, and the comparison is a real number, not a vibe. This is the same discipline this app's own anti-hallucination system prompts (lib/ai/prompts/tutor.ts, lib/ai/prompts/interview.ts) would need before any meaningful edit: a fixed set of test questions, run against both the old and new prompt, to check the change didn't quietly loosen the constraint against answering outside the given context.
"How would you know if a change to your prompt actually made things better?" is a real question that separates candidates who reach for a systematic eval (fixed cases, automated or LLM-as-judge scoring, a real before/after comparison) from those who'd just try it a few times and go with their gut.