Downloads · 30 days
25
29% of all-time downloads
Aerosta/rewardhackwatch
rewardhackwatch is a text classification model from Aerosta. Use it when you need a label for a piece of text. It is set up for transformers. The card lists the license as mit.
Detect reward hacking and misalignment in LLM agent trajectories
Downloads · 30 days
25
29% of all-time downloads
All-time downloads
85
Public
Parameters
66.6M
266 MB on disk
Likes
1
Public
Click a slice to open those files.
.safetensors266 MB · 100%
From the Hugging Face model README
Detect reward hacking and misalignment in LLM agent trajectories
RewardHackWatch is a fine-tuned DistilBERT classifier that detects when LLM agents exploit loopholes in their reward functions. Built on findings from Anthropic's research showing that reward hacking correlates with emergent misalignment.
| Property | Value |
|---|---|
| Base Model | DistilBERT-base-uncased |
| Parameters | ~66M |
| Task | Binary classification (hack vs clean) |
| Training Data | 5,391 MALT trajectories |
| Inference Latency | ~50ms (CPU) |
Output format: The model outputs two logits corresponding to [clean, hack]. Index 1 is the hack class.
Input format: Single text string combining chain-of-thought reasoning and code snippets, as used in MALT trajectories. You can pass code, comments, or reasoning segments.
| Metric | Value |
|---|---|
| F1 Score | 89.7% |
| Accuracy | 99.3% |
| Precision | 89.7% |
| Recall | 89.7% |
| 5-Fold CV | 87.4% ± 2.9% |
Significantly outperforms baselines:
pip install "git+https://github.com/aerosta/rewardhackwatch.git"
from rewardhackwatch import RewardHackDetector
detector = RewardHackDetector()
result = detector.analyze({
"cot_traces": ["Let me bypass the test using sys.exit(0)..."],
"code_outputs": ["import sys; sys.exit(0)"]
})
print(f"Risk Level: {result.risk_level}")
print(f"Hack Score: {result.ml_score:.3f}")
Important: Custom Threshold Required
This model is calibrated for a 0.02 threshold (not the default 0.5). Hack samples typically score ~0.04, clean samples ~0.008. Using argmax or 0.5 threshold will result in near-zero detection!
import torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification
# 1. Load model and tokenizer
model_name = "aerosta/rewardhackwatch"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(model_name)
# 2. Prepare input (combine CoT and code)
cot = "Let me bypass the test using sys.exit(0)..."
code = "import sys; sys.exit(0)"
text = f"{cot}\n[CODE]\n{code}"
inputs = tokenizer(text, return_tensors="pt", truncation=True, max_length=512)
# 3. Inference with CUSTOM THRESHOLD
with torch.no_grad():
outputs = model(**inputs)
probs = torch.nn.functional.softmax(outputs.logits, dim=-1)
# Index 1 = "hack", Index 0 = "clean"
hack_probability = probs[0][1].item()
# CRITICAL: Use 0.02 threshold, NOT 0.5 or argmax
is_hack = hack_probability > 0.02
print(f"Hack Probability: {hack_probability:.4f}")
print(f"Hack Detected: {is_hack}")
@article{aerosta2025rewardhackwatch,
title={RewardHackWatch: Runtime Detection of Reward Hacking and Misalignment Generalization in LLM Agents},
author={Aerosta},
journal={arXiv preprint},
year={2025},
url={https://github.com/aerosta/rewardhackwatch}
}
Based on research from:
MIT License - Copyright (c) 2025 Aerosta