Integrations & interoperability
VeriGrad's propensity probes are intentionally tiny and provider-neutral: a probe is a prompt template plus a deterministic detector that reads the model's text and returns a label. That design lets the same detectors be driven by other people's open-source harnesses instead of only our native runner, which is the difference between a one-off microsite and a tool that lives in the ecosystem.
Shipped
Inspect AI (UK AI Safety Institute): verigrad_rl/integrations/inspect_task.py
Inspect is the open evaluation framework from the
UK AI Safety Institute and the de-facto standard for safety evals. We ship a real
adapter that exposes Answer-Under-Pressure as Inspect Tasks. Because Inspect
owns the model layer, the probes now run against any provider Inspect supports,
not just the Anthropic lineup the native runner targets.
pip install "verigrad-rl[inspect]"
# Deference (sycophancy under a confident wrong reviewer)
inspect eval verigrad_rl/integrations/inspect_task.py@deference \
--model anthropic/claude-sonnet-4-6 -T n_tasks=150
# Same probe, OpenAI; nothing else changes
inspect eval verigrad_rl/integrations/inspect_task.py@deference \
--model openai/gpt-4o -T n_tasks=150
# Same probe, a local model behind Ollama / vLLM
inspect eval verigrad_rl/integrations/inspect_task.py@deference \
--model ollama/llama3.1 -T n_tasks=50
Four tasks are exposed:
| Task | Framing | accuracy() reports |
|---|---|---|
capability |
control | plain GSM8K accuracy (the capability floor) |
deference |
authority_wrong | safe-rate = 1 − deference (sycophancy) |
spec_gaming |
grader_gameable | safe-rate = 1 − spec-gaming rate |
answer_under_pressure |
parametric | pick any framing with -T condition=... |
Each score also carries the full deterministic label record in its metadata
(deferred, gamed, checker_pass, numbers_on_line, …), so you can recompute
any propensity from an Inspect .eval log. Anchors are seeded identically to the
native runner (Random(seed * 1_000_003 + problem_id)), so a number produced under
Inspect on seed=7 matches verigrad propensity --seed 7.
Real public datasets
Tasks come from GSM8K (Cobbe et al., 2021) and CommonsenseQA, downloaded
from the official sources and cached, never generated or modified. The gold answer
is parsed from the dataset's own marker. See verigrad_rl/propensity/dataset.py.
Anthropic API
Models under test and the independent reliability judge are real Anthropic models
called through the API (anthropic>=0.40). Every dollar figure in the report is
measured token usage × published list price. The harness never invents a number.
Patterned after / compatible by design
These are not bundled adapters; they are the projects whose conventions VeriGrad deliberately mirrors so it slots into a real safety-eval workflow. Listed honestly as influences and interop targets, not shipped integrations.
| Project | Relationship |
|---|---|
| garak (NVIDIA) | Probe/detector split mirrors garak's vulnerability-scanner taxonomy; our detectors are deterministic and reproducible. |
| lm-evaluation-harness (EleutherAI) | The control task is a capability baseline; the label records export cleanly to a harness-style results table. |
| HELM (Stanford CRFM) | Scenario/metric separation and confidence-interval reporting follow HELM's holistic-evaluation style. |
| TransformerLens | The activation-level RL-from-verifier baseline (verigrad_rl/mech) targets the same white-box, mechanistic-interpretability workflow. |
| petri (Anthropic) | Auditing-agent philosophy: probe what a model will do under pressure, not just what it can do. |
Adding your own adapter
Everything an adapter needs is in verigrad_rl/integrations/_logic.py (no
third-party harness imported, fully offline-testable):
from verigrad_rl.integrations import build_pressure_samples, label_response, safe_behavior
samples = build_pressure_samples("authority_wrong", n_tasks=150, seed=7)
# -> render samples[i].prompt in your harness, collect the model's text, then:
labels = label_response("authority_wrong", model_text, samples[i].gold, samples[i].anchor)
held = safe_behavior("authority_wrong", labels) # True == did not cave
Translate those to your framework's Sample / Score types and you have a new
adapter. See inspect_task.py for a ~120-line reference.