Skip to content

Memory Types

LangMem offers three types of memory to help your chatbot recall important information about users and conversations: User State, Semantic Memory, and Append-only State. Each type strikes a different balance between structure and flexibility.

User State

User State is a structured profile that LangMem maintains for each user. It's perfect for tracking key user attributes that fit a predefined schema.

How to Define

Provide one or more structured schemas representing the attributes your assistant should learn about users.

from pydantic import BaseModel, Field
from langmem import Client

class UserProfile(BaseModel):
   name: str = Field(description="The user's name")
   age: int = Field(description="The user's age")
   interests: List[str] = Field(description="The user's interests")
   relationships: Dict[str, str] = Field(
       description="The user's friends, family, pets,and other relationships."
   )
   ai_instructions: List[str] = Field(
       description="Prompt instructions that you as the AI assistant"
       " should always retain in subsequent conversations."
   )

client = Client()
memory_function = await client.create_memory_function(
   UserProfile,
   target_type="user_state",
   custom_instructions="Remember that this schema must be useful for prompt engineering an AI assistant."
)

Querying

Call GET on the user's state using the user ID and schema ID. LangMem returns the up-to-date object based on your schema, ready to be included in your system prompt.

Direct call:

state = client.get_user_memory(user_id, memory_function_id=memory_function["id"])

Combined query:

memory_response = client.query_user_memory(
    user_id, text="Foo", states_to_return=[memory_function["id"]],
)
state = memory_response["state"][0]

Management

Whenever messages are posted, LangMem automatically processes the new information and determines what (if any) to modify about the current user state. This is done primarily via function calling.

Semantic Memory

Semantic Memory is an unstructured memory that generates knowledge triplets from conversations. It offers maximum flexibility by letting LangMem determine what information is important to remember.

How to Define

No configuration needed! This memory is automatically represented as knowledge triplets.

Querying

Send a query text (representing the context, recent conversation turn, etc.). LangMem returns a ranked list of unstructured memories as facts, such as "user X likes coffee in the morning" or "user X has brother Zihan". Results are ranked based on semantic relevance, significance, and recency. You can optionally control the weights for each factor.

memory_response = client.query_user_memory(user_id, text="Foo")
state = [mem["text"] for mem in memory_response["memories"]]

Customize how much to weight different aspects of the memory's strength.

memory_response = client.query_user_memory(
    user_id, 
    text="Foo",
    weights={
        "recency": 1.0,
        "importance": 0,
        "relevance": 0,
    }
)

Management

When messages are posted, LangMem extracts important facts and other memories and stores them automatically.

Append-only State

Append-only State is a hybrid between User State and Semantic Memory. It lets you customize the memory schema while still retrieving information based on relevance and recency.

How to Define

Provide one or more structured schemas representing the insights your assistant should extract and retain from the conversation.

class UserPreference(BaseModel):
   preference: str = Field(description="The preference.")
   why: str = Field(description="Why the user prefers this.")
   context: str = Field(description="The context in which this prefernce is appropriate")
   source_comment: str = Field(description="The raw user utterance where you identified this preference.")

client = Client()
memory_function = await client.create_memory_function(
   UserPreference,
   target_type="user_append_state",
   custom_instructions="Extract as many preferences from the conversation as you are able."
)

Querying

Send a query text and optionally select a subset of the schemas. LangMem returns a ranked list of memory objects, based on semantic similarity and recency. If schemas are specified, only those types of memory objects are returned.

Management

Whenever messages are posted, LangMem extracts any relevant memory objects. These objects are appended to user memory for that schema ID.

Thread Summary

In addition to user-specific memories, LangMem can also generate summaries for entire conversation threads. You can define a custom schema to populate for each thread. Common fields to include for this type are:

  • Title: A distinct title for the conversation
  • Summary: A high-level overview of the interactions
  • Topics: Key topics discussed in the conversation
  • Participants: Users who participated in the conversation
  • Action items: (if using this in a work context)

Thread summaries are automatically generated when messages are posted and can be retrieved via the API to help organize and understand conversation history.

How to define

from pydantic import BaseModel, Field
from langmem import Clientl

class ThreadSummary(BaseModel):
   titles: str = Field(description="Concise 2-5 word title for the conversation.")
   summary: str
   topics: List[str] = Field(description="Topics discussed")
   questions: List[str] = Field(descriptin="Any questions you'd like to follow up on next time.")

thread_memory_function = await client.create_memory_function(
   ThreadSummary,
   target_type="thread_summary",
   custom_instructions="Summarize this thread."
)

Querying

thread_memory = client.get_thread_memory(thread_id, memory_function_id=thread_memory_function["id"])

As a part of a combined query:

memory_response = client.query_user_memory(
    user_id, 
    # Query semantic memory
    text="Foo", 
    # Also include thread summaries from this function
    thread_summaries=[thread_memory_function["id"]]
    # Include up to the three most recent summaries for each thread_summary_function
    thread_summaries_k=3
)
thread_summaries = memory_response["thread_summaries"][thread_memory_function["id"]]

Choosing the Right Memory Type

1. User State:

  1. This is more useful than the other types if you want to se langmem for “user analytics” → you have a single source of truth representing all the user’s relevant characteristics
  2. It’s the easiest to conform to a memory “panel” in your app where you can let the end user manually update what the chat bot “knows” about them
  3. It’s also the simplest to inject into your assistant, since you don’t need to think about how to query the memory

2. Append State (Events)

The memory types provide a continuum of control and transparency.

  1. You get to define what’s salient

    • This means that if certain domain-specific knowledge is important, LangMem is more likely to extract this in an appropriate format vs. if you only use the unstructured memory.
  2. You can query information relevant to your context

    • This may be easier than having a single massive user state. You could treat this essentially as a versioned table of user states, where you can query over all versions at any given time.
    • One trick to consider is to include contextual information in the schema (like the source sentence or context that led to the discovered information), which may be useful for recalling and incorporating knowledge downstream (your assistant will more easily know if/when the context is relevant)
    • The assistant never “forgets”

    • We never explicitly delete fields in the schema (though the retrieval mechanism down-weights old memories over time, and you can manually delete things), so you don’t have to worry about the system automatically overriding the user state

3. Unstructured

  1. Use this if you don’t want to constrain your system to specific memory content
  2. This is useful if your domain is very open-ended and you want to let the memory service flexibly determine what other memories it would like to store
  3. It is often the most concise, since each “memory” is a short assertion/statement about the user