BabyAGI started life as a single Python file you could read in one sitting. It took an objective, generated a to-do list, picked the next task, executed it, then wrote new tasks based on what it had just learned. Then it did that again. And again, until you pulled the plug or the budget ran out.
The story of how BabyAGI sparked the autonomy revolution is really a story about a demo, not a product. That is exactly why the code is worth rebuilding yourself. When you write the loop by hand, autonomous agents stop feeling like magic and start feeling like a control system you can tune: prompts, memory, stop conditions, cost.
This walkthrough gets a working BabyAGI-style agent running in about an hour. No orchestration framework, no agent library. An LLM API key, a vector store, and some discipline about scope.
What the loop actually does
Five moving parts, and none of them are complicated on their own:
- Objective — one sentence, pasted at the top of every prompt.
- Task list — an ordered queue, usually just a list of strings.
- Execution agent — does the task on top of the queue, optionally with tools like web search or a calculator.
- Task creation agent — reads the result and proposes new tasks.
- Prioritisation agent — reorders the queue, drops duplicates, promotes whatever comes next.
Memory sits underneath all of it. Every result gets embedded and stored, and before each execution the agent pulls back the few most similar past results. Without that step, your agent forgets it already checked a fact three tasks ago and grinds in circles. With it, the loop converges.
Step 1: Pick an objective with a finish line
“Research the EV market” is a bad objective. It never ends, and the task creation agent will happily generate subtasks until your card declines. Something like “Produce a 1,200-word briefing on the five largest public EV charging networks in the Netherlands, with price per kWh and a source URL for each” is a good one. You can tell instantly when it has been satisfied.
My rough test: if a freelance researcher couldn’t quote you a fixed price for the job, it needs narrowing. Set a task ceiling at the same time. Fifteen to twenty-five tasks covers most research work.
Step 2: Give it memory that survives a restart
Use Chroma, FAISS, or pgvector if you already run Postgres. Embed each result with the same model you use to embed task descriptions, or similarity scores will be meaningless.
Before every execution, query for the top three to five similar results and paste them into the prompt under a heading like “relevant context”. Two details save real headaches here: keep each stored result under roughly 2,000 characters, and stamp it with its task ID and a timestamp. Six tasks later, when a claim looks shaky, the timestamp is how you trace it back.
Step 3: Wire up the execution agent
This is the unglamorous, load-bearing part. The execution prompt needs four things: the objective, the current task, retrieved context, and the tools on offer.
Keep the tool list short and explicit. Two tools — web search and a page fetcher — will carry you a long way, provided you tell the model to attach a URL to every factual claim. If the job doesn’t need live data, drop search entirely. It runs faster, costs less, and is far easier to debug.
Log everything: raw prompt, raw completion, token counts, latency, dollar cost. When the run derails at task 11, that log is the only way to find out why.
Step 4: Write the task-creation and prioritisation prompts
These two prompts carry most of the intelligence, and both are short.
Task creation
Ask for JSON only — an array of three to five strings, each specific enough to finish in one step. Include the full task list and the latest result so it stops proposing work that’s already done. Something like “list candidate companies” is fine. “Understand the market” is not; it will get re-queued forever.
Prioritisation
Hand it the objective plus the unordered list, and ask for the list back in the order that best advances the objective, trimmed to the top ten. Cap that number or the queue grows faster than it drains, which is the classic way these agents stall.
One trick worth adopting early: have the prioritisation step return a short reason alongside each reordered task. You don’t need to display it, but it makes bad runs obvious. When the reasoning reads “prerequisite for task 4”, that’s healthy. When it reads “explore topic further”, your objective is too vague.
Step 5: Build the leash before the features
Three guardrails, each a handful of lines:
- Max iterations. A hard stop at 25. No exceptions, no continuation prompt.
- Max spend. Track cumulative tokens and abort at $2 for a first run.
- Human checkpoint. Every five tasks, print the queue and wait for a keypress. It keeps you honest and catches nonsense before it compounds.
Add one more cheap rule: if a newly proposed task is over 90% similar to something already completed, discard it. A quick string similarity check kills most of the noise.
A worked example: a 30-minute competitive scan
Objective: “Identify five direct competitors to a mid-market expense tool in the UK, with each one’s pricing model and a one-line positioning statement.”
Task 1 is almost always “List candidate companies”. The execution agent comes back with seven names. Task creation spins off “Find pricing for [company]” for each. The prioritisation agent notices the objective only wants five companies and pushes verification tasks up the queue. Around task nine, results start referencing earlier ones because retrieval is pulling them into the prompt. By task fourteen the agent proposes its own synthesis task and drafts the comparison itself. Running on a mid-tier model, the whole thing lands under $0.60.
Where it goes sideways is scope creep. Unconstrained, you’ll see tasks like “research the history of expense management software” appear around task eight. That’s not a bug in the loop; it’s a sign the objective needs a narrower fence around it.
Failure modes you’ll meet in the first week
- Infinite regress. Task creation keeps adding “verify the verification”. Cap the list and stop accepting new tasks after iteration eighteen unless the objective is unmet.
- Duplicate labour. Two tasks fetch the same page. The similarity check from step 5 handles it.
- Context bloat. Dumping twenty retrieved results into one prompt degrades output quality and doubles your bill. Five is a better number.
- Confident nonsense. The agent writes a pricing figure with no source. Require a URL per claim and let the synthesis task flag anything uncited.
Where to take it next
Once the loop runs reliably, the upgrades that pay off are tools (code execution, a spreadsheet writer for results), persistence (resume a run from a database rather than memory), and scheduling (a nightly cron job that emails you the queue).
If you’d rather not maintain all that plumbing yourself, OpenManus is an open-source agent that keeps you in control, with the same plan-act-observe loop but visible approval steps before anything irreversible happens. It’s a sensible reference implementation to read once you’ve built your own and understand which parts matter.
And if you want to see how much of this pattern came from that original hundred-line script, the earlier piece on the tiny open-source agent that started it all is worth twenty minutes. Then go build the loop. You’ll learn more from 25 logged iterations than from any architecture diagram.

