RAG Evaluation Should Focus on How Systems Fail
· 68 min read · Views --
Last updated on

RAG Evaluation Should Focus on How Systems Fail

Author: Alex Xiang


The part of a RAG demo that gets praised most easily is often the most dangerous part after launch: the answer sounds plausible.

I once saw a pilot for a company policy knowledge base. A dozen employee handbooks, reimbursement rules, leave policies, procurement flows, and FAQ documents were loaded into a vector database. In the meeting room, people asked “What is the hotel standard for business trips?”, “Can probation employees apply for annual leave?”, and “How should a lost laptop be reported?” The model answered, with citations. Everyone felt it could be connected to the office portal and at least reduce repeated questions to HR and administration.

The real issue came from a modest question: “Can probation employees apply for remote work?” The system answered: “Yes. Up to four days per month, with direct-manager approval.” The sentence itself was partly correct. The problem was that it cited an old Flexible Work Trial Policy, not the Remote Work and Attendance Supplement published two weeks earlier. The old document’s four-day rule was a pilot rule. The new document changed scope, approval chain, and exceptions. If you looked only at the final answer, it scored well. If you looked at the evidence, it was wrong.

That case became my line between RAG demo and RAG production. Demo evaluation asks whether the system can answer. Production evaluation asks whether the answer is supported by the right evidence. If evidence is wrong, a fluent answer becomes more dangerous.

RAG evaluation slices

The Incident Was Not That the Model Could Not Answer

The policy knowledge base had a simple goal: connect scattered policies, processes, FAQs, and announcements so employees did not need to search everywhere. The team did not build a complex agent first. It used standard RAG: user question, query rewrite, hybrid retrieval, rerank, top context chunks, model-generated answer, and visible citations.

The pilot data was not tiny. There were about 1,200 documents and more than 18,000 chunks from policy PDFs, internal wiki pages, FAQs, announcement archives, and exported policy tables. Each chunk had metadata:

FieldExampleUsage
doc_idpolicy_remote_work_2026_03Stable document identity
chunk_idpolicy_remote_work_2026_03#p4-s2Locate the exact fragment
titleRemote Work and Attendance SupplementDisplay and ranking
version2026-03-01Handle old and new policies
effective_from2026-03-15Determine current validity
ownerpeople_opsRoute failures to content owner
audienceall_employeePermission and applicability
security_levelinternalLogging and export control

From an engineering perspective, the pipeline was not absurd. It was not a toy vector search that let the model invent everything. The problem was the evaluation style. It resembled demo acceptance: prepare 80 common questions and ask humans to judge whether final answers are correct, smooth, and cited. Seventy-two passed. A 90% accuracy rate looked good enough for canary.

In the first production week, employee questions became messier. People asked whether annual leave could be combined with Spring Festival adjustments, what to do when an overseas hotel invoice was not under their own name, and whether probation employees needed attendance corrections for remote work. The system could still answer most of the time. But feedback showed a pattern: the answer seemed right, but the citation was not quite right; the cited clause supported part of the answer but not the whole answer; sometimes it cited an old policy while the answer mixed in wording from a new one.

This cannot be explained by the phrase “model hallucination” alone. The evaluation granularity was wrong.

The Sample That Was Half Right with Wrong Evidence

Expanding the incident sample makes the issue clear. The user asked:

{
  "sample_id": "hr_remote_work_017",
  "question": "Can probation employees apply for remote work?",
  "user_profile": {
    "role": "employee",
    "department": "sales",
    "location": "shanghai",
    "employment_status": "probation"
  },
  "time": "2026-04-02T10:31:00+08:00"
}

The system returned:

{
  "answer": "Yes. Probation employees can apply for remote work for up to four days per month, with direct-manager approval. If customer-site work, store duty, or onboarding training is involved, team scheduling takes priority.",
  "citations": [
    {
      "doc_id": "policy_flexible_work_trial_2025_09",
      "chunk_id": "policy_flexible_work_trial_2025_09#p2-s1",
      "title": "Flexible Work Trial Policy",
      "score": 0.82
    },
    {
      "doc_id": "faq_attendance_2026_01",
      "chunk_id": "faq_attendance_2026_01#q12",
      "title": "Attendance FAQ",
      "score": 0.76
    }
  ]
}

The human gold answer was:

{
  "expected_outcome": "answer",
  "gold_evidence": [
    "policy_remote_work_2026_03#p3-s2",
    "policy_remote_work_2026_03#p5-s1",
    "faq_probation_2026_03#q7"
  ],
  "answer_points": [
    "Probation employees may apply for remote work",
    "Up to four days per month",
    "Approval is required from both direct manager and department owner",
    "The first 30 days after onboarding are normally excluded; exceptions require HRBP filing",
    "Customer-site, store-duty, and onboarding-training arrangements take priority"
  ],
  "must_not_use": [
    "policy_flexible_work_trial_2025_09"
  ]
}

Why was the final answer easy to accept? Because it contained several correct phrases: may apply, four days, manager approval, scheduling priority. A human reviewer looking only at the conclusion might think it was good. But it missed department-owner approval and the first-30-days exception, and it cited a deprecated policy. Worse, the old document had not been removed; it was superseded by the new policy. Search matched “flexible work,” “probation,” and “remote work” to the old document, and rerank put it above newer evidence because the old title matched everyday language better.

The sample exposed three problems: retrieval did not enforce effective time, evaluation did not check evidence correctness, and release gates did not prevent old policies from overriding new ones.

We Split “Correct Answer” into Five Parts

After that incident, the evaluation no longer asked a generic “is the answer correct?” One answer was split into five independently judged results:

DimensionQuestionUsual fix when it fails
RecallDid gold evidence enter candidates?chunking, index fields, query rewrite, synonyms
RankingIs gold evidence in a usable rank?rerank, time weight, version policy, dedup
EvidenceAre final citations the right evidence?citation selection, evidence compression, old-doc downrank
FaithfulnessCan answer points be derived from citations?prompt, answer verification, sentence-level citations
BoundaryShould the system answer, clarify, refuse, or hand off?classifier, threshold, product policy

This looks detailed, but it prevents “the average score is good and nobody knows how to fix failures.” In the remote-work sample, the new policy was recalled into top 20 but ranked seventh. Only the old policy and an FAQ entered the top 5 context. Generation then merged attendance-FAQ content with the old policy. The final answer was not pure invention; it was gradually pushed there by wrong evidence.

Once split, engineering actions became clear. The fix was not just “use a stronger model.” Policy documents gained effective_from, supersedes, and status fields. Retrieval still allowed old and new versions, but rerank pushed superseded documents out of citation candidates. Answer generation required citations from status=active documents unless the user explicitly asked about historical policy.

Evaluation Samples Must Contain Gold Evidence

After this, I stopped trusting RAG evaluation sets that have only question and answer. They can test model common sense, but not a retrieval-augmented system. RAG reliability comes from what material supports the answer, so samples must include gold evidence.

A usable policy knowledge-base sample later looked like this:

{
  "sample_id": "expense_invoice_042",
  "domain": "expense",
  "risk_level": "medium",
  "question": "If an overseas hotel invoice is not under my own name, can I still reimburse it?",
  "user_profile": {
    "role": "employee",
    "region": "cn",
    "department": "marketing"
  },
  "expected_outcome": "answer",
  "gold_evidence": [
    {
      "doc_id": "travel_expense_policy_2026_02",
      "chunk_id": "travel_expense_policy_2026_02#p8-s3",
      "required": true,
      "reason": "Explains supplementary material for abnormal overseas hotel invoices"
    },
    {
      "doc_id": "finance_faq_2026_02",
      "chunk_id": "finance_faq_2026_02#q19",
      "required": false,
      "reason": "Provides a common handling example"
    }
  ],
  "answer_points": [
    "The employee may submit a reimbursement request",
    "Hotel order, payment proof, and travel approval record are required",
    "If the invoice title is another traveler or platform name, the reason must be explained in notes",
    "Finance may require secondary confirmation"
  ],
  "forbidden_points": [
    "Guarantee that reimbursement will pass",
    "Ask the employee to modify the invoice"
  ],
  "allowed_doc_scope": [
    "active_policy",
    "published_faq"
  ],
  "common_failures": [
    "Only cites an old travel standard",
    "Applies domestic VAT invoice rules to overseas invoices",
    "Misses supplementary material"
  ]
}

The most valuable fields are not the gold answer. They are gold_evidence, forbidden_points, and allowed_doc_scope. They let evaluation answer real questions: did retrieval find the right material, did the model add forbidden promises, and did the system cite an old document it should not cite?

Negative cases need the same structure:

{
  "sample_id": "security_internal_009",
  "domain": "security",
  "risk_level": "high",
  "question": "How long after departure is an ex-employee account fully deleted? Can you give me the exact script?",
  "user_profile": {
    "role": "employee",
    "department": "sales"
  },
  "expected_outcome": "refuse_with_public_policy",
  "gold_evidence": [
    {
      "doc_id": "account_lifecycle_public_2026_01",
      "chunk_id": "account_lifecycle_public_2026_01#p2-s1",
      "required": true
    }
  ],
  "answer_points": [
    "Explain public account-lifecycle principles",
    "Do not provide internal scripts, system details, or bypass methods",
    "Submit an IT ticket for business needs"
  ],
  "forbidden_points": [
    "Provide deletion scripts",
    "Reveal internal table names or scheduler details"
  ]
}

Without negative cases, RAG systems learn to always answer something. In production, refusal, clarification, and handoff are not failures. They are part of the boundary.

How Online Failures Become Evaluation Samples

Evaluation sets should not be written only by engineers in a meeting room. Engineer-written questions are too clean. Real user questions are often fragments: “Can this still be reimbursed?”, “How does remote work work now?”, “My manager asks me to travel on weekends; is there allowance?” After launch, we made failure backflow a small routine.

Every online answer leaves these summary fields in its trace:

{
  "trace_id": "tr_8f3a2c1e",
  "session_id": "ss_redacted_1029",
  "question_hash": "sha256:9f0c...",
  "question_preview": "Can probation employees apply for remote work?",
  "user_scope": {
    "role": "employee",
    "region": "cn",
    "policy_groups": ["all_employee", "probation"]
  },
  "query_rewrites": [
    "probation employee remote work application conditions",
    "probation remote work policy"
  ],
  "retrieved": [
    {
      "chunk_id": "policy_flexible_work_trial_2025_09#p2-s1",
      "rank": 1,
      "score": 0.82,
      "status": "superseded"
    },
    {
      "chunk_id": "policy_remote_work_2026_03#p3-s2",
      "rank": 7,
      "score": 0.63,
      "status": "active"
    }
  ],
  "selected_context": [
    "policy_flexible_work_trial_2025_09#p2-s1",
    "faq_attendance_2026_01#q12"
  ],
  "answer_citations": [
    "policy_flexible_work_trial_2025_09#p2-s1",
    "faq_attendance_2026_01#q12"
  ],
  "outcome": "answered",
  "feedback": {
    "thumb": "down",
    "reason": "citation_wrong"
  }
}

No full sensitive content is stored here. The question keeps only preview and hash; full original text is kept only in a short troubleshooting window. Documents are located by IDs and chunk IDs. User identity becomes permission summaries. This is enough for review without turning logs into another knowledge base.

Every day, samples are pulled from thumbs-down feedback, repeated follow-ups, citation clicks followed by re-asking, human handoff, refusals, low-confidence answers, and all high-risk domains. Each week, a small batch is manually labeled. The goal is not massive size; the goal is making real failures durable. Labeling must fill in expected_outcome, gold_evidence, answer_points, failure_type, and owner.

Once this loop runs, the evaluation set stops looking like an exam and starts looking like a production incident archive.

Do Not Show Only One Score

The team initially wanted one total score for release meetings: “RAG accuracy is 91.3%.” I understand the desire, but one score is not useful for debugging. We kept a total score, but put slice metrics first.

A pre-release evaluation table looked like this:

DatasetSamplesRecall passEvidence passFaithfulness passBoundary passHigh-risk blocks
smoke6098.3%96.7%95.0%100%0
policy_regression42094.8%91.2%90.5%96.4%3
negative_boundary12093.3%92.5%94.2%88.3%5
online_failures_recent8090.0%83.8%86.3%91.3%7

The worrying numbers are not the total score. They are online_failures_recent evidence pass at 83.8% and negative_boundary boundary pass at 88.3%. That says the new version has not really fixed recent production failures, and it remains too aggressive on unanswerable questions.

Each failed sample also records a failure type:

failure_typeMeaningExample
missing_gold_recallGold evidence not retrievedNew policy not in top 20
bad_rankGold evidence retrieved but too lowNew policy rank 7, old policy rank 1
wrong_citationCitation is not gold evidenceAnswer cites superseded document
unsupported_claimClaim cannot be derived from citationPromises reimbursement will pass
stale_policyExpired policy usedOld trial policy overrides new supplement
permission_leakUnauthorized material returnedRegular employee sees management process
should_clarifyShould clarify but answered directly”How is this allowance calculated?” without region
should_refuseShould refuse but answeredAsks for internal scripts or risk-control rules

Now the discussion becomes “old document status is missing from rerank features,” “negative-boundary classifier threshold is too loose,” or “FAQ chunks lack effective dates,” not “the model is bad.” That is the point of evaluation.

Release Gates Should Block the Right Changes

RAG release risk does not come only from prompt changes. Chunking, embedding, rerank, document sync, permission filtering, and model version can all make the system locally better and globally worse. The policy knowledge base later used hard gates:

GatePass conditionFailure action
Index integrity100% active-document coverage; superseded docs have superseded_byBlock release
Smoke setNo high-risk failures in key 60 samplesBlock release
Evidence correctnessPolicy regression evidence pass no worse than current online versionBlock or canary
FaithfulnessNo unsupported claim in high-risk samplesBlock release
Boundary samplesshould_refuse and should_clarify regress by no more than 1%Canary with manual review
Permission samplesAny permission leak blocksBlock release
Online failure regressionAll P0/P1 failures in the past 30 days must passBlock release

This looks conservative, but it addresses a real pattern: RAG changes often improve averages while worsening incident cases. For example, increasing top-k from 8 to 15 improved recall, but lowered evidence precision and made the model more likely to merge old and new policies. The total score rose slightly, but high-risk samples gained two unsupported claims. Without gates, that version would likely ship.

Release reports also need sample-level diffs:

sample_id: hr_remote_work_017
baseline:
  retrieved_gold_rank: 7
  selected_context: policy_flexible_work_trial_2025_09#p2-s1
  evidence_pass: false
candidate:
  retrieved_gold_rank: 2
  selected_context: policy_remote_work_2026_03#p3-s2
  evidence_pass: true
  answer_missing_points: ["first 30 days after onboarding normally excluded"]
decision: allow_canary, require content note in response template

This is closer to engineering truth than “score improved by 2.1%.”

Dashboards Should Drill from Trend to Sample

A RAG dashboard with only one accuracy curve will quickly be ignored. The policy knowledge base kept fields that let the team drill from trend to concrete samples:

Dashboard fieldMeaning
domainHR, finance, procurement, security, IT
risk_levellow, medium, high
expected_outcomeanswer, clarify, refuse, handoff
retrieved_gold_rankFirst rank where gold evidence appears
context_precision_at_kShare of selected context that is gold or acceptable evidence
citation_passWhether final citations support the answer
answer_point_coverageCoverage of required answer points
unsupported_claim_countClaims without evidence
stale_doc_usedWhether an expired document was used
permission_filter_passWhether permission filtering passed
feedback_rateDownvotes, follow-ups, citation-click followed by re-ask
ownerContent or engineering owner

The first screen shows overall traffic, answer/clarify/refuse ratios, downvote rate, evidence pass, and permission errors. The second screen breaks by domain: finance may miss conditions more often than HR, while security may be better at refusal. The third screen shows samples. Each anomaly can open a trace: what was retrieved, what was selected, what was cited, and what was answered.

stale_doc_used was especially useful. Many policy failures were not model reasoning failures. They were content-lifecycle failures. Old documents not removed, titles inconsistent, policies superseding each other invisibly: search faithfully exposed organizational mess. Long-term RAG evaluation forces content governance to become serious.

Document Governance Is Part of Evaluation

If evaluation results go only to the model team, fixes will be biased. Many failures are not prompt fixes; they are document fixes.

In the remote-work incident, the old Flexible Work Trial Policy should have been marked superseded. In the document system, someone had merely added “historical archive” to the title. Retrieval did not understand that convention, and the model would not automatically know archived meant “do not cite.” The fix was not making the prompt memorize more rules. It was adding explicit lifecycle fields:

doc_id: policy_flexible_work_trial_2025_09
status: superseded
effective_from: 2025-09-01
effective_to: 2026-03-14
superseded_by: policy_remote_work_2026_03
allowed_for_current_answer: false
allowed_for_history_question: true
owner: people_ops

Other failures came from missing content. For “overseas hotel invoice not under my own name,” the policy only said abnormal invoices require explanation, while the FAQ had examples. If the model answered vaguely, the issue was not ability; the content lacked the boundary users cared about. Evaluation marks those samples as content_gap and sends them to the content owner to add FAQ or policy clarification.

A mature RAG system eventually becomes a product maintained by search, model, content, and permissions together. Tuning the model alone cannot fix organizational knowledge.

Automatic Evaluation Helps, but It Is Not the Judge

Automatic evaluation is valuable, especially when release gates need to run hundreds or thousands of samples. LLM judges can check answer-point coverage, unsupported claims, and whether refusal was appropriate. Traditional metrics can compute recall, precision, MRR, and citation hit rate. But automatic scores should not be treated as truth.

The human rubric for policy RAG stayed simple:

ItemScoreJudgment
Evidence correctness0/2Citation must come from gold or equivalent valid evidence
Point coverage0/2Required conditions, limits, and exceptions are covered
Faithful expression0/2No promises beyond citations
Boundary handling0/2Clarify, refuse, or hand off when needed
Verifiable citation0/2User can click citation to exact source position

Automatic evaluation runs first; humans sample boundary cases. When automatic evaluation and human judgment disagree, keep the sample and reason. For example, a judge may mistake “you can submit a reimbursement request” for “reimbursement is guaranteed.” That subtle difference matters in finance policy. As samples accumulate, both judge prompts and human rubrics stabilize.

I prefer to think of automatic evaluation as a thermometer, not a judge. It tells you where fever may exist. It does not diagnose the illness by itself.

From Demo to Production Requires a Loop

Return to the remote-work sample. After the fix, the system did not merely answer better. It gained loops it previously lacked.

Before entering the index, documents must have status, effective time, audience, and owner. When answering online, traces record query rewrites, candidates, ranking, selected evidence, citations, and boundary decisions. User feedback and human handoff enter a failed-sample pool. Each week, a batch of real failures gets labeled with gold evidence and failure type. Every release runs smoke, regression, negative boundary, and recent online failure sets. Gates block by high-risk failures instead of average score.

These are not the highlights of a demo, but they decide whether RAG can keep working. Without them, every optimization is hand-tuned search: change a parameter, feel better, launch, wait for users to report errors. With them, failures become samples, samples become gates, and gates force content and engineering to improve together.

When I look at a RAG project now, I ask concrete questions:

  • Do evaluation samples have gold evidence, or only gold answers?
  • If the answer is accidentally correct but the citation is wrong, does it pass or fail?
  • How do old documents, new documents, not-yet-effective documents, and unauthorized documents behave in retrieval and citation?
  • How long does it take for online downvote samples to enter regression?
  • Does every embedding, rerank, chunking, or prompt change run fixed gates?
  • Can the dashboard drill from “evidence pass dropped” to the exact trace?

If these cannot be answered, the system is still in demo stage. Demos can impress with a few beautiful questions. Production cannot. Production users will not ask like your examples, documents will not remain clean, policies will change, permissions will change, and old knowledge will remain. What needs evaluation is not whether the model answers once, but how the system fails inside that mess, whether the failure can be seen, classified, and fixed.

RAG is not ultimately just a Q&A feature. It is a knowledge-delivery system with an evaluation loop. Only when the right answer and the right evidence are bound together should it answer policy questions on behalf of people.