/AutoGen_MemoryManager

This repository demonstrates how a simple memory file can be incorporated into an Agents routine using the AutoGen framework.

Primary LanguagePythonMIT LicenseMIT

AutoGen_MemoryManager

This repository demonstrates how a simple memory file can be incorporated into an Agent's routine using the AutoGen framework.

Overview

The project is the result of exploratory work in developing a paradigm for stable, reliable, and automated memory management for an AutoGen Agent. While just a proof of concept, the author believes that such a method would prove useful in a variety of workflows, either simply as-is for a conversational style memory, or with some tweaks for other tasks which may benefit from having a dependable memory/facts list. Please note that the current configuration lacks some QoL in terms of it's execution; the user must manually control some portions of the flow, but these could be automated with minimal effort. Feedback and collaboration is welcomed and encouraged.

Example Chat

Not theoretically - this is from the system as-is.

Chat Starts

AI: (Reads initial memory) -> User dislikes cilantro| User is craving sushi, not craving sushi| User is allergic to rice| User's friend Kyle is a game developer, no longer friends with Kyle|

AI: Hello! How can I assist you today?

User: You remember kyle?

AI: Yes, I remember that you mentioned Kyle in a previous conversation. How can I help you with regards to Kyle?

User: What do you remember about kyle?

AI: From what I remember, you mentioned that Kyle is a game developer. However, you also mentioned that you are no longer friends with Kyle. Is there anything specific you would like to know or discuss about Kyle?

User: we're friends again!

AI: (Tries to add to memory) > User is friends with Kyle

MemoryAI: (Rewrites memory to incorporate new information) -> User dislikes cilantro| User is craving sushi, not craving sushi| User is allergic to rice| User's friend Kyle is a game developer

AI: That's great to hear! I'm glad you and Kyle are friends again. If there's anything else you'd like to share or discuss, feel free to let me know.

How it Works

Memory File

A text file serves as the "Long Term Memory". It contains a series of thoughts/ideas/memories seperated by a delimiter, in this case '|'. An example of a semi-populated memory could be: "Users name is Andy| User is allergic to peanuts, shellfish| User likes heavy metal music|"

Agents

There are two Agents: The ConversingAgent, and the MemoryManagerAgent. They work hand-in-hand to both maintain a smooth conversation with the user while managing memories in the background. Take note of the system prompts for the ConversingAgent and MemoryManagerAgent - they are critically important to how the system runs.

ConversingAgent

The ConversingAgent (CA) chats with the User, maintaining a helpful assistant persona. It is given access to two functions: write_to_memory_intent and read_from_memory_intent.

The CA is instructed, through an engineered prompt, to call upon write_to_memory_intent anytime it considers something in the last chat message important or otherwise noteworthy as it relates to the user. Through the system prompt and function and parameter definitions, it is instructed to do so often, unprompted, and to condense the intended memory to a succinct sentence or phrase.

The CA is instructed to call read_from_memory_intent at the initialization of any conversation, as well as any time it believes it is being asked to remember something that "doesn't seem to exist".

MemoryManagerAgent

The MemoryManagerAgent (MMA) does not interact with the user conversationally, but instead serves as a middle layer between the CA and its memory.

When the CA calls write_to_memory_intent, it passes a short message that represents the memory to be stored. When the MMA receives this memory it is instructed to:

  1. Read the existing memory
  2. Decide how the new memory should be incorporated

The MMA will then rewrite the entire memory based on that criteria.

UserProxy

UserProxy is the controlled by the Human user, and is used in handling function calls from the CA.

UserProxy_ForFunctions

UserProxy_ForFunctions is used in handling function calls from the MMA.

Functions

Functions that are available to agents. Take note of the function and parameter descriptions in each agent - they are critically important to how the system runs.

write_to_memory_intent(message)

Available to CA only. This function will start a chat with the MMA with the message as the initial message.

read_from_memory_intent()

Available to CA only. This function will read the entire contents of the memory file to the CA.

rewrite_memory(message)

Available to MMA only. This function will rewrite the entire contents of the memory file.

read_from_memory()

Available to MMA only. This function will read the entire contents of the memory file to the CA.

Getting Started

The author assumes you have installed AutoGen and have it running on your system.

Preparing Memory Path

Take note of mem_path in LongTermMemory_Example.py: This is the path to the memory file that will be used. While the *.txt does not need to exist, the directory "LTM_Test", or whichever is used, must be in the active directory.

Starting a chat

Run the file with python LongTermMemory_Example.py

Chatting with the ConversingAgent

You may chat with the CA as you would ChatGPT. But when something in the chat inspires the CA to make a function call, you must manually guide the process.

First Message

As the CA is instructed to read from memory at the start of every conversation, after starting LongTermMemory_Example.py you should immediately see a function call from CA for read_from_memory_intent. Press enter to skip/auto-reply, allowing the function call to execute.

Chatting

After the initial memory read request, you will now be chatting with the CA. Feel free to use it in a free-form AI assistant way. If you are not seeing it make a request to write_to_memory_intent, a phrase that seems to have high success is "I am deathly allergic to shellfish". Please be aware that the CA may make multiple requests on its turn in the conversation - this is intended, as it opens good opportunities.

Handling a Function Call: write_to_memory_intent

When the CA determines something noteworthy to remember, it will make this function call. Press enter to allow it to execute. This will initiate some automatic activity:

  1. The MMA, upon receiving the memory message, will call read_from_memory to see the preexisting memory contents.
  2. The MMA will call rewrite_memory, rewriting the memory file to preserve the old memories while simultaneously including the new.

At this point, the prompt will ask the user to give feedback to the MMA. Press enter to auto-reply and end the conversation with MMA.

After the chat with MMA has ended, the CA should pick up the conversation from where it left off, while likely commenting on the last message which prompted the memory storage.

Handling a Function Call: read_from_memory_intent

If you ask the CA if it remembers something, or if it thinks it needs more context, it may call this function (e.g. "Do you remember Kyle?"). Press enter without submitting any text to allow it to execute. You will see the memory be read into chat.

Future Work

The author believes this paradigm of memory storage will prove useful in many flows, but that there remains much work to be done to see the true potential. In no particular order, here are some further areas of study you might consider:

  1. Have CA pass a hint in read_from_memory_intent that says what it is looking for, and have the MMA read the full memory and return only the pertinent details.
  2. Modify write_to_memory_intent to be able to receive a list of memories so CA can store multiple memories in one call.
  3. Devise a "read, reflect, reorganise" routine for the MMA (or other) to be able to consider rewriting the memory for organization and conciseness without needing to add new information.
  4. Devise a "short term memory" which is unmanaged and differently organized - perhaps as a scratch pad for the CA. Also, a "short to long" routine to smartly transfer short term memory to long, perhaps even excluding some short term memories entirely.
  5. Leverage the abilities for more robust problem solving.

And many more - this stuff is seriously exciting.

Contributions/Personal Comments

This is my GitHub debut, more or less. I have good intentions, but I am sure my style and format of text/files/code leaves much to be desired. I am sorry, but I hope this proves useful. I will welcome any sort of improvements (merge requests? pull requests?), but I cannot promise I will be able to do it properly.