Skip to content

Repository files navigation

Memor Logo

Memor: Reproducible Structured Memory for LLMs


PyPI versionbuilt with Python3GitHub repo sizeDiscord Channel

Overview

With Memor, users can store their LLM conversation history using an intuitive and structured data format. It abstracts user prompts and model responses into a "Session", a sequence of message exchanges. In addition to the content, it includes details like decoding temperature and token count of each message. Therefore users could create comprehensive and reproducible logs of their interactions. Because of the model-agnostic design, users can begin a conversation with one LLM and switch to another keeping the context the same. For example, they might use a retrieval-augmented model (like RAG) to gather relevant context for a math problem, and then switch to a model better suited for reasoning to solve the problem based on the retrieved information presented by Memor.

Memor also lets users select, filter, and then share the specific parts of the past conversations across different models. This means users are not only able to reproduce and review previous chats through structured logs, but can also flexibly transfer the content of their conversations between LLMs. In a nutshell, Memor makes it easy and effective to manage and reuse conversations with large language models.

PyPI Counter
Github Stars
Branchmaindev
CI
Code QualityCodeFactor

Installation

PyPI

Source code

Usage

Memor provides Prompt, Response, and Session as abstractions by which you can save your conversation history much structured. You can set a Session object before starting a conversation, make a Prompt object from your prompt and a Response object from LLM's response. Then adding them to the created Session can keep the conversation history.

frommemorimportSession, Prompt, ResponsefrommemorimportRenderFormatfrommistralaiimportMistralclient=Mistral(api_key="YOUR_MISTRAL_API")
session=Session()
whileTrue:
user_input=input(">> You: ")
prompt=Prompt(message=user_input)
session.add_message(prompt) # Add user input to sessionresponse=client.chat.complete(
model="mistral-large-latest",
messages=session.render(RenderFormat.OPENAI) # Render the whole session history
)
print("<< MistralAI:", response.choices[0].message.content)
response=Response(message=response.choices[0].message.content)
session.add_message(response) # Add model response to session

Your conversations would carry the past interactions and LLM remembers your session's information:

>> You: Imagine you have 3 apples. You eat one of them. How many apples remain?
<< MistralAI: If you start with 3 apples and you eat one of them, you will have 2 apples remaining.
>> You: How about starting from 2 apples?
<< MistralAI: If you start with 2 apples and you eat one of them, you will have 1 apple remaining. Here's the simple math:
2 apples - 1 apple = 1 apple

In the following, we detail different abstraction levels Memor provides for the conversation artifacts.

Prompt

The Prompt class is a core abstraction in Memor, representing a user prompt. The prompt can be associated with one or more responses from an LLM, with the first one being the most confident usually. It encapsulates not just the prompt text but also metadata, a template for rendering into the API endpoint, and serialization capabilities that enable saving and reusing prompts.

frommemorimportPrompt, Response, PresetPromptTemplateprompt=Prompt(
message="Hello, how are you?",
responses=[
Response(message="I'm fine."),
Response(message="I'm not fine."),
],
template=PresetPromptTemplate.BASIC.PROMPT_RESPONSE_STANDARD
)
prompt.render()
# Prompt: Hello, how are you?# Response: I'm fine.

Parameters

NameTypeDescription
messagestrThe core prompt message content
responsesList[Response]List of associated responses
roleRoleRole of the message sender (USER, SYSTEM, etc.)
tokensintToken count
templatePromptTemplate | PresetPromptTemplateTemplate used to format the prompt
file_pathstrPath to load a prompt from a JSON file
init_checkboolWhether to verify template rendering during initialization

Methods

MethodDescription
add_responseAdd a new response (append or insert)
remove_responseRemove the response at specified index
clear_responsesRemove all responses from the prompt
select_responseMark a specific response as selected to be included in memory
update_templateUpdate the rendering template
update_responsesReplace all responses
update_messageUpdate the prompt text
update_message_from_xmlUpdate the prompt text from XML
update_roleChange the prompt role
update_tokensSet a custom token count
to_json / from_jsonSerialize or deserialize the prompt data
to_dictConvert the object to a Python dictionary
save / loadSave or load prompt from file
renderRender the prompt in a specified format
check_renderValidate if the current prompt setup can render
estimate_tokensEstimate the token usage for the prompt
get_sizeReturn prompt size in bytes (JSON-encoded)
copyClone the prompt
regenerate_idReset the unique identifier of the prompt
contains_xmlCheck if the prompt contains any XML tags
set_size_warning / reset_size_warningSet or reset size warning

Response

The Response class represents an answer or a completion generated by a model given a prompt. It encapsulates metadata such as score, temperature, model, tokens, inference time, and more. It also provides utilities for JSON serialization, rendering in multiple formats, and import/export functionality.

frommemorimportResponse, Role, LLMModelresponse=Response(
message="Sure! Here's a summary.",
score=0.94,
temperature=0.7,
model=LLMModel.OpenAI.GPT_4,
inference_time=0.3
)
response.render()
# Sure! Here's a summary.

Parameters

NameTypeDescription
messagestrThe content of the response
scorefloatEvaluation score representing the response quality
roleRoleRole of the message sender (USER, SYSTEM, etc.)
temperaturefloatSampling temperature
top_kintk in top-k sampling method
top_pfloatp in top-p (nucleus) sampling
tokensintNumber of tokens in the response
inference_timefloatTime spent generating the response (seconds)
modelLLMModel.<provider> | strModel used
gpustrGPU model used
datedatetime.datetimeTimestamp of the creation
file_pathstrPath to load a saved response

Methods

MethodDescription
update_scoreUpdate the response score
update_temperatureSet the generation temperature
update_top_kSet the top-k value
update_top_pSet the top-p value
update_modelSet the model name or enum
update_gpuSet the GPU model identifier
update_inference_timeSet the inference time in seconds
update_messageUpdate the response message
update_message_from_xmlUpdate the response message from XML
update_roleUpdate the sender role
update_tokensSet the number of tokens
to_json / from_jsonSerialize or deserialize to/from JSON
to_dictConvert the object to a Python dictionary
save / loadSave or load the response to/from a file
renderRender the response in a specific format
check_renderValidate if the current response setup can render
estimate_tokensEstimate the token usage for the response
get_sizeReturn response size in bytes (JSON-encoded)
copyClone the response
regenerate_idReset the unique identifier of the response
contains_xmlCheck if the response contains any XML tags
set_size_warning / reset_size_warningSet or reset size warning

Prompt Templates

The PromptTemplate class provides a structured interface for managing, storing, and customizing text prompt templates used in prompt engineering tasks. This class supports template versioning, metadata tracking, file-based persistence, and integration with preset template formats. It is a core component of the memor library, designed to facilitate reproducible and organized prompt workflows for LLMs.

frommemorimportPrompt, PromptTemplatetemplate=PromptTemplate(content="{instruction}, {prompt[message]}", custom_map={"instruction": "Hi"})
prompt=Prompt(message="How are you?", template=template)
prompt.render()
'Hi, How are you?'

Parameters

NameTypeDescription
titlestrThe template name
contentstrThe template content string with placeholders
custom_mapDict[str, str]A dictionary of custom variables used in the template
file_pathstrPath to a JSON file to load the template from
engineTemplateEngineTemplate engine (FORMAT, JINJA)

Methods

MethodDescription
update_titleUpdate the template title
update_contentUpdate the template content
update_mapUpdate the custom variable map
update_engineUpdate the engine
get_sizeReturn the size (in bytes) of the JSON representation
get_missing_variablesReturn the list of missing template variables
from_content_fileCreate a template from a text file by loading its contents as the template content
save / loadSave or load the template to/from a file
to_json / from_jsonSerialize or deserialize to/from JSON
to_dictConvert the template to a plain Python dictionary
copyReturn a shallow copy of the template instance
renderRender the template
check_renderReturn True if the template renders without error

Preset Templates

Memor provides a variety of pre-defined PromptTemplates to control how prompts and responses are rendered. Each template is prefixed by an optional instruction string and includes variations for different formatting styles. Following are different variants of parameters:

  • INSTRUCTION1: "I'm providing you with a history of a previous conversation. Please consider this context when responding to my new question."
  • INSTRUCTION2: "Here is the context from a prior conversation. Please learn from this information and use it to provide a thoughtful and context-aware response to my next questions."
  • INSTRUCTION3: "I am sharing a record of a previous discussion. Use this information to provide a consistent and relevant answer to my next query."
Template TitleDescription
PROMPTOnly includes the prompt message
RESPONSEOnly includes the response message
RESPONSE0 to RESPONSE3Include specific responses from a list of multiple responses
PROMPT_WITH_LABELPrompt with a "Prompt: " prefix
RESPONSE_WITH_LABELResponse with a "Response: " prefix
RESPONSE0_WITH_LABEL to RESPONSE3_WITH_LABELLabeled response for the i-th response
PROMPT_RESPONSE_STANDARDIncludes both labeled prompt and response on a single line
PROMPT_RESPONSE_FULLA detailed multi-line representation including role, date, model, etc

You can access them using:

frommemorimportPresetPromptTemplatetemplate=PresetPromptTemplate.INSTRUCTION1.PROMPT_RESPONSE_STANDARD

Session

The Session class represents a conversation session composed of Prompt and Response messages. It supports creation, modification, saving, loading, searching, rendering, and token estimation — offering a structured way to manage LLM interaction histories. Each session tracks metadata such as title, creation/modification time, render count, and message activation (masking) status.

frommemorimportSession, Prompt, Responsesession=Session(title="Q&A Session", messages=[
Prompt(message="What is the capital of France?"),
Response(message="The capital of France is Paris.")
])
session.add_message(Prompt(message="What is the population of Paris?"))
print(session.render())
# What is the capital of France?# The capital of France is Paris.# What is the population of Paris?results=session.search("Paris")
print("Found at indices:", results)
# Found at indices: [1, 2]tokens=session.estimate_tokens()
print("Estimated tokens:", tokens)
# Estimated tokens: 35

Parameters

ParameterTypeDescription
titlestrThe title of the session
messagesList[Prompt or Response]The list of initial messages
init_checkboolWhether to check rendering at initialization
file_pathstrThe Path to a saved session file

Methods

MethodDescription
add_messageAdd a Prompt or Response to the session
remove_messageRemove a message by index or ID
remove_message_by_indexRemove a message by numeric index
remove_message_by_idRemove a message by its unique ID
update_titleUpdate the title of the session
update_messagesReplace all messages and optionally update their status list
update_messages_statusUpdate the message status without changing the content
clear_messagesRemove all messages from the session
get_messageRetrieve a message by index, slice, or ID
get_message_by_indexGet a message by integer index or slice
get_message_by_idGet a message by its unique ID
enable_messageMark the message at the given index as active
enable_all_messagesMark all the messages as active
disable_messageMark the message as inactive (masked)
disable_all_messagesMark all the messages as inactive (masked)
mask_messageAlias for disable_message()
unmask_messageAlias for enable_message()
searchSearch for a string or regex pattern in the messages
save / loadSave or load the session to/from a file
to_json / from_jsonSerialize or deserialize the session to/from JSON
to_dictReturn a Python dict representation of the session
to_dataframe/from_dataframeSerialize or deserialize the session to/from Pandas DataFrame
renderRender the session in the specified format
check_renderReturn True if the session renders without error
get_sizeReturn session size in bytes (JSON-encoded)
copyReturn a shallow copy of the session
estimate_tokensEstimate the token count of the session content
set_size_warning / reset_size_warningSet or reset size warning
reset_render_counterReset render counter

Examples

You can find more real-world usage of Memor in the examples directory. This directory includes concise and practical Python scripts that demonstrate key features of Memor library.

Issues & bug reports

Just fill an issue and describe it. We'll check it ASAP! or send an email to memor@openscilab.com.

  • Please complete the issue template

You can also join our discord server

Discord Channel

Show your support

Star this repo

Give a ⭐️ if this project helped you!

Donate to our project

If you do like our project and we hope that you do, can you please support us? Our project is not and is never going to be working for profit. We need the money just so we can continue doing what we do ;-) .

Memor Donation

Releases

Packages

Used by

Contributors

Languages