Support chat history persistence in AutoGPT (#5716)

**Short Description**
Added a new argument to AutoGPT class which allows to persist the chat
history to a file.

**Changes**
1. Removed the `self.full_message_history: List[BaseMessage] = []`
2. Replaced it with `chat_history_memory` which can take any subclasses
of `BaseChatMessageHistory`

---------

Co-authored-by: Harrison Chase <hw.chase.17@gmail.com>
This commit is contained in:
Alon Roth 2023-06-16 03:49:03 +03:00 committed by GitHub
parent 1913320cbe
commit 0013256e81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 58 additions and 301 deletions

View File

@ -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",
"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"
}
],
"execution_count": null,
"outputs": [],
"source": [
"agent.run([\"write a weather report for SF today\"])"
]
],
"metadata": {
"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": [
"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": {

View File

@ -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))