Asking a model to "make it better" and then asking again tends to make a draft different rather than better. Each pass fixes something the last one noticed and quietly moves something else. The film shows the loop that keeps iteration honest, often called self-refine or evaluator-optimiser: a writer model drafts, a critic model scores the draft against a written rubric and returns a structured verdict, your code picks one target, the writer revises, and the loop stops when every check passes or its lap budget runs out.
The task is a customer-facing status update for a payments incident, written from an internal log that invites trouble on purpose: it names the on-call engineer, a paging mistake, and the vendor whose key rotation caused the outage. The rubric has five checks. The update must say who is affected and what they cannot do, say when it began (14:02 UTC), say when the next update comes (15:00 UTC), stay under 80 words, and blame no person, team or vendor. Start time, next update and length are checked in code. Impact and blame need judgement, so the critic decides them.
Every text and verdict in the film is real. Both parts were played by `google/gemini-3.8-flash` through OpenRouter at temperature 0 on 11 September 2026, the critic in its own call. It got the rubric and the draft under a strict JSON schema, a pass and a one-line note for every criterion plus a list of what fails, and it ran three times per version. The three runs agreed on every criterion of every version. One further reply arrived cut off mid-JSON and failed to parse, which is exactly why the loop reads the reply with `Verdict.parse(JSON.parse(raw))` and asks again rather than trusting whatever came back.
The first draft ran to 136 words, and the critic failed it on length. It passed the start time, in all three runs, with the note "Mentions orders placed between 14:02 and 14:31 UTC": the only 14:02 in the draft is about which orders might show as payment pending, not when the outage began. The code check needs 14:02 stated as a start, so it fails, and because the loop spreads the code checks over the critic's scores, code wins wherever code can count. The critic also miscounted words, 35 for a draft of 43 and 52 for one of 58. The loop then took one target, the first failing criterion in rubric order, and sent it to the writer with the whole rubric. Version two came back in 43 words, the loop re-scored all five criteria rather than only the target, every one passed, and the loop stopped and kept it.
Then the failure mode, which we set up on purpose and want to be plain about. An earlier recording, where each lap simply fixed the next failing criterion with the rubric in view, produced no regression at all. So the third version comes from the kind of request that often arrives mid-review: one narrow stakeholder ask, "make the impact clearer: tell customers exactly what went wrong and why", sent with the update but without the rubric. The model did what was asked. Version three is clearer, and it grew to 103 words and explained that the outage "was caused by an unannounced security key update from our third-party payment vendor". The word count failed in code and the critic voted three to nothing that it blamed the vendor. Two checks that version two passed turned red, and neither was what the edit aimed at. The fix sent the edit again with the rubric back in the prompt, version two in view as the last version that passed, and an instruction to lose nothing that had passed. Version four keeps the new detail about pending orders and duplicate charges, drops the blame, fits in 58 words and passes all five.
Two honest notes. The code checks are only as good as their patterns: a regular expression that matched 14:02 anywhere would have passed the first draft exactly as the critic did, so the check has to say what it means, a start. And the code on screen is the shape of what ran rather than every line of it; the lap budget of four never bit here, because the loop converged on its second lap, but a loop without one can spend forever on a rubric its writer cannot meet.
What to keep: let code decide whatever it can count, put the whole rubric in the prompt with every edit, re-score every criterion after it, keep the last version that passed so a bad edit can be undone, and cap the laps.
The maths
- Every version gets the whole rubric
Each criterion is a check that passes or fails. The loop scores all five for every version, whichever one the edit aimed at, and a version is only kept when every check passes.
- A regression
A check the previous version passed and this one fails. Version three regressed on two: length and blame. Only re-scoring every criterion after every edit finds these, because neither was the target of the edit that broke it.
- Code checks overrule the critic
Start time, next update and length are deterministic checks in code, two regular expressions and a word count, and where code can count, its answer replaces the critic's. Impact and blame need judgement, so the critic scored each version three times and the majority stands; p_ir is 1 when run r passes criterion i. The critic passed the first draft's start time in all three runs; the code check failed it.
- The loop stops on a pass or a budget
Each lap the writer W gets the current version, one target (the first failing criterion in rubric order) and the whole rubric R. The loop returns as soon as nothing fails, and throws after K = 4 laps (MAX_LAPS in the code) so a loop that never converges still stops. Here it converged on the second lap.
Transcript
The narration, chapter by chapter. A timestamp opens the film at that moment.
- 0:00One rubric
- Asking a model to keep improving a draft makes it different rather than better, so this loop scores every version of an outage update against one written rubric: five checks, three in code and two by a model.
- 0:15First draft
- Trace one update: the writer model turns the team's internal outage log into a first draft of 136 words, far over the 80-word limit.
- 0:26The critic's JSON
- Next, a second call, the critic, scores that draft against all five criteria and returns JSON, and it passes the start time, fooled by the only 14:02 in the text, which is about pending orders.
- 0:42Code decides
- So your loop re-checks, for free, the three things code can count, and where code can count, code decides: the start time fails, and the draft has two failures, not one.
- 0:55One target
- The writer gets one target, the start time, with the whole rubric in view, and version two comes back in 43 words.
- 1:03Re-check all five
- The part people miss is that the loop then re-scores all five criteria, not only the target, and version two passes every one, so the loop stops and keeps it.
- 1:16A narrow ask
- Here is the failure mode, set up on purpose: a stakeholder asks only for a clearer impact and the reason why, and that edit goes to the writer without the rubric.
- 1:28Regression
- Version three is clearer, but at 103 words it fails the length check, and the critic says it blames the vendor, so two passing checks turn red.
- 1:38The fix
- The fix sends the same ask with the rubric back and version two in view, and version four keeps the new detail, drops the blame and passes all five in 58 words.
- 1:51What to keep
- So let code decide whatever it can count, show the whole rubric with every edit, re-score every criterion after it, and cap the laps, since each lap costs two model calls and a loop that never converges must still stop.
Also available as captions (WebVTT), the video file and a Markdown copy of this page.
Related terms
- Self-critiqueSelf-critique is asking a model to attack its own output, or having a fresh agent do it, to catch bugs and bad assumptions before you ship. It is a direct counter to a model's tendency to agree with whatever it just produced.
- Automated checkAn automated check is a machine-verifiable gate that agent output has to pass, like tests, a type check, a linter, or a build. It either passes or fails with no judgment, which makes it the backbone of trusting agent code, especially when you are running unattended.
- Automated reviewAutomated review is putting a change through an AI reviewer before a person sees it, so a second agent flags likely bugs, missed edge cases, and smells. It catches the obvious cheaply, but it does not replace human judgment about whether the change is right.
- SpecA spec is a written description of what to build and why, handed to the agent up front. Specs-as-context reliably beat vague one-line requests.
- Human reviewHuman review is a person actually reading what an agent produced, understanding it, and taking responsibility for shipping it. It is the final quality gate that tests and automated review can support but never replace.
More visualisations
Embed this film
Paste this into a post, a course page or a newsletter. The film plays in place, with the same controls as here, and credits the source.