A cross-encoder model for detecting citation drift in Retrieval-Augmented Generation (RAG) systems. Given a user-facing claim, an evidence representation, and a source passage, the model predicts whether the citation is valid (the source supports the claim).
Model Description
This model addresses a critical reliability problem in RAG systems: citation drift, where generated text diverges from source documents in ways that break attribution. The problem is particularly severe in cross-lingual settings where the answer language differs from source document language.
Unlike embedding-based approaches that encode texts separately, the cross-encoder sees all three components together, enabling:
Cross-attention between claim and source
Detection of subtle semantic mismatches
Better handling of paraphrases vs. factual errors
Intended Use
Primary Use Cases
Post-hoc citation verification: Validate citations in RAG outputs before serving to users
Citation drift detection: Identify claims that have semantically drifted from their sources
Training signal: Provide rewards for citation-aware generation
Out of Scope
General NLI/entailment (model is specialized for RAG citation patterns)
Fact-checking against world knowledge (requires source passage)
Non-English source documents (trained on English sources only)
How to Use
Installation
pip install transformers torch
Basic Usage
python
1from transformers import AutoTokenizer, AutoModelForSequenceClassification
2import torch
34# Load model5model_name ="anonymous-acl2026/dualtrack-alignment"# Replace with actual path6tokenizer = AutoTokenizer.from_pretrained(model_name)7model = AutoModelForSequenceClassification.from_pretrained(model_name)8model.eval()910defcheck_citation(user_claim:str, evidence:str, source:str, threshold:float=0.5)->tuple[bool,float]:11"""
12 Check if a citation is valid.
1314 Args:
15 user_claim: The claim shown to the user
16 evidence: Evidence track representation (can be same as user_claim)
17 source: The source passage being cited
18 threshold: Classification threshold (default from training)
1920 Returns:
21 (is_valid, probability)
22 """23# Format input24 text =f"User claim: {user_claim}\n\nEvidence: {evidence}\n\nSource passage: {source}"2526# Tokenize27 inputs = tokenizer(text, return_tensors="pt", truncation=True, max_length=512)2829# Predict30with torch.no_grad():31 outputs = model(**inputs)32 prob = torch.softmax(outputs.logits, dim=-1)[0,1].item()3334return prob >= threshold, prob
3536# Example: Valid citation37is_valid, prob = check_citation(38 user_claim="Python was created by Guido van Rossum.",39 evidence="Python was created by Guido van Rossum.",40 source="Python is a programming language created by Guido van Rossum in 1991."41)42print(f"Valid: {is_valid}, Probability: {prob:.3f}")43# Output: Valid: True, Probability: 0.954445# Example: Invalid citation (wrong date)46is_valid, prob = check_citation(47 user_claim="Python was created in 1989.",48 evidence="Python was created in 1989.",49 source="Python is a programming language created by Guido van Rossum in 1991."50)51print(f"Valid: {is_valid}, Probability: {prob:.3f}")52# Output: Valid: False, Probability: 0.12
Batch Processing
python
1defbatch_check_citations(examples:list[dict], batch_size:int=16)->list[float]:2"""
3 Check multiple citations efficiently.
45 Args:
6 examples: List of dicts with keys 'user', 'evidence', 'source'
7 batch_size: Batch size for inference
89 Returns:
10 List of probabilities
11 """12 all_probs =[]1314for i inrange(0,len(examples), batch_size):15 batch = examples[i:i + batch_size]1617 texts =[18f"User claim: {ex['user']}\n\nEvidence: {ex['evidence']}\n\nSource passage: {ex['source']}"19for ex in batch
20]2122 inputs = tokenizer(23 texts,24 return_tensors="pt",25 truncation=True,26 max_length=512,27 padding=True28)2930with torch.no_grad():31 outputs = model(**inputs)32 probs = torch.softmax(outputs.logits, dim=-1)[:,1].tolist()3334 all_probs.extend(probs)3536return all_probs