When Google DeepMind and OpenAI announced that their systems had cleared the gold-medal threshold at the 2025 International Mathematical Olympiad, the takeaway most people walked away with was simple: the models are getting smarter. A pair of researchers at UCLA made a quieter, more uncomfortable point — you didn't need those specialised systems at all. With nothing but a publicly available Gemini 2.5 Pro and a carefully built loop wrapped around it, they solved five of the six IMO 2025 problems. That's the same bar the headline systems cleared.
The model didn't change. The scaffolding did.
The numbers that should reset your priorities
Ask Gemini 2.5 Pro to solve olympiad problems the obvious way — generate a batch of candidate solutions and keep the best of 32 — and it gets about 31% of them right. Wrap that exact same model in the right pipeline and the success rate jumps to roughly 86% (5 out of 6).
The same pipeline lifted Grok-4 from 21% and GPT-5 from 38% into the same gold-medal range. One loop, three different frontier models, the same dramatic gain.
That is not a model improvement — it's an orchestration improvement. And because it reproduces across three unrelated models, it's a property of the method, not a quirk of one vendor's weights.
What the loop actually does
The pipeline is deliberately unglamorous. It's three moves, run until the answer holds up:
- Generate with rigour. The model is forced to produce a full proof under strict formatting rules — no hand-waving, no "it is easy to see that." Structure alone eliminates a whole class of sloppy answers.
- Self-refine. The model is sent back over its own draft to strengthen weak steps and close gaps before anything else looks at it.
- Verify independently, then iterate. A separate instance acts as an adversarial checker whose only job is to find the flaw. If it finds one, the problem goes back to step 2 with that specific critique attached. Repeat until the verifier is satisfied.
solution = generate(problem, strict_format=True)
while True:
solution = self_refine(solution)
verdict = verify(problem, solution) # fresh instance, hunting for the flaw
if verdict.is_sound:
break
solution = revise(solution, verdict.critique)
The trick isn't any single prompt. It's that a generator and a critic have different failure modes, so pointing one at the other catches mistakes that neither would catch alone.
Why this lands even if you never touch a proof
Most of us aren't solving olympiad geometry. But the lesson generalises to almost anything you build on top of an LLM: the leverage is in the loop, not the single call.
A one-shot prompt asks a model to be right on the first try, every time — a bet it will lose often enough to matter. A generate → verify → refine loop only asks it to recognise a good answer once it sees one, which models are markedly better at than producing one cold. If you've been building agentic systems, this is the same instinct behind a dedicated critic step, a separate reviewer role, or a tool that checks work before it's returned. This paper is the cleanest evidence yet that the pattern is worth the extra calls.
It also reframes a decision a lot of teams get backwards. When output quality is disappointing, the reflex is to reach for a bigger, pricier model. This result says: try building the loop first. A verification-and-refinement wrapper around a mid-tier model beat best-of-32 sampling from a frontier one — at a fraction of the reasoning you'd assume it needed.
The takeaway
Before you upgrade the model, upgrade the process around it. Give it a way to check its own work with fresh eyes, feed the critique back in, and let it iterate. The IMO result is a striking headline, but the engineering lesson is portable and cheap: a good loop turns an ordinary model into a reliable one.
Sources: Winning Gold at IMO 2025 with a Model-Agnostic Verification-and-Refinement Pipeline (arXiv 2507.15855) — Yichen Huang & Lin F. Yang, UCLA · Reference implementation.