learn-agent-launch-with-phoebe / Builder session 2 of 10
Learn Agent Launch with Phoebe · Builder track · Session 2 of 10

Quality metrics: the formulas, and how much the definition moves the number

Faithfulness, groundedness, answer relevancy, hallucination rate. Four names, and underneath most of them one piece of arithmetic. This session gives you the actual formulas so you can read a vendor number without being fooled by it, and then shows you the uncomfortable part: the same models score 0.7% hallucination under one published definition and 12% under another. The metric is not the number. The definition is.

🟢 Builder track AI engineers · ML engineers · technical PMs 45 min
0-3 · Welcome 3-22 · The formulas + definition sensitivity 22-40 · Build-along: score one answer, then freeze the contract 40-45 · Q&A
Part 0

What this page covers, and what it deliberately does not

Metric depth lives in two sibling courses and this one does not re-teach it. Learn Evals goes properly into retrieval and generation metrics, RAGAS internals and tracing. Model Evaluation covers the classic and LLM-era metric canon side by side, including the Goodhart trap. Go there to learn the metrics. Stay here for the only question this course cares about: which of these numbers can you put on a launch gate, and what exactly does the number mean when you do?

Live - presented in session Self-study - read after class Official sources covered
★ What you walk out with today The literal formulas behind faithfulness, response relevancy, groundedness and hallucination rate; the one wrinkle in RAGAS relevancy that can push it outside 0 to 1 and break a naive gate; proof that a stricter definition moves a hallucination number roughly tenfold; and Beacon's frozen metric contract - the document that stops your quarterly number quietly re-baselining itself.
The running case: Beacon Three bots this quarter. The support bot answers customers and can issue a refund credit, so it is tier T3. The Analyst Bot turns questions into warehouse queries. The Insight Bot writes summaries for executives. Today only the support bot and the Insight Bot are in scope - they are the two whose correctness is an opinion until a metric supplies one. The Analyst Bot is executable and gets its own treatment in b6.
Part 1 · the claim-support family

One formula wearing three different names 7 min live

Faithfulness, groundedness and hallucination rate are usually the same measurement reported three ways. Once you see the shared pipeline, the interesting question stops being "which metric" and becomes "who decides what counts as a claim".

1 · Split the answer into atomic claims - one fact per claim ▸ 2 · Check each claim against the retrieved context, not the web ▸ 3 · NLI verdict entailed or not entailed. Binary. ▸ 4 · Divide supported claims over total claims faithfulness = supported claims / total claims RAGAS. Same arithmetic under three different names, and the whole page turns on step 1. Faithfulness (RAGAS) supported / total claims, 0 to 1 The reference definition, and the one the others rename. Groundedness (TruLens) TruLens decomposes a response into claims and searches for supporting evidence. Hallucination rate the same check inverted and tracked over live traffic instead of a frozen set. The three names differ in scale and tooling, not in arithmetic. If you can defend the claim extraction step, all three are defensible. If you cannot, none of them are.
🔍 Click to zoom - one pipeline, one division, three product names
★ Faithfulness, in four lines
claims       = extract_claims(answer)        # one fact per claim
supported    = [c for c in claims
                if entailed(c, retrieved_context)]   # NLI verdict
faithfulness = len(supported) / len(claims)  # RAGAS, 0 to 1
LiveStep 1 is the whole metric, and nobody audits it4 min▶

Every number in this family is a fraction, and a fraction is only as stable as its denominator. The denominator is "total claims" - which is decided by a claim extractor, usually another language model, using a prompt you did not write.

Take one Beacon answer: "Refunds are processed within 5 business days, and you can track them in the billing portal." A coarse splitter sees one claim. A fine splitter sees three: refunds are processed; the window is 5 business days; tracking happens in the billing portal. If the 5-day figure is the wrong one and everything else is right, the coarse splitter scores 0.00 and the fine splitter scores 0.67. Same answer, same context, same model, same error - a two-thirds swing in the metric from a prompt nobody reviewed.

The practical consequence for a launch gate: freeze the extractor and version it. Treat a change to the claim splitter exactly as you would treat a change to the model - it re-baselines every historical number you have, and a quarter-over-quarter comparison across a splitter change is meaningless.

Self-studyGroundedness on an ordinal scale, and why you cannot average it3 min read▶

Some platforms report the same idea as an ordinal judge score rather than a fraction. Azure AI Foundry's groundedness evaluator runs on a 1 to 5 scale, where 5 means the facts in the response are verifiable in the provided source. Azure's agent evaluators use the same 1-5 shape with a default pass threshold of 3.

An ordinal scale is not a rate, and this trips up gates constantly. The distance between a 1 and a 2 is not the distance between a 4 and a 5, so an average of 4.1 tells you very little: it is equally consistent with "everything scored 4" and with "most things scored 5 and eight answers were fabrications scored 1". Gate on the distribution, not the mean - for example, "no case below 4 on the policy slice" rather than "mean above 4". Session b4 builds the rubric discipline that makes ordinal judge scores trustworthy in the first place.

Part 2 · the headline

The definition moves the number roughly tenfold 6 min live

This is the single most useful fact on the page, and the one that changes how you read every vendor claim afterwards. Two published scoring definitions were run over the same leaderboard. Not different models, not different prompts - the same outputs, scored twice.

One set of models, one set of outputs, two published scoring definitions Vectara hallucination leaderboard, then FaithJudge re-scoring of the same leaderboard Vectara HHEM the leaderboard's own automatic scorer 0.7% - 4.4% FaithJudge re-scoring stricter definition, same models 7% - 12% 0% 2% 4% 6% 8% 10% 12% 14% reported hallucination rate The definition moves the number by roughly 10x Nothing about the models changed between these two rows. One scorer asks whether the summary is supported; the other applies a stricter claim-level standard. Same evidence, a tenfold difference in the headline figure. So a vendor claiming 2% and a vendor claiming 10% may be running identical models. Ask which definition. A launch gate must name its metric definition, not just its threshold. A 95% bar under one scorer can be an 85% bar under another, and neither team is lying.
🔍 Click to zoom - same models, two definitions, a tenfold gap in the headline
Real world

What this does to a procurement conversation. Two vendors present. The first reports a 2% hallucination rate, the second reports 9%. The instinct in the room is that the first bot is four times better. The honest reading is that you have no idea, because you have been handed two numbers produced by two scorers with different standards for what counts as unsupported. The only comparison worth making is on your data with one scorer, and the only question worth asking in the meeting is which definition produced the figure on the slide. Session a3 turns this into a list of grilling questions for leaders; here it becomes a line in your eval config.

Self-studyWhy stricter definitions always look worse, and why that is fine2 min read▶

A strict scorer marks a claim unsupported unless the context entails it outright. A lenient scorer accepts plausible elaboration, common knowledge, and paraphrase that goes slightly beyond the source. Real answers are full of small elaborations, so the strict scorer finds far more of them. Neither is wrong; they are answering different questions.

The decision you actually have to make is which question matches your blast radius. Beacon's support bot states refund policy to paying customers, so "plausible elaboration" is exactly the failure mode that costs money - it should be scored strictly. An internal Insight Bot summarising a dashboard for a weekly review can tolerate a looser standard, because a human reads every line before it travels. Pick the strictness from the tier, then never move it because the number came back ugly.

Part 3 · the other metrics

Relevancy, citations, verbosity - and their wrinkles 6 min live

Faithfulness only tells you the answer is supported. It says nothing about whether the answer addresses the question, whether the citations are usable, or whether the reply was four paragraphs where one would do. Four more metrics, each with a wrinkle you have to gate around.

Metric What it outputs The wrinkle you gate around Faithfulness RAGAS 0 to 1, continuous supported / total claims Depends entirely on how a claim is defined. Same answer, different splitter, different score. Response relevancy RAGAS mean cosine similarity of N=3 reverse-engineered questions to the input Cosine runs -1 to 1, so this metric can land outside 0 to 1. Clamp it or your gate breaks. Groundedness Azure AI Foundry integer 1 to 5 5 = the facts are verifiable in the source An ordinal scale, not a rate. Averaging 1-5 scores hides how many 1s you shipped. CitationPrecision + CitationCoverage Amazon Bedrock two scores, and AWS recommends using both together, not either alone Precision alone rewards citing nothing. Coverage alone rewards citing everything. Hence the pair. Verbosity Vertex AI, pointwise 0 to 5 judge score on one response at a time, no comparison Judges whether the answer is appropriately concise, not overly wordy or excessively brief. Also a cost metric - b3 picks it up. Four vendors, four scales, and not one of them is a percentage you can compare to another number. Pick one definition per gate, write it into the eval config, and never change it mid-quarter.
🔍 Click to zoom - five metrics, five outputs, five wrinkles that break naive gates
★ Response relevancy, and the wrinkle
qs        = generate_questions(answer, n=3)   # RAGAS default N = 3
sims      = [cosine(embed(q), embed(user_input)) for q in qs]
relevancy = mean(sims)   # cosine is -1..1, so this can exceed [0,1]

Read what that is actually doing. RAGAS does not compare the answer to the question directly - it asks a model to reverse-engineer the questions the answer would be a good reply to, embeds them, and measures how close they land to the question the user really asked. Three questions by default. It is a genuinely clever construction, and it measures whether the answer is on topic, not whether it is correct. A confidently wrong answer to exactly the right question scores beautifully here, which is precisely why it is never a gate on its own.

MetricCatchesCompletely missesGate it as
FaithfulnessFacts not present in the retrieved contextAnswers that are supported but irrelevant, or that omit the key factMean plus a per-case floor
Response relevancyOff-topic, evasive and padded answersConfident wrongness on exactly the right topicNever alone. Pair with faithfulness
Groundedness 1-5Fabrication, at a resolution a human can reviewAnything below the threshold that the mean hidesDistribution, not average
Citation pairCiting nothing, and citing everythingCorrect citations attached to a wrong conclusionBoth scores, both above the bar
Hallucination rateDrift in fabrication over live trafficThe cases nobody sampled that weekA trend with a rollback trigger
Verbosity 0-5Four paragraphs where one would doEverything about correctnessA UX gate and a cost gate at once
Verbosity is where this page hands off to b3 Conciseness looks like a taste metric and behaves like a budget line. Every extra token is a token you paid to generate, a token the user waited for, and a token in the context window of the next turn. Vertex scores it as a pointwise 0-5 judgement of whether a response is appropriately concise without being overly wordy or excessively brief. Session b3 shows you the same measurement wearing its other hat - as cost per task and as time-to-last-token - and why a "make it more thorough" prompt change quietly turns two gates red at the same time.
Demo 1 of 2

Score one answer by hand, twice ★ 10 min · everyone builds

You cannot gate on a metric you have never computed manually. Take one real answer from your own bot - or one from Beacon's support bot - and run the pipeline with a pen. It takes eight minutes and it permanently changes how you read a faithfulness score.

Pick one answer where the bot got something subtly wrong, and paste it next to the retrieved context that was actually in the prompt. Not the knowledge base. The passages the retriever returned on that specific call. If you cannot recover them, that is your first finding of the day and b10 is about fixing it.

Split the answer into atomic claims, coarsely - one claim per sentence. Mark each supported or unsupported against the context only. Compute supported / total. Write the number down.

Now split it again, finely - one claim per assertable fact, so a sentence with a number, a timeframe and a location becomes three claims. Score it again. Write the second number down next to the first.

Compare. On most real answers the two numbers differ by 15 to 40 points, and the bot did not change between them. That gap is definition sensitivity at the scale of a single answer - the same thing the HHEM-versus-FaithJudge gap shows at the scale of a leaderboard.

Last, score the same answer for relevancy the RAGAS way, by hand: write down the three questions this answer would be a perfect reply to. If none of them is the question the user asked, you have found an evasive answer that a faithfulness gate would have passed happily.

The trap in step 2 Almost everybody scores against what they know to be true rather than against the retrieved context. A claim that is factually correct but absent from the context is unsupported, and it must be marked unsupported - that is the entire point of the metric. A bot that produces true statements it could not have known from its context is a bot that is guessing well today and will guess badly next week.
Demo 2 of 2

Freeze Beacon's metric contract ★ 8 min · everyone writes

A metric contract is one small file that says, for each gate, which definition produced the number and which knobs are frozen. It exists so that six months from now nobody can improve a score by changing a prompt in the grader. Write yours in this session; it is shorter than you expect.

★ Beacon support bot - metric contract, v1
support_bot:            # tier T3, can issue refund credits
  faithfulness:
    source:   RAGAS - supported claims / total claims
    splitter: claim_splitter_v3   # FROZEN. changing it rebaselines
    strict:   true                # no credit for elaboration
    gate:     mean >= 0.90  and  no single case below 0.60
  groundedness:
    source:   Azure 1-5 ordinal, 5 = verifiable in the source
    gate:     no case below 4 on the policy slice
  citations:
    source:   Bedrock CitationPrecision + CitationCoverage
    gate:     both >= 0.85        # never one without the other
  relevancy:
    source:   RAGAS, N = 3 reverse-engineered questions
    clamp:    [0, 1]              # cosine is -1..1
    gate:     reported, not blocking    # never a gate on its own

Write one block per metric you intend to gate on. If a metric is not on a gate, it does not belong in this file - it belongs on a dashboard. Contracts get long and stop being read.

For every metric, record the source definition by name and the version of anything that produces the number: the claim splitter, the judge model, the judge prompt, the embedding model. These are the four knobs that silently move scores.

Mark each gate as blocking or reported. Relevancy is reported, because it passes confident wrongness. Faithfulness is blocking. Being explicit here is what stops a green dashboard from being mistaken for a green gate.

Add the per-case floor, not just the mean. "Mean at or above 0.90" is satisfied by ninety perfect answers and ten fabrications. A floor closes that door, and on a T3 bot the floor matters more than the mean.

Commit the file next to your eval code and put it under review. A pull request that changes a threshold or a splitter version should be as visible as one that changes the model - because it moves the number by just as much.

Where this file gets used Session b4 fills in the judge blocks with calibration evidence. Sessions b5, b6 and b7 add the archetype-specific gates for the three Beacon bots. Session b9 reads the whole contract into the launch scorecard, and b10 wires the blocking lines into CI. Everything downstream assumes this file exists, so write a rough one today rather than a perfect one later.
Homework

Try it yourself - this week ◐ 45-60 min total

Source material

Official sources covered

Every formula and figure on this page traces to a primary source - vendor evaluation documentation, published leaderboards and papers catalogued in this course's source map. This page covers:

✓RAGAS faithfulness = supported claims / total claims, with the claim-extract then NLI-verify pipelinePart 1 · derivation and variants in Learn Evals
✓RAGAS response relevancy = mean cosine similarity of N reverse-engineered questions, N default 3Part 3 · including the out-of-range wrinkle
✓Definition sensitivity: 0.7%-4.4% on Vectara HHEM vs 7-12% under FaithJudge re-scoringPart 2 · the headline of this session, reused in a3
✓Azure groundedness on a 1-5 scale, 5 = facts verifiable in the source; agent evaluators default threshold 3Part 1 self-study + Part 3 · ordinal, so gate the distribution
✓Bedrock RAG evaluation adds CitationPrecision and CitationCoverage, and AWS recommends both togetherPart 3 · one without the other is gameable
✓TruLens groundedness: decompose the response into claims, then search for supporting evidencePart 1 · same arithmetic, different product name
◐Vertex pointwise verbosity judge, 0-5, appropriately concise without being wordy or briefPart 3 · introduced here as quality, costed in b3
◐Judge calibration, position swapping and the four documented judge biasesNamed here as why ordinal scores need rubrics · measured in b4
◐Full metric derivations, retrieval metrics and the Goodhart trapNot covered by design · Learn Evals and Model Evaluation own these
Check yourself

Three questions before you go 🎯 ◐ 90 seconds

1 · A vendor reports 2% hallucination and a competitor reports 10% on the same benchmark family. What is the most likely explanation?

Definition sensitivity is the largest single source of variation in published hallucination numbers, and it is larger than most model differences. Until you know which scorer produced a figure, comparing two figures across vendors tells you about the scorers, not the models. The only fix is to run one definition over your own data, which is exactly what the metric contract in Demo 2 exists to pin down.

2 · Your CI gate is written as "RAGAS response relevancy at or above 0.7" and it occasionally sees a value of -0.12. Is this a bug?

RAGAS reverse-engineers N questions from the answer, embeds them, and averages their cosine similarity to the original input. Cosine similarity is defined on -1 to 1, so the mean of several of them is too. A wildly off-topic answer can genuinely produce a negative score. It is not a defect - it is the definition - but a gate that assumes a 0-to-1 range will misbehave, so clamp explicitly and say so in the contract.

3 · Why does AWS recommend using CitationPrecision and CitationCoverage together rather than picking one?

A bot that attaches one very safe citation and says little else scores near-perfect precision. A bot that staples every retrieved passage to every sentence scores near-perfect coverage. Both are useless to a customer trying to check a policy claim, and both pass a single-metric gate. The pair closes the loophole in each direction, which is why it is a pair and not an average - averaging would let a strong score on one side hide a failure on the other, exactly like the conjunctive gates in b9.

Builder session 2 cheat sheet · pin this

FaithfulnessSupported claims / total claims (RAGAS). Extract claims, verify each against the retrieved context, divide.
Three names, one formulaFaithfulness, groundedness and hallucination rate are the same claim-support check, renamed and rescaled.
The splitter is the metricCoarse or fine claim extraction swings the same answer by tens of points. Freeze it, version it, review changes.
Definition moves the number ~10x0.7%-4.4% on Vectara HHEM, 7-12% under FaithJudge, same models. Always ask which scorer produced a figure.
Relevancy is topic, not truthMean cosine of N=3 reverse-engineered questions vs the input. Cosine is -1 to 1, so clamp. Never a gate alone.
Ordinal scales are not ratesAzure groundedness is 1-5, where 5 = verifiable in the source. Gate the distribution, never the average.
Citations come in pairsBedrock CitationPrecision plus CitationCoverage, used together. One alone is gameable in the opposite direction.
Conciseness is two gatesVertex scores verbosity 0-5 as quality. The same tokens are latency and money, so b3 gates it again.