TL;DR
CFR is a two-step prompt for tasks with strict requirements on the answer: first the model writes out all the constraints (should the answer be an integer, a multiple of something, within a certain range, in a certain format), and only then solves the problem, checking against that list at every step.
Models often nail the logic but break the formal requirements on the answer — forgetting to take the remainder mod something, giving a fraction where an integer was required, or mixing up the answer format (say, "find p+q, where gcd(p,q)=1"). The reason is simple: in a long chain of reasoning, a condition stated at the very beginning fades from attention by the time the model formulates its final answer — like forgetting what you agreed on at the start of a long conversation by the time it wraps up.
CFR fixes this by front-loading the constraints instead of checking them after the fact: first, as a separate step, collect all the requirements on the answer into an explicit list, then solve the problem while keeping that list in view and checking intermediate results against it.
Method Blueprint
STEP 1 (separate or in the same prompt): Extract constraints →
list: type (integer / multiple / range / parity / answer format),
their implications, the narrowest valid range, the required answer format
STEP 2: Solve the problem step by step →
after each major step — cross-check against the constraint list
if an intermediate result violates a condition — stop, reconsider
before the final answer — confirm that all conditions are satisfied
Both steps can be run in a single prompt — the model will first output the constraint list, then the solution.
Example
Task: You're a seller on an online marketplace. You need to order a batch of T-shirts from a factory. Packaging comes in units of 36. Minimum order is 2000 units. Budget allows for a maximum of 2500 units. You need a quantity that's divisible by 36 (packaging), falls between 2000 and 2500, and divides evenly by 3 (three sizes S/M/L).
Prompt:
Solve this problem in two steps.
STEP 1 — Extract all constraints on the answer from the problem statement. For each one,
state its type (multiple, range, divisibility) and how it narrows down the possible answers.
Output the final list: what number the answer must satisfy.
STEP 2 — Solve the problem by finding a number that satisfies ALL the constraints
from the list above. Once you have a candidate, check it against each item
on the list separately. If even one item fails — find another number
and check again. Give the final answer only once all checks pass.
Task: [insert the problem statement with numbers]
Result: The model first outputs an explicit list: "the number must be a multiple of 36," "the number must be between 2000 and 2500," "the number must be a multiple of 3." It then works through the search or calculation, and at the end shows the candidate being checked against every item on the list before naming the final number.
Why This Works
A model can get the logic right but still lose sight of a requirement stated at the beginning of the prompt — especially in a long chain of reasoning. This isn't because the model "didn't understand" the requirement, but because in the flow of tokens, early information literally loses weight by the time the answer gets generated.
A model's strength is that it holds onto what's explicitly written right before the answer quite well. If the constraint list sits right before the solution (rather than buried at the start of a long problem statement), the model checks against it far more reliably.
CFR takes advantage of this: it turns an implicit "the problem said something about this earlier..." into an explicit text list that's physically located right next to where the model formulates its answer. It's not magic — it's about managing what the model has "at hand" at the moment of generation.
Control levers: - Constraint categories (in the original: domain, modulus, parity, bounds, format) — swap these out for categories that fit your task: dates, amounts, document formats, legal requirements. - The "stop and reconsider" step — can be softened to "flag the mismatch and continue" if you don't need a hard stop. - Level of detail in the constraint list — for simple tasks, ask for a shorter list (3-4 items); for complex ones, ask for a JSON structure with a more detailed breakdown.
Prompt Template
Solve the problem in two steps.
STEP 1 — CONSTRAINT EXTRACTION
Read the problem statement and write out all the constraints the answer must satisfy:
- Answer type (integer, range, format)
- Numeric conditions (multiples, divisibility, bounds)
- Any other requirements from the text
Output the result: the narrowest set of conditions the answer must meet.
STEP 2 — SOLVE WITH VERIFICATION
Solve the problem step by step. After each significant step, check the intermediate
result against the list from STEP 1. If the result violates
even one condition — stop and revise the step.
Before the final answer, explicitly confirm: all conditions from the list are satisfied.
Task: {task_text}
Plug any task with clear requirements on the answer into {task_text} — a budget calculation, batch-order planning, resource allocation under constraints, or a legal document with strict formatting requirements.
🚀 Quick start — paste into the chat:
Here's the Constraint-First Reasoning template. Adapt it to my task: {your task}.
Ask me questions to fill in the fields.
[insert the template above]
The LLM will ask which specific constraints matter for your task (numeric, format, timing) — because without that, STEP 1 can't build a correct list, and the whole method loses its point.
Limitations
⚠️ Not for tasks without explicit constraints: if the task has no clear requirements on format or range for the answer (just "write some text" or "give advice"), the method has no effect — there's simply nothing to extract.
⚠️ Increases response length: the method almost always generates noticeably more tokens than a direct answer — the model spends time explicitly listing and checking things. For quick, simple tasks, that's wasted overhead.
⚠️ Can backfire on weaker models: if the model itself is bad at extracting conditions, it adds nonexistent or incorrect constraints to the list — then "solves" the problem under the wrong conditions. The weaker the model, the higher the risk of this kind of error.
⚠️ Doesn't replace proof verification: the method is built for tasks with a checkable numeric or format-based answer, not for tasks that require rigorous proof-level reasoning.
How It Was Studied
Researchers tested the method on four models of varying scale — from a small 1.5B up to a top-tier model — on math olympiad problems (AIME, CMIMC, BRUMO, and others), where each problem has clear requirements on the answer (integer, range, format). They compared it against plain step-by-step reasoning and against other techniques — planning, self-verification, and simple unstructured listing of conditions.
The result is interesting: the method's gains depend heavily on how well the model can extract conditions in the first step. The top-tier model showed a noticeable accuracy boost (a few percentage points), while the smallest model saw almost no improvement, since it kept tripping over the constraint list and tacking on irrelevant items.
They also checked the cost: the method uses roughly 1.5-2x more tokens than plain reasoning — the overhead of explicit listing and checking isn't free. The authors are upfront that this isn't a universal improvement but a targeted intervention: it works where constraints are explicit and the model can correctly pull them out, and it's nearly useless where there are no real constraints or the model is too weak to extract them without errors.
Want this for your own case? Apply this study to your task: AI adapts its method to what you are working on and writes the prompt.