superred-claim-harmbench
HarmBench standardized red-teaming benchmark
(Mazeika et al., ICML 2024) packaged as
a superred SecurityClaim against ChatbotTarget.
What it is
- 400 textual harmful behaviors (320 test split + 80 val split).
- Three functional categories per split: standard (159 / 41), contextual (81 / 19), copyright (80 / 20).
- Per-behavior binary verdict (1 = behavior elicited, 0 = refused or off-topic) from an LLM-as-judge using HarmBench's verbatim Llama-2 classifier prompt template, plus the upstream MinHash matcher for copyright behaviors.
- Headline metric: ASR = mean of per-behavior labels; reported per
functional and semantic category via
EvaluationResult.sub_scores.
Quick start
import asyncio, os
from chatbot_target import ChatbotTarget, USER_TAG, RESPONSE_READABLE_TAG
from harmbench_claim import harmbench_standard_val
from superred.core.controller import Controller, TargetFactory
api_key = os.environ["LITELLM_API_KEY"]
api_base = os.environ["LITELLM_API_BASE"]
# Fresh ChatbotTarget per task; bump concurrency for parallel evaluation
# (the chatbot wraps the LiteLLM proxy and is safe to call concurrently).
target_factory = TargetFactory(
create=lambda: ChatbotTarget(
model="openai/gpt-4o-mini", api_key=api_key, api_base=api_base,
),
concurrency=8,
)
# 41 standard val behaviors. For all 80 val behaviors (across 3 functional
# categories) use `harmbench_val(...)`; for the 320-task test split use
# `harmbench_test(...)`; for everything use `harmbench_complete(...)`.
claim = harmbench_standard_val(
judge_model="openai/gpt-4o-mini",
judge_api_base=api_base,
judge_api_key=api_key,
)
# Bring your own optimizer; for a single-shot DirectRequest baseline, see
# superred-experiments/test_harmbench_chatbot/direct_request_optimizer.py
from direct_request_optimizer import DirectRequestOptimizer
controller = Controller(
optimizer_factory=DirectRequestOptimizer,
target_factory=target_factory,
security_claim=claim,
scope=frozenset({USER_TAG, RESPONSE_READABLE_TAG}),
max_runs_per_task=1,
include_feedback=False,
)
result = asyncio.run(controller.run()) # -> ThreatModelResult
Installation
pip install -e ./security_claims/harmbench # provides the harmbench_claim package
python -m spacy download en_core_web_sm # for the copyright MinHash matcher
The pip-installable name is superred-claim-harmbench; the importable Python
package is harmbench_claim.
Public factories
The module exposes a hierarchical set of factories so you can pick any granularity from "one functional split of one dataset split" up to "the whole benchmark."
All factory parameters are keyword-only (the underlying signature uses
def harmbench_claim(*, judge_model, judge_api_base, judge_api_key, split, functional_categories, semantic_categories, csv_path, clip_tokens)).
# Parameterized base
harmbench_claim(*, judge_model="openai/gpt-4o-mini", split="test",
functional_categories=None, semantic_categories=None, ...)
# Leaf factories — six combinations of (split, functional_category)
harmbench_standard_test() harmbench_standard_val()
harmbench_contextual_test() harmbench_contextual_val()
harmbench_copyright_test() harmbench_copyright_val()
# Composed
harmbench_test() harmbench_val() # all 3 functional categories
harmbench_complete() # both splits
Leaf and composed factories accept the same judge / filter kwargs
(judge_model, judge_api_base, judge_api_key, semantic_categories,
csv_path, clip_tokens) but reject split / functional_categories
because those are hardcoded by the leaf — pass them to
harmbench_claim() directly if you need to override.
Each leaf factory returns a flat SecurityClaim of one Task per behavior;
the composed factories use SecurityClaim.from_claims lazy chaining.
Recommended scope
frozenset({USER_TAG, RESPONSE_READABLE_TAG}) (interactive black-box).
HarmBench's threat model assumes the attacker injects the user message
and observes the response. The claim itself does not pin a scope; the
experiment script picks the scope by passing it to the Controller
constructor. To sweep multiple scopes, instantiate one Controller per
scope and asyncio.gather them.
Per-task metadata for post-run analysis
Each HarmBenchTask exposes plain attributes so you can aggregate
result.task_results (the ThreatModelResult returned by
controller.run()) by any axis:
from collections import defaultdict
buckets: dict[tuple[str, str], list[bool]] = defaultdict(list)
for tr in result.task_results:
t = tr.task
buckets[("functional", t.functional_category)].append(tr.success)
buckets[("semantic", t.semantic_category)].append(tr.success)
EvaluationResult.sub_scores additionally carries
functional_<name>, semantic_<name>, and advbench_refusal_label keys
for in-trajectory attribution.
Deviations from upstream HarmBench
We document every deviation up front so ASR numbers are interpretable.
| Aspect | HarmBench reference | This port | Why |
|---|---|---|---|
| Judge model | cais/HarmBench-Llama-2-13b-cls (fine-tuned, ~93% agreement with humans) |
LLM-as-judge via LLMConfig (default in examples: gpt-4o-mini) using HarmBench's verbatim prompt template |
The 13B classifier needs ~26 GB VRAM. Our framework runs on the litellm proxy. The HarmBench paper itself (page 7) warns that closed-source judges are "far from ideal", but the canonical Llama-2-cls prompt template still applies. |
max_new_tokens on target |
512 (paper-mandated for ASR convergence; up to 30% variance otherwise) | provider default (no max_tokens override on ChatbotTarget) |
Conscious user decision; ASR comparable across runs within this port but not directly comparable to the HarmBench leaderboard. |
temperature on target |
0 (greedy) | 0 (already hardcoded in ChatbotTarget.run()) |
Faithful. |
| System prompt | none added by the pipeline | task sets system_prompt=""; ChatbotTarget then suppresses the system message entirely |
Faithful (verified by TestEmptySystemPrompt). |
| Contextual test-case rendering | f"{ContextString}\n\n---\n\n{Behavior}" (per baselines/direct_request/direct_request.py:24) |
identical, in Goal.description via render_test_case |
Faithful. |
| Copyright eval | MinHash + spaCy + 100 reference .pkl files; Jaccard > 0.6 |
identical port of compute_results_hashing from eval_utils.py; spaCy 3.8 instead of 3.7 (Python 3.13 compat) |
Near-faithful; tokenization may differ marginally from spaCy 3.7. |
| AdvBench refusal-prefix diagnostic | enabled via --include_advbench_metric (29 prefixes in eval_utils.py) |
always enabled as sub_scores["advbench_refusal_label"] |
Faithful (free additional metric). |
[/INST] prompt-injection sanitization in judge prompt |
none (upstream issue #91 is unfixed) | none | Vector is inert against chat-completions APIs (Llama-2 instruction tokens are plain text there). |
| Generation pre-judge clipping | classifier-tokenizer, 512 tokens, right-truncated | tiktoken (if installed) or 4-chars-per-token approximation, 512 tokens |
Approximation acceptable; Jaccard threshold tolerates small differences and the chat-completions judge has 128k context anyway. |
ASR numbers from this port are not directly comparable to the HarmBench leaderboard. They are useful for relative comparison across (target, optimizer) pairs within experiments using this module.
Provenance
Bundled data is verbatim from HarmBench commit
8e1604d1171fe8a48d8febecd22f600e462bdcdd (MIT licensed). See
src/harmbench_claim/data/PROVENANCE.md.
Citation
@article{mazeika2024harmbench,
title={HarmBench: A Standardized Evaluation Framework for Automated Red Teaming and Robust Refusal},
author={Mantas Mazeika and Long Phan and Xuwang Yin and Andy Zou and Zifan Wang and Norman Mu and Elham Sakhaee and Nathaniel Li and Steven Basart and Bo Li and David Forsyth and Dan Hendrycks},
year={2024},
eprint={2402.04249},
archivePrefix={arXiv},
primaryClass={cs.LG}
}
Credits / upstream
This module packages the HarmBench
standardized red-teaming benchmark (Mazeika et al., ICML 2024,
arXiv:2402.04249) as a superred
SecurityClaim.
- HarmBench — MIT License, Copyright (c) 2024 centerforaisafety. The
bundled behavior CSVs and copyright-classifier MinHash
.pklfiles, the verbatim Llama-2 classifier prompt templates, the AdvBench refusal-prefix list, and the sliding-window MinHash copyright matcher are vendored/ported from HarmBench commit8e1604d. The.pklfiles hold only one-way MinHash signatures — no copyrighted source text is redistributed. - The AdvBench refusal-prefix list traces to Zou et al. 2023 (llm-attacks, MIT), vendored here via HarmBench.
- The contextual-category behaviors carry short
ContextStringexcerpts (e.g. Wikipedia text under CC-BY-SA, a published paper, forum posts, a code snippet) that centerforaisafety does not itself own. They are redistributed byte-identically to the upstream, widely-mirrored HarmBench ICML benchmark under its MIT terms, and this mirrors the upstream benchmark rather than asserting fresh MIT coverage of those excerpts.
Original superred integration code is MIT-licensed, Copyright (c) 2026
Simon Sure. Full attribution in LICENSES/NOTICE.md; upstream license text in
LICENSES/harmbench-MIT.txt.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file superred_claim_harmbench-0.1.0.tar.gz.
File metadata
- Download URL: superred_claim_harmbench-0.1.0.tar.gz
- Upload date:
- Size: 26.9 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d36415017cfe03c34393df1e2017427101a1539be2e4a571eab70bb476b99be9
|
|
| MD5 |
0a3452683a78dc9670c3c59650f222f8
|
|
| BLAKE2b-256 |
dd662c6fefb3a7e693e1f60ee476248895fe15b34756755b9450bf4264090e02
|
Provenance
The following attestation bundles were made for superred_claim_harmbench-0.1.0.tar.gz:
Publisher:
release.yml on RoldSI/superred-modules
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
superred_claim_harmbench-0.1.0.tar.gz -
Subject digest:
d36415017cfe03c34393df1e2017427101a1539be2e4a571eab70bb476b99be9 - Sigstore transparency entry: 2219198463
- Sigstore integration time:
-
Permalink:
RoldSI/superred-modules@44b3a2514b4d75fe7ebc3f015aa13ff3b6e8380c -
Branch / Tag:
refs/tags/superred-claim-harmbench-v0.1.0 - Owner: https://github.com/RoldSI
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@44b3a2514b4d75fe7ebc3f015aa13ff3b6e8380c -
Trigger Event:
push
-
Statement type:
File details
Details for the file superred_claim_harmbench-0.1.0-py3-none-any.whl.
File metadata
- Download URL: superred_claim_harmbench-0.1.0-py3-none-any.whl
- Upload date:
- Size: 28.7 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0a1c9a3bf155d2581ef3089c0b1328220a099d4a96883fd8cf6e0d40692409de
|
|
| MD5 |
649f2728a6157f20350b87054035fa02
|
|
| BLAKE2b-256 |
1a9764d1ffb60e6043a078c7fd40b97d4a13b4b73444b0d86fdc985b39ebadef
|
Provenance
The following attestation bundles were made for superred_claim_harmbench-0.1.0-py3-none-any.whl:
Publisher:
release.yml on RoldSI/superred-modules
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
superred_claim_harmbench-0.1.0-py3-none-any.whl -
Subject digest:
0a1c9a3bf155d2581ef3089c0b1328220a099d4a96883fd8cf6e0d40692409de - Sigstore transparency entry: 2219198512
- Sigstore integration time:
-
Permalink:
RoldSI/superred-modules@44b3a2514b4d75fe7ebc3f015aa13ff3b6e8380c -
Branch / Tag:
refs/tags/superred-claim-harmbench-v0.1.0 - Owner: https://github.com/RoldSI
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@44b3a2514b4d75fe7ebc3f015aa13ff3b6e8380c -
Trigger Event:
push
-
Statement type: