Vol. 12 · Evaluation & Improvement

Evaluation Process & LLM-as-Judge

How to build the process of evaluating LLM systems from scratch: minimum viable eval, guardrails vs evaluators, why a binary assessment is better than a scale of 1–5, negative scenarios, LLM-as-judge with correlation to people, detection of degradation after release, synthetic data - when it helps and when it harms.

Retrieval answer

How to build the process of evaluating LLM systems from scratch: minimum viable eval, guardrails vs evaluators, why a binary assessment is better than a scale of 1–5, negative scenarios, LLM-as-judge with correlation to people, detection of degradation after release, synthetic data - when it helps and when it harms. This New Runtime record is an evidence-linked retrieval unit.

01

Eval Process: where to start

4 cards
01ProcessMinimum Viable Eval: from scratch in 3 steps1 visual1 source note

Most teams put off evaluation because it seems like expensive infrastructure is needed. No: the minimum working eval is 20–50 examples, pass/fail criteria and one “benevolent dictator” - a person with domain expertise, whose opinion is considered the standard.

Source-complete notesstart antipatterns

start antipatterns

  • We are waiting for the “correct” infrastructure
  • we immediately build LLM-judge without baseline
  • generate a dataset LLM without verification
  • 20 manual examples > 1000 synthetic ones
02ProcessError Analysis: hands before automation2 source notes

After each significant change to the system (prompt, model, chunking, retriever), be sure to read 20–50 outputs manually. Automated metrics hide error patterns that are instantly visible to the eye.

Source-complete noteserror analysis protocol · practice
error analysis protocolsql
# After any change:
sample = random_sample(outputs, n=30)
# or: all fails from eval for the period

# For each read:
Is the answer correct in meaning?
Is the answer based on context or fictitious?
Is the formatting as expected?
Is the answer too long/short/evasive?
✓ Does the model respond when it should fail?
✓ Does the model refuse when it should respond?

# Group errors by type:
hallucination |  wrong_refusal
off_topic |  format_error
incomplete |  tone_mismatch

# Most common category → fix first

practice

  • read the fails yourself - don’t delegate to the junior
  • 30 examples give 80% of the picture
  • every bug → test case in the dataset
03ProcessResponse metrics vs pipeline metrics1 visual1 source note

Key principle: a good bottom line metric doesn't tell you where it's broken. Measure each pipeline node separately - retrieval, rerank, prompt, generation - otherwise you won’t understand what to fix.

Visual model · Concept treeTrace the hierarchy and branches that make up Response metrics vs pipeline metrics.
Source-complete notesrule

rule

  • change one variable at a time
  • record the dataset, model, index when comparing
  • comparing on different datasets = pointless
04ProcessTrace: what must be logged2 source notes

Trace - a record of everything that happened in the pipeline for one request. Without traces, you cannot debug, build eval and detect degradation. The minimum set of fields is the one without which it is impossible to answer “why the answer is incorrect.”

Source-complete notesrequired trace fields · tools
required trace fieldsjson
{
  "trace_id": "uuid", # end-to-end ID
  "timestamp": "ISO-8601",
  "user_id": "...", # for user-level analysis

  // Input
  "query": "original query",
  "query_rewrite":"after augmentation", # if any

  // Retrieval
  "retrieved_chunks": ["chunk_id", "score", "text"],
  "reranked_chunks": ["chunk_id", "score"],

  //Generation
  "prompt_tokens": 1240,
  "completion_tokens": 312,
  "model": "claude-sonnet-4",
  "response": "final response",
  "latency_ms": 1840,

  // Eval (async, after request)
  "faithfulness": 0.92,
  "refusal": false
}

tools

  • Langfuse - open-source, self-hosting
  • Phoenix Arize - traces + eval
  • the trace structure is more important than the tool
02

Binary vs Scale: why pass/fail wins

3 cards
05BinaryWhy binary rating is better than 1-5 scale1 visual1 source note

Intuition suggests: a scale of 1–5 is more accurate, because it contains more information. Experience suggests the opposite: numerical scales are unstable and there is little agreement between raters (humans and LLMs) on what a “3” vs “4” means.

Visual model · Formula mapConnect the quantities and operations that determine Why binary rating is better than 1-5 scale.
Source-complete noteswhen the scale is still justified

when the scale is still justified

  • ranking of multiple options (A/B/C/D)
  • quality gradations with clear categories and examples
  • only if κ > 0.6 on the pilot marking
  • never for automation without verification
06BinaryHow to formulate pass/fail criteria2 source notes

The criterion must be formulated so that any reasonable person (or LLM) would give the same answer. Test: give a criterion to two people without explanation - if they don’t match, the criterion is bad.

Source-complete notesgood criterion template · practice
good criterion templatesql
# Structure: "The answer [does X]?" where X is specifically

✗ Bad (blurry):
  "Is the answer quality?"
  "Is the answer useful to the user?"
  "Is the answer correct?"

✓ Good (specific):
  "Does the answer contain at least one specific number?"
  "The answer doesn't mention a competitor company?"
  "Is the answer written in Russian?"
  “The answer begins with a direct answer, not with introductory words?”
  "Does the answer contain statements that are not in the context?"

# Criterion test:
sample = 20 examples
human_1_labels = [...]
human_2_labels = [...]
κ = cohens_kappa(human_1_labels, human_2_labels)
# κ > 0.6 → criterion is valid
# κ < 0.4 → reformulate

practice

  • one criterion → one question
  • formulation through specific behavior
  • abstract words: “quality”, “useful”
07BinaryFalse Refusal vs Hallucination: how to choose a balance1 visual1 source note

These are two opposite types of errors. If the model is too careful, it refuses to answer when the answer would be correct (false refusal). If she is too bold, she makes up facts (hallucination). The balance depends on the domain and the cost of the error.

Visual model · Formula mapConnect the quantities and operations that determine False Refusal vs Hallucination: how to choose a balance.
Source-complete notestypical thresholds

typical thresholds

  • medicine: hallucination < 1%, refusal ok
  • e-commerce: refusal < 5%, hallucination < 10%
  • always measure separately - one final figure hides
03

LLM-as-Judge: correlation with people

4 cards
08JudgeCorrelation of LLM-judge with human eval1 visual1 source note

LLM-judge is only useful if his scores match how people score. Validation of judge is a mandatory step before trusting automatic scores. The binary score gives a significantly better correlation than the numerical scale.

Visual model · Formula mapConnect the quantities and operations that determine Correlation of LLM-judge with human eval.
Source-complete notesknown problems of LLM-judge

known problems of LLM-judge

  • self-enhancement bias: the model prefers its own answers
  • verbose bias: long answer scores higher
  • position bias: the first in a pair gets an advantage
  • use a stronger model as judge
09JudgeJudge Prompt: Structure for Reliability2 source notes

The quality of judge critically depends on the structure of its prompt. Template: clear criterion → CoT reasoning → final verdict. CoT before the verdict significantly improves quality and provides an explanation for the debug.

Source-complete notesjudge prompt template · how to increase stability
judge prompt templatetext
SYSTEM:
  You evaluate the quality of the AI assistant's answers.
  Answer strictly according to the format below.

USER:
  USER QUESTION: {question}
  CONTEXT (sources): {context}
  ASSISTANT'S REPLY: {answer}

  CRITERIA:
  Are all the facts in the answer supported by context?
  A fact is considered confirmed if it is clearly
  is present in one of the sources above.

  Step 1. Explain: List all statements in your answer.
  and for each, indicate whether it is in the context.

  Step 2. Verdict: PASS or FAIL.
  (PASS only if ALL statements are confirmed)

EXPECTED FORMAT:
  Analysis: [chain of reasoning]
  Verdict: PASS/FAIL

how to increase stability

  • Temperature=0 for reproducibility
  • 3 runs → majority vote at T>0
  • swap A/B in pairwise comparison
  • CoT before the verdict - not after
10JudgeWhen BERT, when LLM as a judge2 source notes

Not every check needs to be done through an LLM call. Many criteria are checked cheaper and more reliably by deterministic code, regex or BERT classifier. LLM-judge - only where understanding of the meaning is needed.

Source-complete notestable · principle
What we checkBest toolWhy
JSON validityjson.parse()deterministic, 0ms
Response Lengthlen(text)deterministic
Availability of keywordsregex / str.containsquickly, accurately
PII (email, phone)regex / spaCy NERcheaper, more reliable
ToxicityBERT classifierfast, calibrated
Semantic similaritycosine(embed_A, embed_B)without LLM call
Faithfulness (facts vs source)LLM-judge / NLIneed understanding
Tone, style, "Useful framing"LLM-judge with rubriconly if κ>0.6

principle

  • cheap first: regex → BERT → LLM
  • LLM-judge everywhere = expensive and unstable
11JudgeLLM-judge as guardrail: why not2 source notes

It would seem logical: put LLM-judge directly into the pipeline as a filter for each answer. In practice, this is almost always a bad idea - due to latency and instability.

Source-complete noteswhy not · exceptions
why nottext
Problem 1: Latency
  Main call: 800ms
  + LLM-judge: +600ms ← +75% latency
  = total: 1400ms ← user notices

Problem 2: Instability
  The same request, judge in the pipeline:
  Run 1: PASS → response sent
  Run 2: FAIL → response blocked
  ← non-deterministic UX

Problem 3: False locks
  judge is wrong → the correct answer is blocked
  the user receives a refusal to a valid question

──────────────────────── ─────────────────────────
What to do instead:

In-pipeline (guardrail): regex + BERT (fast)
Async eval (evaluator): LLM-judge on sample
  → estimate 10% of traffic asynchronously
  → do not block the user
  → alert when metrics drop

exceptions

  • very high rates (medicine) → latency can be tolerated
  • then: cache judge on similar queries
04

Guardrails vs Evaluators: different roles

3 cards
12GuardrailGuardrail vs Evaluator: architectural difference1 visual1 source note

Guardrail is part of the production pipeline, works synchronously, blocks or modifies output in real time. Evaluator is a separate quality assessment service that works asynchronously or offline and does not directly affect the user’s UX.

Visual model · Concept treeTrace the hierarchy and branches that make up Guardrail vs Evaluator: architectural difference.
Source-complete noteskey rule

key rule

  • Guardrail = security and format
  • Evaluator = quality and improvement
  • do not confuse the roles - LLM-judge is not guardrail
13GuardrailWhat to install in Guardrail: tools1 source note

The rule of choice: the cheaper and more deterministic the tool, the better for guardrail. Layered approach: first cheap checks, then expensive ones - only if you pass the cheap ones.

Source-complete notesguardrails stack by cost
guardrails stack by costtext
Layer 1 - deterministic (0ms, $0)
  regex: prohibited words, PII patterns
  schema: JSON validation, data type
  length: min/max tokens
  format: expected response structure

Layer 2 - BERT/classifier (5–20ms, ~$)
  toxicity: BERT toxicity classifier
  PII: spaCy NER for email/phone/passport
  topic: zero-shot classifier (not our topic?)
  lang: detect_language(response) == "ru"

Layer 3 - Light LLM (50–200ms, $$)
  safety: haiku/mini checks safety
  schema: "response is valid JSON with fields X,Y?"
  ← only if the first layers were skipped

Layer 4 - heavy LLM (never in guardrail)
  faithfulness, helpfulness → evaluator only
14GuardrailEvaluator as a separate service2 source notes

Evaluator is an asynchronous service subscribed to a log queue. Evaluates a random sample of traffic and builds metrics. The main task: to give a signal that “the system has degraded” even before users start complaining.

Source-complete notesevaluator service architecture · what to monitor
evaluator service architecturepython
# Data stream
PROD TRAFFIC → message queue (Kafka/SQS)

              sampling: 10% of requests


              EVALUATOR WORKER
                  for each trace:
                    faithfulness = llm_judge(...)
                    format_ok = regex_check(...)
                    refusal = detect_refusal(...)


              METRICS STORE (TimeSeries DB)


              ALERT if score_7d_avg drops > 5%

what to monitor

  • faithfulness_score (moving average)
  • refusal_rate (growth = problem)
  • latency p50/p95/p99
  • alert when deviation > 2σ from baseline
05

Negative Scenarios: dataset for failures

3 cards
15NegativeNegative Scenarios: why and how to build a dataset1 visual1 source note

Most teams only test the happy path: “ask a question, get an answer.” But the system must be able to intelligently refuse: when there is no information in the context, when the request is outside the domain, when the request is unsafe. Each type requires a separate dataset.

Visual model · Process flowFollow the sequence behind Negative Scenarios: why and how to build a dataset and locate where work or state changes.
Complete view · 9 layers
Source-complete notesmetrics on negative dataset

metrics on negative dataset

  • correct_refusal_rate → should be high
  • false_answer_rate (hallucination) → should be low
  • measure separately for each type
16NegativeDataset for testing whether the model knows when it does not know1 source note

A special class of tests: queries that the model has no reason to answer. The goal is to check that the model is not making things up, but admitting ignorance. Pattern: correct question + obviously empty or irrelevant context.

Source-complete notesconstruction patterns
construction patternssql
# Pattern 1: there is context, no answer
context = "WB commission for clothes: 12%. Shoes: 15%."
question = "What is the commission for electronics?"
expected = REFUSE # "The source contains no electronics data"

# Pattern 2: question about the future/non-existent
question = "What will the dollar exchange rate be in 2030?"
expected = REFUSE # "Can't predict the future"

# Pattern 3: Conflicting Context
context = "Commission 12%. Commission 18%."
question = "What is the commission?"
expected = REFUSE/CLARIFY # indicate a contradiction

# How to evaluate automatically:
judge_prompt = """
  Did the assistant answer the question using
  ONLY information from context?
  If the context does not contain an answer, is it correct?
  the assistant refused to answer? PASS/FAIL
"""
17NegativeHallucination Probing: test for fiction2 source notes

Active testing: intentionally give the model a false or empty context and see if it uses its “prior knowledge” instead of the context. This test often reveals problems that are not visible in a normal eval.

Source-complete notesprobing techniques · starting frequency
probing techniquestext
# Technique 1: False Fact Context
context = "The company was founded in 2031."  # lies
question = "When was the company founded?"

✓ Correct: “In 2031” ← follows the context
✗ Problem: “In 1998” ← ignores context, returns prior

# Technique 2: empty context
context = ""
question = "What is the VAT rate in Russia?"

✓ Correct: "There is no data in the provided context"
✗ Problem: “VAT in Russia is 20%” ← hallucination

#Technique 3: Irrelevant context
context = "Borscht recipe: beets, potatoes..."
question = "What are the delivery terms?"

✓ Correct: refusal / clarification
✗ Problem: invents delivery terms

starting frequency

  • every time the prompt changes - mandatory
  • when changing model - required
  • ~10% of the dataset = hallucination probes
06

Drift Detection: degradation after release

3 cards
18DriftTypes of system degradation after release2 source notes

The system can degrade without a single code change - due to changes in the external environment: new documents in the knowledge base, changes in user request patterns, changes in the API of the model provider. Understanding the sources of drift is critical to proper diagnosis.

Source-complete notestable · degradation signals that are visible in metrics
Drift typeReasonDetectorTreatment
Data driftNew documents in KB do not match the old chunkingretrieval recall@k crashesre-embed new docs
Query driftUsers started asking about new topicsout-of-domain rate is growingextend KB / update prompt
Model driftThe provider has changed the model (silent update)response format/tone changespin version of the model
Concept driftReality has changed (new law, prices)faithfulness falls due to new factsupdate KB, add date
Prompt driftThe prompt was changed and eval did not runpass_rate for golden setCI for prompts
degradation signals that are visible in metricstext
Early signals (fast): rising → bad sign
  ↑ refusal_rate — the model refuses more often
  ↑ response_length — “inflates” responses
  ↑ latency_p99 - something in the pipeline has slowed down
  ↑ token_count - context is growing (context pollution)

Delayed signals (via eval): falling → bad sign
  ↓ faithfulness_score
  ↓ recall@k (retriever)
  ↓ task_success_rate (agent)
  ↓ user_thumbs_up rate
19DriftGolden Set: monitoring without a person2 source notes

Golden dataset is a fixed set of examples with known expected answers. Run regularly (daily) on a production system without changes - any drop in pass_rate signals drift.

Source-complete notesmonitoring structure · practice
monitoring structurepython
# Daily scheduled job
for example in golden_set:
    response = system.run(example.query)
    score = evaluate(response, example.criteria)
    metrics_store.record(score, timestamp=today)

# Comparison with baseline (release day)
delta = today_pass_rate - baseline_pass_rate

if delta < -0.05: # fell by 5%
    alert(channel="#ml-alerts",
          msg=f"Golden set: {delta:+.1%}")

# What should be in the golden set:
# - typical cases (50%)
# - edge cases (30%)
# - negative scenarios (20%)

practice

  • 50–200 examples are enough for a signal
  • update golden set when changing domain
  • don’t update with every improvement - you lose baseline
20DriftControlled experiments: what to record1 source note

The purity of the experiment is the main condition for meaningful comparison. Change one variable at a time. Without this, you won’t understand what exactly improved or broke the system.

Source-complete notescontrolled experiment protocol
controlled experiment protocoltext
# Fix (do not change):
FIXED = {
  "eval_dataset": "v3.1", # one dataset
  "vector_index": "2025-06-01", # index snapshot
  "embed_model": "text-emb-3",
  "llm_model": "claude-sonnet-4-6",
  "temperature": 0.0, # reproducible
  "k": 5,
}

# Change (one at a time):
VARIABLE = "chunk_size" #512 -> 256

# Run both options on the same dataset
results_A = run(system_A, FIXED, dataset)
results_B = run(system_B, FIXED, dataset)

# Compare metrics
# Make sure the difference is statistically significant
# p-value < 0.05 for n >= 100
07

Synthetic Data: when it helps, when it harms

3 cards
21SyntheticStructured Synthetic Generation: not just “give me 100 questions”1 visual1 source note

A naive approach—asking an LLM to generate 100 questions—yields a homogeneous, biased dataset. Structural approach: first a taxonomy of complexity and types, then generation for each matrix cell, then verification.

Visual model · MatrixRead Structured Synthetic Generation: not just “give me 100 questions” across the dimensions encoded by rows and columns.
Source-complete notespractice

practice

  • matrix approach → diversity
  • sample verification is mandatory
  • 100% LLM without verification → confirmation bias
  • start with real examples anyway
22SyntheticWhen is synthetic data harmful?1 source note

Synthetic data carries risks that are easy to overlook, especially when the same model is used for both dataset generation and evaluation. This is called model collapse or circular evaluation.

Source-complete notescases when synthetic is a bad choice
cases when synthetic is a bad choicetext
1. Circular eval (main problem)
   GPT-4 generates QA → GPT-4 evaluates QA
   ← the model evaluates “itself”, there will always be a good score
   ← does not detect model system errors

2. Distribution mismatch
   Synthetic questions - literary Russian
   Real users - colloquial, with typos
   ← eval shows good, cont shows bad

3. Coverage gaps
   LLM does not know what NOT to generate (edge cases in prod)
   ← does not cover real problem queries

4. Incorrect reference answers
   LLM generates "correct answer" with error
   Let's use it as ground truth for eval
   ← testing on obviously incorrect examples

When synthetic is acceptable:
  ✓ expansion of a small dataset of real examples
  ✓ type coverage (not replacing real examples)
  ✓ with verification by an expert
23SyntheticKeeping the golden dataset up to date2 source notes

The Golden dataset is becoming obsolete: the business domain is changing, new types of questions appear, the product is changing. An updating process is needed - without it, eval begins to measure something else.

Source-complete noteslifecycle dataset · practice
lifecycle datasettext
# Update triggers:
→ A bug was found in the product → add as a fail test
→ Product has changed → update expected
→ New feature → add new cases
→ Once a quarter → review of outdated examples

# Versioning:
datasets/
  golden_v1.jsonl # ← do not delete! baseline for comparison
  golden_v2.jsonl
  golden_current → golden_v2.jsonl # symlink

# Metadata for each example:
{
  "id": "tc_087",
  "added": "2025-04-12",
  "source": "prod_bug_#2341",
  "last_reviewed": "2025-06-01",
  "tags": ["refusal", "no-context"]
}

practice

  • every product bug → test case
  • versioning the dataset as code
  • keep old versions for comparison
  • update golden set without committing baseline

No dead end

Keep moving through the map.

Continue in sequence, switch to a related guide, or return to the seven-track learning map.

Discovery graph / next reads

Continue through New Runtime

Open the graph
  1. 01learning trackEvaluation And ImprovementOpen the complete learning track.
  2. 02related materialLLM Observability & EvaluationsContinue with another guide in this learning track.
  3. 03related materialThe Production Observability & Evaluation LoopContinue with another guide in this learning track.
  4. 04related materialThe Data Flywheel: From Production Cases to Release GatesContinue with another guide in this learning track.
  5. 05related materialLLM-as-Judge Meta-EvaluationContinue with another guide in this learning track.

These links are also published in this page’s JSON twin and as typed edges in DiscoveryGraph v1.

Who read this page?Machine requests, hidden until opened

Loading the privacy-safe route aggregate…

Open the JSON contract