Capstone Project: Is BabyAGI a fire alarm?

Initial thoughts

[Please note these are just very rough thoughts, I wanted to do a thoughtful write-up but then I started research with Ethan Perez during MATS]

BabyAGI is a self-prompting / auto-prompting framework that iterates to answer an overall goal by creating subtasks, executing them and prioritising as it goes. There are similar repos that are popular at the moment, for example AutoGPT which aims to iteratively build code using similar techniques.

Why I think BabyAGI is a fire alarm:

Why I don’t think it is:


I'm going to run tests with BabyAGI in a sandbox text-only environment to see how it can go off the rails and if there are cases where it is misaligned with user intent. I might start with goals such as these:


I wrote improvements to BabyAGI to better visualise what was going on, see summary tweet here. The project log for this and more is below.


Project Log

09/04/23 (3h)

I pulled the BabyAGI repo and started experimenting with the initial example of “Solve world hunger”. I couldn’t be bothered to set up a pinecone instance so I quickly coded up a datastore that stores the data in memory and uses cosine similarity to return the top_k elements (see commit here).


I noticed a few problems on first run through (see screenshots below):


Small bits of work I’d like to add to aid faster workflow

I also noticed there seems to be no way of stopping it breaking down a subtask into more subtasks even when the subtask is simple. This issue says the same.  Therefore, this loop will just run forever carrying on expanding and never reaching a conclusion. This needs to be addressed.  [Done 26/04]


I don’t think the current information retrieval would work very well. The reason is choosing the nearest context might not be the best way to build a thought model that uses all previous answers to questions. It would be better if there was more of a task decomposition structure in place, where each of the parent nodes uses the results of the tasks beneath it. This would require a first pass of generating all subtasks first and knowing when to stop. Then slowly work your way back up the tree before reaching the final goal. I might experiment implementing this too. It has big links to the task decomposition stages of IDA. Perhaps with human feedback this could form a new way to make IDA usable for real world problems?


Another thought is this could be reformulated as Debate. Though I’m unsure if the assumptions would hold true given the inconsistency of the LLM’s output at times. This could be a further extension of this work.


I’m going to spend the next hour or so looking into improve the first few bullet points to give me a solid foundation to iterate on.

Tasks for next time: save state, tree structure visualisation, build in task decomposition and ensure the loop reaches a conclusion and terminates.


10/04/23 (15mins)

Some more thoughts:

22/04/23 (4h)

Lots of upgrades to BabyAGI in the last 2 weeks. I'm going to spend some time looking through whats new.

AutoGPT is more active in terms of merge requests and features but for now I'm going to stick to the simplificty of BabyAGI.

I'm still going to push down the task decomposition route and I'm thinking I need tools to see the constructed DAG nicely. I learnt about the new tools weights and biases are building to support prompt engineering at the London event last Thursday. Here is the tool and it could be useful: https://wandb.ai/site/prompts 


Coding for today:


Plan for next session:

23/04/23 (6h)

Just got the Dash visualisation working (see screenshot below).

Also did a big refactor which included having a TaskList object, clearing out unrequired code (such as pinecone and dot env). See the main run.py to see the improvements over the old babyagi.py script.

26/04/23 (3h)

Added tracking of state to the visualisation by colour coding the nodes (commit). Incomplete nodes are yellow, red nodes are cancelled and green nodes are complete.

Add task decomposition agent that is aware it needs to break down tasks rather than just create them. Further more the subtask number could be limited and a stopping criterion of "the task has been adequately answered and breaking it down into further tasks will not help the ultimate objective" was added (commit).

Added summarisation agent that would trace back up the tree and combine subtask results. Ultimately it would lead to a final summary that encompasses all the information in the nodes (commit).

I tried this for the task "Create a new Magic The Gathering commander card for Draconic Destruction" and the final solution was:

After conducting research and analyzing existing commander cards in Magic The Gathering, it was found that there is a lack of options for players who want to focus on a dragon-themed deck specifically focused on destruction as their main strategy. To create a new Draconic Destruction commander card, it was recommended to incorporate abilities that allow players to deal damage to opponents or destroy their creatures while providing bonuses for having dragons in play. In addition, the card should have a lower mana cost to make it more accessible for players.

Based on the analysis, a possible concept for the new Draconic Destruction card would be a dragon-themed card with the ability to deal damage to opponents and destroy their creatures. To incentivize players to build a dragon-centric deck, the card would grant additional power and toughness to all dragons on the battlefield. The card would also have a lower mana cost and a lower casting cost for dragon creatures, enabling players to easily summon powerful dragons onto the battlefield. An ability that allows players to search their library for a dragon creature and put it into their hand was also recommended for increased consistency in building a dragon-themed deck.

The new Draconic Destruction commander card will have a mana cost of 3 red, 3 colorless, a power of 4, and a toughness of 4. Its abilities will include "Dragonlord's Might," which grants additional power and toughness to all dragons on the battlefield, "Draconic Blast," which allows players to deal damage to opponents and destroy their creatures, and "Dragonlord's Call," which allows players to search their library for a dragon creature and put it into their hand.

The tree for this task is below:

We now have a BabyAGI framework that we can visualise in a structured way, ensure it stops given some criterion, and give a solution that combines all of the work it has carried out. 

There are some key limitations I want to address before delving into the safety concerns of this. The stop criterion is too sensitive. Even for a broad task of "solve world hunger" it stops after the very first task creation stage.

Ideas to implement next:

Viz:

27/04/23 (2h)

The stop criterion as part of the execution agent did not work well. It always decided it should stop even when trying lots of different stopping criterions. This was also the case when it was part of the task decomposition agent. Therefore, I created a new stop criterion agent that would just return yes or no for if the current task should be broken down further based on the result. (commit)

The stop criterion that worked well was: "the task is very simple already and breaking it down further will not lead to any more insights (no further research is required given the contents of the result)"

When using this a simple task such as "Create a new Magic The Gathering commander card for Draconic Destruction" would complete with just 4 subtasks. The complex task of "solve world hunger" would continue to break tasks down beyond 50+ subtasks. This is what I would expect. See the difference in trees below.

I also implemented a way to resolve the tree and get to a final solution even if the tree did not completely terminate (commit). This was important so I could test the final solution to solve world hunger even if it hadn't completely broken it down fully.

29/04/23 (1h)

Made the graph react in real time as nodes are created. (commit)

Added summary as tree is resolved to viz. (commit)

Made summarization aware of main objective since it improves the final answer (commit)