new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

LangChain · LangGraph · all subjects

memory/persistence

14 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Memory capabilities in LangGraph

LangGraph enables creating stateful agents with comprehensive memory including both short-term working memory for ongoing reasoning and long-term memory across sessions.

How to store and retrieve persistent data across multiple agent interactions

To store and retrieve persistent data across multiple agent interactions using LangGraph, configure the graph with both a checkpointer (for thread-scoped state) and a store (for cross-thread data). Pass the thread_id in the configurable section of the graph.invoke() call. The checkpointer maintains conversation continuity within a thread, while the store persists application-defined key-value data that can be accessed across different threads and interactions. For production environments, use persistent implementations like PostgresSaver or SqliteSaver instead of in-memory options.

Stores vs checkpointers: cross-thread persistence

Stores provide cross-thread long-term memory for arbitrary key-value data accessible from any thread, complementing per-thread checkpointer persistence. Checkpointers save the full graph state scoped to one thread, while stores hold arbitrary key-value data accessible from any thread, including user preferences, accumulated knowledge, and facts that should survive beyond a single conversation.

Store namespaces are tuples of strings

Memories are namespaced by tuples, which can be any length and represent anything, such as (user_id, 'memories'). The namespace does not have to be user-specific.

Store.put saves key-value pairs to a namespace

Use the store.put method to save memories to a namespace. Specify the namespace and a key-value pair where the key is a unique identifier (memory_id) and the value is a dictionary containing the memory data.

InMemoryStore for development and testing

InMemoryStore is suitable for development and testing. For production, use persistent stores like PostgresStore, MongoDBStore, RedisStore, or UpstashStore. All implementations extend BaseStore, which is the type annotation to use in node function signatures.

Compile graph with checkpointer and store

Compile a graph with both checkpointer and store using: graph = builder.compile(checkpointer=checkpointer, store=store). The checkpointer enables threads (conversations) while the store allows storing arbitrary information accessible across threads.

Cross-thread memory access with same user_id

If you create a new thread with a different thread_id but the same user_id, you can still access the same memories stored in the namespace keyed by that user_id. The store namespace is independent of thread_id.

Invoke graph with thread_id and user_id context

Invoke the graph with a config containing thread_id and a context parameter with user_id: config = {'configurable': {'thread_id': '1'}}; graph.stream({...}, config, context=Context(user_id='1')). The user_id serves as the namespace for memories.

BaseStore required async methods for custom store

All five async methods are required when subclassing BaseStore: aput(namespace, key, value, index=None), aget(namespace, key), adelete(namespace, key), asearch(namespace_prefix, *, query=None, filter=None, limit=10, offset=0), and alist_namespaces(*, prefix=None, suffix=None, max_depth=None, limit=100, offset=0).

Custom store namespace design requirements

Store implementations must support prefix matching where asearch(('alice',)) returns items under all sub-namespaces, and exact key lookup where aget(('alice', 'memories'), 'some-key') is O(1) or close to it.

Store values are plain Python dicts

Store values are plain Python dictionaries—no special serializer is required. Serialize with json.dumps/json.loads or a JSONB column. Do not store raw Python objects that are not JSON-serializable.

Persistent data retrieval using thread_id and checkpointer

To store and retrieve persistent data across multiple agent interactions, provide an InMemorySaver() or other checkpointer to @entrypoint, and invoke the workflow with config containing configurable.thread_id. The 'previous' parameter in the entrypoint receives the last saved value.

OAuth token storage and reuse

Agent Auth stores and refreshes OAuth tokens after initial authentication. Future uses of the service by either the user or agent do not require re-running the OAuth flow.

Give your agent this brain