in a state of affairs the place you’ve loads of concepts on enhance your product, however no time to check all of them? I guess you’ve.
What if I informed you that you simply not need to do all of it by yourself, you possibly can delegate it to AI. It will probably run dozens (and even a whole bunch) of experiments for you, discard concepts that don’t work, and iterate on those that really transfer the needle.
Sounds wonderful. And that’s precisely the thought behind autoresearch, the place an LLM operates in a loop, repeatedly experimenting, measuring affect, and iterating from there. The strategy sounded compelling, and lots of of my colleagues have already seen advantages from it. So I made a decision to strive it out myself.
For this, I picked a sensible analytical activity: advertising finances optimisation with a bunch of constraints. Let’s see whether or not an autonomous loop can attain the identical outcomes as we did.
Background
Let’s begin with some background to set the context. Autoresearch was developed by Andrej Karpathy. As he wrote in his repository:
Someday, frontier AI analysis was executed by meat computer systems in between consuming, sleeping, having different enjoyable, and synchronizing infrequently utilizing sound wave interconnect within the ritual of “group assembly”. That period is lengthy gone. Analysis is now fully the area of autonomous swarms of AI brokers working throughout compute cluster megastructures within the skies. The brokers declare that we at the moment are within the 10,205th technology of the code base, in any case nobody might inform if that’s proper or improper because the “code” is now a self-modifying binary that has grown past human comprehension. This repo is the story of the way it all started. -@karpathy, March 2026.
The concept behind autoresearch is to let an LLM function by itself in an atmosphere the place it might probably repeatedly run experiments. It adjustments the code, trains the mannequin, evaluates whether or not efficiency improves, after which both retains or discards every change earlier than repeating the loop. Ultimately, you come again and (hopefully) discover a higher mannequin than you began with. Utilizing this strategy, Andrej was in a position to considerably enhance nanochat.
The unique implementation was targeted on optimising an ML mannequin. Nonetheless, simialr strategy may be utilized to any activity with a transparent goal (from decreasing web site load time to minimising errors when scraping with Playwright). Shopify later open-sourced an extension of the unique autoresearch, pi-autoresearch. It builds on pi, a minimal open-source terminal coding harness.
It follows an analogous loop to the unique autoresearch, with a number of key steps:
- Outline the metric you wish to enhance, together with any constraints.
- Measure the baseline.
- Speculation testing: in every iteration, the agent proposes an concept, writes it down, and assessments it. There are three potential outcomes: it doesn’t work (discard), it worsens the metric (discard), or it improves the goal (maintain it and iterate from there).
- Repeat: the loop continues till you cease it, enhancements plateau, or it reaches a predefined iteration restrict.
So the core concept is to outline a transparent goal and let the agent strive daring concepts and study from them. This strategy can uncover potential enhancements to your KPIs by testing concepts your workforce merely by no means had the time to discover. It positively sounds attention-grabbing, so let’s strive it out.
Process
I want to check this strategy on an analytical activity, since in analytical day-to-day duties we regularly have clear targets and have to iterate a number of instances to succeed in an optimum answer. So, I went by means of all of the posts I’ve written for In direction of Knowledge Science through the years and located a activity round optimising advertising campaigns, which we mentioned within the article “Linear Optimisations in Product Analytics”.
The duty is sort of frequent. Think about you’re employed as a advertising analyst and have to plan advertising actions for the following month. Your aim is to maximise income inside a restricted advertising finances ($30M).
You’ve got a set of potential advertising campaigns, together with projections for every of them. For every marketing campaign, we all know the next:
nationand advertisingchannel,marketing_spending— funding required for this exercise,income— anticipated income from acquired clients over the following 12 months (our goal metric).
We even have some extra info, such because the variety of acquired customers and the variety of buyer assist contacts. We are going to use these to iterate on the preliminary activity and make it progressively tougher by including further constraints.

It’s helpful to present the agent a baseline strategy so it has one thing to begin from. So, let’s put it collectively. One easy answer for this optimisation is to concentrate on the top-performing segments by income per greenback spent. We are able to kind all campaigns by this metric and choose those that match throughout the finances. In fact, this strategy is sort of naive and may positively be improved, nevertheless it supplies a great place to begin.
import pandas as pd
df = pd.read_csv('marketing_campaign_estimations.csv', sep='t')
# --- Baseline: grasping by revenue-per-dollar ---
df['revenue_per_spend'] = df.income / df.marketing_spending
df = df.sort_values('revenue_per_spend', ascending=False)
df['spend_cumulative'] = df.marketing_spending.cumsum()
selected_df = df[df.spend_cumulative <= 30_000_000]
total_spend = selected_df.marketing_spending.sum()
revenue_millions = selected_df.income.sum() / 1_000_000
assert total_spend <= 30_000_000, f"Funds violated: {total_spend}"
print(f"METRIC revenue_millions={revenue_millions:.4f}")
print(f"Segments={len(selected_df)} spend={total_spend/1e6:.2f}M")
I put this code in optimise.py within the repository.
If we run the baseline, we see that the ensuing income is 107.9M USD, whereas the entire spend is 29.2M.
python3 optimise.py
# METRIC revenue_millions=107.9158
# Segments=48 spend=29.23M
Establishing
Earlier than shifting on to the precise experiment, we first want to put in pi_autoresearch. We begin by organising pi itself by following the directions from pi.dev. Fortunately, it may be put in with a single command, providing you with a pi coding harness up and working domestically that you could already use to assist with coding duties.
npm set up -g @mariozechner/pi-coding-agent # set up pi
pi # begin pi
/login # choose supplier and specify APIKey
Nonetheless, as talked about earlier, our aim is to strive the pi-autoresearch extension on high of pi, so let’s set up that as effectively.
pi set up https://github.com/davebcn87/pi-autoresearch
I additionally needed some guardrails in place, so I created an autoresearch.config.json file within the root of my repo to outline the utmost variety of iterations. This helps restrict what number of iterations the agent can run and, in flip, retains token prices below management throughout experiments. You may also set a per-API-key spending restrict together with your LLM supplier for even tighter management.
{
"maxIterations": 30
}
Yow will discover all the small print on configuration in the docs.
That’s it. The setup is finished, and we’re prepared to begin the experiment.
Experiments
Lastly, it’s time to begin utilizing the autoresearch strategy to determine which advertising campaigns we must always run. I’m fairly positive our preliminary strategy isn’t optimum, so let’s see whether or not autoresearch can enhance it. Let the journey start.
I began autoresearch by calling the ability.
/ability:autoresearch-create
After that, autoresearch tries to deduce the optimisation aim, and if it fails, it asks for extra particulars.
In my case, it merely inspected the code we applied in optimise.py and created an autoresearch.md file summarising the duty. Right here’s what we received (a reasonably strong abstract, contemplating it solely noticed our baseline optimisation perform). We are able to see that it clearly outlined the metrics and constraints. I additionally preferred that it explicitly highlighted that altering the enter knowledge isn’t allowed. That’s a great guardrail.
# Autoresearch: maximize advertising marketing campaign income below finances
## Goal
Enhance `optimise.py` so it selects a set of marketing campaign segments with **most complete income** whereas respecting the fastened advertising finances of **30,000,000**. The present implementation is a grasping heuristic: it kinds by revenue-per-spend, takes a cumulative prefix, and stops as soon as the following merchandise would exceed finances. Which means it might probably depart finances unused and by no means contemplate cheaper worthwhile objects later within the sorted listing.
The workload is tiny (62 rows), so higher-quality combinatorial optimization methods are doubtless sensible. We should always favor actual or near-exact choice logic over fragile heuristics when the runtime stays quick.
## Metrics
- **Major**: `revenue_millions` (thousands and thousands, larger is healthier) - complete chosen income divided by 1,000,000
- **Secondary**:
- `spend_millions` - complete chosen spend divided by 1,000,000
- `budget_slack_millions` - unused finances in thousands and thousands
- `segment_count` - variety of chosen segments
## Tips on how to Run
`./autoresearch.sh` - runs a fast syntax pre-check, then `optimise.py`, which should emit `METRIC title=quantity` strains.
## Information in Scope
- `optimise.py` - campaign-selection logic and metric output
- `autoresearch.sh` - benchmark harness and pre-checks
- `autoresearch.md` - session reminiscence / findings
- `autoresearch.concepts.md` - backlog for promising deferred concepts
## Off Limits
- `marketing_campaign_estimations.csv` - enter knowledge; don't edit
- Git historical past / department construction exterior the autoresearch workflow
## Constraints
- Should maintain spend `<= 30_000_000`
- Should maintain the script runnable with `python3 optimise.py`
- No dataset adjustments
- Preserve the answer easy and explainable except further complexity yields materially higher income
- Runtime ought to stay quick sufficient for a lot of autoresearch iterations
## What's Been Tried
- Baseline code kinds by `income / marketing_spending`, computes cumulative spend, and retains solely the sorted prefix below finances.
After defining the duty, it instantly began the loop. It will probably run for a while, however you continue to retain visibility. You’ll be able to see each its reasoning and a few key stats within the widget (comparable to the present iteration, greatest goal worth, and enchancment over the baseline), which is sort of useful.

Because it iterates, it additionally writes an autoresearch.jsonl file with full particulars of every experiment and the ensuing goal metric. This log may be very helpful each for reviewing what has been tried and for the mannequin itself to maintain observe of which hypotheses it has already examined.
In my case, regardless of the configured restrict of 30 iterations, it determined to cease after simply 5. The agent explored a number of totally different methods: actual knapsack optimisation, search-space pruning, and a Pareto-frontier dynamic programming strategy. Let’s undergo the small print:
- Iteration 1: Reproduced our baseline strategy. The prefix-greedy technique (income/spend) reached 107.9M, however stopped early when objects didn’t match, lacking higher downstream mixtures. No breakthrough right here, only a sanity verify of the baseline.
- Iteration 2: Precise knapsack solver. The agent switched to a branch-and-bound (0/1 knapsack) strategy and reached 110.16M income (+2.25M uplift), which is a transparent enchancment. A powerful acquire already within the second iteration.
- Iteration 3: Dominance pruning. This iteration tried to shrink the search area by eradicating pairwise dominated segments (i.e., segments worse in each spend and income than one other). Whereas intuitive, this assumption doesn’t maintain within the 0/1 knapsack setting: a “dominating” section could already be chosen, whereas a “dominated” one can nonetheless be helpful together with others. Because of this, this strategy failed and dropped to 95.9M income, and was discarded. An excellent instance of trial and error. We examined it, it didn’t work, and we instantly moved on.
- Iteration 4: Dynamic programming frontier. The agent switched to a Pareto-frontier dynamic programming strategy, nevertheless it achieved the identical end result as iteration 2. From an analyst perspective, that is nonetheless helpful. It confirms we’ve doubtless reached the optimum.
- Iteration 5: Integer accounting. This iteration transformed all financial values from floats to integer cents to enhance numerical stability and reproducibility, however once more produced the identical ultimate worth. It is sensible that the agent stopped there.
So in the long run, the optimum answer was already discovered within the second iteration and it matches the answer we present in my article with linear programming. The agent nonetheless tried a number of different concepts, however stored ending up with the identical end result and ultimately stopped (as an alternative of burning much more tokens).
Now we are able to end the analysis by working the /ability:autoresearch-finalize command, which commits and pushes all the pieces to GitHub. Because of this, it created a brand new department with a PR, saving each the adjustments to the optimise.py code and the intermediate reasoning information. This fashion, we are able to simply observe what occurred all through the method.
The agent simply solved our preliminary activity. Subsequent, let’s strive making it extra life like by including extra constraints from the Operations workforce. Assume we realised that we additionally want to make sure there are not more than 5K incremental buyer assist tickets (so the Ops workforce can deal with the load), and that the general buyer contact fee stays under 4.2%, since that is certainly one of our system well being checks. This makes the issue tougher, because it provides further constraints and forces the agent to revisit the answer area and seek for a brand new optimum.
To kick this off, I merely restarted the /ability:autoresearch-create course of, offering the extra constraints.
/ability:autoresearch-create I've extra constraints for our CS contacts to make sure that our Operations
workforce can deal with the demand in a wholesome approach:
- The variety of extra CS contacts ≤ 5K
- Contact fee (CS contacts/customers) ≤ 0.042
This time, it picked up precisely the place we left off. It already had full context from the earlier run, together with all the pieces we had executed thus far. Because of updating the duty, the agent revised the autoresearch.md file to incorporate the brand new constraints.
## Constraints
- Should maintain spend `<= 30_000_000`
- Should maintain extra CS contacts `<= 5_000`
- Should maintain contact fee `<= 0.042`
- Should maintain the script runnable with `python3 optimise.py`
- No dataset adjustments
- Preserve the answer easy and explainable except further complexity yields materially higher income
- Runtime ought to stay quick sufficient for a lot of autoresearch iterations
It ran 8 extra iterations and converged to the next answer (once more matching what we had seen beforehand):
- Income: $109.87M,
- Funds spent: $29.9981M (below $30M),
- Buyer assist contacts: 3,218 (below 5K),
- Contact fee: 0.038 (below 0.042).
After introducing the brand new constraints, the agent reformulated the issue and switched to an exact MILP solver. It shortly discovered the optimum answer, reaching 109.87M income whereas satisfying all constraints. A lot of the later iterations didn’t actually change the end result, they only cleaned issues up: eliminated fallback logic, lowered dependencies, and improved runtime. So, as soon as the issue was well-defined, the agent stopped “looking out” and began “engineering”. What’s much more attention-grabbing is that it knew when to cease optimising and didn’t run all the best way to the 30-iteration restrict.
Lastly, I requested the agent to finalise the analysis. This time, for some motive, /ability:autoresearch-finalize didn’t push all of the adjustments, so I needed to manually ask pi to create two PRs: one with clear code adjustments, and another with the reasoning and supporting information. You’ll be able to undergo the PRs if you wish to see extra particulars about what the agent tried.
That’s all for the experiments. We received wonderful outcomes and was in a position to see the capabilities of autoresearch. So, it’s time to wrap it up.
Abstract
That was a extremely attention-grabbing experiment. The agent was in a position to attain the identical optimum answer we beforehand discovered, fully by itself. Whereas it didn’t push the end result additional (which isn’t shocking given how well-studied issues like knapsack are), it was spectacular to see how an LLM can iteratively discover options and converge to a strong final result with out guide steerage.
I consider this strategy has sturdy potential throughout a number of domains (from coaching ML fashions and fixing analytical duties to extra engineering-heavy issues like optimising system efficiency or loading instances). In lots of groups, we merely don’t have the time to check all potential concepts, or we dismiss a few of them too early. An autonomous loop like this will systematically strive totally different approaches and validate them with precise metrics.
On the similar time, that is positively not a silver bullet. There shall be instances the place the agent finds “optimum” options that aren’t possible in apply, for instance, enhancing web site loading pace at the price of breaking person expertise. That’s the place human supervision turns into vital: not simply to validate outcomes, however to make sure the answer is sensible holistically.
From what I’ve seen, this strategy works greatest when you’ve a transparent goal, well-defined constraints, and one thing measurable to optimise. It’s a lot more durable to use it to extra ambiguous issues, like making a product extra user-friendly, the place success is much less clearly outlined.
Total, I’d positively suggest attempting out pi-autoresearch or comparable instruments by yourself issues. It’s a robust approach to check concepts you wouldn’t usually have time to discover and see what truly works in apply. And there’s one thing nearly magical about your product enhancing when you sleep.
Disclaimer: I work at Shopify, however this publish is impartial of my work there and displays my private views.

