A continuous evaluation pipeline treats every prompt or model change like a code change: it runs an automated eval suite in CI, compares pass rates against a baseline, and blocks the merge if quality regresses past a threshold. It closes the loop by feeding production failures back into the eval set, so the suite keeps pace with real usage.
Quick Answer: Wire your eval suite into CI so it runs on every PR touching a prompt, model version, or retrieval config. Gate the merge on a defined pass-rate threshold (e.g., no more than a 5-point drop from baseline), then run lighter-weight online evals post-deploy and route failures back into the offline test set.
Why Prompts Need CI/CD, Not Just a Vibe Check
Prompt changes behave like code changes but ship with fewer safety nets: a one-line edit to a system prompt can silently shift output quality across dozens of downstream use cases. Treating continuous evaluation LLM practices as a first-class engineering discipline — not a manual spot-check before launch — is what closes that gap.
Traditional software CI/CD works because tests are deterministic: same input, same expected output, pass or fail. LLM outputs are non-deterministic — the same prompt can produce different phrasing, different reasoning paths, occasionally different correctness, across runs. That doesn't mean testing is impossible; it means the test suite has to measure distributions and pass rates rather than exact-match assertions.
Google's ML Test Score framework, one of the earliest widely cited attempts to formalize ML production readiness, made a related point back in 2017: most ML system failures come from data and pipeline issues, not model architecture. The same logic applies to prompts — most regressions come from an untested edit interacting badly with an edge case, not a fundamentally broken idea.
What Breaks Without a Pipeline
Without continuous evaluation, teams typically discover regressions in one of three ways, all worse than a blocked PR:
- A user complaint surfaces a broken response days after a prompt tweak shipped.
- A dashboard metric drifts slowly enough that nobody notices until it's a trend, not a blip — the pattern covered in why quality drift doesn't throw a stack trace.
- An engineer "eyeballs" five examples, calls it good, and ships a change that breaks a segment those five examples didn't cover.
Each of these is a manual gate standing in for an automated one. The fix is structural, not cultural: make the eval suite the thing that has to pass, not a person's judgment call.
Designing the Eval Suite as Your CI Gate
A CI-ready eval suite needs three ingredients before it can gate anything: a representative test set, a scoring method per test, and a defined pass/fail threshold tied to a baseline. Skipping any one of these produces a suite that runs but doesn't actually protect you.
Building the Test Set
The test set should mirror production traffic, not just happy-path examples a developer wrote in five minutes. A reasonable composition:
- Golden examples — hand-curated inputs with verified correct outputs, covering your highest-value use cases.
- Edge cases — ambiguous inputs, adversarial phrasing, empty or malformed fields, and known historical failure modes.
- Regression cases — every past production bug, converted into a permanent test case so it can never silently reappear.
- Sampled production traffic — a rotating slice of real (anonymized) inputs, refreshed on a cadence, so the suite doesn't calcify around last quarter's usage patterns.
This is the same discipline behind closing the loop from failures to eval cases: every real failure becomes a permanent, automated check rather than a one-time fire drill.
Choosing Scoring Methods
| Scoring method | Best for | Cost/latency | Determinism |
|---|---|---|---|
| Exact match / regex | Structured outputs (JSON schema, classification labels) | Very low | Fully deterministic |
| Rule-based heuristics | Format checks, forbidden phrases, length bounds | Very low | Fully deterministic |
| Embedding similarity | Semantic closeness to a reference answer | Low-medium | Deterministic given fixed embeddings |
| LLM-as-judge | Open-ended quality, tone, reasoning correctness | Medium-high | Non-deterministic; needs its own calibration |
| Human review | High-stakes or ambiguous cases, judge calibration | High, slow | Ground truth, but not CI-speed |
Mixing tiers keeps the pipeline fast where it can be and rigorous where it must be. A common pattern: exact-match and rule-based checks run on every PR in seconds; LLM-as-judge runs on a sampled subset; human review happens periodically to recalibrate the judge itself, since an uncalibrated LLM judge can drift from human preference over time — a risk documented in work like Zheng et al.'s "Judging LLM-as-a-Judge" study on judge bias and consistency.
Setting the Threshold
Anthropic's own guidance on building effective agents emphasizes starting simple and measuring before adding complexity — the same applies to thresholds. Start with a baseline pass rate measured on the current production prompt, then define an acceptable drop, commonly 3-5 percentage points, before a change is blocked. Too tight a threshold blocks noise; too loose a threshold lets real regressions through.
Pipeline Stages: From PR to Production
A continuous evaluation pipeline has three distinct stages, each with a different speed/rigor trade-off: fast automated checks at PR time, a stricter gate before merge, and lighter continuous checks after deploy. Understanding which stage catches which failure mode is what makes the pipeline effective rather than just present.
Stage 1 — Eval on PR
Every pull request that touches a prompt template, system message, model version, temperature setting, or retrieval configuration triggers the eval suite automatically. This mirrors how a code CI pipeline runs unit tests on every push — the trigger condition is the file path, not a human deciding to run it.
- Run the fast, deterministic checks (exact-match, rule-based) on the full test set.
- Run the sampled LLM-as-judge checks on a representative subset to control cost and latency.
- Post the results as a PR comment or check status, visible before anyone reviews the code.
Stage 2 — Threshold Gates Before Merge
This is the actual gate: a required CI check that fails the build if the new pass rate drops below the baseline minus the allowed margin. It should behave exactly like a failing unit test — it blocks the merge button, not just a warning in a Slack channel.
name: Prompt Evaluation Gate
on:
pull_request:
paths:
- "prompts/**"
- "config/model.yaml"
jobs:
eval-gate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run eval suite
run: python run_evals.py --output results.json
- name: Compare against baseline
run: |
python compare_baseline.py \
--current results.json \
--baseline baseline_scores.json \
--max-drop 5.0
# compare_baseline.py exits non-zero if pass_rate
# drops more than 5.0 points versus baseline,
# failing this step and blocking the merge.
The --max-drop 5.0 argument is the whole point: a 5-point pass-rate drop fails the job, GitHub marks the check red, and branch protection rules stop the merge — the same mechanism that blocks a PR with a failing unit test, applied to non-deterministic behavior.
Stage 3 — Online Eval Post-Deploy
Offline evals can't cover every input a live system will see, so a lighter-weight online eval runs continuously against production traffic after deploy. This typically samples a percentage of real requests, scores them asynchronously (so it doesn't add latency to the user-facing response), and feeds results into the same dashboards used for the three dashboards every AI product needs on day one.
- Sample 1-5% of production traffic for judge-scored review.
- Track pass rate as a rolling metric, not just a point-in-time number.
- Alert when the rolling pass rate crosses the same threshold used at merge time — consistency between offline and online gates prevents "it passed CI but broke in prod" confusion.
The Flywheel: Feeding Production Back Into Eval
The pipeline is only as good as its test set is current, and the test set only stays current if production failures automatically become new eval cases. This flywheel — production traffic informing eval design, eval design catching regressions before they reach production — is what separates a one-time eval script from a durable quality system.
Closing the Loop Mechanically
- Capture — every flagged or low-scoring production response gets logged with its input, output, and context.
- Triage — a human (or a structured review step) confirms which flagged cases are genuine failures versus false positives from an overly strict judge.
- Convert — confirmed failures become new golden or regression test cases, added to the offline suite with the correct expected behavior annotated.
- Re-baseline — as the test set grows, periodically re-measure the baseline pass rate so thresholds stay meaningful rather than drifting against a stale reference.
This mirrors how mature engineering teams handle production incidents: a bug becomes a regression test, permanently, so the exact same failure can never silently reappear. Applied to prompts, it's the difference between a static eval set that slowly loses relevance and one that compounds in value with every production cycle.
Where This Connects to Broader LLMOps Practice
Continuous evaluation is one piece of a larger discipline — see the complete guide to LLMOps and observability for how eval pipelines fit alongside tracing, cost monitoring, and drift detection. It's also worth grounding eval design in how real users actually engage with the product: frameworks like jobs to be done and mapping the customer journey help identify which use cases deserve golden test coverage in the first place, since not every possible input is equally worth protecting.
Designing Your Eval Suite in Prodinja
The eval suite you design there is meant to be the gate this pipeline runs on every prompt or model change before it merges — the design work and the CI enforcement are two halves of the same practice, not separate efforts. As a prototype experience, it's designed to walk you through structuring that thinking; it doesn't execute live model calls or produce real scores itself.
Key Takeaways
- Treat prompts like code: every change to a prompt, model version, or retrieval config should trigger an automated eval suite in CI, not a manual spot-check.
- Mix scoring methods — exact-match and rule-based checks for speed,
LLM-as-judgefor open-ended quality, periodic human review to keep the judge calibrated. - Set a concrete threshold, commonly a 3-5 point allowed pass-rate drop from baseline, and enforce it as a required, blocking CI check.
- Run three pipeline stages: eval on PR for fast feedback, a threshold gate before merge, and online eval sampling production traffic after deploy.
- Build the flywheel: capture production failures, triage them, convert confirmed ones into permanent regression test cases, and periodically re-baseline.
- Refresh the test set regularly with sampled production traffic so the suite doesn't calcify around outdated usage patterns.
Frequently Asked Questions
What is continuous evaluation for LLMs?
Continuous evaluation is the practice of automatically running a defined test suite against every change to a prompt, model, or retrieval configuration, comparing results to a baseline, and blocking deployment if quality regresses beyond a set threshold — the same discipline as CI testing, applied to non-deterministic outputs.
How is CI/CD for prompts different from CI/CD for code?
The core mechanics — trigger on change, run tests, gate the merge — are identical. The difference is in the tests themselves: prompt evals measure pass rates and distributions across a scored test set rather than deterministic pass/fail assertions, since the same input can produce varying but still-correct outputs.
What should trigger an automated eval pipeline run?
Any pull request touching a prompt template, system message, model version, temperature or sampling setting, or retrieval/context configuration should trigger the suite automatically, scoped by file path so the check only fires on relevant changes rather than every commit.
How do you decide the pass-rate drop threshold for a CI gate?
Start by measuring the current production prompt's baseline pass rate, then pick an allowed drop — commonly 3-5 percentage points — small enough to catch real regressions but large enough to tolerate normal eval noise; tighten it over time as your test set and judge calibration mature.
Can online evaluation replace offline eval-on-PR checks?
No — online eval catches what offline tests miss (real-world input variety) but runs after deploy, so it's a complement, not a substitute. Offline eval-on-PR is what prevents a known-bad regression from reaching production in the first place.