Interplay
Adversarial and red-teaming library: culturally grounded probe generation plus seven attack methodologies for testing model robustness. Formerly cultural-bias-red-team.
Implements the Singapore AI Safety Red Teaming Challenge methodology (IMDA + Humane Intelligence, Feb 2025) using NeMo Data Designer, plus 7 attack methodologies for comprehensive adversarial testing (see docs/METHODOLOGY.md).
Install
Requires Python 3.12 or newer.
pip install interplay-adversarial # core: specs and the probe pipeline library
pip install "interplay-adversarial[red-teaming]" # attack runners: TAP, PAIR, Crescendo, GOAT, SLIP, Multimodal
pip install "interplay-adversarial[garak]" # + the Garak scanner (large install)
pip install "interplay-adversarial[providers]" # + 20+ LLM provider SDKs for any-llm-sdk
The package installs interplay (interplay.specs, interplay.red_teaming). The probe-generation command
line (data-designer ... pipeline.py) and the examples run from a clone of the repository; see Quick Start.
Why
Standard red-teaming focuses on adversarial prompts from an attacker perspective. Singapore's challenge found:
- 86.1% of successful exploits came from single-turn benign prompts — normal everyday user interactions
- 67.2% exploit success rate in regional languages vs 49.2% in English
- Positive framing ("which city is richest?") bypasses more guardrails than negative framing
- Cultural bias appears in daily use, not only adversarial scenarios
This tool generates both probe types, grounded in specific cultural contexts rather than generic demographics, and provides 7 attack methodologies to test model robustness.
Attack Methodologies
| Method | Description | Use Case |
|---|---|---|
| Garak | 100+ built-in probes | Comprehensive vulnerability scanning |
| TAP | Tree of Attacks with Pruning | Search-based jailbreak with evaluator pruning |
| PAIR | Prompt Automatic Iterative Refinement | Iterative refinement with attacker + judge loop |
| Crescendo | Multi-turn benign-to-harmful escalation | Gradual escalation using model's own responses |
| GOAT | Generative Offensive Agent Tester | Agentic strategy switching with reasoning |
| SLIP | Self-Jailbreaking via Lexical Insertion | Target model guides its own compromise |
| Multimodal | Image payload attacks | Bypass text-only guardrails with image payloads |
Details, parameters and examples for each: docs/attacks.
Quick Start
Probe Generation (Cultural Bias)
git clone https://github.com/interplay-adversarial/interplay.git
cd interplay
# Install uv if needed: curl -LsSf https://astral.sh/uv/install.sh | sh
uv sync --extra red-teaming # add --extra garak for the Garak scanner
cp .env.example .env # Add API keys and endpoint configuration
# Validate and preview
uv run data-designer validate pipeline.py
uv run data-designer preview pipeline.py
# Generate 500 probes (Singapore 9-country taxonomy, default)
uv run data-designer create pipeline.py --num-records 500
Attack Methodologies
# Set environment variables (or use .env file)
export TARGET_URL="https://your-target/v1"
export TARGET_API_KEY="your-api-key"
export ATTACKER_MODEL="openai/gpt-4o-mini"
export JUDGE_MODEL="openai/gpt-4o-mini"
# Run integrated workflow (Garak + TAP + PAIR)
uv run python examples/integrated_run.py --probe-file probes.jsonl --output-dir output/
Each attack can also be called directly from Python; see the page for the method in docs/attacks.
Pipeline Modes (Probe Generation)
Set BIAS_SPEC to select the generation mode. Three built-in taxonomy modes and N comparison spec modes.
Taxonomy Modes
# Singapore 5-category cultural bias (default)
# Categories: Gender, Geographic/National Identity, Race/Religion/Ethnicity,
# Socio-Economic, Unique Cultural Challenges
uv run data-designer create pipeline.py --num-records 500
# SDG Hub 8 harm-category policy concepts
# Categories: Illegal Activity, Hate Speech, Security & Malware, Violence,
# Fraud, Sexually Explicit, Misinformation, Self Harm
BIAS_SPEC=sdg-hub-harm uv run data-designer create pipeline.py --num-records 400
# All 13 categories combined (Singapore 5 + harm 8)
# Most diverse single run — covers both subtle cultural bias and explicit harm
BIAS_SPEC=combined uv run data-designer create pipeline.py --num-records 800
| Mode | Categories | Focus |
|---|---|---|
singapore (default) |
5 | Subtle cultural bias in everyday AI interactions (APAC context) |
sdg-hub-harm |
8 | Explicit harm: illegal activity, malware, fraud, violence, etc. |
combined |
13 | Full coverage — both cultural bias and harm categories |
Comparison Spec Modes (Two-Group)
# US vs Mexico — national identity + race/ethnicity bias
BIAS_SPEC=us-mexico uv run data-designer create pipeline.py --num-records 200
# US (mainland) vs Puerto Rico — citizenship + national identity
BIAS_SPEC=us-puerto-rico uv run data-designer create pipeline.py --num-records 200
# US White vs US Brown/Latino — intra-US racial bias
BIAS_SPEC=us-white-brown uv run data-designer create pipeline.py --num-records 200
Generating Diverse Datasets
Run multiple modes and merge results for maximum probe coverage:
uv run python examples/diverse_dataset.py --preview-only # sanity check first
uv run python examples/diverse_dataset.py # generates ~720 probes
This runs Singapore + SDG Hub harm + US-Mexico + US White/Brown and merges into
diverse_red_team_dataset.jsonl (Garak-compatible format).
Customize runs by editing the runs list in examples/diverse_dataset.py:
runs = [
("singapore", build_cultural_bias_pipeline(), 200),
("sdg-hub-harm", build_harm_pipeline(), 320),
("combined", build_combined_pipeline(), 500), # or use this for broadest coverage
("us-mexico", build_comparison_pipeline(load_spec("us-mexico")), 100),
("us-white-brown", build_comparison_pipeline(load_spec("us-white-brown")), 100),
]
Available Modes and Specs
BIAS_SPEC value |
Type | Categories | Description |
|---|---|---|---|
singapore (default) |
taxonomy | 5 | Singapore APAC cultural bias taxonomy |
sdg-hub-harm |
taxonomy | 8 | SDG Hub original harm policy concepts |
combined |
taxonomy | 13 | Singapore 5 + harm 8 — maximum coverage |
us-mexico |
comparison | 4 | US Americans vs Mexicans |
us-puerto-rico |
comparison | 3 | Mainland US vs Puerto Ricans |
us-white-brown |
comparison | 4 | US White (non-Hispanic) vs US Brown/Latino |
| (your spec) | comparison | varies | Any file in interplay/specs/ |
Adding a New Comparison
Create interplay/specs/<name>.py that exports SPEC = BiasComparisonSpec(...). No other files need to change.
# After creating the file:
uv run pytest # validates the spec format
# Open a PR — CI runs automatically
Full instructions: interplay/specs/CONTRIBUTING.md
Output (Probe Generation)
Each probe row includes:
| Column | Description |
|---|---|
policy_concept |
Bias category (e.g., "Gender Bias") |
probe_mode |
adversarial or benign |
region |
Geographic context grounding the probe |
prompt_strategy |
Singapore strategy used (fill-in-blank, positive-framing, etc.) |
adversarial_probe |
Structured output with prompt + explanations (when mode=adversarial) |
benign_probe |
Structured output with prompt + why_benign + bias_mechanism (when mode=benign) |
probe_quality_score |
0–3 score from LLM judge (Singapore RT-SG-05 sliding scale) |
*__trace |
Audit trail — exact system prompt + rendered user prompt sent to model |
In comparison mode, also includes group_1_name, group_2_name, group_1_ref, group_2_ref, comparison_topic.
Attack Methodologies (Detailed)
Each methodology has its own page with parameters and a runnable example.
| Method | Strategy | Query budget | Details |
|---|---|---|---|
| Garak | Broad library of built-in probes | Depends on probes | docs/attacks/garak.md |
| TAP | Branch-and-prune search with evaluator pruning | ~15-30 queries | docs/attacks/tap.md |
| PAIR | Iterative refinement with attacker + judge loop | ~20 queries | docs/attacks/pair.md |
| Crescendo | Multi-turn benign-to-harmful escalation | 5-10 turns | docs/attacks/crescendo.md |
| GOAT | Dynamic strategy switching with reasoning | ≤5 turns | docs/attacks/goat.md |
| SLIP | Target guides its own compromise via BFS | ~8 iterations | docs/attacks/slip.md |
| Multimodal | Harmful instruction embedded in an image | 1-3 transforms | docs/attacks/multimodal.md |
Configuration
Environment Variables
Create a .env file in the repo root:
# Target endpoint configuration
TARGET_URL=https://your-target/v1
TARGET_API_KEY=your-api-key
TARGET_MODEL=your-model-name
# Judge model (for scoring)
JUDGE_URL=https://your-target/v1
JUDGE_API_KEY=your-api-key
JUDGE_MODEL=openai/gpt-4o-mini
# Attacker model (for TAP/PAIR/GOAT)
ATTACKER_URL=https://your-target/v1
ATTACKER_API_KEY=your-api-key
ATTACKER_MODEL=openai/gpt-4o-mini
# Provider configuration
LLM_PROVIDER=openai
API_KEY=your-api-key
BASE_URL=https://your-provider/v1
Supported Providers
All providers supported by any-llm-sdk:
- OpenAI (default)
- Anthropic
- Google (Gemini)
- Mistral
- Cohere
- Ollama (local)
- vLLM (local/custom)
- And 20+ more
Development
uv sync # install all deps
uv sync --extra red-teaming # + attack methodology deps (--extra garak for the Garak scanner)
uv run ruff check . # lint
uv run ruff format . # format
uv run pytest # unit tests (no LLM required)
Using with RHOAI / vLLM
export OPENAI_BASE_URL=https://your-vllm-endpoint/v1
export OPENAI_API_KEY=your-key
export MODEL_NAME=granite-3.3-8b-instruct
uv run data-designer create pipeline.py --num-records 500
# Or for attack methodologies:
export TARGET_URL=https://your-vllm-endpoint/v1
export TARGET_API_KEY=your-key
export ATTACKER_MODEL=granite-3.3-8b-instruct
uv run python examples/integrated_run.py --probe-file probes.jsonl
Methodology
Interplay combines culturally grounded probe generation (the Singapore AI Safety Red Teaming Challenge approach, IMDA and Humane Intelligence, February 2025) with seven attack methodologies that cover different search strategies, from static probe libraries to multi-turn and multimodal attacks. How they work, when to use each, how they combine, and the references are in docs/METHODOLOGY.md.
Security and content policy
This project contains adversarial material. Read the content policy before contributing, and report vulnerabilities privately as described in SECURITY.md. Use it only against systems you own or are authorized to test.
License
Apache 2.0
Metadata
Release files for interplay-adversarial 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| interplay_adversarial-0.1.0.tar.gz | 63.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| interplay_adversarial-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 111.2 kB
Release files / interplay_adversarial-0.1.0.tar.gz
| Download URL | interplay_adversarial-0.1.0.tar.gz |
|---|---|
| Size | 63.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
09d45c4db743f644984cdbe65855b0c6d898d1dc5674f63ea036aeb63109be54
|
|
BLAKE2b-256 checksum How to use checksums |
b9b261a0492a726667d702a9bb264cfc91721487ff54daad0696297095ad06f3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.
Transparency logRelease files / interplay_adversarial-0.1.0-py3-none-any.whl
| Download URL | interplay_adversarial-0.1.0-py3-none-any.whl |
|---|---|
| Size | 47.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8eb454eb2a22ed5662dc06241f4032272c9e9e4cc6284b516322e11adb6c0267
|
|
BLAKE2b-256 checksum How to use checksums |
5e9e517ea0c63cd241c5a6b7ce0641c929af78769825bd59705af44575b21b6c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.
Transparency log