Verifiers for Reasoning Models
One function scores the benchmark and rewards the policy. Measure its false positives before trusting either number.
Jump to a section
Why this matters
A verifier decides whether a model's answer is correct without asking a human. For math, it extracts the final answer, normalizes it, and checks equivalence with a reference. For code, it runs tests. The same function serves two jobs: evaluation (what fraction of a benchmark does the model solve?) and reward (the signal RLVR training optimizes).
That double role is the reason to build it carefully. A verifier measures only what it checks. A lenient parser inflates benchmark scores; during RL, the policy will find and exploit the same leniency.
Build the mental model
A reasoning model writes a long solution and ends with something like \boxed{\frac{3}{4}}. The reference answer is 0.75. A string comparison says wrong. A useful verifier finds the final boxed expression, strips formatting, converts both sides to a canonical form, and only then compares.
Three steps between a response and a reward
Follow one response through extraction, normalization and comparison. Each step can create a false positive or a false negative.
The visual loads as you reach this section.
Read the connections
Model response -> Extract answer : last boxed Extract answer -> Normalize : strip LaTeX Normalize -> Compare : canonical form Compare -> Reward : 1 or 0 Extract answer -> Logged failure : none found
Every step can fail in both directions. Extraction can grab an intermediate number. Normalization can merge answers that are not equal. Equivalence checking can time out on a hard symbolic expression. Log each failure type separately so that a change in score can be traced to the model or to the checker.
Work through the math
Treat the verifier as a classifier of whether response answers prompt correctly. Against true correctness , it has a false-negative rate and a false-positive rate . If the model's true accuracy is , the measured accuracy is
so with no false negatives, a 5% false-positive rate on a model with 40% true accuracy adds 3 points of measured accuracy that do not exist. In RL, the expected reward of a policy is exactly this , so the gradient also rewards whatever raises .
DeepSeek-R1-Zero used two rule-based rewards: an accuracy reward from checking the final answer, and a format reward for placing reasoning between thinking tags. The paper reports avoiding neural reward models for this stage because of reward hacking at scale.
Key takeaway: Report the verifier with the score. A benchmark number is a property of the model and the checker.
| Domain | Verifier | Typical false positive | Typical false negative |
|---|---|---|---|
| Math with numeric answers | Extract, normalize, compare | Lenient parsing of a partial answer | Equivalent forms not recognized |
| Symbolic math | Computer algebra equivalence | Simplification bugs | Timeouts on hard expressions |
| Code | Unit tests in a sandbox | Weak or incomplete tests | Flaky tests, environment errors |
| Formatting | Regex on structure | Format satisfied, content wrong | Valid answer, unexpected format |
Outcome versus process checks
An outcome verifier scores only the final answer, so a correct answer reached by flawed reasoning still earns full credit. A process reward model scores intermediate steps, which gives denser feedback but is a learned model with its own errors. Lightman et al. compared the two on MATH; the MATH-500 split commonly used for evaluation comes from that work.
Read the implementation
Extract the last \boxed{...} with brace matching, then compare numerically where possible.
1from fractions import Fraction
2
3def last_boxed(text: str) -> str | None:
4 start = text.rfind("\\boxed{")
5 if start < 0:
6 return None
7 i, depth = start + len("\\boxed{"), 1
8 for j in range(i, len(text)):
9 depth += {"{": 1, "}": -1}.get(text[j], 0)
10 if depth == 0:
11 return text[i:j]
12 return None # unbalanced braces: no answer
13
14def canonical(ans: str):
15 s = ans.replace(" ", "").replace("\\left", "").replace("\\right", "").strip("$")
16 if s.startswith("\\frac{") and "}{" in s and s.endswith("}"):
17 num, den = s[len("\\frac{"):-1].split("}{", 1)
18 s = f"{num}/{den}"
19 try:
20 return Fraction(s)
21 except (ValueError, ZeroDivisionError):
22 return s
23
24def verify(response: str, reference: str) -> int:
25 pred = last_boxed(response)
26 return int(pred is not None and canonical(pred) == canonical(reference))
27
28print(verify("... so the answer is \\boxed{\\frac{3}{4}}", "0.75")) # 1This handles a narrow set of forms. Production math verifiers add symbolic equivalence with a timeout, unit handling, and an explicit list of known false positives as regression tests.
Questions and trade-offs
- Conceptual: Why use the same verifier for evaluation and RL rewards? (It keeps the training signal and the measurement consistent, but any verifier error then shapes both the model and its reported score.)
- Applied: Measured accuracy jumped after a verifier change. What do you check? (Rescore a fixed set of saved responses with both versions and inspect every flipped label.)
- Implementation: Why take the last boxed answer? (Reasoning traces often box intermediate results; the final one is the committed answer. This is a convention, so state it.)
- Systems-level: What must a code verifier isolate? (Execution: time limits, memory limits, no network or file system access beyond the sandbox.)
- Failure modes: How can a format reward be hacked? (The policy can emit the required tags around empty or irrelevant reasoning. Keep format rewards small relative to accuracy.)
Check your understanding
From memory: write measured accuracy in terms of true accuracy and the two verifier error rates, and list the three verifier steps. Check against Stage 3.
Sources and further reading
- Lightman et al., Let's Verify Step by Step: outcome versus process supervision, and the source of the MATH-500 split.
- Hendrycks et al., Measuring Mathematical Problem Solving with the MATH Dataset: the MATH benchmark.
- DeepSeek-AI, DeepSeek-R1: rule-based accuracy and format rewards.
- Raschka, Building Reasoning Models from the Ground Up: builds a math verifier, then reuses it as the RLVR reward.
Oliver Perrin
Machine Learning Engineer · Founder, LiminalML
LiminalML brings together concept explanations, mathematical examples, and working visuals. Find more writing by Oliver on the LiminalML Substack.
Keep exploring the idea.
Ask a follow-up in a guided session, work through the self-check, or open the visual in Studio to build on it.
Related concepts
LLMs
GRPO and Verifiable Rewards
Replace PPO's value model with a group of sampled responses. Trace the advantage, the clipped update and the KL term that trained DeepSeek-R1.
LLMs
Inference-Time Scaling
Sample more, then select well. See exactly when majority voting helps, when it hurts, and why the selection rule matters as much as the samples.
LLMs
Reasoning Distillation
Separate imitating a teacher's text from matching its distribution, and see why distillation is cheap but capped by the teacher.