diff --git a/docs/use_cases/autonomous_agents/autogpt.ipynb b/docs/use_cases/autonomous_agents/autogpt.ipynb index be2d34b5..9b0d9308 100644 --- a/docs/use_cases/autonomous_agents/autogpt.ipynb +++ b/docs/use_cases/autonomous_agents/autogpt.ipynb @@ -124,310 +124,63 @@ }, { "cell_type": "markdown", - "id": "fc9b51ba", - "metadata": {}, "source": [ "## Run an example\n", "\n", "Here we will make it write a weather report for SF" - ] + ], + "metadata": { + "collapsed": false + } }, { "cell_type": "code", - "execution_count": 7, - "id": "c032b182", + "execution_count": null, + "outputs": [], + "source": [ + "agent.run([\"write a weather report for SF today\"])" + ], "metadata": { - "scrolled": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "\n", - "\u001b[1m> Entering new LLMChain chain...\u001b[0m\n", - "Prompt after formatting:\n", - "\u001b[32;1m\u001b[1;3mSystem: You are Tom, Assistant\n", - "Your decisions must always be made independently \n", - " without seeking user assistance. Play to your strengths \n", - " as an LLM and pursue simple strategies with no legal complications. \n", - " If you have completed all your tasks, \n", - " make sure to use the \"finish\" command.\n", - "\n", - "GOALS:\n", - "\n", - "1. write a weather report for SF today\n", - "\n", - "\n", - "Constraints:\n", - "1. ~4000 word limit for short term memory. Your short term memory is short, so immediately save important information to files.\n", - "2. If you are unsure how you previously did something or want to recall past events, thinking about similar events will help you remember.\n", - "3. No user assistance\n", - "4. Exclusively use the commands listed in double quotes e.g. \"command name\"\n", - "\n", - "Commands:\n", - "1. search: useful for when you need to answer questions about current events. You should ask targeted questions, args json schema: {\"query\": {\"title\": \"Query\", \"type\": \"string\"}}\n", - "2. write_file: Write file to disk, args json schema: {\"file_path\": {\"title\": \"File Path\", \"description\": \"name of file\", \"type\": \"string\"}, \"text\": {\"title\": \"Text\", \"description\": \"text to write to file\", \"type\": \"string\"}}\n", - "3. read_file: Read file from disk, args json schema: {\"file_path\": {\"title\": \"File Path\", \"description\": \"name of file\", \"type\": \"string\"}}\n", - "4. finish: use this to signal that you have finished all your objectives, args: \"response\": \"final response to let people know you have finished your objectives\"\n", - "\n", - "Resources:\n", - "1. Internet access for searches and information gathering.\n", - "2. Long Term memory management.\n", - "3. GPT-3.5 powered Agents for delegation of simple tasks.\n", - "4. File output.\n", - "\n", - "Performance Evaluation:\n", - "1. Continuously review and analyze your actions to ensure you are performing to the best of your abilities.\n", - "2. Constructively self-criticize your big-picture behavior constantly.\n", - "3. Reflect on past decisions and strategies to refine your approach.\n", - "4. Every command has a cost, so be smart and efficient. Aim to complete tasks in the least number of steps.\n", - "\n", - "You should only respond in JSON format as described below \n", - "Response Format: \n", - "{\n", - " \"thoughts\": {\n", - " \"text\": \"thought\",\n", - " \"reasoning\": \"reasoning\",\n", - " \"plan\": \"- short bulleted\\n- list that conveys\\n- long-term plan\",\n", - " \"criticism\": \"constructive self-criticism\",\n", - " \"speak\": \"thoughts summary to say to user\"\n", - " },\n", - " \"command\": {\n", - " \"name\": \"command name\",\n", - " \"args\": {\n", - " \"arg name\": \"value\"\n", - " }\n", - " }\n", - "} \n", - "Ensure the response can be parsed by Python json.loads\n", - "System: The current time and date is Tue Apr 18 21:31:28 2023\n", - "System: This reminds you of these events from your past:\n", - "[]\n", - "\n", - "\n", - "Human: Determine which next command to use, and respond using the format specified above:\u001b[0m\n", - "\n", - "\u001b[1m> Finished chain.\u001b[0m\n", - "{\n", - " \"thoughts\": {\n", - " \"text\": \"I will start by writing a weather report for San Francisco today. I will use the 'search' command to find the current weather conditions.\",\n", - " \"reasoning\": \"I need to gather information about the current weather conditions in San Francisco to write an accurate weather report.\",\n", - " \"plan\": \"- Use the 'search' command to find the current weather conditions in San Francisco\\n- Write a weather report based on the information gathered\",\n", - " \"criticism\": \"I need to make sure that the information I gather is accurate and up-to-date.\",\n", - " \"speak\": \"I will use the 'search' command to find the current weather conditions in San Francisco.\"\n", - " },\n", - " \"command\": {\n", - " \"name\": \"search\",\n", - " \"args\": {\n", - " \"query\": \"what is the current weather in san francisco\"\n", - " }\n", - " }\n", - "}\n", - "\n", - "\n", - "\u001b[1m> Entering new LLMChain chain...\u001b[0m\n", - "Prompt after formatting:\n", - "\u001b[32;1m\u001b[1;3mSystem: You are Tom, Assistant\n", - "Your decisions must always be made independently \n", - " without seeking user assistance. Play to your strengths \n", - " as an LLM and pursue simple strategies with no legal complications. \n", - " If you have completed all your tasks, \n", - " make sure to use the \"finish\" command.\n", - "\n", - "GOALS:\n", - "\n", - "1. write a weather report for SF today\n", - "\n", - "\n", - "Constraints:\n", - "1. ~4000 word limit for short term memory. Your short term memory is short, so immediately save important information to files.\n", - "2. If you are unsure how you previously did something or want to recall past events, thinking about similar events will help you remember.\n", - "3. No user assistance\n", - "4. Exclusively use the commands listed in double quotes e.g. \"command name\"\n", - "\n", - "Commands:\n", - "1. search: useful for when you need to answer questions about current events. You should ask targeted questions, args json schema: {\"query\": {\"title\": \"Query\", \"type\": \"string\"}}\n", - "2. write_file: Write file to disk, args json schema: {\"file_path\": {\"title\": \"File Path\", \"description\": \"name of file\", \"type\": \"string\"}, \"text\": {\"title\": \"Text\", \"description\": \"text to write to file\", \"type\": \"string\"}}\n", - "3. read_file: Read file from disk, args json schema: {\"file_path\": {\"title\": \"File Path\", \"description\": \"name of file\", \"type\": \"string\"}}\n", - "4. finish: use this to signal that you have finished all your objectives, args: \"response\": \"final response to let people know you have finished your objectives\"\n", - "\n", - "Resources:\n", - "1. Internet access for searches and information gathering.\n", - "2. Long Term memory management.\n", - "3. GPT-3.5 powered Agents for delegation of simple tasks.\n", - "4. File output.\n", - "\n", - "Performance Evaluation:\n", - "1. Continuously review and analyze your actions to ensure you are performing to the best of your abilities.\n", - "2. Constructively self-criticize your big-picture behavior constantly.\n", - "3. Reflect on past decisions and strategies to refine your approach.\n", - "4. Every command has a cost, so be smart and efficient. Aim to complete tasks in the least number of steps.\n", - "\n", - "You should only respond in JSON format as described below \n", - "Response Format: \n", - "{\n", - " \"thoughts\": {\n", - " \"text\": \"thought\",\n", - " \"reasoning\": \"reasoning\",\n", - " \"plan\": \"- short bulleted\\n- list that conveys\\n- long-term plan\",\n", - " \"criticism\": \"constructive self-criticism\",\n", - " \"speak\": \"thoughts summary to say to user\"\n", - " },\n", - " \"command\": {\n", - " \"name\": \"command name\",\n", - " \"args\": {\n", - " \"arg name\": \"value\"\n", - " }\n", - " }\n", - "} \n", - "Ensure the response can be parsed by Python json.loads\n", - "System: The current time and date is Tue Apr 18 21:31:39 2023\n", - "System: This reminds you of these events from your past:\n", - "['Assistant Reply: {\\n \"thoughts\": {\\n \"text\": \"I will start by writing a weather report for San Francisco today. I will use the \\'search\\' command to find the current weather conditions.\",\\n \"reasoning\": \"I need to gather information about the current weather conditions in San Francisco to write an accurate weather report.\",\\n \"plan\": \"- Use the \\'search\\' command to find the current weather conditions in San Francisco\\\\n- Write a weather report based on the information gathered\",\\n \"criticism\": \"I need to make sure that the information I gather is accurate and up-to-date.\",\\n \"speak\": \"I will use the \\'search\\' command to find the current weather conditions in San Francisco.\"\\n },\\n \"command\": {\\n \"name\": \"search\",\\n \"args\": {\\n \"query\": \"what is the current weather in san francisco\"\\n }\\n }\\n} \\nResult: Command search returned: Current Weather ; 54°F · Sunny ; RealFeel® 66°. Pleasant. RealFeel Guide. Pleasant. 63° to 81°. Most consider this temperature range ideal. LEARN MORE. RealFeel ... ']\n", - "\n", - "\n", - "Human: Determine which next command to use, and respond using the format specified above:\n", - "AI: {\n", - " \"thoughts\": {\n", - " \"text\": \"I will start by writing a weather report for San Francisco today. I will use the 'search' command to find the current weather conditions.\",\n", - " \"reasoning\": \"I need to gather information about the current weather conditions in San Francisco to write an accurate weather report.\",\n", - " \"plan\": \"- Use the 'search' command to find the current weather conditions in San Francisco\\n- Write a weather report based on the information gathered\",\n", - " \"criticism\": \"I need to make sure that the information I gather is accurate and up-to-date.\",\n", - " \"speak\": \"I will use the 'search' command to find the current weather conditions in San Francisco.\"\n", - " },\n", - " \"command\": {\n", - " \"name\": \"search\",\n", - " \"args\": {\n", - " \"query\": \"what is the current weather in san francisco\"\n", - " }\n", - " }\n", - "}\n", - "System: Command search returned: Current Weather ; 54°F · Sunny ; RealFeel® 66°. Pleasant. RealFeel Guide. Pleasant. 63° to 81°. Most consider this temperature range ideal. LEARN MORE. RealFeel ...\n", - "Human: Determine which next command to use, and respond using the format specified above:\u001b[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "\u001b[1m> Finished chain.\u001b[0m\n", - "{\n", - " \"thoughts\": {\n", - " \"text\": \"I have found that the current weather in San Francisco is sunny with a temperature of 54°F. I will now write a weather report for San Francisco today using the 'write_file' command.\",\n", - " \"reasoning\": \"I need to write a weather report for San Francisco today based on the information I gathered from the 'search' command.\",\n", - " \"plan\": \"- Use the 'write_file' command to write a weather report for San Francisco today based on the information gathered\",\n", - " \"criticism\": \"I need to make sure that the weather report is accurate and informative.\",\n", - " \"speak\": \"I will use the 'write_file' command to write a weather report for San Francisco today.\"\n", - " },\n", - " \"command\": {\n", - " \"name\": \"write_file\",\n", - " \"args\": {\n", - " \"file_path\": \"weather_report.txt\",\n", - " \"text\": \"Weather Report for San Francisco Today:\\n\\nThe current weather in San Francisco is sunny with a temperature of 54°F. It is expected to remain sunny throughout the day with a high of 62°F and a low of 50°F. There is no chance of precipitation today. It is recommended to wear light clothing and sunscreen if spending time outdoors.\\n\\nStay safe and enjoy the beautiful weather!\"\n", - " }\n", - " }\n", - "}\n", - "\n", - "\n", - "\u001b[1m> Entering new LLMChain chain...\u001b[0m\n", - "Prompt after formatting:\n", - "\u001b[32;1m\u001b[1;3mSystem: You are Tom, Assistant\n", - "Your decisions must always be made independently \n", - " without seeking user assistance. Play to your strengths \n", - " as an LLM and pursue simple strategies with no legal complications. \n", - " If you have completed all your tasks, \n", - " make sure to use the \"finish\" command.\n", - "\n", - "GOALS:\n", - "\n", - "1. write a weather report for SF today\n", - "\n", - "\n", - "Constraints:\n", - "1. ~4000 word limit for short term memory. Your short term memory is short, so immediately save important information to files.\n", - "2. If you are unsure how you previously did something or want to recall past events, thinking about similar events will help you remember.\n", - "3. No user assistance\n", - "4. Exclusively use the commands listed in double quotes e.g. \"command name\"\n", - "\n", - "Commands:\n", - "1. search: useful for when you need to answer questions about current events. You should ask targeted questions, args json schema: {\"query\": {\"title\": \"Query\", \"type\": \"string\"}}\n", - "2. write_file: Write file to disk, args json schema: {\"file_path\": {\"title\": \"File Path\", \"description\": \"name of file\", \"type\": \"string\"}, \"text\": {\"title\": \"Text\", \"description\": \"text to write to file\", \"type\": \"string\"}}\n", - "3. read_file: Read file from disk, args json schema: {\"file_path\": {\"title\": \"File Path\", \"description\": \"name of file\", \"type\": \"string\"}}\n", - "4. finish: use this to signal that you have finished all your objectives, args: \"response\": \"final response to let people know you have finished your objectives\"\n", - "\n", - "Resources:\n", - "1. Internet access for searches and information gathering.\n", - "2. Long Term memory management.\n", - "3. GPT-3.5 powered Agents for delegation of simple tasks.\n", - "4. File output.\n", - "\n", - "Performance Evaluation:\n", - "1. Continuously review and analyze your actions to ensure you are performing to the best of your abilities.\n", - "2. Constructively self-criticize your big-picture behavior constantly.\n", - "3. Reflect on past decisions and strategies to refine your approach.\n", - "4. Every command has a cost, so be smart and efficient. Aim to complete tasks in the least number of steps.\n", - "\n", - "You should only respond in JSON format as described below \n", - "Response Format: \n", - "{\n", - " \"thoughts\": {\n", - " \"text\": \"thought\",\n", - " \"reasoning\": \"reasoning\",\n", - " \"plan\": \"- short bulleted\\n- list that conveys\\n- long-term plan\",\n", - " \"criticism\": \"constructive self-criticism\",\n", - " \"speak\": \"thoughts summary to say to user\"\n", - " },\n", - " \"command\": {\n", - " \"name\": \"command name\",\n", - " \"args\": {\n", - " \"arg name\": \"value\"\n", - " }\n", - " }\n", - "} \n", - "Ensure the response can be parsed by Python json.loads\n", - "System: The current time and date is Tue Apr 18 21:31:55 2023\n", - "System: This reminds you of these events from your past:\n", - "['Assistant Reply: {\\n \"thoughts\": {\\n \"text\": \"I have found that the current weather in San Francisco is sunny with a temperature of 54°F. I will now write a weather report for San Francisco today using the \\'write_file\\' command.\",\\n \"reasoning\": \"I need to write a weather report for San Francisco today based on the information I gathered from the \\'search\\' command.\",\\n \"plan\": \"- Use the \\'write_file\\' command to write a weather report for San Francisco today based on the information gathered\",\\n \"criticism\": \"I need to make sure that the weather report is accurate and informative.\",\\n \"speak\": \"I will use the \\'write_file\\' command to write a weather report for San Francisco today.\"\\n },\\n \"command\": {\\n \"name\": \"write_file\",\\n \"args\": {\\n \"file_path\": \"weather_report.txt\",\\n \"text\": \"Weather Report for San Francisco Today:\\\\n\\\\nThe current weather in San Francisco is sunny with a temperature of 54°F. It is expected to remain sunny throughout the day with a high of 62°F and a low of 50°F. There is no chance of precipitation today. It is recommended to wear light clothing and sunscreen if spending time outdoors.\\\\n\\\\nStay safe and enjoy the beautiful weather!\"\\n }\\n }\\n} \\nResult: Command write_file returned: File written to successfully. ', 'Assistant Reply: {\\n \"thoughts\": {\\n \"text\": \"I will start by writing a weather report for San Francisco today. I will use the \\'search\\' command to find the current weather conditions.\",\\n \"reasoning\": \"I need to gather information about the current weather conditions in San Francisco to write an accurate weather report.\",\\n \"plan\": \"- Use the \\'search\\' command to find the current weather conditions in San Francisco\\\\n- Write a weather report based on the information gathered\",\\n \"criticism\": \"I need to make sure that the information I gather is accurate and up-to-date.\",\\n \"speak\": \"I will use the \\'search\\' command to find the current weather conditions in San Francisco.\"\\n },\\n \"command\": {\\n \"name\": \"search\",\\n \"args\": {\\n \"query\": \"what is the current weather in san francisco\"\\n }\\n }\\n} \\nResult: Command search returned: Current Weather ; 54°F · Sunny ; RealFeel® 66°. Pleasant. RealFeel Guide. Pleasant. 63° to 81°. Most consider this temperature range ideal. LEARN MORE. RealFeel ... ']\n", - "\n", - "\n", - "System: Command write_file returned: File written to successfully.\n", - "Human: Determine which next command to use, and respond using the format specified above:\u001b[0m\n", - "\n", - "\u001b[1m> Finished chain.\u001b[0m\n", - "{\n", - " \"thoughts\": {\n", - " \"text\": \"I have completed my task of writing a weather report for San Francisco today. I will now use the \\'finish\\' command to signal that I have finished all my objectives.\",\n", - " \"reasoning\": \"I have completed all my objectives and there are no further tasks to be completed.\",\n", - " \"plan\": \"- Use the \\'finish\\' command to signal that I have completed all my objectives.\",\n", - " \"criticism\": \"I need to make sure that I have completed all my objectives before using the \\'finish\\' command.\",\n", - " \"speak\": \"I have completed my task of writing a weather report for San Francisco today. I will now use the \\'finish\\' command to signal that I have finished all my objectives.\"\n", - " },\n", - " \"command\": {\n", - " \"name\": \"finish\",\n", - " \"args\": {\n", - " \"response\": \"I have completed all my objectives.\"\n", - " }\n", - " }\n", - "}\n" - ] - }, - { - "data": { - "text/plain": [ - "'I have completed all my objectives.'" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } + "collapsed": false + } + }, + { + "cell_type": "markdown", + "source": [ + "## Chat History Memory\n", + "\n", + "In addition to the memory that holds the agent immediate steps, we also have a chat history memory. By default, the agent will use 'ChatMessageHistory' and it can be changed. This is useful when you want to use a different type of memory for example 'FileChatHistoryMemory'" ], + "metadata": { + "collapsed": false + } + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], "source": [ - "agent.run([\"write a weather report for SF today\"])" - ] + "from langchain.memory.chat_message_histories import FileChatMessageHistory\n", + "\n", + "agent = AutoGPT.from_llm_and_tools(\n", + " ai_name=\"Tom\",\n", + " ai_role=\"Assistant\",\n", + " tools=tools,\n", + " llm=ChatOpenAI(temperature=0),\n", + " memory=vectorstore.as_retriever(),\n", + " chat_history_memory=FileChatMessageHistory('chat_history.txt')\n", + ")" + ], + "metadata": { + "collapsed": false + } + }, + { + "cell_type": "markdown", + "source": [], + "metadata": { + "collapsed": false + } } ], "metadata": { diff --git a/langchain/experimental/autonomous_agents/autogpt/agent.py b/langchain/experimental/autonomous_agents/autogpt/agent.py index 025f6ca4..6139d94c 100644 --- a/langchain/experimental/autonomous_agents/autogpt/agent.py +++ b/langchain/experimental/autonomous_agents/autogpt/agent.py @@ -14,9 +14,10 @@ from langchain.experimental.autonomous_agents.autogpt.prompt import AutoGPTPromp from langchain.experimental.autonomous_agents.autogpt.prompt_generator import ( FINISH_NAME, ) +from langchain.memory import ChatMessageHistory from langchain.schema import ( AIMessage, - BaseMessage, + BaseChatMessageHistory, Document, HumanMessage, SystemMessage, @@ -37,15 +38,16 @@ class AutoGPT: output_parser: BaseAutoGPTOutputParser, tools: List[BaseTool], feedback_tool: Optional[HumanInputRun] = None, + chat_history_memory: Optional[BaseChatMessageHistory] = None, ): self.ai_name = ai_name self.memory = memory - self.full_message_history: List[BaseMessage] = [] self.next_action_count = 0 self.chain = chain self.output_parser = output_parser self.tools = tools self.feedback_tool = feedback_tool + self.chat_history_memory = chat_history_memory or ChatMessageHistory() @classmethod def from_llm_and_tools( @@ -57,6 +59,7 @@ class AutoGPT: llm: BaseChatModel, human_in_the_loop: bool = False, output_parser: Optional[BaseAutoGPTOutputParser] = None, + chat_history_memory: Optional[BaseChatMessageHistory] = None, ) -> AutoGPT: prompt = AutoGPTPrompt( ai_name=ai_name, @@ -74,6 +77,7 @@ class AutoGPT: output_parser or AutoGPTOutputParser(), tools, feedback_tool=human_feedback_tool, + chat_history_memory=chat_history_memory, ) def run(self, goals: List[str]) -> str: @@ -90,15 +94,15 @@ class AutoGPT: # Send message to AI, get response assistant_reply = self.chain.run( goals=goals, - messages=self.full_message_history, + messages=self.chat_history_memory.messages, memory=self.memory, user_input=user_input, ) # Print Assistant thoughts print(assistant_reply) - self.full_message_history.append(HumanMessage(content=user_input)) - self.full_message_history.append(AIMessage(content=assistant_reply)) + self.chat_history_memory.add_message(HumanMessage(content=user_input)) + self.chat_history_memory.add_message(AIMessage(content=assistant_reply)) # Get command name and arguments action = self.output_parser.parse(assistant_reply) @@ -138,4 +142,4 @@ class AutoGPT: memory_to_add += feedback self.memory.add_documents([Document(page_content=memory_to_add)]) - self.full_message_history.append(SystemMessage(content=result)) + self.chat_history_memory.add_message(SystemMessage(content=result))