Reasoning models, demystified: build a test-time-compute loop
“Reasoning model” sounds like marketing, but it names a concrete trick: spend more compute at inference and you often get a better answer. By the end of this post you’ll have a short self-consistency loop (about forty lines) that you can wrap around any chat model, local or hosted, to make it reason harder on the tasks that actually deserve it.
1. Train-time compute vs. test-time compute
For most of the deep-learning era, a better answer meant a bigger investment before the model ever met your prompt: more parameters, more data, more training. That’s train-time compute, and it’s fixed by the time you call the API.
The shift that defined 2025 was learning to spend on the other side of the clock. Test-time compute is computation spent at inference (generating a longer chain of reasoning, or sampling several attempts and reconciling them) to improve the answer without touching the trained weights. It’s a different axis: instead of paying once, up front, for a smarter model, you pay per query for a more deliberate one. The practical consequence is that you hold the dial. You can spend more on the hard questions and nothing extra on the easy ones.
2. What a reasoning model actually does
A reasoning model generates a long internal chain of thought (it “thinks” in tokens) before committing to a final answer. Those intermediate tokens are the test-time compute: the model works through the problem in writing, and that extra deliberation is what tends to buy the accuracy.
This is now an industry-wide pattern. OpenAI’s o-series and GPT-5 family (GPT-5 released August 2025) are built around it, and every major lab now ships a “thinking” mode of some kind. The mechanics differ, but the shape is the same: more tokens spent deliberating, then an answer. Which is also the sharp edge: those thinking tokens cost money and add latency, so “always reason” is not a free upgrade.
3. The landmark case: DeepSeek-R1
The result that made the mechanism concrete was DeepSeek-R1 (DeepSeek), whose paper, “DeepSeek-R1 incentivizes reasoning in LLMs through reinforcement learning”, was published in Nature in September 2025 as the journal’s cover article. The headline finding: strong reasoning behavior could be incentivized largely through reinforcement learning, rewarding the model for reaching correct answers rather than hand-labeling every step of the reasoning.
Two things are worth holding onto, and one worth resisting. Hold onto: reasoning is a learnable behavior, and it’s an inference-time behavior. The model produces more useful deliberation, and more deliberation is something you can also induce from the outside. Resist: the temptation to claim R1 “beats” some other model on some benchmark. The durable, defensible lesson here is the mechanism, not a leaderboard number.
4. The cheap DIY version: self-consistency
You don’t need a purpose-built reasoning model to get some of the benefit. Self-consistency (Wang et al., 2022) is a model-agnostic technique: instead of trusting a single greedy answer, sample several reasoning paths at nonzero temperature and take the majority answer. Where one attempt might slip on a single arithmetic step, a vote across several diverse attempts is more robust: the wrong answers scatter, the right one tends to pile up.
A close cousin is best-of-N with a verifier: generate N candidates, score each with something that can actually check them (a unit test, a schema validator, a second model), and keep the best. Reach for self-consistency when the answer collapses to a small discrete set you can vote on; reach for a verifier when you can mechanically check correctness.
The caveat: more sampling shifts the odds, it doesn’t repeal them. A model that is confidently and consistently wrong will vote itself a wrong majority. Self-consistency raises reliability; it does not guarantee correctness.
5. Wrap any chat model and vote
Here’s the whole loop. It talks to any OpenAI-compatible chat endpoint: a hosted API, or the local model from our laptop LLM tutorial, which exposes one at http://localhost:11434/v1. It samples N reasoned attempts, extracts each final answer, and returns the majority.
# self_consistency.py (Python 3.11+)
# pip install "requests==2.34.2"
import os, re, requests
from collections import Counter
BASE_URL = os.environ.get("LLM_BASE_URL", "http://localhost:11434/v1") # local Ollama, or any OpenAI-compatible API
API_KEY = os.environ.get("LLM_API_KEY", "not-needed-locally")
MODEL = os.environ.get("LLM_MODEL", "qwen3:8b") # whatever you pulled / are serving
SYSTEM = "Reason step by step. End your reply with a line exactly like: Answer: <value>"
def call_model(prompt, temperature):
r = requests.post(
f"{BASE_URL}/chat/completions",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"model": MODEL,
"messages": [
{"role": "system", "content": SYSTEM},
{"role": "user", "content": prompt},
],
"temperature": temperature,
},
timeout=180,
)
r.raise_for_status()
return r.json()["choices"][0]["message"]["content"]
def final_answer(text):
hits = re.findall(r"Answer:\s*(.+)", text, flags=re.IGNORECASE)
return hits[-1].strip() if hits else None
def self_consistency(prompt, n=5, temperature=0.8):
votes = [a for a in (final_answer(call_model(prompt, temperature))
for _ in range(n)) if a]
if not votes:
return None, []
winner, _ = Counter(votes).most_common(1)[0]
return winner, votes
if __name__ == "__main__":
q = "A shirt costs $40 after a 20% discount. What was the original price, in dollars?"
answer, votes = self_consistency(q, n=5)
print("votes :", votes)
print("answer:", answer)
The important choices: temperature is above zero so the samples actually differ (self-consistency needs diverse paths, not five copies of the same one); the system prompt forces a parseable Answer: line so the vote is over clean values; and the aggregation is a plain majority with collections.Counter. Swap MODEL for whatever you’re running. To hide the latency, fire the N calls concurrently rather than in a loop; they’re independent.
6. When it’s worth it, and when it isn’t
Reasoning is not free. N samples cost roughly N times the tokens, and (unless you parallelize) N times the latency. So spend the budget where a wrong answer is expensive and the answer is checkable or discrete: math, extraction you can validate, classification, code that either runs or doesn’t. Don’t spend it on simple lookups, high-volume low-stakes calls, or latency-critical paths where a single fast pass is the right call.
And whatever you do, keep a check on the value, not just the vote count. The whole point of test-time compute is to trade compute for reliability — but reliability you can measure, not assume. Working out where reasoning actually pays off in a product (which requests deserve the extra compute and which don’t) is exactly the kind of question a short architecture review with CloudSignal is built to answer.
Sources / further reading
- DeepSeek-R1, Nature (2025): https://www.nature.com/articles/s41586-025-09422-z
- Self-Consistency Improves Chain-of-Thought Reasoning (Wang et al., arXiv:2203.11171): https://arxiv.org/abs/2203.11171
- Companion tutorial: Run a capable LLM on your laptop: /blog/run-a-local-llm-laptop/
Written by Ashwin Rajendraprasad for CloudSignal AI. The code above is free to reuse.