Measure LLM Quality and Detect Hallucinations, Then Implement an Evaluation Component
Company: Microsoft
Role: Machine Learning Engineer
Category: Machine Learning
Difficulty: medium
Interview Round: Onsite
This is a hands-on AI exercise in a machine learning loop for LLM products. The discussion goes deep on how to measure LLM performance and how to detect hallucinations, and it ends with you implementing a small component in code.
Answer the discussion parts as you would out loud, then write the code. The component used in the interview was not reported, so Part 3 specifies a representative one for practice. Assume an application that generates answers from supplied context passages (for example, retrieved documents), so hallucinations can be checked against that context, but be ready to discuss the case with no context as well.
### Clarifying Questions
- Does the model answer from supplied context, from its own knowledge, or both? That changes what a hallucination is checked against.
- Are reference answers available for an evaluation set, or must quality be judged without them?
- Will hallucination detection run offline for evaluation, or inline on each response before the user sees it, and what latency and cost does that allow?
- What should happen when a response is flagged: block it, regenerate it, add a warning, or only log it?
### Part 1 — Measuring LLM performance
How would you measure whether an LLM feature is performing well, and whether a new prompt or model version is better than the current one? Cover metrics, evaluation data, scoring methods, and how you compare versions.
```hint Layer the metrics
Separate what can be checked mechanically, what needs a reference answer, and what needs judgment, and think about how much data a comparison needs before you trust it.
```
#### What This Part Should Cover
- Task-specific quality dimensions alongside latency and cost
- How evaluation sets are built, versioned and kept representative, including hard cases
- Scoring methods and how their reliability is checked
- How a comparison between two versions is made trustworthy
### Part 2 — Detecting hallucinations
Define the kinds of hallucination you would look for, describe several ways to detect them, and explain how you would measure whether your detector works.
```hint What counts as evidence?
For each detection method, ask what it compares the generated text against, and what that comparison would miss.
```
#### What This Part Should Cover
- A clear definition of the hallucination types that matter for this product
- Several detection methods with their cost, latency and blind spots
- Evaluating the detector itself and choosing its operating point
- What the product does when a response is flagged
### Part 3 — Implement a groundedness scorer
For practice, implement this component:
```python
from typing import Callable
def score_groundedness(
answer: str,
contexts: list[str],
support_fn: Callable[[str, str], float],
threshold: float = 0.5,
) -> dict:
...
```
- `support_fn(context, claim)` returns a number in `[0, 1]` for how strongly one context passage supports one claim. In production it would wrap an entailment model or a model-based judge; treat it as an expensive black box.
- Split the answer into sentences and treat each sentence as one claim. A simple punctuation-based splitter is acceptable if you state its limits.
- A sentence's support is its highest score across all passages, and its best passage is the index that achieves that score (the lowest index on ties). The sentence is supported when its support is at least `threshold`.
- Return each sentence's text, support, best passage index and supported flag, plus the answer-level groundedness (the fraction of sentences that are supported) and whether the answer has any unsupported sentence.
- Choose and document the behavior for an empty answer, an empty passage list, and an out-of-range threshold or score.
- Then write `evaluate_dataset(examples, support_fn, threshold)`, which takes `(answer, contexts)` pairs and reports the mean groundedness and the hallucination rate (the share of answers with at least one unsupported sentence).
```hint Pin down the semantics first
Decide what each edge case should return before writing the loop, and keep the expensive scorer behind the interface you were given.
```
#### What This Part Should Cover
- Correct per-sentence logic for the maximum over passages, the threshold rule and ties
- Explicit, documented edge-case behavior and input validation
- Cost in calls to `support_fn`, and ways to reduce it
- Tests, and an honest account of where sentence-level checking falls short
### What a Strong Answer Covers
- Connects evaluation metrics to what users of the product need
- Recognizes that LLM-based judges and detectors are models that must themselves be validated
- Compares detection methods on cost, latency and coverage instead of naming a single one
- Writes clean, tested code with clear semantics for edge cases
- Explains the limits of the implemented approach and how to go beyond it
### Follow-up Questions
- Long sentences often mix supported and unsupported facts. How would you split answers into atomic claims, and how would you check that the splitting is reliable?
- A claim is supported only by combining two passages. How does your scorer handle it, and how would you change it?
- How would you detect hallucinations when the model answers from its own knowledge with no context passages?
- The detector must run inline under a tight latency budget. What would you change?
Overview: A hands-on LLM evaluation exercise on measuring model quality, comparing prompt or model versions, and detecting hallucinations against supplied context. It also asks for a small Python groundedness scorer that flags unsupported sentences and aggregates a hallucination rate, testing evaluation judgment and clean, well-tested code.
Read the full Microsoft Machine Learning Engineer interview experience this question came from