Overview

A prompt is production code, so it needs an eval set, a metric, a regression run, and a promotion gate, the same way a function needs unit tests. Without them every prompt edit is a guess and every model upgrade is a coin flip. Build the eval set first and iterate on the prompt second. For whole-system evaluation beyond single prompts, see evaluation.

Build a fixed eval set from real inputs

Each case is an input the user might send plus the output a domain expert would accept. Start with real traffic samples; synthetic cases are fine to bootstrap but go stale. Add a case every time production fails. Keep adversarial and edge cases as their own slice so a regression is visible per slice.

{"id": "billing-001",
 "input": "I was charged twice for my October subscription.",
 "expected": {"label": "billing"}}

See golden-set for the split between a regression set that you tune against and a held-out gold set that audits.

Pick the metric that matches the success criterion

  • Exact or structured-field match: extraction, classification, JSON where some fields must be exact and others tolerant.
  • Execution: SQL or code generation; run the output and grade on whether it works.
  • LLM-as-judge: open-ended output graded against a rubric by a separate strong model. See llm-as-judge.
  • BLEU, ROUGE, BERTScore: translation and summarization only, noisy on small sets; add a human spot-check.

Most production prompts need two metrics: a strict one (does it parse?) and a semantic one (is it right?).

Run the set on every prompt or model change

Wire the run into CI on every pull request that touches a prompt, template, schema, or model ID, and block merge on a score drop. Pin the judge model and the judge prompt so scores stay comparable; a drifting judge invalidates the history.

Track scores with the prompt hash and model ID

Store timestamp, prompt hash, model ID, and score for every run. The history is what separates a model-upgrade regression from noise.

2026-09-01  prompt v3.b  claude-opus-4-8  0.91
2026-09-02  prompt v3.b  claude-opus-5-5  0.88   <- model change, same prompt

Promote only when the win is statistically real

Two scores of 0.87 and 0.89 on 100 cases usually are not distinguishable. Run both prompts on the same cases and sign-test the per-case wins, excluding ties. With 100 decisive cases the new prompt needs about 61 wins for p below 0.05 (two-sided); with 50 it needs 33. A 55-percent win rate on 100 cases is not enough. Judge scores are noisy: run the judge more than once and average.

Keep prompts and cases together

prompts/
  classifier.v3.prompt.md
  evals/
    classifier.v3.cases.json
    classifier.v3.runs.json

When the prompt schema changes, update the cases in the same commit so both share one git history. See prompt-templates.

Pitfalls

  • Judging by eye (“it looks right”). It is not reproducible and misses model-upgrade regressions.
  • Scoring only the new prompt. Re-run the production prompt on the same cases.
  • A set so small that variance swamps the signal. Grow it with every failure.
  • Tuning against the gold set. Once you tune on it, it stops auditing.