swarm class simplification boss node is pre configed and worker node is pre configed

Former-commit-id: cba0d4c759
pull/47/head
Kye 1 year ago
parent 56237cf361
commit 7a9392a4e1

@ -20,7 +20,7 @@ class BossNodeInitializer:
The BossNode class is responsible for creating and executing tasks using the BabyAGI model. The BossNode class is responsible for creating and executing tasks using the BabyAGI model.
It takes a language model (llm), a vectorstore for memory, an agent_executor for task execution, and a maximum number of iterations for the BabyAGI model. It takes a language model (llm), a vectorstore for memory, an agent_executor for task execution, and a maximum number of iterations for the BabyAGI model.
""" """
def __init__(self, llm, vectorstore, agent_executor, max_iterations): def __init__(self, llm, vectorstore, agent_executor, max_iterations, human_in_the_loop, embedding_size):
if not llm or not vectorstore or not agent_executor or not max_iterations: if not llm or not vectorstore or not agent_executor or not max_iterations:
logging.error("llm, vectorstore, agent_executor, and max_iterations cannot be None.") logging.error("llm, vectorstore, agent_executor, and max_iterations cannot be None.")
raise ValueError("llm, vectorstore, agent_executor, and max_iterations cannot be None.") raise ValueError("llm, vectorstore, agent_executor, and max_iterations cannot be None.")
@ -28,6 +28,8 @@ class BossNodeInitializer:
self.vectorstore = vectorstore self.vectorstore = vectorstore
self.agent_executor = agent_executor self.agent_executor = agent_executor
self.max_iterations = max_iterations self.max_iterations = max_iterations
self.human_in_the_loop = human_in_the_loop
self.embedding_size = embedding_size
try: try:
self.baby_agi = BabyAGI.from_llm( self.baby_agi = BabyAGI.from_llm(
@ -35,7 +37,7 @@ class BossNodeInitializer:
vectorstore=self.vectorstore, vectorstore=self.vectorstore,
task_execution_chain=self.agent_executor, task_execution_chain=self.agent_executor,
max_iterations=self.max_iterations, max_iterations=self.max_iterations,
human_in_the_loop=True human_in_the_loop=self.human_in_the_loop
) )
except ValidationError as e: except ValidationError as e:
logging.error(f"Validation Error while initializing BabyAGI: {e}") logging.error(f"Validation Error while initializing BabyAGI: {e}")
@ -50,7 +52,7 @@ class BossNodeInitializer:
""" """
try: try:
embeddings_model = OpenAIEmbeddings(openai_api_key=self.openai_api_key) embeddings_model = OpenAIEmbeddings(openai_api_key=self.openai_api_key)
embedding_size = 1536 embedding_size = self.embedding_size
index = faiss.IndexFlatL2(embedding_size) index = faiss.IndexFlatL2(embedding_size)
return FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {}) return FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {})
except Exception as e: except Exception as e:

@ -16,8 +16,8 @@ from langchain.vectorstores import FAISS
from swarms.agents.tools.main import WebpageQATool, process_csv from swarms.agents.tools.main import WebpageQATool, process_csv
from swarms.boss.boss_node import BossNodeInitializer as BossNode from swarms.boss.boss_node import BossNode
from swarms.workers.worker_node import WorkerNodeInitializer from swarms.workers.worker_node import WorkerNode
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
@ -36,16 +36,13 @@ class HierarchicalSwarm:
def __init__( def __init__(
self, self,
openai_api_key: Optional[str] = "", openai_api_key: Optional[str] = "",
use_vectorstore: Optional[bool] = True, use_vectorstore: Optional[bool] = True,
embedding_size: Optional[int] = None, embedding_size: Optional[int] = None,
use_async: Optional[bool] = True, use_async: Optional[bool] = True,
worker_name: Optional[str] = "Swarm Worker AI Assistant", worker_name: Optional[str] = "Swarm Worker AI Assistant",
verbose: Optional[bool] = False, verbose: Optional[bool] = False,
human_in_the_loop: Optional[bool] = True, human_in_the_loop: Optional[bool] = True,
boss_prompt: Optional[str] = "You are an Boss in a swarm who performs one task based on the following objective: {objective}. Take into account these previously completed tasks: {context}.\n", boss_prompt: Optional[str] = "You are an Boss in a swarm who performs one task based on the following objective: {objective}. Take into account these previously completed tasks: {context}.\n",
worker_prompt: Optional[str] = None, worker_prompt: Optional[str] = None,
temperature: Optional[float] = 0.5, temperature: Optional[float] = 0.5,
max_iterations: Optional[int] = None, max_iterations: Optional[int] = None,
@ -53,144 +50,38 @@ class HierarchicalSwarm:
self.openai_api_key = openai_api_key self.openai_api_key = openai_api_key
self.use_vectorstore = use_vectorstore self.use_vectorstore = use_vectorstore
self.use_async = use_async self.use_async = use_async
self.human_in_the_loop = human_in_the_loop self.human_in_the_loop = human_in_the_loop
self.embedding_size = embedding_size self.embedding_size = embedding_size
self.boss_prompt = boss_prompt self.boss_prompt = boss_prompt
self.worker_prompt = worker_prompt self.worker_prompt = worker_prompt
self.temperature = temperature self.temperature = temperature
self.max_iterations = max_iterations self.max_iterations = max_iterations
self.logging_enabled = logging_enabled self.logging_enabled = logging_enabled
self.verbose = verbose self.verbose = verbose
self.worker_node = WorkerNode(
openai_api_key=self.openai_api_key,
use_vectorstore=self.use_vectorstore,
embedding_size=self.embedding_size,
worker_name=self.worker_name,
worker_prompt=self.worker_prompt,
temperature=self.temperature,
human_in_the_loop=self.human_in_the_loop,
verbose=self.verbose
)
self.boss_node = BossNode(
worker_node=self.worker_node,
max_iterations=self.max_iterations,
human_in_the_loop=self.human_in_the_loop,
embedding_size=self.embedding_size
)
self.logger = logging.getLogger() self.logger = logging.getLogger()
if not logging_enabled: if not logging_enabled:
self.logger.disabled = True self.logger.disabled = True
def initialize_llm(self, llm_class):
"""
Init LLM
Params:
llm_class(class): The Language model class. Default is OpenAI.
temperature (float): The Temperature for the language model. Default is 0.5
"""
try:
# Initialize language model
return llm_class(openai_api_key=self.openai_api_key, temperature=self.temperature)
except Exception as e:
logging.error(f"Failed to initialize language model: {e}")
def initialize_tools(self, llm_class, extra_tools=None):
"""
Init tools
Params:
llm_class (class): The Language model class. Default is OpenAI
extra_tools = [CustomTool()]
worker_tools = swarms.initialize_tools(OpenAI, extra_tools)
"""
try:
llm = self.initialize_llm(llm_class)
# Initialize tools
web_search = DuckDuckGoSearchRun()
tools = [
web_search,
WriteFileTool(root_dir=ROOT_DIR),
ReadFileTool(root_dir=ROOT_DIR),
process_csv,
WebpageQATool(qa_chain=load_qa_with_sources_chain(llm)),
]
if extra_tools:
tools.extend(extra_tools)
assert tools is not None, "tools is not initialized"
return tools
except Exception as e:
logging.error(f"Failed to initialize tools: {e}")
raise
def initialize_vectorstore(self):
"""
Init vector store
"""
try:
embeddings_model = OpenAIEmbeddings(openai_api_key=self.openai_api_key)
embedding_size = self.embedding_size
index = faiss.IndexFlatL2(embedding_size)
return FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {})
except Exception as e:
logging.error(f"Failed to initialize vector store: {e}")
return None
def initialize_worker_node(self, worker_tools, vectorstore, llm_class=ChatOpenAI):
try:
llm = self.initialize_llm(ChatOpenAI)
worker_node = WorkerNodeInitializer(llm=llm, tools=worker_tools, vectorstore=vectorstore)
worker_node.create_agent(ai_name=self.worker_name, ai_role="Assistant", search_kwargs={}, human_in_the_loop=self.human_in_the_loop)
worker_description = self.worker_prompt
worker_node_tool = Tool(name="WorkerNode AI Agent", func=worker_node.run, description= worker_description or "Input: an objective with a todo list for that objective. Output: your task completed: Please be very clear what the objective and task instructions are. The Swarm worker agent is Useful for when you need to spawn an autonomous agent instance as a worker to accomplish any complex tasks, it can search the internet or write code or spawn child multi-modality models to process and generate images and text or audio and so on")
return worker_node_tool
except Exception as e:
logging.error(f"Failed to initialize worker node: {e}")
raise
def initialize_boss_node(self, vectorstore, worker_node, llm_class=OpenAI):
"""
Init BossNode
Params:
vectorstore (object): the vector store object.
worker_node (object): the worker node object
llm_class (class): the language model class. Default is OpenAI
max_iterations(int): The number of max iterations. Default is 5
verbose(bool): Debug mode. Default is False
"""
try:
# Initialize boss node
llm = self.initialize_llm(llm_class)
# prompt = self.boss_prompt
todo_prompt = PromptTemplate.from_template(self.boss_prompt)
todo_chain = LLMChain(llm=llm, prompt=todo_prompt)
tools = [
Tool(name="TODO", func=todo_chain.run, description="useful for when you need to come up with todo lists. Input: an objective to create a todo list for your objective. Note create a todo list then assign a ranking from 0.0 to 1.0 to each task, then sort the tasks based on the tasks most likely to achieve the objective. The Output: a todo list for that objective with rankings for each step from 0.1 Please be very clear what the objective is!"),
worker_node,
]
suffix = """Question: {task}\n{agent_scratchpad}"""
prefix = """You are an Boss in a swarm who performs one task based on the following objective: {objective}. Take into account these previously completed tasks: {context}.\n """
prompt = ZeroShotAgent.create_prompt(tools, prefix=prefix, suffix=suffix, input_variables=["objective", "task", "context", "agent_scratchpad"],)
llm_chain = LLMChain(llm=llm, prompt=prompt)
agent = ZeroShotAgent(llm_chain=llm_chain, allowed_tools=[tool.name for tool in tools])
agent_executor = AgentExecutor.from_agent_and_tools(agent=agent, tools=tools, verbose=self.verbose)
return BossNode(llm, vectorstore,
agent_executor, max_iterations=self.max_iterations)
except Exception as e:
logging.error(f"Failed to initialize boss node: {e}")
raise
def run(self, objective): def run(self, objective):
""" """
Run the swarm with the given objective Run the swarm with the given objective
@ -199,24 +90,13 @@ class HierarchicalSwarm:
objective(str): The task objective(str): The task
""" """
try: try:
# Run the swarm with the given objective task = self.boss_node.create_task(objective)
worker_tools = self.initialize_tools(OpenAI)
assert worker_tools is not None, "worker_tools is not initialized"
vectorstore = self.initialize_vectorstore() if self.use_vectorstore else None
assert vectorstore is not None, "vectorstore is not initialized"
worker_node = self.initialize_worker_node(worker_tools, vectorstore)
boss_node = self.initialize_boss_node(vectorstore, worker_node)
task = boss_node.create_task(objective)
logging.info(f"Running task: {task}") logging.info(f"Running task: {task}")
if self.use_async: if self.use_async:
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
result = loop.run_until_complete(boss_node.run(task)) result = loop.run_until_complete(self.boss_node.run(task))
else: else:
result = boss_node.run(task) result = self.boss_node.run(task)
logging.info(f"Completed tasks: {task}") logging.info(f"Completed tasks: {task}")
return result return result
except Exception as e: except Exception as e:
@ -257,3 +137,161 @@ def swarm(
logging.error(f"An error occured in swarm: {e}") logging.error(f"An error occured in swarm: {e}")
return None return None
# class HierarchicalSwarm:
# def __init__(
# self,
# openai_api_key: Optional[str] = "",
# use_vectorstore: Optional[bool] = True,
# embedding_size: Optional[int] = None,
# use_async: Optional[bool] = True,
# worker_name: Optional[str] = "Swarm Worker AI Assistant",
# verbose: Optional[bool] = False,
# human_in_the_loop: Optional[bool] = True,
# boss_prompt: Optional[str] = "You are an Boss in a swarm who performs one task based on the following objective: {objective}. Take into account these previously completed tasks: {context}.\n",
# worker_prompt: Optional[str] = None,
# temperature: Optional[float] = 0.5,
# max_iterations: Optional[int] = None,
# logging_enabled: Optional[bool] = True):
# self.openai_api_key = openai_api_key
# self.use_vectorstore = use_vectorstore
# self.use_async = use_async
# self.human_in_the_loop = human_in_the_loop
# self.embedding_size = embedding_size
# self.boss_prompt = boss_prompt
# self.worker_prompt = worker_prompt
# self.temperature = temperature
# self.max_iterations = max_iterations
# self.logging_enabled = logging_enabled
# self.verbose = verbose
# self.worker_node = WorkerNode(openai_api_key)
# self.logger = logging.getLogger()
# if not logging_enabled:
# self.logger.disabled = True
# def initialize_worker_node(self, worker_tools, vectorstore, llm_class=ChatOpenAI):
# try:
# worker_node = self.worker_node.create_worker_node(llm_class=llm_class, ai_name=self.worker_name, ai_role="Assistant", human_in_the_loop=self.human_in_the_loop, search_kwargs={}, verbose=self.verbose)
# worker_description = self.worker_prompt
# worker_node_tool = Tool(name="WorkerNode AI Agent", func=worker_node.run, description= worker_description or "Input: an objective with a todo list for that objective. Output: your task completed: Please be very clear what the objective and task instructions are. The Swarm worker agent is Useful for when you need to spawn an autonomous agent instance as a worker to accomplish any complex tasks, it can search the internet or write code or spawn child multi-modality models to process and generate images and text or audio and so on")
# return worker_node_tool
# except Exception as e:
# logging.error(f"Failed to initialize worker node: {e}")
# raise
# def initialize_boss_node(self, vectorstore, worker_node, llm_class=OpenAI):
# """
# Init BossNode
# Params:
# vectorstore (object): the vector store object.
# worker_node (object): the worker node object
# llm_class (class): the language model class. Default is OpenAI
# max_iterations(int): The number of max iterations. Default is 5
# verbose(bool): Debug mode. Default is False
# """
# try:
# # Initialize boss node
# llm = self.worker_node.initialize_llm(llm_class)
# # prompt = self.boss_prompt
# todo_prompt = PromptTemplate.from_template(self.boss_prompt)
# todo_chain = LLMChain(llm=llm, prompt=todo_prompt)
# tools = [
# Tool(name="TODO", func=todo_chain.run, description="useful for when you need to come up with todo lists. Input: an objective to create a todo list for your objective. Note create a todo list then assign a ranking from 0.0 to 1.0 to each task, then sort the tasks based on the tasks most likely to achieve the objective. The Output: a todo list for that objective with rankings for each step from 0.1 Please be very clear what the objective is!"),
# worker_node,
# ]
# suffix = """Question: {task}\n{agent_scratchpad}"""
# prefix = """You are an Boss in a swarm who performs one task based on the following objective: {objective}. Take into account these previously completed tasks: {context}.\n """
# prompt = ZeroShotAgent.create_prompt(tools, prefix=prefix, suffix=suffix, input_variables=["objective", "task", "context", "agent_scratchpad"],)
# llm_chain = LLMChain(llm=llm, prompt=prompt)
# agent = ZeroShotAgent(llm_chain=llm_chain, allowed_tools=[tool.name for tool in tools])
# agent_executor = AgentExecutor.from_agent_and_tools(agent=agent, tools=tools, verbose=self.verbose)
# return BossNode(llm, vectorstore, agent_executor, self.max_iterations)
# except Exception as e:
# logging.error(f"Failed to initialize boss node: {e}")
# raise
# def run(self, objective):
# """
# Run the swarm with the given objective
# Params:
# objective(str): The task
# """
# try:
# # Run the swarm with the given objective
# worker_tools = self.worker_node.initialize_tools(OpenAI)
# assert worker_tools is not None, "worker_tools is not initialized"
# vectorstore = self.worker_node.initialize_vectorstore() if self.use_vectorstore else None
# assert vectorstore is not None, "vectorstore is not initialized"
# worker_node = self.initialize_worker_node(worker_tools, vectorstore)
# boss_node = self.initialize_boss_node(vectorstore, worker_node)
# task = boss_node.create_task(objective)
# logging.info(f"Running task: {task}")
# if self.use_async:
# loop = asyncio.get_event_loop()
# result = loop.run_until_complete(boss_node.run(task))
# else:
# result = boss_node.run(task)
# logging.info(f"Completed tasks: {task}")
# return result
# except Exception as e:
# logging.error(f"An error occurred in run: {e}")
# return None
# # usage-# usage-
# def swarm(
# api_key: Optional[str]="",
# objective: Optional[str]="",
# ):
# """
# Run the swarm with the given API key and objective.
# Parameters:
# api_key (str): The OpenAI API key. Default is an empty string.
# objective (str): The objective. Default is an empty string.
# Returns:
# The result of the swarm.
# """
# if not api_key or not isinstance(api_key, str):
# logging.error("Invalid OpenAI key")
# raise ValueError("A valid OpenAI API key is required")
# if not objective or not isinstance(objective, str):
# logging.error("Invalid objective")
# raise ValueError("A valid objective is required")
# try:
# swarms = HierarchicalSwarm(api_key, use_async=False) #logging_enabled=logging_enabled) # Turn off async
# result = swarms.run(objective)
# if result is None:
# logging.error("Failed to run swarms")
# else:
# logging.info(f"Successfully ran swarms with results: {result}")
# return result
# except Exception as e:
# logging.error(f"An error occured in swarm: {e}")
# return None

@ -34,8 +34,9 @@ class WorkerNodeInitializer:
llm: Optional[Union[InMemoryDocstore, ChatOpenAI]] = None, llm: Optional[Union[InMemoryDocstore, ChatOpenAI]] = None,
tools: Optional[List[Tool]] = None, tools: Optional[List[Tool]] = None,
vectorstore: Optional[FAISS] = None, vectorstore: Optional[FAISS] = None,
ai_name: str = "Swarm Worker AI Assistant", embedding_size: Optional[int] = 1926,
ai_role: str = "Assistant", worker_name: str = "Swarm Worker AI Assistant",
worker_role: str = "Assistant",
human_in_the_loop: bool = False, human_in_the_loop: bool = False,
search_kwargs: dict = {}, search_kwargs: dict = {},
verbose: bool = False, verbose: bool = False,
@ -46,8 +47,8 @@ class WorkerNodeInitializer:
self.vectorstore = vectorstore #if vectorstore is not None else #FAISS(faiss.IndexFlatIP(512)) self.vectorstore = vectorstore #if vectorstore is not None else #FAISS(faiss.IndexFlatIP(512))
# Initializing agent in the constructor # Initializing agent in the constructor
self.ai_name = ai_name self.worker_name = worker_name
self.ai_role = ai_role self.worker_role = worker_role
self.human_in_the_loop = human_in_the_loop self.human_in_the_loop = human_in_the_loop
self.search_kwargs = search_kwargs self.search_kwargs = search_kwargs
self.verbose = verbose self.verbose = verbose
@ -62,8 +63,8 @@ class WorkerNodeInitializer:
if self.vectorstore is None: if self.vectorstore is None:
raise ValueError("Vectorstore is not initialized in WorkerNodeInitializer") raise ValueError("Vectorstore is not initialized in WorkerNodeInitializer")
self.agent = AutoGPT.from_llm_and_tools( self.agent = AutoGPT.from_llm_and_tools(
ai_name=self.ai_name, worker_name=self.worker_name,
ai_role=self.ai_role, worker_role=self.worker_role,
tools=self.tools, tools=self.tools,
llm=self.llm, llm=self.llm,
memory=self.vectorstore.as_retriever(search_kwargs=self.search_kwargs), memory=self.vectorstore.as_retriever(search_kwargs=self.search_kwargs),
@ -101,7 +102,6 @@ class WorkerNodeInitializer:
logging.error(f"While running the agent: {str(e)}") logging.error(f"While running the agent: {str(e)}")
raise e raise e
class WorkerNode: class WorkerNode:
def __init__(self, openai_api_key): def __init__(self, openai_api_key):
if not openai_api_key: if not openai_api_key:
@ -109,6 +109,7 @@ class WorkerNode:
raise ValueError("openai_api_key cannot be None") raise ValueError("openai_api_key cannot be None")
self.openai_api_key = openai_api_key self.openai_api_key = openai_api_key
self.worker_node_initializer = WorkerNodeInitializer(openai_api_key)
def initialize_llm(self, llm_class, temperature=0.5): def initialize_llm(self, llm_class, temperature=0.5):
if not llm_class: if not llm_class:
@ -126,7 +127,6 @@ class WorkerNode:
logging.error("llm_class not cannot be none") logging.error("llm_class not cannot be none")
raise ValueError("llm_class cannot be none") raise ValueError("llm_class cannot be none")
try: try:
logging.info('Creating WorkerNode') logging.info('Creating WorkerNode')
llm = self.initialize_llm(llm_class) llm = self.initialize_llm(llm_class)
web_search = DuckDuckGoSearchRun() web_search = DuckDuckGoSearchRun()
@ -145,26 +145,24 @@ class WorkerNode:
except Exception as e: except Exception as e:
logging.error(f"Failed to initialize tools: {e}") logging.error(f"Failed to initialize tools: {e}")
def initialize_vectorstore(self):
try:
embeddings_model = OpenAIEmbeddings(openai_api_key=self.openai_api_key)
embedding_size = 1536
index = faiss.IndexFlatL2(embedding_size)
return FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {})
except Exception as e:
logging.error(f"Failed to initialize vector store: {e}")
raise
def create_worker_node(self, llm_class=ChatOpenAI, ai_name="Swarm Worker AI Assistant", ai_role="Assistant", human_in_the_loop=False, search_kwargs={}, verbose=False): def create_worker_node(self, llm_class=ChatOpenAI, ai_name="Swarm Worker AI Assistant", ai_role="Assistant", human_in_the_loop=False, search_kwargs={}, verbose=False):
if not llm_class: if not llm_class:
logging.error("llm_class cannot be None.") logging.error("llm_class cannot be None.")
raise ValueError("llm_class cannot be None.") raise ValueError("llm_class cannot be None.")
try: try:
worker_tools = self.initialize_tools(llm_class) worker_tools = self.initialize_tools(llm_class)
vectorstore = self.initialize_vectorstore() vectorstore = self.worker_node_initializer.initialize_vectorstore()
worker_node = WorkerNode(llm=self.initialize_llm(llm_class), tools=worker_tools, vectorstore=vectorstore) worker_node = WorkerNodeInitializer(
worker_node.create_agent(ai_name=ai_name, ai_role=ai_role, human_in_the_loop=human_in_the_loop, search_kwargs=search_kwargs, verbose=verbose) openai_api_key=self.openai_api_key,
llm=self.initialize_llm(llm_class),
tools=worker_tools,
vectorstore=vectorstore,
ai_name=ai_name,
ai_role=ai_role,
human_in_the_loop=human_in_the_loop,
search_kwargs=search_kwargs,
verbose=verbose
)
return worker_node return worker_node
except Exception as e: except Exception as e:
logging.error(f"Failed to create worker node: {e}") logging.error(f"Failed to create worker node: {e}")
@ -176,12 +174,8 @@ def worker_node(openai_api_key):
raise ValueError("OpenAI API key is required") raise ValueError("OpenAI API key is required")
try: try:
worker_node = WorkerNode(openai_api_key)
initializer = WorkerNodeInitializer(openai_api_key) return worker_node.create_worker_node()
worker_node = initializer.create_worker_node()
return worker_node
except Exception as e: except Exception as e:
logging.error(f"An error occured in worker_node: {e}") logging.error(f"An error occured in worker_node: {e}")
raise raise

Loading…
Cancel
Save