02 · RAG · LLM evaluation

QuoteGuard

I built a policy-question assistant that finds supporting clauses, cites its sources and shows why it answers or refuses.

Find the clause behind the answer.

A simple insurance question can depend on definitions, exclusions and conditions several pages apart. I built QuoteGuard to retrieve those passages, answer with page references and refuse requests for advice or pricing. I tested retrieval and refusals separately so I could check each part of the system.

Intended user

Customers and service teams

People seeking factual explanations of policy wording, with page citations they can inspect.

Product boundary

Information, not advice

The assistant explains the supplied document but does not recommend cover, personalise advice or generate a premium.

Core constraint

Require supporting text

If retrieval finds no support, the assistant should say it cannot answer from the document.

One real policy, three purpose-built evaluation sets.

The source is an Allianz Business Insurance product disclosure statement. A structure-preserving parser recovered 619 sections and their page locations. Evaluation material is kept separate from the document chunks used by the retriever.

Gold questions
66 total: 61 answerable and 5 deliberately unanswerable
Evidence validation
Each answerable question is anchored to a supporting span and source page
Adversarial set
40 prompts across seven attack and boundary categories
Benign controls
30 legitimate questions used to measure over-refusal

Separate retrieval quality, answer grounding and guardrail behaviour.

I combined two text-search methods, then reranked the candidate passages before producing a cited answer. Each response includes a trace showing which checks passed or caused a refusal: pricing, advice, prompt injection, document scope or supporting evidence.

Implementation scope: the professional implementation listed in my résumé used Azure OpenAI and Azure AI Search, with RAGAS evaluation work and MLflow experiment tracking. The public repository is intentionally portable: it uses TF-IDF/BM25 hybrid retrieval, a cross-encoder reranker, local or API language-model clients and an extractive fallback. The metrics on this page come from the versioned public evaluation artefacts unless stated otherwise.

Public source

The linked repository contains the portable pipeline, evaluation code and saved results. The professional Azure implementation is separate and is not included.

Check the request, find evidence, then check the answer.

  1. Input guardDetect advice, pricing, injection and obvious personal data.
  2. Hybrid retrievalCombine TF-IDF and BM25 candidates with rank fusion.
  3. RerankUse a cross-encoder to reorder the most relevant passages.
  4. AnswerGenerate or extract only from supplied policy evidence.
  5. Output checksValidate citations, grounding and advice leakage.

The browser demo uses BM25 search, rule-based checks and quoted passages. It omits the language model, cross-encoder and learned injection detector; all processing stays in your browser.

Test whether the clause was found before grading the answer built from it.

Retrieval evaluation: the 61 answerable questions are run through each retrieval configuration. A hit is defined by overlap with the gold supporting page. Recall@5 asks whether the answer page appears anywhere in the top five; hit@1, MRR@5 and nDCG@5 capture rank quality. Bootstrap confidence intervals are retained in the project artefacts.

Guardrail evaluation: 40 adversarial prompts and 30 benign controls are scored deterministically. Safe-rate measures correct handling of risky prompts; benign false-positive rate catches a system that becomes “safe” by refusing useful questions.

Answer evaluation: outputs record whether a cited page was actually retrieved and preserve the evidence shown to the answerer. In the Azure work, RAGAS experiments and MLflow runs were used to compare broader response-quality dimensions; those scores are not presented here because they are not in the public repository artefacts.

Bar chart comparing recall at five and nDCG at five across QuoteGuard retrieval configurations
Hybrid retrieval plus cross-encoder reranking led on point estimates. BM25 plus reranking was close enough that the small sample does not support a strong claim of superiority.

Retrieval improved, and the revised checks passed the tuned prompt suite.

0.803
Recall@5 · hybrid retrieval plus reranking · n=61
0.632
nDCG@5 · rewards placing the supporting passage higher
72.5 → 100%
Safe-rate on the 40-prompt tuned adversarial suite
QuoteGuard retrieval results on 61 answerable questions
RetrieverHit@1Recall@5MRR@5nDCG@5
TF-IDF0.4100.6890.5090.540
Dense (bge-small)0.3770.6070.4660.498
TF-IDF + rerank0.4750.7380.5660.590
Hybrid + rerank0.4920.8030.5960.632
QuoteGuard chart showing adversarial safe-rate rising from 72.5 to 100 percent and benign over-refusal falling from 6.7 to zero percent
After tightening intent patterns and adding a semantic scope gate, the system handled all 40 prompts in the same adversarial suite; benign over-refusal fell from 6.7% to 0%.

A larger question set changed which retriever I would choose.

The first benchmark was too small

TF-IDF looked strongest on an early 20-question set. On 61 answerable questions, BM25 clearly beat it. The earlier result had been overfit to a narrow sample.

Dense retrieval underperformed

Dense embeddings were weakest on this term-heavy policy. That does not imply dense retrieval is generally worse; it means the corpus and questions rewarded exact terminology.

The safety result is tuned, not universal

The 100% safe-rate is on 40 prompts used during one tighten-and-rerun cycle. It is evidence that the identified gaps were closed, not proof against unseen attacks.

Retrieval is not answer correctness

Recall@5 shows that supporting pages were surfaced. It does not by itself prove that every generated answer was complete, faithful or appropriately qualified.

One document limits generalisation

Layout, terminology and policy structure vary by insurer and product. Parser and retrieval choices need retesting across a broader document set.

Add independent evaluation and production observability.

  1. Freeze an unseen adversarial holdout and commission independent prompt attacks.
  2. Evaluate multiple policies, scanned PDFs, tables and cross-document questions.
  3. Expand end-to-end answer grading for completeness, citation entailment and unsupported claims.
  4. Measure latency and cost by stage in both the portable and Azure deployments.
  5. Monitor retrieval drift, refusal rates and citation failures in MLflow or an equivalent audit trail.

Ask a policy question — or try to cross a boundary.

This lightweight demo runs entirely in your browser. It loads the public policy chunks only when opened, uses BM25 retrieval and shows its guardrail trace and cited evidence. No question is sent to an API.

Load QuoteGuard in this page

Faithful but lighter: this browser version omits LLM synthesis, the cross-encoder reranker and the learned injection model. It demonstrates retrieval, heuristic guardrails, extractive grounding and citation checks.

Open this panel to load the in-browser engine.

← Previous: Legal Text Anonymiser Next: Touchline →