Goals
- Understand when relative (preference-based) rewards beat absolute scoring
- Learn the judging toolkit: pairwise judges with constitutional principles, and group ranking
- Implement
score_groupso a trainer can have the environment judge a whole GRPO group
Prerequisites
openreward>=0.1.157- Completing the Using LLM Graders, Chat Backends and Using Rubrics tutorials
Introduction
Rubrics score one response at a time against criteria — the pointwise half of constitutional AI, where a judge checks a response against principles. But the reinforcement-learning half of constitutional AI (RLAIF) is inherently pairwise: the judge is shown a conversation and two candidate responses, and picks the better one against a principle. The preference signal is relative, not absolute. Relative rewards suit group-based RL algorithms like GRPO unusually well. GRPO normalizes rewards within a group of rollouts, so only their ordering matters — and pointwise judge scores tend to cluster tightly within a group, letting the normalization amplify judge noise into illusory advantages. Win-rates over pairwise comparisons spread by construction. Two things ship for this:- A judging toolkit —
openreward.judging— with a pairwise judge, constitutional principles, and group-ranking helpers. It’s a plain library built on chat backends, usable anywhere. - A
score_groupcapability — an optional method on your environment that a trainer can call with a whole group’s candidate trajectories after the rollouts finish, receiving one reward per candidate.
The pairwise judge
list[Message]). By default the judge sees only a transcript’s final output — see view below. context is the task conversation the candidates respond to.
The defaults follow the constitutional-AI literature rather than convenience:
- One principle is sampled per comparison from
principles. Ensembling over principles gives a more robust preference signal than judging everything against one fixed rubric string. - Presentation order is shuffled per comparison (
shuffle=True). Pairwise judges show model-specific position bias; shuffling decorrelates it.both_orders=Trueupgrades this to judging both presentations (2× cost): agreement keeps the winner, disagreement becomes a tie. - A broken judge raises, it never scores. An unparseable verdict gets a bounded corrective retry (
max_retries), then raisesJudgeFailure. Silent zeros corrupt training; catch the exception at the reward boundary and fail loudly.
Ranking a group
rank_group turns pairwise verdicts over a group into one scalar per candidate:
The aggregator decides how verdicts become scalars:
winrate (wins / games, ties count half) or rank (ordering only, evenly spaced — for when you trust the judge’s ordering but not its magnitudes).
What the judge sees: view
By default judges reward the output, not the chain of thought: with view="output" (the default), a transcript candidate renders as only the final assistant turn’s visible content — no reasoning, no tool history, no earlier turns. This judges the behavior you actually deploy, and it keeps optimization pressure off the reasoning itself.
view="trajectory" is an advanced opt-in for the narrower case where the actions matter: agentic tasks where the judge should see tool calls and their results — did the candidate verify before answering, did it take a destructive shortcut (requires openreward>=0.1.157 for candidates carrying rich blocks). Be aware that everything shown to the judge is under optimization pressure, and the trajectory view includes any reasoning in the transcript — so if you use it, write principles that reference actions and outcomes, never reasoning style or thoroughness, and consider sending candidates without reasoning blocks at all. Expect the judge bill to grow with transcript length. The task context always renders in full under either view; it’s the shared prompt, not the thing being judged.
At N=8 rollouts a round robin is 28 comparisons per task per step — budget accordingly, or drop to knockout (7) or the single-call GroupwiseJudge.
Group scoring: score_group
Within a session, an environment only ever sees its own rollout — sibling rollouts live in sibling sessions. score_group is the protocol surface that closes the gap: after a trainer collects a GRPO group’s N rollouts for one task, it sends the N candidate trajectories to the environment and gets N rewards back. The environment owns the constitution and the judging.
Override the method to enable it:
GroupCandidate carries the candidate as role-tagged messages plus optional trainer-owned metadata, echoed back for correlation. With the default view="output" only the final assistant turn is judged, so output-only candidates suffice; send fuller trajectories (optionally with reasoning/tool blocks) only for view="trajectory" environments. Return exactly one score per candidate, index-aligned; bare floats are coerced to GroupScore. If the judge fails, let the exception propagate — the trainer receives a clean failure for the group instead of fabricated rewards.
Support is advertised automatically: environments that override score_group report supports_score_group: true in their tool list (the same optional-field pattern as the terminal tool), so harnesses can detect it before spending a single rollout.
Calling it from a trainer
ScoreGroupUnsupported (the environment doesn’t implement it, or the server predates 0.1.157) and ScoreGroupFailed (the judging raised). Neither kills the session — scoring reads the candidates without advancing environment state, so a trainer can retry or fall back to the pointwise rewards it already holds.
Comparative rewards arrive alongside the pointwise rewards the sessions emitted, never instead of them. How the two combine — sum, replace, gate — is trainer policy, deliberately outside the environment’s contract.
Limitations of Preference Rewards
Preference judging inherits every LLM-as-judge failure mode, plus a few of its own:- Judge gaming. Policies learn what the judge likes — verbosity, confident tone, claim-dense answers — independent of quality. Pairwise comparison fixes advantage conditioning; it does not fix judge exploitability. Keep prescriptive anti-hacking principles in the constitution (“do not reward length”, “penalize unsupported claims”), and evaluate checkpoints against judges other than the training judge.
- Position bias. Left on by default (
shuffle), upgradeable toboth_orders. Don’t turn it off to save calls; the bias is real and model-specific. - Non-transitivity. Judges produce cycles (A ≻ B ≻ C ≻ A). Win-rate aggregation over more pairs is more robust than single-elimination when cycles are common; if the same group keeps producing near-tied win-rates, the judge is at its resolution limit and the signal is mostly noise.
- Cost. Comparisons are judge calls over full trajectories. Round robin is quadratic in group size; budget with the topology table above, and consider escalating to pairwise only for groups where cheaper signals produce zero variance.
Next Steps
Multi-turn Conversations
Serve the conversation the candidates respond to as a role-tagged prompt
Chat Backends
The dedicated judge-model channel the judging toolkit is built on

