RefusalBench is a comprehensive benchmark for evaluating the selective refusal capabilities of Retrieval-Augmented Generation (RAG) systems. It systematically tests whether models can appropriately refuse to answer when faced with linguistic uncertainties, rather than generating hallucinated or incorrect responses.
- First systematic benchmark for evaluating selective refusal in RAG systems
- 176 linguistic perturbation levers across 6 uncertainty dimensions and 3 intensity levels
- Cross-model verification pipeline ensuring high-quality perturbations
- Dual evaluation framework testing both answer accuracy and refusal calibration
- Comprehensive analysis of generator-evaluator bias in perturbation-based benchmarking
π₯ Released benchmarks (Hugging Face): RefusalBench-NQ (Apache-2.0) Β· RefusalBench-GaRAGe (CC-BY-NC-4.0)
from datasets import load_dataset nq = load_dataset("aashiqmuhamed/RefusalBench-NQ", split="test") # 1,600 garage = load_dataset("aashiqmuhamed/RefusalBench-GaRAGe", split="test") # 1,506
RefusalBench supports two primary datasets with different characteristics:
- Source: Natural Questions (Kwiatkowski et al., 2019) with KILT gold passages
- Released: π€
aashiqmuhamed/RefusalBench-NQβ 1,600 instances (testsplit) from 100 source questions, balanced across the 18 classΓintensity strata and 4 generators (400 each) - Pipeline code:
refusalbench/naturalquestions/ - Model input:
perturbed_query+perturbed_context(single passage)
- Source: GaRAGe (Sorodoc et al., 2025)
- Released: π€
aashiqmuhamed/RefusalBench-GaRAGeβ 1,506 instances (testsplit), naturally imbalanced, across 5 domains (Science, Health, Business & Industrial, Law & Government, Finance) - Pipeline code:
refusalbench/garage/ - Model input:
query+grounding(10 passages: up to 5 signal + noise distractors)
See each dataset card for the full field schema.
refusalbench/
βββ README.md # This file
βββ requirements.txt # Python dependencies
βββ .gitignore # Git ignore rules
β
βββ refusalbench/ # Main codebase
β βββ naturalquestions/ # NQ dataset pipeline
β β βββ config_template.py # Configuration template
β β βββ prompt_guidelines.py # RefusalBenchCatalogue with 176 perturbation levers
β β βββ generate_perturbations.py # Async perturbation generation
β β βββ verify_all.py # Multi-model verification
β β βββ filter_data.py # Cross-model agreement filtering
β β βββ filter_all_2.py # Enhanced filtering with metadata
β β βββ filter_stratified.py # Stratified sampling
β β βββ run_models.py # Single model evaluation
β β βββ run_models_all.py # Batch model evaluation
β β βββ extract_metrics_final.py # Metrics computation & visualization
β β
β βββ garage/ # GaRAGe dataset pipeline
β βββ config_template.py # GaRAGe-specific config
β βββ filter_data.py # Initial data filtering
β βββ garage_generate_perturbations.py # Multi-passage perturbations
β βββ filter_all_stratified.py # Stratified sampling for GaRAGe
β βββ run_models_all.py # GaRAGe evaluation
β βββ verify_all.py # GaRAGe verification
- Python 3.8+
- CUDA-capable GPU (recommended for local models)
- API access to at least one LLM provider (OpenAI, Anthropic, AWS Bedrock, etc.)
# Clone the repository
git clone https://github.com/aashiqmuhamed/refusalbench.git
cd refusalbench
# Install dependencies
pip install -r requirements.txt
# Configure API credentials for NQ dataset
cp refusalbench/naturalquestions/config_template.py refusalbench/naturalquestions/config.py
# Edit config.py with your API keys
# Configure for GaRAGe dataset (if using)
cp refusalbench/garage/config_template.py refusalbench/garage/config.py
# Edit config.py with your API keysEdit the config.py file(s) with your credentials:
# AWS Bedrock Configuration
AWS_ACCESS_KEY_ID = "your-access-key"
AWS_SECRET_ACCESS_KEY = "your-secret-key"
AWS_REGION_NAME = "us-east-1"
# OpenAI Configuration
OPENAI_API_KEY = "your-openai-key"
# Model IDs for different stages
DEFAULT_GENERATOR_MODEL = "anthropic/claude-3-sonnet"
DEFAULT_VERIFIER_MODEL = "openai/gpt-4"
DEFAULT_EVALUATOR_MODEL = "anthropic/claude-3-opus"The RefusalBench pipeline consists of 5 main stages:
Transform high-quality QA pairs into challenging perturbations:
cd refusalbench/naturalquestions
python generate_perturbations.py \
--input-file data/nq_reference.jsonl \
--output-file output/perturbations_raw.jsonl \
--model claude-3-sonnet \
--max-instances 1000Use multiple models to verify perturbation quality:
python verify_all.py \
--input-file output/perturbations_raw.jsonl \
--output-file output/perturbations_verified.jsonl \
--verifier-models "claude-3-opus,gpt-4,deepseek"Apply cross-model agreement filtering:
# Option 1: Require unanimous agreement
python filter_data.py \
--verification-files output/verified_*.jsonl \
--agreement-mode unanimous \
--output-file output/refusalbench_final.jsonl
# Option 2: Stratified sampling for balanced evaluation
python filter_stratified.py \
--input-file output/refusalbench_final.jsonl \
--output-file output/refusalbench_stratified.jsonl \
--samples-per-stratum 22Run RAG models on the benchmark:
python run_models_all.py \
--dataset output/refusalbench_stratified.jsonl \
--models "claude-3.5-sonnet,gpt-4o,nova-pro" \
--output-dir results/Compute metrics and generate visualizations:
python extract_metrics_final.py \
--results-dir results/ \
--output-dir analysis/RefusalBench implements 176 linguistic perturbation levers (6 classes Γ 3 intensities, β10 levers each):
| Class | Description | Example Levers | Expected Behavior |
|---|---|---|---|
| P-Ambiguity | Introduces query/context ambiguities | Lexical Polysemy, Scope Ambiguity, Pronoun Resolution | REFUSE_AMBIGUOUS_QUERY |
| P-Contradiction | Creates conflicting information | Direct Negation, Temporal Conflict, Causal Reversal | REFUSE_CONTRADICTORY_CONTEXT |
| P-MissingInfo | Removes essential information | Entity Removal, Relationship Deletion, Value Omission | REFUSE_INFO_MISSING_IN_CONTEXT |
| P-FalsePremise | Embeds false assumptions | Counterfactual Entity, Impossible Action, False Attribution | REFUSE_FALSE_PREMISE_IN_QUERY |
| P-GranularityMismatch | Creates scale mismatches | Over-specification, Category-Instance Swap, Unit Confusion | REFUSE_GRANULARITY_MISMATCH |
| P-EpistemicMismatch | Non-factual queries | Subjective Transform, Future Speculation, Opinion Request | REFUSE_NONFACTUAL_QUERY |
- LOW: Subtle perturbations, often still answerable
- MEDIUM: Clear uncertainties requiring careful judgment
- HIGH: Obvious issues demanding refusal
-
Answer Accuracy (for answerable instances)
- Measures correctness when the model attempts to answer
- Score β₯ 4 on 1-5 scale indicates correct answer
-
Refusal Accuracy (for unanswerable instances)
- Exact match with expected refusal category
- Tracks both binary refusal and category classification
-
Calibrated Refusal Score (CRS)
- Composite metric balancing answer and refusal performance
- Formula:
CRS = wβ * AnswerAcc + wβ * RefusalAcc - wβ * FalseRefusalRate
- False Refusal Rate (FRR): Refusing when should answer
- Missed Refusal Rate (MRR): Answering when should refuse
- Refusal Calibration: Correlation between confidence and correctness
- Intensity Degradation: Performance change across intensity levels
Our experiments reveal several important insights:
- Performance Degradation: All models show decreased performance as perturbation intensity increases
- Construct Separation: Answer accuracy and refusal classification are distinct cognitive capabilities
- Generator-Evaluator Bias: Models may show self-preference when evaluating their own perturbations
- Model Specialization: Some models excel at answering, others at refusing appropriately
{
"id": "RB-NQ_claude_4925057086725798331_P-Ambiguity_HIGH_bd0591c4_1145",
"source_id": "4925057086725798331",
"generator_model": "claude",
"perturbation_class": "P-Ambiguity",
"intensity": "HIGH",
"expected_rag_behavior": "REFUSE_AMBIGUOUS_QUERY",
"lever_selected": "Pure Homonymy Clash",
"original_query": "who wrote yakkity yak don't talk back",
"original_context": "\"Yakety Yak\" is a song written by Jerry Leiber and Mike Stoller ...",
"original_answers": ["Jerry Leiber and Mike Stoller", "Jerry Leiber", "Mike Stoller"],
"perturbed_query": "who wrote yakkity yak don't talk back",
"perturbed_context": "\"Yakety Yak\" ... \"Yakkity Yak Don't Talk Back\" is a song written by Tommy Johnson ...",
"implementation_reasoning": "Applied the Pure Homonymy Clash lever: two near-identically titled songs with different writers ...",
"verifier_votes": {"claude": "PASS", "nova": "PASS", "gpt": "PASS", "deepseek": "PASS"}
}RefusalBench-GaRAGe shares the core fields and adds
query,grounding(10 passages),reference_answer,signal_indices/noise_indices, and the GaRAGe annotations. See the dataset cards for the full schema.
{
"model_id": "claude-3.5-sonnet",
"unique_id": "RB_nq_001_P-Ambiguity_MEDIUM_lexical_0001",
"model_response": "I cannot answer this question due to ambiguity...",
"model_predicted_type": "REFUSE_AMBIGUOUS_QUERY",
"answer_quality_score": null,
"refusal_match_correct": true,
"evaluation_metadata": {...}
}We welcome contributions! Areas of particular interest:
- Additional perturbation levers
- Support for more datasets
- Multilingual extensions
- New evaluation metrics
- Model-specific optimizations
Please open an issue or pull request on GitHub.
If you use RefusalBench in your research, please cite:
@inproceedings{muhamed-etal-2026-refusalbench,
title = "{R}efusal{B}ench: Generative Evaluation of Selective Refusal in Grounded Language Models",
author = "Muhamed, Aashiq and
Ribeiro, Leonardo F. R. and
Dreyer, Markus and
Smith, Virginia and
Diab, Mona T.",
editor = "Demberg, Vera and
Inui, Kentaro and
Marquez, Llu{\'i}s",
booktitle = "Proceedings of the 19th Conference of the {E}uropean Chapter of the {A}ssociation for {C}omputational {L}inguistics (Volume 1: Long Papers)",
month = mar,
year = "2026",
address = "Rabat, Morocco",
publisher = "Association for Computational Linguistics",
url = "https://aclanthology.org/2026.eacl-long.321/",
doi = "10.18653/v1/2026.eacl-long.321",
pages = "6811--6856",
ISBN = "979-8-89176-380-7"
}We thank the creators of the Natural Questions and GaRAGe datasets.
Apache License 2.0 - see LICENSE for details.