Evaluate a detector in minutes

Install the SDK, load attack/control pairs in the view your agent sees, and score a detector in Python or from the command line.

GitHub ↗ · Hugging Face ↗

Install

Python 3.10 or later. The SDK is not on PyPI yet; install it from GitHub.

shell
pip install "browsesafe-pp[eval] @ git+https://github.com/perplexityai/browsesafe-plus-plus.git"

Load data

The dataset is gated: request access on Hugging Face and accept the terms, then log in with that account. One request covers the training split and the test inputs; the test inputs are licensed for evaluation only.

shell
hf auth login

A pair holds two pages: the attacked page and its control. n_pairs=100 loads up to 200 pages; iteration yields the attacked page and then the control of each pair.

python
import browsesafe_pp as bs

bench = bs.load(split="train", n_pairs=100)   # 100 pairs = 200 pages, HTML view
pair = bench.pairs[0]

pair.malicious.content     # attacked page in the selected view
pair.malicious.injected    # True
pair.benign.injected       # False: same page without the injection
pair.metadata              # language, page type, attack type, task, ...

The SDK loads the training split (29,500 pairs). The test inputs are for the leaderboard, and their labels stay private. See Submit to the leaderboard.

Choose the view with view=, and select by metadata with filters=. Filters match the attacked page and keep its control.

python
md = bs.load(split="train", view="markdown", n_pairs=100)
ax = bs.load(split="train", view="accessibility", n_pairs=100)
spanish = bs.load(filters={"language_payload": ["es"]}, n_pairs=100)

The dataset id can be set with an environment variable:

shell
# Override the SDK's default dataset if needed
export BROWSESAFE_DATASET="perplexity-ai/browsesafe-plus-plus"

Evaluate in Python

A detector is a function that receives one page and returns a prediction. Return bs.Prediction(injected=None) to abstain. The detector input excludes tasks, labels and reference annotations.

python
import browsesafe_pp as bs

def predict(request):
    # request.content: the page in the selected view
    # request.view: "html", "markdown" or "accessibility"
    flagged = "ignore previous instructions" in request.content.lower()
    return bs.Prediction(injected=flagged)

bench = bs.load(split="train", n_pairs=100)
report = bs.evaluate(bench, predict)
report.save("results/my-detector")

Reports include precision, recall, the false-positive rate on control pages, paired correctness, errors and abstentions. Each page gets one attempt; failures are counted, not retried.

Command line

Point --predict at any importable module:function. Run once per view you want to report.

shell
# mymod.py defines predict(request) -> bs.Prediction
browsesafe evaluate --predict mymod:predict --view html \
  --output results/mymod-html
browsesafe evaluate --predict mymod:predict --view markdown \
  --output results/mymod-markdown

Evaluate a hosted model

To score a model behind an OpenAI-compatible chat endpoint, set the endpoint, key and model name. Prompted models on the leaderboard use the published BrowseSafe detection prompt.

shell
export BROWSESAFE_MODEL_ENDPOINT="https://your-endpoint.example/v1"
export BROWSESAFE_API_KEY="..."
export BROWSESAFE_MODEL="your-model-name"

browsesafe evaluate --model "$BROWSESAFE_MODEL" --view html \
  --output results/your-model-html

Submit to the leaderboard

Test-split scores come from the leaderboard Space. You run the detector; the Space holds the labels.

  1. With access to the dataset (see Load data), run browsesafe predict. It writes one decision per page and view to a JSON Lines file.
  2. Sign in to the Space with your Hugging Face account, upload the file and receive aggregate scores for each view.
shell
browsesafe predict --predict mymod:predict --view html --view markdown \
  --view accessibility --output predictions.jsonl

One submission per Hugging Face account per week. Maintainers review every request to publish; approved results appear on the leaderboard within about an hour, for every view in which each page has a decision. By default the leaderboard shows the top five community results per view and hides results with an F1 below 50. The submission guide covers the file format and the rules.

Adaptive attacks

Static replays understate risk. BrowseSafe-Adapt starts from a benchmark injection, runs a browsing agent on the task, and revises the injection from the agent's behaviour. In the paper, attacks that succeed on a few percent of tasks when replayed succeed on up to 95% after adaptation.

The SDK includes the campaign framework for running adaptive attacks against your own agent; see the adaptive attack guide. The paper's results are on the adaptive leaderboard.