How to Know Your AI Feature Actually Works: Evaluating LLM Outputs
Traditional software is deterministic: given the same input, you get the same output, and a test either passes or fails. Language models break that assumption. The same prompt can produce different wording each time, and "correct" is often a matter of degree — a summary can be accurate but miss the point, a classification can be defensible but not the one you wanted. So how do you know your AI feature works — and stays working when you change a prompt, swap a model, or tweak retrieval? You evaluate it, systematically. This is the discipline that separates teams shipping reliable AI features from teams shipping demos, and it's far less work than its reputation suggests.
Why "it looked good when I tried it" isn't enough
Manually eyeballing a few outputs is how every AI feature starts, and it's fine for the first hour. But it doesn't scale and it doesn't protect you. You'll change the prompt to fix one case and silently break three others — prompts are global; every edit touches every request. You'll upgrade the model and not notice quality dropped on one important category. You'll argue in review about whether the new version is better, with no evidence either way.
There's also a subtler trap: when you test your own feature, you type reasonable inputs. Users don't. The gap between "inputs I thought to try" and "inputs production delivers" is where AI features die, and evaluation is how you close it.
Step 1: Build an evaluation set
The foundation is a collection of real examples — inputs paired with what a good output looks like. This is the single most valuable asset in an LLM project; models and prompts come and go, but the eval set compounds.
- Use real inputs. Pull from actual usage (or realistic drafts if you haven't launched), not tidy hypotheticals. Real inputs are messier — typos, fragments, mixed languages, half-formed questions — and messiness is exactly what you need to test.
- Cover the hard cases. Include edge cases, ambiguous inputs, empty inputs, adversarial ones, and the categories you most care about getting right. A set of fifty where ten are genuinely difficult beats two hundred easy ones.
- Start small. Even 20–50 well-chosen examples are enormously useful — enough to catch most regressions and settle most "which prompt is better" debates. Grow the set over time, especially by adding every failure you find in production: yesterday's bug becomes tomorrow's regression test, and after six months the set is a written history of every lesson the feature has learned.
Store it as data in your repo — a JSON or CSV file is plenty — so it's versioned alongside the prompts it tests.
Step 2: Decide how to score
Different tasks need different scoring methods. Pick the lightest one that captures what matters, and don't be embarrassed by how simple it is.
- Exact / rule-based checks. When there's a right answer or a hard requirement, just assert it: is it valid JSON? does it contain the required fields? is the classification correct? is it under the length limit? does it avoid mentioning competitors? These are cheap, fast, and unambiguous — use them wherever you possibly can. A shocking amount of "LLM quality" reduces to rule-checkable properties.
- Reference comparison. For tasks with a known good answer, compare the output to a reference — exact match for structured tasks, similarity scoring for text.
- LLM-as-judge. For open-ended quality (helpfulness, tone, faithfulness), use a separate model call to score outputs against a rubric. It scales where humans can't and it's surprisingly effective — but treat the judge as a component that itself needs testing: calibrate it against human judgement on a sample first, keep the rubric specific ("does the answer cite the provided context?" beats "is it good?"), and know the documented biases — judges favour longer answers, confident phrasing, and outputs that resemble their own style.
- Human review. The gold standard for nuanced quality. Too slow for every change, but invaluable periodically, for calibrating your automated judges, and for the final call on user-facing tone.
Most real eval suites are a pyramid: many rule checks, some judge scores, occasional human passes.
Step 3: Measure what you actually care about
Define the specific qualities that matter for your feature and score each separately. Common ones:
- Correctness / faithfulness — is it accurate, and grounded in the provided context rather than hallucinated? (For RAG features, also score retrieval separately — did the right chunks even arrive? — because that's where most failures actually live.)
- Format — does it match the required structure?
- Relevance — does it address what was asked?
- Safety — does it avoid disallowed content and resist the adversarial cases in your set?
Tracking these individually tells you how a change helped or hurt, not just that an overall number moved. "The new prompt improved faithfulness but broke format on empty inputs" is actionable; "score went from 78 to 81" is not.
Step 4: Run evals on every change
Wire the evaluation set into your workflow so it runs whenever you edit a prompt, change a model, or adjust retrieval — before the change ships, not after. Compare scores side by side. This turns risky guesswork into something like normal engineering: changes that improve the numbers land, changes that regress get fixed or dropped, and nobody has to argue from vibes.
This is also what makes cost optimization safe. "Can we use the cheaper model?" stops being a leap of faith and becomes an afternoon's experiment with a numeric answer.
Step 5: Close the loop with production
Evaluation isn't a one-time gate. In production:
- Log inputs and outputs (respecting privacy — redact what you must) so you can see real behaviour, not remembered behaviour.
- Capture failure signals — thumbs-down, user corrections, retries, abandoned sessions — and review them regularly. Every confirmed failure goes into the eval set.
- Watch for drift. Providers update models under the same name; your quality can change without you deploying anything. A periodic scheduled eval run catches this quietly instead of via user complaints.
Don't over-engineer it
You don't need a platform, a dashboard, or a vendor to start. A folder of example inputs, a script that runs them through your feature, and a handful of assert statements will put you ahead of most teams shipping AI today. The discipline matters more than the tooling. Add sophistication only when the simple version stops answering your questions — open-source harnesses like promptfoo and Inspect exist for when that day comes.
Summary
Evaluating LLM outputs is what turns an AI demo into a dependable feature. Build a set of real examples (small is fine, real is mandatory), choose the lightest scoring that captures what matters — rules where possible, LLM-as-judge for nuance, humans for calibration — measure the specific qualities you care about separately, and run the evals on every change. Then keep feeding production failures back in, so the set grows sharper as your feature ages. You can't improve — or safely ship — what you don't measure.
Further reading
- Judging LLM-as-a-Judge (Zheng et al.) — the research grounding for model-graded evaluation, including its biases.
- promptfoo — a practical open-source eval harness when your script outgrows itself.
- Prompt engineering for production apps — the discipline evals make safe.
- Keeping LLM costs under control — the savings evals unlock.