Customers and service teams
People seeking factual explanations of policy wording, with page citations they can inspect.
02 · RAG · LLM evaluation
A guardrailed retrieval system for insurance policy questions: find the right clause, answer from quoted evidence, refuse unsafe requests, and record why each decision was made.
Problem
Insurance product disclosure statements are long, structured and easy to misread. A customer may ask a simple question whose answer depends on a definition, exclusion and section-specific condition several pages apart. A fluent answer without the right clause is worse than a clear refusal.
People seeking factual explanations of policy wording, with page citations they can inspect.
The assistant explains the supplied document but does not recommend cover, personalise advice or generate a premium.
If retrieval does not surface support, the correct behaviour is “I don’t have that information,” not improvisation.
Data
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.
Approach
The public companion parses the policy, retrieves with lexical signals, fuses rankings, reranks candidates and produces a cited answer or explicit refusal. Each safety decision is recorded in a trace so a reviewer can see whether pricing, advice, injection, scope or grounding caused the response.
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.
Azure, RAGAS and MLflow are relevant experience, but the public repository does not pretend to contain proprietary work code. The open companion demonstrates the same evaluation logic with inspectable components.
System architecture
The browser demo keeps the interaction entirely client-side. It uses BM25 plus heuristic guards and extractive answers; it omits the language-model synthesiser, cross-encoder and learned injection detector. That keeps the demo free and inspectable while labelling what is and is not faithful to the full pipeline.
Evaluation method
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.
Results
| Retriever | Hit@1 | Recall@5 | MRR@5 | nDCG@5 |
|---|---|---|---|---|
| TF-IDF | 0.410 | 0.689 | 0.509 | 0.540 |
| Dense (bge-small) | 0.377 | 0.607 | 0.466 | 0.498 |
| TF-IDF + rerank | 0.475 | 0.738 | 0.566 | 0.590 |
| Hybrid + rerank | 0.492 | 0.803 | 0.596 | 0.632 |
Failure cases & trade-offs
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 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 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.
Recall@5 shows that supporting pages were surfaced. It does not by itself prove that every generated answer was complete, faithful or appropriately qualified.
Layout, terminology and policy structure vary by insurer and product. Parser and retrieval choices need retesting across a broader document set.
What I would improve next
Live demo & source
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.
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.