Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to persist LangChain conversation memory (save and load)?

I'm creating a conversation like so:

llm = ChatOpenAI(temperature=0, openai_api_key=OPENAI_API_KEY, model_name=OPENAI_DEFAULT_MODEL)
conversation = ConversationChain(llm=llm, memory=ConversationBufferMemory())

But what I really want is to be able to save and load that ConversationBufferMemory() so that it's persistent between sessions. There doesn't seem to be any obvious tutorials for this but I noticed "Pydantic" so I tried to do this:

saved_dict = conversation.memory.chat_memory.dict()
cm = ChatMessageHistory(**saved_dict) # or cm = ChatMessageHistory.parse_obj(saved_dict)

But this fails:

ValidationError: 6 validation errors for ChatMessageHistory
messages -> 0
  Can't instantiate abstract class BaseMessage with abstract method type (type=type_error)

Thoughts? I'd love links to any sort of guide, repo, reference, etc.

like image 500
Neil C. Obremski Avatar asked Nov 17 '25 06:11

Neil C. Obremski


2 Answers

I just did something similar, hopefully this will be helpful. On a high level:

  1. use ConversationBufferMemory as the memory to pass to the Chain initialization
llm = ChatOpenAI(temperature=0, model_name='gpt-3.5-turbo-0301')
original_chain = ConversationChain(
    llm=llm,
    verbose=True,
    memory=ConversationBufferMemory()
)
original_chain.run('what do you know about Python in less than 10 words')
  1. extract messages from memory in the form of List[langchain.schema.HumanMessage|AIMessage] (not serializable)
extracted_messages = original_chain.memory.chat_memory.messages
  1. transform the extracted message to serializable native Python objects
ingest_to_db = messages_to_dict(extracted_messages)
  1. perform db operations to write to and read from database of your choice, I'll just use json.dumps and json.loads to illustrate
retrieve_from_db = json.loads(json.dumps(ingest_to_db))
  1. transform the retrieved serialized object back to List[langchain.schema.HumanMessage|AIMessage]
retrieved_messages = messages_from_dict(retrieve_from_db)
  1. construct ChatMessageHistory from the messages
retrieved_chat_history = ChatMessageHistory(messages=retrieved_messages)
  1. construct ConversationBufferMemory from ChatMessageHistory
retrieved_memory = ConversationBufferMemory(chat_memory=retrieved_chat_history)
  1. pass memory back to the newly initiated Chain
reloaded_chain = ConversationChain(
    llm=llm,
    verbose=True,
    memory=retrieved_memory
)

You can find the full code snippet at this GitHub Link

like image 131
Shum Avatar answered Nov 18 '25 19:11

Shum


Rather than mess around too much with LangChain/Pydantic serialization issues, I decided to just use Pickle the whole thing and that worked fine:

pickled_str = pickle.dumps(conversation.memory)
conversation2 = ConversationChain(llm=llm, memory=pickle.loads(pickled_str)
like image 33
Neil C. Obremski Avatar answered Nov 18 '25 20:11

Neil C. Obremski