Hill climbing with agents

This is an agentic workflow that borrows the concept of hill climbing from the local-search optimisation algorithm of the same name. The tldr is that you start with a solution, try some changes, and move to one with a better score. This workflow is useful to improve solutions through verified changes.

The Workflow:

Start candidate -> Agent proposes (or you can provide multiple ideas/techniques) and implements changes -> Verify

Here it is, nicer:

Hill-climbing feedback loop: Start candidate, Propose changes, Implement, Verify. If the target is reached, end; otherwise continue the loop.

This workflow needs these things:

  1. a Goal: What are we trying to achieve? What are we trying to improve? This can also include any additional guidance/direction to try.
  2. a Verification method: How do we check whether the change actually helps? (I actually think this is the most important part of agentic coding/workflows, lmk if anyone wants to chat about it!) How do we give the agents the ability to measure the effect of the change?
  3. a Target: What is a good enough result to stop?
  4. a Budget (optionally): How many max attempts in the loop?

The clearer these are, the less the agent has to guess on. A vague request like "make this faster!!!" gives the agent lots of wiggle room to make plausible changes without knowing which ones truly matter.

Why does this work?

Agent's answers are proposals, its task is only complete when the proposal meets the target. When it runs a compiler, tests or a benchmark and sees the results, it can use those results to then choose its next change. Compiler feedback (rust compiler is even better in this case!!) or failed tests narrows the problem. A benchmark that gets worse results tells the agent that its proposal did not work.

This is awfully similar to one approach to post train most models today: the RLVR framework or something really similar, tldr is that a model is rewarded for a correct answer or for making the right choice. For example, a post training task can ask the model to write a function. Its code can be checked against test cases, including ones the model has not been shown. The results provide a way for the model's code to be graded, which the training process uses to then update the model's weights. Across many such tasks, the model is encouraged to produce solutions that pass the checks.

With this workflow, we're giving the model a similar kind of problem and environment to work in. A goal, a way to verify its answer and a target. We still own the goal and the checks and ideally even a direction to explore. I think the similarity between this workflow and how the model is trained is one reason why I have found this workflow to be super successful.

This is why I think the verification method is the most important part of the workflow, if the agent cannot verify this just does not work. The budget makes sure its not stuck in the loop.

An example from a real project

I helped a friend with a project which processes game data in the background as jobs. Some jobs update live results, others recheck and reconcile saved results. The background work was falling behind even though it was allowed to run more jobs at once.

We can frame this problem as a hill-climb quite simply:

  • the Goal: Complete more background jobs per minute without delaying live updates or changing the results. Start with how workers pick up jobs: look for unused slots, one kind of job crowding out the others, and job workers sleeping despite available work. Measure time spent waiting to take work and repeatedly planning the same db query.
  • the Verification method: I actually had this as a project specific skill, its basically said - run the same queue through the worker before and after each change, keeping the worker and workload settings fixed, and compare completed jobs per minute. Check that both job types get a turn, live updates should not be delayed, and the correctness tests should still pass.
  • the Target: 1000 background jobs per minute with the same worker capacity and job limits.
  • I did not set a budget for this hill climb since I was confident the agent could reach the target within a few turns because the architecture easily allowed for this throughput.
What happened

The agent tried the direction I'd mentioned and worked on how jobs were being picked up. Once that improved, measuring again showed the next bottleneck - workers were spending time repeatedly planning the same db query.

Background jobs/minute Improvement vs baseline
Baseline 422 -
Improvement 1 802 +90%
Improvement 2 1,090 +158%

These are real results from controlled runs in testing environment.

My final thoughts

In this case only 2 improvements were enough to meet the target, and this is what I found too, this workflow is very time efficient. Since the agents are very good and quick at doing guided grunt work, and when given a clear task with a clear "Done" state to work towards and some additional guidance, its surprising how much work we can get done and the results we can achieve without much babysitting.

Thank you for taking the time out to read this fully. I was really looking forward to being there and sharing this with you all, so I'm sorry I couldn't make it in person. I hope you find this useful!