Inspiration

Nowadays machine learning engineers spend their days iterating on the same system, over and over. Add a feature, change the structure, add regularization, swap the loss function, train, look at the number, do it again. Every day is the same loop: look at the result, work out what's wrong, change something, check whether it helped. It gets repetitive fast. So my friends and I started asking the obvious question — why not give this to an agent?

Most agents that automate this loop skip the first two steps. They mutate code and keep whatever makes the number go up. That works, and it teaches you nothing.

Therefore, an agent that can find the problem and effectively solve it is what our team built.

What it does

You give it a dataset and a scoring rule. Then nobody touches the keyboard.

Each round runs four LLM roles, with plain deterministic code between them:

Doctor — reads the scorecard, names what is wrong, ranks findings by severity card matcher — pure code: intersects the symptoms with the method-card library Strategist — picks 3 candidate remedies, each with a written causal chain from evidence to root cause to fix scheduler — pure code: picks 1 by cost/benefit and chooses the data fidelity Implementer — writes the actual code: a config change, or a new module training — real training, real scoring, a new scorecard Reflector — judges whether the hypothesis held, and updates that card's trust score

The two pure code steps call no model. The LLM is woken at four decision points only — which is how the token budget stays small, and token usage is scored.

How we built it

We were building a hospital for machine learning models. Four of us, four parts of it.

Hu Yaofu got the patient ready. None of this means anything without data you can trust. They took the raw dataset, cleaned it up, and split it the way the organisers split it — not the way that would have made our scores look better. They are also the reason we score with the organisers' own code instead of writing our own version. A scorer that is nearly right is the worst kind. It agrees with you all week, then disagrees on the one day that counts.

Wang Jingjie wrote the pharmacy. They read their way through recommender systems — how people actually fix a ranking model when it is broken — and turned each technique into a card. Every card says the same four things: what it treats, why it should work, how to build it, and what it looks like when it fails. So when the agent has a diagnosis, it has somewhere to look it up.

Then he did the harder half. Jingjie gave the agent hands. It doesn't only pick cards off a shelf — it can write the code itself. New features, new model parts, new training tricks. Whatever it writes goes straight into the pipeline and gets trained.

Xu Shuyao built the medical team. One model staring at one scorecard was never going to be enough. So the thinking got split into four. A doctor, who reads the report and says what is wrong. A strategist, who picks the treatment and has to argue for it. An engineer, who writes it. And a reviewer, who checks afterwards whether the thing they were treating actually got better.

Getting them to talk to each other was the easy part. The hard part was making sure the reviewer couldn't quietly let the strategist off the hook — so those checks are code that fails, not instructions we hoped would be followed. And any one of the four can fall over without bringing the whole run down with it.

Zhu Penglong ran it for real. Everything above is a theory until somebody presses go on the real dataset and watches it break. They ran the real sessions, found where it fell apart, and fixed it. Most of what we now know about this system, we know because they ran it and it didn't work.

None of the four was optional, and we found that out in order. Until the data was right, nobody could tell whether the agent was wrong or the exam was. Until the agent had somewhere to look things up, it had good instincts and nothing to do with them. And until someone ran the whole thing end to end, we were all just fairly confident.

Challenges we ran into

We expected the hard part to be making the agent clever. It wasn't. Every problem that actually cost us time had the same shape: it looked like one thing and turned out to be another. A cautious agent that was really a blind one. A limit on its knowledge that was really a decision we had made. And a success that was really nothing at all.

  1. The doctor kept saying it couldn't tell.

We came back to the first real run expecting to read arguments. We read the same sentence twenty times. No findings this round. The session had converged having written nothing, and the two roles that do the actual work had never been woken up.

Our instinct was that the doctor was too timid. Before loosening it we read what it had written, which we should have done first:

Needs the training-set score. Not here. Needs the per-bucket numbers. Not here. Needs users split into seen and unseen. Not here.

It was right. Almost nothing a doctor diagnoses is the total score — overfitting is a distance, cold start is one bucket against another. Our scorecard had three validation numbers on it. We had handed it a thermometer and asked for a diagnosis.

So we rebuilt the scorecard and left the doctor alone. Next run: two real problems found, four ruled out, numbers for all six.

  1. A library of methods always runs out.

Every technique we knew went onto a card — what it treats, why it works, how to build it, what failure looks like. Which means, on the face of it, the agent can never be smarter than our reading list.

The obvious answer is to hand it the papers. We think that is worse: it would re-read the shelf every round and decide by feel what applied, with a fresh chance each time to invent a connection that isn't there.

So we distilled instead of dumping. A card is a paper reduced to the four things you need at the moment of choosing, labelled with the problems it treats — using the same fixed vocabulary the doctor is restricted to. Finding the right card is then not a judgement at all. It is an intersection of two sets: free, instant, and unable to invent a match.

Then we gave the strategist a way out of the library. When nothing fits, or everything that fits has already failed, it may propose something that exists on no card — it just has to sketch the implementation itself and face the same review afterwards. That path gets used. Some of its inventions came from reading the error message of something that had broken two rounds earlier.

The library turned out to be the floor, not the ceiling.

  1. The score went up and it meant nothing.

This is the failure we feared most, because it arrives dressed as success.

The agent decides cold-start items are the problem, writes a fix, and the score improves. Except the cold-start bucket never moved — the gain came from somewhere else. Write that down as "it worked" and it reaches for the same fix next time, and the card's trust score climbs. Twenty rounds later you have a rising number and a completely wrong picture of your own model.

It is the maths tutor problem. The child is bad at maths, you hire a maths tutor, the term score goes up three points — and maths is unchanged, the gain came from an easy literature paper. Now you will hire that tutor again.

So the reviewer may not look at the total. It has to name the number it was aiming at and report what that number did. And we wrote those rules as checks that fail, not instructions that ask: it cannot claim success while admitting nothing improved, cannot call a problem fixed while its own before and after are identical, cannot claim a win smaller than the noise, and cannot promise to treat three problems and account for one.

Every rule we wrote as an instruction was eventually ignored. Every rule we wrote as a check held.

Accomplishments that we're proud of

The agent writes real code, not just numbers. It can add a feature, define a model, or change how training works by writing an actual Python module that gets imported and trained. New columns it invents join the feature table on their own. And it is bounded the way a human contributor is bounded: it may only create files in one directory, every statistic is fitted on the training split, and target statistics go through an out-of-fold path so a row can never be encoded using its own label.

It cannot quietly mark its own homework. Six distinct ways for a conclusion to be internally inconsistent are rejected by code, with the exact violation handed back for another attempt. It cannot claim success while admitting nothing improved. It cannot call a problem solved while its own before and after are identical. It cannot claim a win smaller than the noise it measured.

Its negative results are as good as its positive ones. In a real run it reported two problems with numbers behind each, and ruled out four others with numbers behind those too — cold-start ruled out because the coldest bucket actually scored above the hottest one, new users ruled out because unseen users scored higher than seen ones, drift ruled out because the last two days went up rather than down. It also noticed that one bucket held only 166 positive examples and refused to use it as evidence at all. Knowing what is not wrong is most of diagnosis.

And the whole thing can be rehearsed for free. There is an offline mode with a fake model and a fake executor, and you can inject failures on demand — a role that breaks in round 3, a training run that dies halfway. The entire loop, including every recovery path, is testable with no network, no GPU and no API spend. 312 tests, about five seconds.

What we learned

Automating Machine Learning turned out to much more fun than we expected.

We arrived thinking of a model as something you ask questions. We left having built something that asks its own. The first time it read a result, decided the model was memorising its training set, argued for a fix, wrote the code, and then came back to tell us that its own idea hadn't worked — that was the moment this stopped being an assignment.

We also understand multi-agent systems far better than we did three weeks ago.

One model asked to do everything does all of it vaguely. Four roles with a clear handoff between them do each part sharply. But collaboration isn't free. They need a shared vocabulary or they talk past each other, and somebody has to check the others' work or they agree far too easily.

Most of what we actually built is the space between the roles, not the roles.

And we learned what dividing up work looks like when part of your team isn't human.

The four of us split the project almost exactly the way the agent is split inside: someone prepared the data, someone stocked the knowledge, someone built the roles, someone ran it and found where it fell over.

Our own jobs changed shape while we did it. We spent much less time writing models, and much more deciding what the agent should be allowed to see, what it must never be allowed to conclude, and how we would know if it were fooling itself. That felt less like engineering and more like management — which is probably what a lot of engineering is about to feel like.

What's next for ML Doctor

What our team really care about is not a better recommender, but a research method that happens to be pointed at one.

The interesting bottleneck becomes the knowledge, not the agent.

Every card in our library was written by a human, which means the agent's ceiling is our reading list. But it already invents remedies that survive review, and when one does, it has produced everything a card needs: what it treats, why it worked, how it was built, what failure looked like. An agent that writes those back is an agent whose library is larger every time it runs — and knowledge that compounds across sessions is worth far more than any single session's score. We want this to be something people actually use.

There is already a console. You point it at your data, press go, and watch the four roles argue in real time — click on any one of them and you can read exactly what it was thinking when it said that. Today it is a debugging tool for us. It should be a tool for somebody else.

The version we want: an engineer points it at their own model. It reads the scorecard, says what is wrong, shows the numbers behind the claim, and proposes something. Then the engineer decides — take it, throw it out, or rewrite it and hand it back. Not an agent that replaces the person, and not a chatbot waiting to be asked. Something that sits next to you, does the parts that are tedious and easy to get wrong, and has to convince you before it is allowed to spend an hour of GPU time.

The log it already produces is shaped like a code review: here is what I thought was wrong, here is the change, here is what happened, here is whether I was right. That is a form teams already know how to read.

And the part worth keeping is not the interface. Every run leaves behind a library that is slightly larger — the remedies that worked, the ones that didn't, and the evidence for both. A team that runs this for six months ends up with something more valuable than any single model it produced.

Built With

Share this project:

Updates

Submission history