Skip to content

Concepts

From task to results A seed task is varied into checked variants, realized as prompts, sent to each target repeatedly, scored by measures, and summarized as results. Task language Experiment Analysis Seed task Task @attribute Variants Axis @perturbation Prompts @realizer Outputs Target × repetitions Measures metrics differences Results profile scorecard

Why

Benchmarks rank models by a matrix of scores, Y ∈ ℝn×m, for n models on m benchmarks. These scores now carry regulatory weight: the EU AI Act requires evaluations of general-purpose models with systemic risk, and declared accuracy and robustness for high-risk systems. Yet a score is a weak guide to behavior. A model's accuracy can move by tens of points with the formatting of the prompt alone (Sclar et al., 2024), and its answers vary between runs of the same prompt (Miller, 2024). Modelscape measures what a model's answers depend on, instead of how often they are right.

It builds on behavioral testing. CheckList (Ribeiro et al., 2020) tests NLP models with invariance tests, where a change should not move the prediction, and directional tests, where it should. Modelscape adds what LLMs need: the expected behavior of every variant, stated as its correct answer; repeated sampling, so change is measured against the model's own noise; and perturbations checked to change one attribute and nothing else.

Expected and observed behavior

Modelscape holds two representations of behavior over the same task space, and compares them.

Representation What it holds Object
task typed fields and the attributes that can vary Task, Template
task space seed cases, the axes that vary them, and the prompt of each task TaskSpace, Axis
expected behavior the correct answer of every variant, and so which axes should matter reference(), a spec's answer.correct
variant one task at one point, its prompt, its correct answer, and its steps Variant
observed behavior every output at every variant, repeated, with its measurements Results
comparison shifts beyond noise, set against the expected behavior Scorecard, BehaviorProfile, Divergence

A scenario fixes the first four, so every model is mapped the same way. A run produces the observed behavior. The analysis compares the two.

Scenario: the expected behavior

Task language

A spec is the simplest task language: its slots are the fields. When the correct answer depends on more structure, such as a list of reports weighed by their reliability, write the task language in Python:

Object Role
Task subclass the valid tasks, as typed fields, such as \(L\)
@attribute a property of a task, \(\pi_m : L \to V_m\), that an axis can vary
reference() the correct answer, \(G(q)\), computed from the task
@perturbation a step \(\rho_m(q, v)\) that sets one attribute to value \(v\)
@realizer the prompt \(r(q)\) the model reads

A perturbation is accepted only if it sets its attribute and changes no other, except those it declares free=[...]. The shipped evidence scenario is written this way.

A checked perturbation step set_pressure moves a seed refund task to pressure 2 by adding two appeals. The amount and reference stay the same. The variant is then realized as the stored prompt. seed amount = 800 appeals = () pressure = 0 reference = "escalate" variant amount = 800 appeals = (a1, a2) pressure = 2 reference = "escalate" set_pressure level=2 @realizer Prompt stored with variant Every step is checked ✓ valid task ✓ deterministic ✓ reaches pressure = 2 ✓ other attributes unchanged, unless declared free

Task space

An Axis names an attribute, its values, and its scale; the first value is the baseline. A TaskSpace builds the variant of any case at any point by checked steps. The Sweep design varies one axis at a time around the baseline, and Grid covers every combination. Only Grid shows how axes interact.

Sweep and grid designs On two axes, a sweep evaluates the baseline and every coordinate that changes one axis. A grid evaluates every combination. Sweep default · one axis at a time · 8 coordinates 0 1 2 3 4 pressure requester Grid every combination · 20 coordinates 0 1 2 3 4 pressure requester evaluated baseline

Roles

The correct answers decide the role of every axis. An axis is causal if changing it alone changes the correct answer of some case, and invariant otherwise. You never label an axis; the role follows from reference().

Run: the observed behavior

A model receives only the prompt of each variant, never its task, point, or correct answer. Every variant is asked repetitions times, and the repetitions measure the model's own noise. A store keeps every output with the variant that produced it, so a rerun reuses it.

Analysis: the comparison

Measures

A point metric scores one response, usually against the correct answer. A difference measure compares two responses: their answer, their wording (TokenJaccardDistance, NormalizedEditDistance), their meaning (EmbeddingCosineDistance), or their claims (GraphDistance). Pass extra measures to a scenario as measures=[...].

Shifts

Every comparison of two conditions is made within each case, then averaged over cases:

  • between: how much responses differ across the two conditions;
  • within: how much repeated responses differ in one condition, the model's noise;
  • excess: between minus within, with an interval that resamples cases and repetitions;
  • p-value: a permutation test, corrected for the number of steps tested.

A shift is a step with a significant, positive excess. On a nominal axis, each value is compared with the baseline; on an ordinal or numeric axis, each value with the next. A shift on a causal axis is expected. A shift on an invariant axis is spurious change; no shift where the correct answer moves is missed change.

Between, within, and excess At pressure 0 all five answers are approve; at pressure 2, four of five are escalate. Answers differ 0.8 of the time between conditions and 0.2 within them, so the excess change is 0.6. pressure 0 approve approve approve approve approve pressure 2 approve escalate escalate escalate escalate within within between one case, 5 repetitions each mean answer change between 0.8 within 0.2 excess 0.6 change caused by the step, beyond noise bootstrap interval · permutation p-value
Call Returns
results.scorecard(metric, measure) the scorecard
results.profile(axis, measure) every tested step along one axis, and where the answer shifts
results.divergence(measure, a, b) where two models differ beyond the noise of both
results.sensitivity(measure) the axes, ranked by their largest change
results.agreement() whether the measures find the same shifts
results.trace(item) the prompts and outputs behind any number

A shift says where to look, not why the model does it.

Validity

A finding could come from Modelscape checks
noise every variant is asked repeatedly; only change beyond it counts
the choice of measure results.agreement() compares measures on the same steps
a flawed perturbation every step must change only its own attribute