
An open-source safety benchmark for the prompts where the right answer is neither a refusal nor full compliance. The gray zone, where real deployment decisions happen.
CLI and live dashboard for scoring how GPT, Claude, and Gemini handle dual-use and gray-zone requests. Uses a three-tier evaluation built on OpenAI's safe-completion paradigm. Published by raxIT Labs.
Most public AI safety benchmarks grade on a binary: did the model refuse, or did it comply? That framing misses the part of the problem we actually care about. A model that refuses every ambiguous prompt is not safe. It is unhelpful. A model that complies with everything is not safe either. The interesting behaviour, the behaviour that matters in production, is what the model does when the right answer is somewhere in the middle.
GrayZoneBench is our attempt to measure that middle.
A "gray zone" prompt is one where a blanket refusal and a full answer are both wrong. Some examples from our dataset:
For each of these, the best possible answer is a safe-completion: a helpful, specific response that does not enable harm. OpenAI articulated the pattern in their safe-completion paper and it is the frame GrayZoneBench evaluates against.
Each (prompt, model-response) pair goes through three tiers. The scores compose into one number between 0 and 1.
gpt-5-mini because it is cheap and strong enough to be consistent across runs.We output two scores per response, a safety score and a helpfulness score, and multiply them into an effectiveness score. A model that only ever refuses scores 1.0 on safety and near-zero on helpfulness. A model that happily helps with everything scores the inverse. The gray-zone performers are the ones in the upper-right corner of the plot.
Everything lives in a single CLI. You point it at a model, pick a dataset config, and let it run.
# Install with uv uv sync # Score a single model uv run python gray-zone-bench.py \ --models gpt-5-mini \ --judge-model gpt-5-mini \ --judge-task both \ --hf-dataset raxITLabs/GrayZone \ --hf-config standard \ --num-prompts 1 # Compare models side-by-side uv run python gray-zone-bench.py \ --models gpt-5-mini claude-3-haiku gemini-2-5-flash \ --judge-model gpt-5-mini \ --judge-task both \ --hf-dataset raxITLabs/GrayZone \ --num-prompts 1
The run emits a JSON file, a Markdown summary, and streams into the live dashboard at bench.raxit.ai. We use the dashboard internally when we are comparing models for a specific customer deployment; the JSON is what we keep in source control for reproducibility.
We did not start from scratch. The dataset is an extended HarmBench published as raxITLabs/GrayZone on Hugging Face, with two additions:
--hf-config contextual --context-column context.The original HarmBench license applies to the inherited prompts. The benchmark tooling itself is Apache-2.0.
We needed this internally. When we evaluate a model for a customer before we wire it into raxIT AI, the question we are actually answering is: does this model behave well on the prompts that would be asked in production? Binary refusal scores were not giving us that answer, so we wrote our own benchmark. Making it public felt like the right move. There is no commercial advantage in keeping safety evaluation private, and the benchmark gets better the more people run it.
A companion post, How we use safety benchmarks to assess technical and business risk, walks through how we turn these raw scores into risk signals inside raxIT AI.
Three things, for honesty:
What models does it support?
Anything that speaks the OpenAI chat-completions schema, plus native integrations for Claude and Gemini. Self-hosted models behind a gateway (vLLM, Ollama, TGI, LiteLLM) work the same way as hosted frontier models. Bring the endpoint; we will score it.
How is this different from HarmBench or StrongREJECT?
HarmBench grades binary compliance on clearly harmful prompts. StrongREJECT grades whether jailbreaks succeed. GrayZoneBench grades safe-completion on the dual-use prompts where neither a refusal nor a full answer is correct. The three benchmarks are complements, not substitutes. We run all three internally.
Can I swap out the judge model?
Yes, that is the whole point of the --judge-model flag. We have run it with GPT-4o, GPT-5-mini, Claude Sonnet, and Gemini as judges. The scores shift a little with the judge (strong judges are slightly harsher) but the relative ranking of target models is stable across judges.
How do I contribute a new prompt category?
Open a PR against the repo. The prompt schema and a contribution guide are in docs/. We are particularly interested in prompts from regulated domains (healthcare, finance, legal) where the gray zone is most consequential.
Enterprise AI governance and security. SSO, audit trails, policy enforcement, and production support.