SCAD-RAG: Plug-and-Play Context-Sufficiency Auditing for RAG Hallucination Diagnosis
SCAD-RAG is a local, reproducible research codebase for claim-level hallucination diagnosis in retrieval-augmented generation (RAG). It treats RAG hallucination diagnosis as a plug-and-play context-sufficiency auditing problem rather than only a closed binary detection problem. The same diagnostic features can run as a standalone lightweight auditor or be attached to strong external detectors as a post-hoc risk-ranking and attribution layer.
The project is designed for Windows 10/11, RTX 4060 8GB-class hardware, and CPU fallback. It does not call OpenAI, Anthropic, Gemini, Cohere, or any commercial LLM API.

RAG hallucination is not only a generation problem. It is a context-use problem across retrieval, context alignment, and generation. SCAD-RAG models this chain with four groups of signals:
The term counterfactual is used operationally: SCAD-RAG performs controlled context-set perturbations to test score robustness. It does not claim formal causal identification of the generator. The theoretical principle is finite-difference context-sensitivity: a reliable claim-level decision should be supported by sufficient context and should respond when that contextual basis is weakened.
Hard negatives are selected without gold labels in default inference. The selector ranks semantically related candidates by relevance, weak entailment, low coverage, and contradiction tendency, then falls back to a low-relevance distractor if no suitable candidate exists. Contradiction attribution is guarded by an NLI reliability gate so high-neutral or low-coverage cases abstain instead of being forced into fine-grained labels.
quick_test runs with toy data and dummy models.RAGTruth is highly imbalanced, so Accuracy is reported as an auxiliary metric. Hallucination-F1, Binary Macro-F1, AUROC, and risk-error correlation are the main paper-facing metrics.
| Method | Hall-F1 | Binary Macro-F1 | AUROC | Accuracy | Risk Corr. |
|---|---|---|---|---|---|
| Majority | 0.1612 | 0.0806 | 0.5489 | 0.0876 | -0.0908 |
| Lexical-overlap | 0.1712 | 0.1626 | 0.5489 | 0.1627 | 0.0182 |
| Similarity-only | 0.1353 | 0.4239 | 0.5489 | 0.5684 | -0.4003 |
| NLI-only | 0.1852 | 0.2741 | 0.5489 | 0.2824 | 0.0831 |
| ESS-rule | 0.1839 | 0.2581 | 0.5489 | 0.2629 | 0.1073 |
| SCAD-RAG-Rule | 0.1856 | 0.2510 | 0.5415 | 0.2462 | 0.1142 |
| SCAD-RAG-Calibrated | 0.2028 | 0.4453 | 0.6061 | 0.5512 | 0.4503 |
SCAD-RAG can also be used as a post-hoc audit layer over strong open-source detectors. In RAGTruth-500 fusion diagnostics, SCAD score fusion improves selective-risk ranking and several detection metrics for LettuceDetect, HHEM, Osiris-3B, and MiniCheck style detectors. Across the four detectors, SCAD-score fusion reduces selective-risk AUC by an average relative reduction of 31.62% and improves accuracy by an average relative gain of 7.86%.
| System | Hall-F1 | AUROC | Accuracy | Brier | SR-AUC |
|---|---|---|---|---|---|
| LettuceDetect | 0.6082 | 0.8527 | 0.9524 | 0.0521 | 0.0244 |
| LD + SCAD-score | 0.6182 | 0.8824 | 0.9552 | 0.0508 | 0.0159 |
| LD + SCAD-risk | 0.6082 | 0.8527 | 0.9524 | 0.0521 | 0.0162 |
| HHEM | 0.2392 | 0.7463 | 0.8372 | 0.2974 | 0.0418 |
| HHEM + SCAD-score | 0.1918 | 0.7529 | 0.8742 | 0.2373 | 0.0336 |
| HHEM + SCAD-risk | 0.2392 | 0.7463 | 0.8372 | 0.2974 | 0.0418 |
| Osiris-3B | 0.1960 | 0.6325 | 0.7143 | 0.2386 | 0.1016 |
| Osiris + SCAD-score | 0.1720 | 0.7187 | 0.8905 | 0.2534 | 0.0365 |
| Osiris + SCAD-risk | 0.1960 | 0.6325 | 0.7143 | 0.2386 | 0.0805 |
| MiniCheck | 0.2222 | 0.7606 | 0.7872 | 0.3691 | 0.0503 |
| MiniCheck + SCAD-score | 0.2264 | 0.7643 | 0.8032 | 0.3020 | 0.0463 |
| MiniCheck + SCAD-risk | 0.2222 | 0.7606 | 0.7872 | 0.3691 | 0.0531 |
Additional paper-facing tables and SVG figures are available in paper_assets/:
paper_assets/tables/ragtruth_main_results.mdpaper_assets/tables/external_detector_fusion.mdpaper_assets/tables/fever_relation_results.mdpaper_assets/tables/risk_diagnostics.mdpaper_assets/figures/evidence_perturbation_probe.svgcd "C:\path\to\scad_rag"
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -e ".[dev]"
For real local Hugging Face models:
pip install -e ".[default,dev]"
If GPU memory is limited, use configs/cpu.yaml or reduce batch_size and nli_batch_size.
The quick test requires no network, no GPU, no real dataset, and no model download:
python -m scad_rag.cli.prepare_data --config configs/quick_test.yaml --dataset toy
python -m scad_rag.cli.run_pipeline --config configs/quick_test.yaml --method scad_rag
python -m scad_rag.cli.evaluate --config configs/quick_test.yaml
python -m scad_rag.cli.compare_baselines --config configs/quick_test.yaml
Or run:
.\scripts\run_quick_test.ps1
Download public RAGTruth files:
python -m scad_rag.cli.download_ragtruth --out_dir data/raw/ragtruth --verify true
Prepare a 500-sample run:
python -m scad_rag.cli.prepare_data --config configs/default.yaml --dataset ragtruth --max_samples 500
python -m scad_rag.cli.tune_thresholds --config configs/default.yaml --dataset ragtruth --split validation --max_samples 500
python -m scad_rag.cli.run_pipeline --config configs/default.yaml --method scad_rag --max_samples 500
python -m scad_rag.cli.compare_baselines --config configs/default.yaml --max_samples 500
Or run the scripted pipeline:
.\scripts\run_ragtruth_500.ps1
.\scripts\run_real_model_smoke_test.ps1
This checks whether local embedding and NLI models load correctly, whether CUDA/CPU device selection works, and whether predictions.csv and metrics.json are generated.
Run the guard before release or experiments:
python -m scad_rag.utils.no_api_guard
The guard scans src/, scripts/, and tests/ for forbidden commercial API imports and endpoints.
Each pipeline run creates experiments/runs/{timestamp}_{method}/ with:
predictions.jsonlpredictions.csvsentence_level_results.csvclaim_evidence_scores.csvsufficient_context_results.csvcounterfactual_audit.csvrisk_calibration.csvmetrics.jsoncase_studies.mderror_analysis.mdlatex_table_metrics.txtGenerated runs, real datasets, and model files are ignored by Git.
configs/quick_test.yaml uses dummy models and bundled toy data.configs/default.yaml uses local Hugging Face models and device: auto.strict_no_gold_inference: true is enabled for prediction by default.This repository contains the core research code, toy data, tests, configuration files, experiment scripts, and lightweight paper-facing assets. It does not include real RAGTruth/FEVER/SciFact files, generated experiment run folders, model checkpoints, or compiled manuscript PDFs.
If this repository is useful, cite the accompanying manuscript:
@misc{scadrag2026,
title = {SCAD-RAG: Plug-and-Play Context-Sufficiency Auditing for RAG Hallucination Diagnosis},
author = {Wang, Yi and Shang, Wenqian and Yi, Tong and Zhu, Haibin},
year = {2026},
note = {Code: https://github.com/wangyi11111111/SCAD-RAG}
}
MIT License. See LICENSE.
10 commits
Python
97.0%
PowerShell
3.0%
SCAD-RAG: Plug-and-Play Context-Sufficiency Auditing for RAG Hallucination Diagnosis
SCAD-RAG is a local, reproducible research codebase for claim-level hallucination diagnosis in retrieval-augmented generation (RAG). It treats RAG hallucination diagnosis as a plug-and-play context-sufficiency auditing problem rather than only a closed binary detection problem. The same diagnostic features can run as a standalone lightweight auditor or be attached to strong external detectors as a post-hoc risk-ranking and attribution layer.
The project is designed for Windows 10/11, RTX 4060 8GB-class hardware, and CPU fallback. It does not call OpenAI, Anthropic, Gemini, Cohere, or any commercial LLM API.

RAG hallucination is not only a generation problem. It is a context-use problem across retrieval, context alignment, and generation. SCAD-RAG models this chain with four groups of signals:
The term counterfactual is used operationally: SCAD-RAG performs controlled context-set perturbations to test score robustness. It does not claim formal causal identification of the generator. The theoretical principle is finite-difference context-sensitivity: a reliable claim-level decision should be supported by sufficient context and should respond when that contextual basis is weakened.
Hard negatives are selected without gold labels in default inference. The selector ranks semantically related candidates by relevance, weak entailment, low coverage, and contradiction tendency, then falls back to a low-relevance distractor if no suitable candidate exists. Contradiction attribution is guarded by an NLI reliability gate so high-neutral or low-coverage cases abstain instead of being forced into fine-grained labels.
quick_test runs with toy data and dummy models.RAGTruth is highly imbalanced, so Accuracy is reported as an auxiliary metric. Hallucination-F1, Binary Macro-F1, AUROC, and risk-error correlation are the main paper-facing metrics.
| Method | Hall-F1 | Binary Macro-F1 | AUROC | Accuracy | Risk Corr. |
|---|---|---|---|---|---|
| Majority | 0.1612 | 0.0806 | 0.5489 | 0.0876 | -0.0908 |
| Lexical-overlap | 0.1712 | 0.1626 | 0.5489 | 0.1627 | 0.0182 |
| Similarity-only | 0.1353 | 0.4239 | 0.5489 | 0.5684 | -0.4003 |
| NLI-only | 0.1852 | 0.2741 | 0.5489 | 0.2824 | 0.0831 |
| ESS-rule | 0.1839 | 0.2581 | 0.5489 | 0.2629 | 0.1073 |
| SCAD-RAG-Rule | 0.1856 | 0.2510 | 0.5415 | 0.2462 | 0.1142 |
| SCAD-RAG-Calibrated | 0.2028 | 0.4453 | 0.6061 | 0.5512 | 0.4503 |
SCAD-RAG can also be used as a post-hoc audit layer over strong open-source detectors. In RAGTruth-500 fusion diagnostics, SCAD score fusion improves selective-risk ranking and several detection metrics for LettuceDetect, HHEM, Osiris-3B, and MiniCheck style detectors. Across the four detectors, SCAD-score fusion reduces selective-risk AUC by an average relative reduction of 31.62% and improves accuracy by an average relative gain of 7.86%.
| System | Hall-F1 | AUROC | Accuracy | Brier | SR-AUC |
|---|---|---|---|---|---|
| LettuceDetect | 0.6082 | 0.8527 | 0.9524 | 0.0521 | 0.0244 |
| LD + SCAD-score | 0.6182 | 0.8824 | 0.9552 | 0.0508 | 0.0159 |
| LD + SCAD-risk | 0.6082 | 0.8527 | 0.9524 | 0.0521 | 0.0162 |
| HHEM | 0.2392 | 0.7463 | 0.8372 | 0.2974 | 0.0418 |
| HHEM + SCAD-score | 0.1918 | 0.7529 | 0.8742 | 0.2373 | 0.0336 |
| HHEM + SCAD-risk | 0.2392 | 0.7463 | 0.8372 | 0.2974 | 0.0418 |
| Osiris-3B | 0.1960 | 0.6325 | 0.7143 | 0.2386 | 0.1016 |
| Osiris + SCAD-score | 0.1720 | 0.7187 | 0.8905 | 0.2534 | 0.0365 |
| Osiris + SCAD-risk | 0.1960 | 0.6325 | 0.7143 | 0.2386 | 0.0805 |
| MiniCheck | 0.2222 | 0.7606 | 0.7872 | 0.3691 | 0.0503 |
| MiniCheck + SCAD-score | 0.2264 | 0.7643 | 0.8032 | 0.3020 | 0.0463 |
| MiniCheck + SCAD-risk | 0.2222 | 0.7606 | 0.7872 | 0.3691 | 0.0531 |
Additional paper-facing tables and SVG figures are available in paper_assets/:
paper_assets/tables/ragtruth_main_results.mdpaper_assets/tables/external_detector_fusion.mdpaper_assets/tables/fever_relation_results.mdpaper_assets/tables/risk_diagnostics.mdpaper_assets/figures/evidence_perturbation_probe.svgcd "C:\path\to\scad_rag"
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -e ".[dev]"
For real local Hugging Face models:
pip install -e ".[default,dev]"
If GPU memory is limited, use configs/cpu.yaml or reduce batch_size and nli_batch_size.
The quick test requires no network, no GPU, no real dataset, and no model download:
python -m scad_rag.cli.prepare_data --config configs/quick_test.yaml --dataset toy
python -m scad_rag.cli.run_pipeline --config configs/quick_test.yaml --method scad_rag
python -m scad_rag.cli.evaluate --config configs/quick_test.yaml
python -m scad_rag.cli.compare_baselines --config configs/quick_test.yaml
Or run:
.\scripts\run_quick_test.ps1
Download public RAGTruth files:
python -m scad_rag.cli.download_ragtruth --out_dir data/raw/ragtruth --verify true
Prepare a 500-sample run:
python -m scad_rag.cli.prepare_data --config configs/default.yaml --dataset ragtruth --max_samples 500
python -m scad_rag.cli.tune_thresholds --config configs/default.yaml --dataset ragtruth --split validation --max_samples 500
python -m scad_rag.cli.run_pipeline --config configs/default.yaml --method scad_rag --max_samples 500
python -m scad_rag.cli.compare_baselines --config configs/default.yaml --max_samples 500
Or run the scripted pipeline:
.\scripts\run_ragtruth_500.ps1
.\scripts\run_real_model_smoke_test.ps1
This checks whether local embedding and NLI models load correctly, whether CUDA/CPU device selection works, and whether predictions.csv and metrics.json are generated.
Run the guard before release or experiments:
python -m scad_rag.utils.no_api_guard
The guard scans src/, scripts/, and tests/ for forbidden commercial API imports and endpoints.
Each pipeline run creates experiments/runs/{timestamp}_{method}/ with:
predictions.jsonlpredictions.csvsentence_level_results.csvclaim_evidence_scores.csvsufficient_context_results.csvcounterfactual_audit.csvrisk_calibration.csvmetrics.jsoncase_studies.mderror_analysis.mdlatex_table_metrics.txtGenerated runs, real datasets, and model files are ignored by Git.
configs/quick_test.yaml uses dummy models and bundled toy data.configs/default.yaml uses local Hugging Face models and device: auto.strict_no_gold_inference: true is enabled for prediction by default.This repository contains the core research code, toy data, tests, configuration files, experiment scripts, and lightweight paper-facing assets. It does not include real RAGTruth/FEVER/SciFact files, generated experiment run folders, model checkpoints, or compiled manuscript PDFs.
If this repository is useful, cite the accompanying manuscript:
@misc{scadrag2026,
title = {SCAD-RAG: Plug-and-Play Context-Sufficiency Auditing for RAG Hallucination Diagnosis},
author = {Wang, Yi and Shang, Wenqian and Yi, Tong and Zhu, Haibin},
year = {2026},
note = {Code: https://github.com/wangyi11111111/SCAD-RAG}
}
MIT License. See LICENSE.
10 commits
Python
97.0%
PowerShell
3.0%