LangMemLangMem 0.0.30 · LangGraph 1.2 · Python 3.10+
Dashboard
0%
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
19 small wins to finish your pathNext lesson →

Collections

A collection is LangMem's default way of keeping memories: many separate memory documents, each with its own id, that grows as later conversations add to it.

Last updated: 30 Sep, 2026 · LangMem 0.0.30

One conversation gave one memory in Extracting memories. A customer comes back many times, so memories have to accumulate. A collection is that list; for each new conversation the manager decides whether to add a memory or change one it already has.

Syntax:

python
first = manager.invoke({"messages": conversation})
existing = [(m.id, m.content) for m in first]
later = manager.invoke({"messages": new_conversation, "existing": existing})

Passing what you already have

existing is a list of (id, content) pairs. The manager returns the whole collection after the conversation, old memories included, so you replace your list with the result.

python
existing = [(memory.id, memory.content) for memory in first]

A second conversation about a different order

python
later = manager.invoke({
    "messages": [{"role": "user", "content": "Order A-1002 is three days late."}],
    "existing": existing,
})

Two conversations with a single-call manager

ExampleAPI key
from langchain.chat_models import init_chat_model
from langmem import create_memory_manager

model = init_chat_model("groq:openai/gpt-oss-120b", temperature=0)
manager = create_memory_manager(
    model,
    instructions="Extract what helps support this customer. Record everything in a single Memory call.",
)

first = manager.invoke({"messages": [
    {"role": "user", "content": "Hi, I'm Asha. Order A-1001 arrived broken. Please email me."},
]})
existing = [(memory.id, memory.content) for memory in first]

later = manager.invoke({
    "messages": [{"role": "user", "content": "Order A-1002 is three days late."}],
    "existing": existing,
})
for memory in later:
    status = "kept id" if memory.id in dict(existing) else "new id"
    print(f"{status:8} | {memory.content.content}")

Why the collection did not grow

  • kept id, and only one line. The second conversation did not add a memory. The model patched the existing one and appended "Additionally, order A-1002 is three days late."
  • The instructions caused it. They asked for everything in a single Memory call, and the model kept everything in a single memory. It works like a single profile document, as in Profiles, and it only grows longer.
  • Runs differ in how they merge. Another run wrote the merged text as a new memory next to the old one, which leaves a near-duplicate. Either way, A-1002 did not get a memory of its own.

Instructions that keep topics apart

The manager does what the instructions say, and "record everything in a single Memory call" reads as "keep one memory". Say how memories should be split, and a new order gets its own memory while the call stays single:

python
manager = create_memory_manager(
    model,
    instructions="Extract what helps support this customer. Record everything in a single Memory call. A new order or a new topic gets a new memory; do not merge it into an existing one.",
)

A new order in a new memory

ExampleAPI key
from langchain.chat_models import init_chat_model
from langmem import create_memory_manager

model = init_chat_model("groq:openai/gpt-oss-120b", temperature=0)
manager = create_memory_manager(
    model,
    instructions="Extract what helps support this customer. Record everything in a single Memory call. A new order or a new topic gets a new memory; do not merge it into an existing one.",
)
first = manager.invoke({"messages": [
    {"role": "user", "content": "Hi, I'm Asha. Order A-1001 arrived broken. Please email me."},
]})
existing = [(memory.id, memory.content) for memory in first]

later = manager.invoke({
    "messages": [{"role": "user", "content": "Order A-1002 is three days late."}],
    "existing": existing,
})
for memory in later:
    status = "kept id" if memory.id in dict(existing) else "new id"
    print(f"{status:8} | {memory.content.content}")

What the collection holds now

  • new id for A-1002. The late order became its own memory, so the collection now holds two.
  • kept id for A-1001: the memory from the first conversation is still there, under its own id.
  • Only the instructions changed between this example and the one above; the model still made one tool call per reply.

Several rounds with max_steps

LangMem's reference documents a second way to get more memories out of one conversation: a max_steps key in the input. The manager then calls the model up to that many times; after each round it tells the model which memories were saved, and from the second round it adds a Done tool the model calls when it has finished. Each round is one more model call.

python
memories = manager.invoke({"messages": conversation, "max_steps": 3})

A conversation with nothing new

A collection only stays useful if nothing is saved twice. Send small talk with the existing memory and count:

ExampleAPI key
from langchain.chat_models import init_chat_model
from langmem import create_memory_manager

model = init_chat_model("groq:openai/gpt-oss-120b", temperature=0)
manager = create_memory_manager(
    model,
    instructions="Extract what helps support this customer. Record everything in a single Memory call.",
)

first = manager.invoke({"messages": [
    {"role": "user", "content": "Hi, I'm Asha. Order A-1001 arrived broken. Please email me."},
]})
existing = [(memory.id, memory.content) for memory in first]

chat = manager.invoke({
    "messages": [{"role": "user", "content": "Thanks! Lovely weather in Pune today."}],
    "existing": existing,
})
print(len(existing), "before,", len(chat), "after")
for memory in chat:
    print(memory.content.content)

1 before, 2 after. Nothing in the message was worth keeping, yet the manager returned a second memory, a word-for-word copy of the first with a new id. When existing memories are passed, LangMem's extractor binds the tools with tool_choice="any", so the model has to call one; here it re-created the memory it already had.

Collection vs profile

CollectionProfile
ShapeMany memory documentsOne document with fixed fields
GrowsWithout limitNever; fields are overwritten
Good forEvents, issues, anything open-endedCurrent preferences and settings
RecallSearch, in Semantic searchRead the one document

When a collection fits

  • A customer's order problems, one memory per problem, kept even after the next one arrives.
  • Notes a research assistant collects across many sessions.
  • Anything where you cannot list the fields in advance.
Watch out. When you pass existing memories, LangMem makes the model call a tool, so every call writes something. Run the manager on conversations that carry information, not on every greeting, and check the collection for copies.
Try it yourself
  • Run the second conversation without existing and compare the ids.
  • Send a third conversation about order A-1001 and see whether the manager adds a memory or patches one.
  • Send the small-talk message with the instructions "Save nothing if the message has no new facts" and count again.
PreviousChat models

Every expert started right here.