API reference
Data
What is the unit a reward model is measured on? A preference. reward_lens.data is the torch-free schema for preferences and the views built on them: pairs, quadruples, tournaments, and agent trajectories, plus the built-in diagnostic set and the lineage that keeps sample sizes honest.
The preference schema
A DataView is an ordered collection of items you can score in one pass. The items themselves are typed: a Pair is a chosen and a rejected response to one prompt, and the higher-order types capture richer preference structure. Why only the difference within a pair carries meaning is the subject of preference geometry.
reward_lens.data.schema.DataView
DataView(items: Sequence[Any], *, name: str | None = None) -> None The uniform, filterable, sliceable, hash-stable iterable the kernel consumes (section 2.4.1).
A view wraps an ordered collection of items (Pairs, or any schema type; a view is homogeneous by
convention but does not enforce it, so mixed diagnostic sets are expressible). It never loads or
mutates data; filter and slice return new views over the same underlying items, so a view is
effectively immutable and safe to share across instruments.
The two methods that carry the data plane’s discipline:
effective_ncomputes the lineage-aware effective sample size (section 2.4.2) by handing the items’ seed ids to the stats engine. A view of forty clones of one seed reports about one.checksumis a content-derivedDatasetIDthat goes into every measurement’s subject reference. It is stable (deterministic given the items and their order) and content-based, so a loader that silently returned the wrong rows produces a different checksum and the dataset registry catches it (section 2.4.5).
Properties
-
items : tuple[Any, ...]
Methods
filter(predicate: Callable[[Any], bool]) -> DataView
src
predicate (order preserved).slice(start: int, stop: int | None = None, step: int | None = None) -> DataView
src
items[start:stop:step].
Provided as an explicit method (in addition to view[start:stop]) because a study spec
names its slice as data, and a method call is what a serialized plan records.
concat(other: DataView, *, name: str | None = None) -> DataView
src
other’s.seed_ids() -> list[str]
src
effective_n() -> float
src
Delegates to reward_lens.stats.ess through data.lineage.effective_sample_size, which is
the canonical implementation when the stats engine is present and an identical local fallback
otherwise. A view of clones reports about one; a view of distinct seeds reports about its
length.
checksum() -> DatasetID
src
DatasetID (ds:...) for this view (section 2.4.1).
Hashes the ordered list of item content. It is content-based and order-sensitive: the same items in the same order always produce the same id, and any change of rows or order changes it. This is the id the dataset registry verifies against a card’s declared checksum, which is where the limit/subset loader bug dies (section 2.4.5).
collapse_duplicates(*, warn: bool = True) -> tuple['DataView', list[int]]
src
(view, weights) (section 2.4.2). reward_lens.data.schema.Pair
@dataclass(frozen=True)
A chosen/rejected preference pair, the native reward-model object (section 2.4.1).
axis names what differs between chosen and rejected by construction: “verbosity”,
“correctness”, “receipt-grounding”. This is the field that makes a pair a controlled stimulus
rather than an arbitrary comparison, and it is what a cross-axis analysis reads. lineage
carries the seed provenance (R7); meta carries difficulty, domain, source, annotator stats.
Attributes
| Name | Type | Default |
|---|---|---|
prompt | str | Prompt | |
chosen | Response | |
rejected | Response | |
axis | str | |
lineage | Lineage | |
meta | dict[str, Any] | field(default_factory=dict) |
Properties
-
prompt_text : str -
seed_id : str
reward_lens.data.schema.make_pair
make_pair(
prompt: str | Prompt,
chosen: str | Response,
rejected: str | Response,
axis: str,
*,
seed_id: str,
builder_id: str,
ops: Sequence[str] = (),
meta: dict[str, Any] | None = None
) -> Pair Construct a Pair with a correctly stamped lineage in one call.
Accepts plain strings for the responses (wrapped in Response) or Response objects when the
caller has typed spans to attach. The lineage content hash is computed from the same canonical
content content_of produces, so pair.lineage.content_hash equals
content_hash(content_of(pair), "ch") and clone detection, the checksum, and the lineage all
agree. This is the builder every dataset constructor should use rather than assembling a Pair
and a Lineage separately, which is how the two could drift.
A Quadruple carries two pairs sharing a prompt, a Tournament a set of pairwise outcomes over many responses, and a Trajectory an agent trace of typed steps.
reward_lens.data.schema.Quadruple
@dataclass(frozen=True)
A controlled 2x2 design (section 2.4.1).
cells maps a (factor_a_level, factor_b_level) key to the response for that cell; the
canonical example is L2’s sycophancy design, agree/disagree crossed with right/wrong. factors
names the two crossed factors. A quadruple lets a study read an interaction (does the grader
reward agreement more when the user is wrong?) that no single pair can express.
Attributes
| Name | Type | Default |
|---|---|---|
prompt | str | Prompt | |
cells | dict[tuple[str, str], Response] | |
factors | tuple[str, str] | |
lineage | Lineage | |
meta | dict[str, Any] | field(default_factory=dict) |
Properties
-
prompt_text : str -
seed_id : str
reward_lens.data.schema.Tournament
@dataclass(frozen=True)
A k-wise comparison collection over one prompt (section 2.4.1).
responses are the competitors; edges are the observed pairwise outcomes. This is the
Hodge-ready object: a preference operator over the responses whose curl (intransitive mass) is
exactly what the topology science measures, and whose edges carry their annotator or judge id so
that measurement can be sliced by source.
Attributes
| Name | Type | Default |
|---|---|---|
prompt | str | Prompt | |
responses | tuple[Response, ...] | |
edges | tuple[EdgeObs, ...] | |
lineage | Lineage | |
meta | dict[str, Any] | field(default_factory=dict) |
Properties
-
prompt_text : str -
seed_id : str
reward_lens.data.schema.Trajectory
@dataclass(frozen=True)
An agent episode: a sequence of steps and its outcome (section 2.4.1).
outcome records how the episode ended (success flag, final reward, task metadata). The
trajectory is the substrate for the receipt/narrative sciences and for trajectory-level reward
signals; its steps carry the typed spans those sciences read.
Attributes
| Name | Type | Default |
|---|---|---|
steps | tuple[TrajStep, ...] | |
outcome | dict[str, Any] | |
lineage | Lineage | |
prompt | str | Prompt | '' |
meta | dict[str, Any] | field(default_factory=dict) |
Properties
-
prompt_text : str -
seed_id : str
The built-in diagnostic set
load_diagnostic_v3 returns fourteen labelled dimensions of matched preference pairs (helpfulness, safety, verbosity, sycophancy, formatting, and the rest), ready to score with no download. It is the substrate under most of the how-to guides, including detect length bias.
reward_lens.data.builtin.diagnostic_v3.load_diagnostic_v3
load_diagnostic_v3() -> dict[str, DataView] Return the diagnostic_v3 set as a DataView per dimension (section 2.4.2).
Keys are the 14 dimension names (the 12 imported plus receipts and contested). Each view
is lineage-honest: its effective_n equals its seed count because every item is an unmutated
seed. The result is cached; the views are immutable, so sharing the cache is safe.
Lineage and spans
Lineage records where each row came from so the effective sample size is computed from real independence, not row count. SpanMap aligns character spans to token spans, which is how typed spans (a receipt, a step, a verdict) survive tokenization.
reward_lens.data.lineage.Lineage
@dataclass(frozen=True)
The provenance of a single stimulus (section 2.4.2).
seed_id names the hand-authored (or externally sourced) seed this item descends from;
resampling happens at this level by default, so clones of one seed count as one. builder_id
names the builder that produced the item. ops is the explicit, ordered list of mutation
operations applied to the seed to reach this item (empty for an unmutated seed). content_hash
is the content-derived id of the item’s payload, which is what clone detection groups on.
Attributes
| Name | Type | Default |
|---|---|---|
seed_id | str | |
builder_id | str | |
ops | tuple[str, ...] | |
content_hash | str |
Methods
with_op(op: str, content: Any) -> Lineage
src
op appended and the content hash recomputed.
A builder that mutates an item calls this: the seed id is preserved (so effective n is unchanged by the mutation), the op is recorded, and the content hash is refreshed to the mutated payload so clone detection and the dataset checksum see the new content.
reward_lens.data.align.SpanMap
@dataclass(frozen=True)
A token-level alignment from sequence a to sequence b (section 2.4.3).
Built by align. Carries the opcodes and both tokenized inputs. The two things instruments read:
map_span, which carries a token span from a into b, and aligned_pairs, the list of
exactly-corresponding token indices. inserts and deletes report the tokens that exist on only
one side, which the receipt sciences need (a deleted receipt has no image in b).
Attributes
| Name | Type | Default |
|---|---|---|
a | TokenizedInput | |
b | TokenizedInput | |
opcodes | tuple[Opcode, ...] | |
exact | bool |
Properties
-
aligned_pairs : tuple[tuple[int, int], ...]: Every(a_index, b_index)token pair that corresponds exactly (from equal blocks). -
inserts : tuple[int, ...]: Token indices inbwith no counterpart ina(insert blocks). -
deletes : tuple[int, ...]: Token indices inawith no counterpart inb(delete blocks).
Methods
map_span(span: Span) -> Span | None
src
a to the corresponding token span in b.
Returns the mapped Span (preserving the kind and meta), or None when the span maps to
nothing because every token it covers was deleted. An empty (zero-width) input span returns
None. The mapped span is the tightest b interval covering the images of all a tokens
in the input span.