The Harness Is the Player
A harness that kept rewriting itself let a small model keep up with a big one.
Get started with AgentEnv Framework by following our docs.
1. The question
If you let an LLM recursively improve its own harness, could it outperform a stronger model at the same tasks? We set out to answer that with three games: basketball, poker, and a cooking simulator.
Tl;dr: Claude Haiku 5.5 started well behind Claude Opus 5.5 in all three. After a handful of edits to its harness it was level in two of them and most of the way there in the third, at a fraction of the cost. The edits that mattered were beyond just improving prompts. The loop turned previous judgements into computation. Every change that persisted in the harness was something that Haiku was guessing at before.
Every replay in this post is a real game, recorded as it was played, so you can watch it happen.
2. The setup
Haiku 5.5 and Opus 5.5 start behind an identical thin harness:
- the prompt
- a renderer that turns game state into text
- an action menu
- a memory file
- a few subroutines.
While Opus keeps the thin one, Haiku's gets iterated on.
The loop is simple. An external agent reads Haiku's recent games and proposes two edits to the harness. A critic throws out anything keyed to specific seeds or opponent quirks. Each candidate is played on a fixed set of games, and it is admitted only if Haiku plays measurably better than before, above a noise band we measured first. Then the admitted harness is tested on games nobody trained on. A generation is one admitted edit. The recipe is adapted from RRSI, with the modular split from ModularRSI and the open-world framing of Harness².
How one generation is made
3. Basketball
- Opus’s edge, pts per 100 possessions
- +220
- gen 0 → gens 1 to 4; within noise of zero from gen 1 on
- Haiku’s wins vs Opus
- 31%41%
- 10 of 32 → 13 of 32, after the first admitted edit
- Haiku turnovers per possession
- 29%16%
- after the first admitted edit
- Haiku vs a scripted team
- −9+18
- pts per 100 possessions on fresh games, gen 0 → gen 4
Haiku and Opus each coach a team of three. The players are not scripted bots; instead each one is a fast decision model (OpenAI's Luna) that picks its own move every second of game clock from whatever its coach last said. Both coaches send instructions to their three player agents at the start of every play and at stoppages.
Then the loop's first admitted edit landed. It added three computed facts to what the coach sees:
- passing lanes coverage
- the value of each zone on the floor
- a suggested play.
Haiku's win rate rose from 31% to 41%, and its turnovers fell from 29% to 16%. Over the next three generations the two coaches stayed even on points per possession. Opus still won 78 of 128 games across those generations, a record that leans Opus but does not clear the bar we set before the runs. Against a fixed scripted team on games it never played on, Haiku's gen 4 coach was clearly better than its gen 0 self.
Harness improvements
- computational
- prompt-level
- computedGen 1: a per-option value line computed from the court state: which passing lanes are covered, the value of each zone, and a suggested play.
- computedGen 2: memory that keeps factual tallies instead of impressions: points per possession by the play the team opened with, and each opponent's drives by side and result.
- promptGen 2: notes on how to read those tallies: lean a defense only toward a side the tally shows repeated drives on, and never contest a dribbler.
- computedGen 3: the value table recalibrated to observed shooting, so pull-up threes stop being overrated; a close defender discounts the pull-up and adds a pump fake; the decision point moves to the top of what the coach reads.
- computedGen 4: the table tuned for possession starts and the moment after a drive beats its man.
- promptGen 4: the coach's notes aligned with the new table, and the set play no longer treated as the free default. The same table without these notes was not admitted; with them it was.
4. Poker
Haiku vs Opus on the thin harness, big blinds per 100 hands (95% CI)
Gen 0: 400 hands. Gens 3 and 6: 1,600 each. The other generations met Opus for 100 to 400 hands, too few to chart.
Poker is no limit heads-up, and every deal is played twice with the seats swapped so luck cancels. Haiku started at a strong disadvantage: −167.8 big blinds per 100 hands against Opus, and it lost every 100 hand session.
Within three generations of harness edits, Haiku was averaging +25.8 bb/100 against the same Opus. After six, it was averaging +35.1 bb/100. Over 1,600 hands we could no longer tell the two apart. All of that while costing about 94% less than Opus per 100 hands.
Harness improvements
- computational
- prompt-level
- computedGen 1: a renderer line that names the hand, counts outs and compares pot odds to the equity needed to call.
- promptGen 1: the action menu reworded so a slightly malformed reply is no longer silently dropped.
- computedGen 2: a running tally of how often the opponent folds and calls.
- promptGen 2: the strategy text keyed to the hand label the renderer now prints.
- computedGen 3: a one-card chart of preflop ranges and standard responses.
- computedGen 4: a first-in button line: open-raise or fold, never limp; is this hand in range, yes or no.
- promptGen 4: raise_pot is the preflop value size.
- computedGen 5: a postflop strength-tier line with a default action attached.
- promptGen 5: bet bigger against callers, but only with strong hands.
- computedGen 6: paired-board labels, so an overpair on a 9-5-5 board is no longer called two pair, and a session memory.
Haiku didn't lack any of this poker insight. However, it was getting a lot of this computation wrong under pressure.
5. The Kitchen
Soups delivered per game on unseen starts
50 unseen starts per arm. Gen 4 closes 70% of the gap [63, 77]; gens 5 to 10 closed 54% of a wider gap in harder kitchens.
Each model gets two cooks and one kitchen. The model is the captain, giving both cooks orders, and racing to deliver as many meals as it can in 400 steps, each cook making one move per step, while new orders keep arriving.
This was where we saw the biggest gap. Opus beat thin-harness Haiku in 50 of 50 training rounds. On the split kitchen, where each cook can only reach half the stations, Haiku sent cooks to places they could not get to 1,786 times and ran out of its call budget in every episode.
The loop's fix was a plan scaffold: before any order goes out, the harness checks which stations each cook can actually reach and refuses the rest. After four admitted generations, on start states Haiku had never seen, it had closed 70% of the gap to Opus. On kitchens it had never seen at all it was nearly four soups ahead of its old self. It was still about two soups a game behind Opus.
Harness improvements
- computational
- prompt-level
- computedGen 1: one renderer line per cook listing the stations it can reach and the counters both cooks can reach.
- promptGen 1: target only reachable stations, relay through hand-off counters, start full pots at once.
- computedGen 2: a next-target suggestion per cook, built from what it holds and what each pot needs, plus a per-pot line (needs two more, start it now).
- promptGen 2: an empty hand at a pot starts a partial soup; pick up from a counter only once the item is there.
- computedGen 3: relays for split kitchens: the supply cook stages ingredients and a dish on a hand-off counter, the pot-side cook carries them.
- computedGen 4: pathing that treats the other cook as an obstacle and picks a station it can actually reach.
- computedGens 5 to 7: a serve play; per-cook targets built only from reachable stations; a per-pot line of what the best open order still needs and whether starting it now pays zero.
- computedGen 8: a distinct relay counter per cook, and a dish with no soup cooking gets parked on a counter only its holder can reach.
- promptGen 8: goto works only on floor cells; when a cook cannot reach a station, items go through a counter both cooks touch.
- computedGen 9: the cannot-reach list persists for the whole game instead of resetting each call.
- promptGen 10: three rules and nothing else: an empty hand at a pot starts it, queue a counter pickup only when the item is listed there, never start a pot whose line says it pays zero. The biggest single gain of the lineage, 396 to 472 points on the training starts.
The later generations ran in harder kitchens: tomatoes as a second ingredient, three live orders, recipe values. There thin Haiku scored 232 points a game on unseen starts to Opus's 636. By gen 10 Haiku was at 451, 54% of the gap closed, and 178 points ahead of its thin self on kitchens it had never seen.
6. Running it yourself
- Ask at decision points, not every second. Reflex cadence hid every difference between the models.
- Expect code first, then prose about the code. The edits that transferred computed something; the prompt lines that stuck told the model how to use it.
- Run the big model on the evolved harness too. It is the cheapest control and it changed our reading the most.
- Don't let "cheaper" count as "better". When iterating on a harness, let the agent know that cost is a tie-breaker between approaches, but not the final goal.
Environment
arena, fixed seeds
Agent artifact
harness, gen N
Paired runs
same seeds, both sides
Proposer + critic
two edits, checked
Admit?
gain above noise
- ↺ the admitted edit becomes gen N+1, a new version of the same artifact
- every stage pre-registered with hashed files and a spend meter · every figure in this post replays one of these runs
All of it ran on AgentEnv Framework. Each harness generation is a versioned agent artifact, so a lineage is just a chain of them. Every comparison is paired: identical seeds, duplicate deals, the same start states. Each stage was pre-registered with hashed frozen files and a spend meter before a paid episode ran. And every replay in this post is a recorded trajectory, not an illustration.
Try AgentEnv Framework
It's open source, and one install away. Its hello task runs on your machine with no Docker, model or cloud account.
pip install agentenv-frameworkThen follow a cookbook to build a complete task, from an empty folder to a graded run.
Acknowledgements
Experiment, harnesses and write-up by Revan Aleti with the AgentEnv team.