LLM Evaluation and Observability Questions
Measuring and monitoring the quality of generative and LLM-powered systems. Covers evaluation approaches for open-ended outputs (human, model-graded, and reference-based), hallucination and safety checks, offline benchmarks versus online monitoring, and tracing and observability for production LLM applications. Emphasizes making non-deterministic systems measurable and trustworthy.
Design a comprehensive monitoring, evaluation, and human-in-the-loop strategy for a deployed generative AI assistant used in customer support. Include safety and quality metrics, data pipelines for feedback, alerting thresholds, human review policies, rollback procedures, and a plan for continuous learning without causing regressions.
Sample Answer
Requirements & constraints:
- Functional: respond to customer queries with accurate, helpful, and timely answers; escalate when uncertain.
- Non-functional: <2s latency target, 99.9% availability, privacy/GDPR compliance, no safety/regulatory breaches.
- Scale: tens of thousands of interactions/day; multi-channel (chat, email).
High-level architecture:
- Inference service (model + safety filter) → Response logger → Monitoring & metrics store → Feedback ingestion pipeline → Human-in-the-loop (HITL) queue & dashboard → Model training/validation pipeline → Staged deploy (canary/blue-green).
Safety & quality metrics:
- Safety: rate of policy violations per 1k responses, toxic/harassment score, PII leakage incidents.
- Correctness: factuality score (automated fact-checking), resolution rate (no follow-ups), accuracy vs. labeled ground truth.
- Utility: user satisfaction (CSAT), acceptance rate, time-to-resolution.
- Robustness: hallucination rate, latency percentiles, error rate.
- Drift: distributional drift (embedding & token-level), intent-class drift.
Data & feedback pipelines:
- Automatic collectors: response + context + metadata + model logits + safety-filter signals.
- User feedback: thumbs up/down, free-form comments, “escalate to human” flags.
- Passive signals: conversation restart, follow-up frequency, time-to-first-human.
- Secure ETL → labeling platform (human labelers + inter-rater agreement) → versioned dataset store.
Alerting thresholds & actions:
- Critical (auto-rollback): >0.1% PII leaks in 1h or any confirmed regulatory breach → immediate rollback + incident response.
- High: safety violations >2x baseline for 30 minutes OR CSAT drop >15% in 1 day → pause new rollouts, divert to fallback flow, ramp down canary.
- Medium: factuality decrease >10% vs baseline across 24h → enqueue for HITL review.
- Low: latency p95 > target → scale inference infra.
Human review policies (HITL):
- Triage rules: all “escalate” flags, random sample (stratified by intent/confidence), high-risk intents (billing, legal, health) always reviewed.
- Review workflow: label for accuracy, safety, tone, PII; provide corrective annotations and alternative responses.
- SLA: urgent escalations reviewed within 30 minutes; sampled reviews within 24 hours.
- Privacy: redaction, least-privilege access, audit logs.
Rollback & incident procedures:
- Automated rollback hook in CI/CD on critical alerts; maintain immutable model versions and data snapshots.
- Playbook: detect → notify on-call → snapshot state → rollback to last good version → postmortem with root cause and action items.
- Communication: customer-facing message template and internal incident channel.
Continuous learning without regressions:
- Staged loop: shadow mode → canary on small % → progressive rollout with metric gates.
- Training cadence: offline retrain weekly on validated, balanced labeled data; use holdout evaluation suite and adversarial tests.
- Regression tests: automated unit tests on core intents, safety test suite, model-specified behavioral tests, synthetic adversarial examples.
- A/B & champion-challenger: compare candidate against champ on key metrics using multi-armed bandit for selection; require no degradation on safety and CSAT before promotion.
- Replay & rollback safety: keep replayable logs so new model can be tested against historical sessions; implement fine-grained feature flags to disable behaviors.
- Human-in-the-loop augmentation: prioritized samples from low-confidence or mispredicted cases are labeled and added to training set with provenance; apply importance sampling to avoid bias.
- Continuous validation: monitor post-deploy for unseen failure modes; require signed-off checklists before each promotion (metrics, fairness, privacy).
Governance & tooling:
- Dashboards for real-time metrics, drift, and alerting (Prometheus + Grafana, MLflow for versions).
- Model cards and dataset cards for transparency.
- Regular audits, periodic red-team exercises, and compliance reviews.
This plan balances automated detection, timely human oversight, safe rollback, and a controlled learning loop to improve the assistant while minimizing regressions and safety incidents.
Medium: For a consumer-facing assistant, propose a strategy to detect and mitigate model overconfidence (high-confidence incorrect answers). Include detection signals, user-facing behavior (e.g., hedging), and backend actions (e.g., fallbacks).
Sample Answer
Approach: combine online detection (signal fusion) + conservative user-facing behavior + robust backend fallbacks and continuous learning.
Detection signals (fused):
- Model calibration score: softmax/logit-derived calibrated confidence (temperature-scaled).
- Ensemble/agreement: disagreement among checkpoints or LLM ensemble.
- Retrieval mismatch: low similarity between generated claims and retrieved evidence or empty knowledge hits.
- Hallucination classifiers: binary detector trained on claim-evidence pairs.
- Metadata heuristics: length/novel-named-entities ratio, unsupported citations, improbable dates/facts.
- User feedback/interaction signals: quick follow-up corrections, high rephrase rate.
User-facing behavior:
- Hedging when uncertainty above threshold: “I may be mistaken, but…”, offer confidence band (e.g., “~70% confident”).
- Show provenance: inline citations, source snippets, or “I don’t have verified info on this.”
- Offer clarifying question before answering uncertain prompts.
- Provide clear “I don’t know / need to check” abstain option with suggested next steps.
Backend actions:
- Tiered fallback:
- Re-query retrieval + ground generation on high-quality sources.
- Switch to more conservative model or constrained template-based response.
- Invoke external tools/APIs (fact-checking, knowledge graph) or prompt verification chain-of-thought.
- Escalate to human review for high-risk queries.
- Logging and weak-supervision: capture false-high-confidence cases, retrain calibration/hallucination detectors.
- Dynamic thresholds: adjust by domain/risk (medical/financial stricter).
- Monitoring & metrics: track calibration error, abstain rate, user corrections, downstream harm, A/B test UX variants.
Why: combining multiple detectors reduces blind spots; hedging + provenance preserves trust; tiered fallbacks keep utility while minimizing harm and enable continuous improvement.
Medium: Given an LLM that sometimes outputs incorrect named entities, propose an automatic post-processing pipeline in Python that: (1) detects named-entity hallucinations using an external KB, (2) replaces or annotates them, and (3) logs corrections for feedback. Describe main components and errors to watch for.
Sample Answer
Approach: build a modular Python pipeline that (A) extracts entities from LLM output, (B) verifies each entity against an external knowledge base (KB) and a fuzzy-matching fallback, (C) either replaces/annotates the entity in text or flags it, and (D) logs corrections for feedback and model fine-tuning.
import re, json, logging
from difflib import get_close_matches
from typing import List, Dict
# Assume we have a KB client with methods: kb.lookup(entity) -> dict|None, kb.search(name) -> list
class KBClient:
def lookup(self, entity): ...
def search(self, name): ...
logging.basicConfig(filename='ner_corrections.log', level=logging.INFO)
def extract_entities(llm_output: str, nlp) -> List[Dict]:
# nlp is a spaCy-like pipeline returning entities with start/end/label/text
doc = nlp(llm_output)
return [{'text': ent.text, 'start': ent.start_char, 'end': ent.end_char, 'label': ent.label_} for ent in doc.ents]
def verify_entity(ent_text: str, kb: KBClient, threshold=0.8):
exact = kb.lookup(ent_text)
if exact:
return {'status':'verified','kb_entry':exact}
# fuzzy match using KB search + ratio heuristic (or embeddings)
candidates = kb.search(ent_text)
names = [c['name'] for c in candidates]
close = get_close_matches(ent_text, names, n=1, cutoff=threshold)
if close:
match = next(c for c in candidates if c['name']==close[0])
return {'status':'fuzzy','kb_entry':match}
return {'status':'unknown', 'kb_entry':None}
def postprocess(llm_output: str, nlp, kb: KBClient):
ents = extract_entities(llm_output, nlp)
out = llm_output
corrections = []
# process in reverse order to preserve character offsets
for e in sorted(ents, key=lambda x: x['start'], reverse=True):
res = verify_entity(e['text'], kb)
if res['status']=='verified':
continue
elif res['status']=='fuzzy':
# annotate suggestion inline
replacement = f"{e['text']} [maybe: {res['kb_entry']['name']}]"
out = out[:e['start']] + replacement + out[e['end']:]
corrections.append({'original':e['text'],'suggestion':res['kb_entry']['name'],'type':'fuzzy'})
else:
out = out[:e['start']] + f"{e['text']} [UNVERIFIED]" + out[e['end']:]
corrections.append({'original':e['text'],'suggestion':None,'type':'unknown'})
logging.info(json.dumps({'input':llm_output,'output':out,'corrections':corrections}))
return out, corrections
Key concepts:
- Use a reliable NER (spaCy/fine-tuned) to extract spans.
- Prefer exact KB lookup (Wikidata/Custom DB). Use fuzzy matching or embedding similarity for aliases.
- Apply replacements/annotations in reverse span order to avoid offset shifts.
- Log original, corrected, confidence, KB ids, and context for feedback loops.
Time/space: linear in text length plus cost of KB queries; optimize by batching and caching.
Errors to watch for:
- Span alignment mismatches between NER and tokenization — always use char offsets.
- False negatives in KB due to alias/multi-language—use alias table or embedding search.
- Overzealous replacements changing meaning; prefer annotations or human-in-the-loop for high-impact cases.
- Rate limits/latency from external KB — add caching and async batching.
- Ambiguity: same surface form maps to multiple KB entries — include context (type, nearby tokens, date) for disambiguation.
Alternatives:
- Use entity linking libraries (REL, BLINK) or vector-based linking (FAISS) for higher recall.
- Train a small verifier model that predicts "hallucinated" vs "real" from context and KB signal.
You're tasked with defining success metrics for a generative AI assistant intended to improve developer productivity. Which quantitative and qualitative metrics would you choose (latency, accuracy, acceptance rate, time saved, user satisfaction), how would you instrument them, and how would you take ownership of improving these metrics over time?
Sample Answer
Success metrics — quantitative and qualitative — should map to developer outcomes (speed, correctness, satisfaction) and system health.
Quantitative metrics
- Latency: p50/p95/p99 end-to-end response time (ms). Instrument with request tracing (distributed trace IDs), capture backend, model decode, and client render times.
- Accuracy/relevance: measured by automated signal (e.g., unit-test pass rate when code suggestions applied, static analysis warnings decreased) and human-labeled relevance scores on sampled responses.
- Acceptance rate: % of suggestions accepted/edited vs. dismissed. Log UI events (shown, accepted, modified, rejected).
- Time saved: infer from telemetry — time between task start and completion with vs. without assistance; or self-reported time reductions in workflows. Use controlled A/B experiments to estimate causal effect.
- Usage & retention: DAU/WAU, sessions per user, feature engagement funnel.
Qualitative metrics
- User satisfaction (CSAT/NPS): short in-product survey after sessions.
- Trust/clarity: qualitative feedback tags and open comments; periodic interviews and usability tests.
- Error impact: severity-weighted incidents when suggestions introduce bugs or security issues.
Instrumentation approach
- Central event schema: immutable event types (request, response, show, accept, edit, reject, error) with context (repo, language, file, prompt, user-id hash, timestamps, trace-id).
- Sampling & labeling pipelines: sample responses for human annotation; store model inputs, outputs, and ground-truth where possible (tests).
- A/B and interleaving experiments for feature changes; use randomized assignment and log exposures.
- Monitor data drift by tracking input distributions and model confidence calibration.
Ownership & improvement plan
- Set SLOs (e.g., p95 latency < 300ms, acceptance rate ≥ X, CSAT ≥ Y) and runbooks tied to alerts.
- Weekly metrics dashboard and monthly deep-dive (accuracy, failure modes).
- Close the loop: prioritize incidents by business impact, run root-cause analysis, push fixes (prompt engineering, model fine-tune, caching, retrieval improvements).
- Continuous telemetry-driven experiments: validate hypotheses via A/B, iterate on prompts/models, retrain on labeled failure cases, and expand unit/integration tests to prevent regressions.
- Cross-functional feedback: sync with developer advocates and UX to translate qualitative inputs into actionable metric targets.
This combination ensures measurable developer productivity gains while controlling latency, correctness, and trust.
Medium: Propose a lightweight method to surface and quantify hallucinations in code-generation models (e.g., generating APIs that don't exist). Explain data sources for verification and how to compute a per-response factuality score.
Sample Answer
Approach (overview): Build a lightweight verification pipeline that extracts claims from generated code (API calls, class names, endpoints), cross-checks them against authoritative sources, and produces a per-response factuality score combining binary existence checks and softer semantic matches.
- Claim extraction
- Parse the generated code with a fast AST/tokenizer to extract external identifiers: package imports, class/function names, URLs, endpoint paths, method signatures.
- Normalize tokens (lowercase, strip versions).
- Verification datasources (prioritized)
- Official docs / API reference (scraped or via sitemap / OpenAPI specs).
- Package registries (PyPI, npm, Maven Central) for package & symbol existence.
- GitHub code search / repo indices (for real-world usage/examples).
- Public OpenAPI / Swagger directories and API catalogs.
- Lightweight fuzzy web search (bing/google custom search) as fallback.
- Scoring per claim
- Existence score S_exist: 1 if exact match found in authoritative source, 0 otherwise.
- Confidence score S_conf: graded match (0–1) from fuzzy matching (Levenshtein / token overlap / signature similarity) and evidence strength (number of independent sources).
- Usage score S_usage: normalized frequency from GitHub/npm indicating real usage (log-scaled).
Aggregate per-response factuality F:
F = w1 * mean(S_exist) + w2 * mean(S_conf) + w3 * mean(S_usage)
Choose weights (e.g., w1=0.6, w2=0.3, w3=0.1) and calibrate on validation set.
Example: Generated code imports "foo.bar.Client" — verifier finds no package "foo" on PyPI (S_exist=0), GitHub shows one repo mentioning "foo-bar" with different API (S_conf=0.4), usage negligible (S_usage=0.0) → response F ~ 0.12 => flagged as likely hallucinated.
Implementation notes:
- Keep it modular and cache verification results.
- Treat external URLs and OpenAPI matches as higher-trust sources.
- Report per-claim evidence links for explainability.
- Edge cases: private/internal APIs (allow manual whitelisting); ambiguous names (use context and signature matching).
Unlock Full Question Bank
Get access to all 27 LLM Evaluation and Observability interview questions and detailed answers.
Sign in to ContinueJoin thousands of developers preparing for their dream job.