forked from yoheinakajima/babyagi
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding BabyAGI Classic - the OG Baby
- Loading branch information
Showing
4 changed files
with
188 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# BabyAgi Classic | ||
|
||
This folder contains the classic version of BabyAGI as a single script. You can use this as a starting point for your own projects built on the original BabyAGI reasoning engine, if the mainline version is too complex for your needs. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# babyagi | ||
|
||
|
||
# Objective | ||
This Python script is an example of an AI-powered task management system. The system uses OpenAI and Pinecone APIs to create, prioritize, and execute tasks. The main idea behind this system is that it creates tasks based on the result of previous tasks and a predefined objective. The script then uses OpenAI's natural language processing (NLP) capabilities to create new tasks based on the objective, and Pinecone to store and retrieve task results for context. This is a paired-down version of the original [Task-Driven Autonomous Agent](https://twitter.com/yoheinakajima/status/1640934493489070080?s=20) (Mar 28, 2023). | ||
|
||
This README will cover the following: | ||
|
||
* How the script works | ||
|
||
* How to use the script | ||
* Warning about running the script continuously | ||
# How It Works | ||
The script works by running an infinite loop that does the following steps: | ||
|
||
1. Pulls the first task from the task list. | ||
2. Sends the task to the execution agent, which uses OpenAI's API to complete the task based on the context. | ||
3. Enriches the result and stores it in Pinecone. | ||
4. Creates new tasks and reprioritizes the task list based on the objective and the result of the previous task. | ||
The execution_agent() function is where the OpenAI API is used. It takes two parameters: the objective and the task. It then sends a prompt to OpenAI's API, which returns the result of the task. The prompt consists of a description of the AI system's task, the objective, and the task itself. The result is then returned as a string. | ||
|
||
The task_creation_agent() function is where OpenAI's API is used to create new tasks based on the objective and the result of the previous task. The function takes four parameters: the objective, the result of the previous task, the task description, and the current task list. It then sends a prompt to OpenAI's API, which returns a list of new tasks as strings. The function then returns the new tasks as a list of dictionaries, where each dictionary contains the name of the task. | ||
|
||
The prioritization_agent() function is where OpenAI's API is used to reprioritize the task list. The function takes one parameter, the ID of the current task. It sends a prompt to OpenAI's API, which returns the reprioritized task list as a numbered list. | ||
|
||
Finally, the script uses Pinecone to store and retrieve task results for context. The script creates a Pinecone index based on the table name specified in YOUR_TABLE_NAME variable. Pinecone is then used to store the results of the task in the index, along with the task name and any additional metadata. | ||
|
||
# How to Use | ||
To use the script, you will need to follow these steps: | ||
|
||
1. Install the required packages: `pip install -r requirements.txt` | ||
2. Set your OpenAI and Pinecone API keys in the OPENAI_API_KEY and PINECONE_API_KEY variables. | ||
3. Set the Pinecone environment in the PINECONE_ENVIRONMENT variable. | ||
4. Set the name of the table where the task results will be stored in the YOUR_TABLE_NAME variable. | ||
5. Set the objective of the task management system in the OBJECTIVE variable. | ||
6. Set the first task of the system in the YOUR_FIRST_TASK variable. | ||
7. Run the script. | ||
|
||
# Warning | ||
This script is designed to be run continuously as part of a task management system. Running this script continuously can result in high API usage, so please use it responsibly. Additionally, the script requires the OpenAI and Pinecone APIs to be set up correctly, so make sure you have set up the APIs before running the script. | ||
|
||
#Backstory | ||
BabyAGI is a paired-down version of the original [Task-Driven Autonomous Agent](https://twitter.com/yoheinakajima/status/1640934493489070080?s=20) (Mar 28, 2023) shared on Twitter. This version is down to 140 lines: 13 comments, 22 blank, 105 code. The name of the repo came up in the reaction to the original autonomous agent - the author does not mean to imply that this is AGI. | ||
|
||
Made with love by [@yoheinakajima](https://twitter.com/yoheinakajima), who happens to be a VC - so if you use this build a startup, ping him! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
import openai | ||
import pinecone | ||
import time | ||
from collections import deque | ||
from typing import Dict, List | ||
|
||
#Set API Keys | ||
OPENAI_API_KEY = "" | ||
PINECONE_API_KEY = "" | ||
PINECONE_ENVIRONMENT = "us-east1-gcp" #Pinecone Environment (eg. "us-east1-gcp") | ||
|
||
#Set Variables | ||
YOUR_TABLE_NAME = "test-table" | ||
OBJECTIVE = "Solve world hunger." | ||
YOUR_FIRST_TASK = "Develop a task list." | ||
|
||
#Print OBJECTIVE | ||
print("\033[96m\033[1m"+"\n*****OBJECTIVE*****\n"+"\033[0m\033[0m") | ||
print(OBJECTIVE) | ||
|
||
# Configure OpenAI and Pinecone | ||
openai.api_key = OPENAI_API_KEY | ||
pinecone.init(api_key=PINECONE_API_KEY, environment=PINECONE_ENVIRONMENT) | ||
|
||
# Create Pinecone index | ||
table_name = YOUR_TABLE_NAME | ||
dimension = 1536 | ||
metric = "cosine" | ||
pod_type = "p1" | ||
if table_name not in pinecone.list_indexes(): | ||
pinecone.create_index(table_name, dimension=dimension, metric=metric, pod_type=pod_type) | ||
|
||
# Connect to the index | ||
index = pinecone.Index(table_name) | ||
|
||
# Task list | ||
task_list = deque([]) | ||
|
||
def add_task(task: Dict): | ||
task_list.append(task) | ||
|
||
def get_ada_embedding(text): | ||
text = text.replace("\n", " ") | ||
return openai.Embedding.create(input=[text], model="text-embedding-ada-002")["data"][0]["embedding"] | ||
|
||
def task_creation_agent(objective: str, result: Dict, task_description: str, task_list: List[str]): | ||
prompt = f"You are an task creation AI that uses the result of an execution agent to create new tasks with the following objective: {objective}, The last completed task has the result: {result}. This result was based on this task description: {task_description}. These are incomplete tasks: {', '.join(task_list)}. Based on the result, create new tasks to be completed by the AI system that do not overlap with incomplete tasks. Return the tasks as an array." | ||
response = openai.Completion.create(engine="text-davinci-003",prompt=prompt,temperature=0.5,max_tokens=100,top_p=1,frequency_penalty=0,presence_penalty=0) | ||
new_tasks = response.choices[0].text.strip().split('\n') | ||
return [{"task_name": task_name} for task_name in new_tasks] | ||
|
||
def prioritization_agent(this_task_id:int): | ||
global task_list | ||
task_names = [t["task_name"] for t in task_list] | ||
next_task_id = int(this_task_id)+1 | ||
prompt = f"""You are an task prioritization AI tasked with cleaning the formatting of and reprioritizing the following tasks: {task_names}. Consider the ultimate objective of your team:{OBJECTIVE}. Do not remove any tasks. Return the result as a numbered list, like: | ||
#. First task | ||
#. Second task | ||
Start the task list with number {next_task_id}.""" | ||
response = openai.Completion.create(engine="text-davinci-003",prompt=prompt,temperature=0.5,max_tokens=1000,top_p=1,frequency_penalty=0,presence_penalty=0) | ||
new_tasks = response.choices[0].text.strip().split('\n') | ||
task_list = deque() | ||
for task_string in new_tasks: | ||
task_parts = task_string.strip().split(".", 1) | ||
if len(task_parts) == 2: | ||
task_id = task_parts[0].strip() | ||
task_name = task_parts[1].strip() | ||
task_list.append({"task_id": task_id, "task_name": task_name}) | ||
|
||
def execution_agent(objective:str,task: str) -> str: | ||
#context = context_agent(index="quickstart", query="my_search_query", n=5) | ||
context=context_agent(index=YOUR_TABLE_NAME, query=objective, n=5) | ||
#print("\n*******RELEVANT CONTEXT******\n") | ||
#print(context) | ||
response = openai.Completion.create( | ||
engine="text-davinci-003", | ||
prompt=f"You are an AI who performs one task based on the following objective: {objective}. Your task: {task}\nResponse:", | ||
temperature=0.7, | ||
max_tokens=2000, | ||
top_p=1, | ||
frequency_penalty=0, | ||
presence_penalty=0 | ||
) | ||
return response.choices[0].text.strip() | ||
|
||
def context_agent(query: str, index: str, n: int): | ||
query_embedding = get_ada_embedding(query) | ||
index = pinecone.Index(index_name=index) | ||
results = index.query(query_embedding, top_k=n, | ||
include_metadata=True) | ||
#print("***** RESULTS *****") | ||
#print(results) | ||
sorted_results = sorted(results.matches, key=lambda x: x.score, reverse=True) | ||
return [(str(item.metadata['task'])) for item in sorted_results] | ||
|
||
# Add the first task | ||
first_task = { | ||
"task_id": 1, | ||
"task_name": YOUR_FIRST_TASK | ||
} | ||
|
||
add_task(first_task) | ||
# Main loop | ||
task_id_counter = 1 | ||
while True: | ||
if task_list: | ||
# Print the task list | ||
print("\033[95m\033[1m"+"\n*****TASK LIST*****\n"+"\033[0m\033[0m") | ||
for t in task_list: | ||
print(str(t['task_id'])+": "+t['task_name']) | ||
|
||
# Step 1: Pull the first task | ||
task = task_list.popleft() | ||
print("\033[92m\033[1m"+"\n*****NEXT TASK*****\n"+"\033[0m\033[0m") | ||
print(str(task['task_id'])+": "+task['task_name']) | ||
|
||
# Send to execution function to complete the task based on the context | ||
result = execution_agent(OBJECTIVE,task["task_name"]) | ||
this_task_id = int(task["task_id"]) | ||
print("\033[93m\033[1m"+"\n*****TASK RESULT*****\n"+"\033[0m\033[0m") | ||
print(result) | ||
|
||
# Step 2: Enrich result and store in Pinecone | ||
enriched_result = {'data': result} # This is where you should enrich the result if needed | ||
result_id = f"result_{task['task_id']}" | ||
vector = enriched_result['data'] # extract the actual result from the dictionary | ||
index.upsert([(result_id, get_ada_embedding(vector),{"task":task['task_name'],"result":result})]) | ||
|
||
# Step 3: Create new tasks and reprioritize task list | ||
new_tasks = task_creation_agent(OBJECTIVE,enriched_result, task["task_name"], [t["task_name"] for t in task_list]) | ||
|
||
for new_task in new_tasks: | ||
task_id_counter += 1 | ||
new_task.update({"task_id": task_id_counter}) | ||
add_task(new_task) | ||
prioritization_agent(this_task_id) | ||
|
||
time.sleep(1) # Sleep before checking the task list again |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
openai==0.27.2 | ||
pinecone-client==2.2.1 |