Agentic Coding · Benchmarks · Claude & Codex
Karpathy's autoresearch, and its loop for parameter optimization
Karpathy's autoresearch runs an AI agent in a keep-or-discard loop. I examined its techniques, then applied the loop to parameter search where a grid stalls.
· 4 min read
Andrej Karpathy released autoresearch in March 2026, and the description is almost too plain to notice: give an AI agent a small but real large language model training setup and let it experiment autonomously overnight. The repository is about 630 lines, small enough to sit inside a model’s context window, so the agent can hold the whole training script in view while it edits. The metric is val_bpb (validation bits per byte), where lower is better and the score is vocab-size independent, so architectural changes compare fairly. In this note I examine what the loop does, and then how I used the same loop for parameter optimization in my own work.
How the loop works
The mechanism is a hill-climb with the language model as the mutation operator.
The agent modifies train.py, trains for exactly five minutes, checks whether
val_bpb improved, and keeps or discards the change before repeating. Five
minutes per run works out to roughly twelve experiments per hour and about a
hundred while you sleep. A kept change is committed to git; a change that fails
to improve the score is reverted with git reset, so the repository history
becomes the memory of what has already been tried. Everything inside the
training file is in scope: model architecture, optimizer, hyperparameters,
batch size, model size.
The agent rewrites the model itself, not only its settings.
The guardrails
A loop that optimizes a single number will game that number if it can, and the
design blocks the obvious routes. prepare.py holds the evaluation harness, the
data loading, and the tokenizer, and the agent may not touch it, so the metric
it is graded on is fixed as ground truth. New package installations are
disallowed, memory is a soft ceiling rather than a free variable, and any run
that exceeds ten minutes is killed and recorded as a failure. Every attempt
lands in a results table with its commit, its val_bpb, its peak memory, a status
of keep, discard, or crash, and a one-line description; a crash is recorded as a
score of 0.000000. There is, however, one rule that outranks the mechanical
ones: a small improvement that adds ugly complexity is not kept. The agent is
told to prefer removing code over adding it.
Using the loop for idea selection
The transferable part is the shape rather than the training code: one file to
change, one mechanical metric, one fixed budget, and a keep-or-discard rule.
Karpathy’s own framing, as one write-up
puts it, is that
the researcher stops writing the experiments and starts writing the program that
runs them. I have started using the same structure earlier in the process, as a
way to decide which ideas are worth a full proposal. If a claim reduces to a
number a script can compute in seconds, an agent can score a dozen variants of
it before I commit to writing any of them up. The ideas that survive that cheap
filter are the ones I develop; the rest are discarded with the indifference the
training loop shows a regression. Therefore the judgment I used to spend on early
execution moves to writing a sharper program.md.
Parameter optimization for a PEM electrolyzer model
The use I care about most is parameter optimization for a PEM (proton exchange membrane) electrolyzer model, a surrogate that stands in for an expensive physical simulation. The gain from such a surrogate is large: one physics-informed model for PEM electrolyzers reports inference five to six orders of magnitude faster than the computational fluid dynamics it replaces, on inputs such as temperature, membrane thickness, current density, and pressure. For years the default way to search that input space was a grid. A grid has three problems that appear quickly: (1) it cannot see an optimum that falls between its own lines, so its blind spots are built in; (2) once its resolution is reached there is nowhere further to go; and (3) each added parameter multiplies the points until the full combination is intractable. The autoresearch loop removes all three. With surrogate error against held-out data as the metric and a fixed evaluation budget per candidate, the agent proposes a configuration, scores it, keeps it if the error dropped, and moves on, searching the continuous space instead of a fixed lattice. It found configurations my grid runs had no structural way to reach, and it kept improving after the grid had run out of resolution. That last part is the one I did not expect: the loop is actually most useful where the grid is weakest, in the many-parameter corner where enumeration stops being an option.
Where it holds and where it stops
The limits are the ones Karpathy states for the original: the loop needs a
metric that already exists and a budget it can run inside, and it cannot invent
either for you. Where those two are given, the pattern travels well past
language-model training, which is why a physics surrogate takes to it so readily.
The same discipline sits behind Claude Code’s own autonomous runs, the
/goal loop I compared against Fable 5,
and behind the instruction files that steer an agent, the subject of my
notes on AGENTS.md; program.md is one
more of those. Next I will test whether scoring two objectives together, the
surrogate error and a physical constraint I currently check by hand, survives
the same keep-or-discard discipline.
Sources
- https://github.com/karpathy/autoresearch
- https://github.com/karpathy/autoresearch/blob/master/program.md
- https://www.marktechpost.com/2026/03/08/andrej-karpathy-open-sources-autoresearch-a-630-line-python-tool-letting-ai-agents-run-autonomous-ml-experiments-on-single-gpus/
- https://www.mager.co/blog/2026-03-14-autoresearch-pattern
- https://arxiv.org/html/2511.05879v2