Skip to main content
MemLayer integrates naturally with LangGraph. The pattern is simple: add two nodes to your graph — one before your agent that loads relevant memories, and one after that saves what was learned. Your agent node doesn’t need to change at all; it just receives enriched state and returns updated state.

Prerequisites

Install both packages and make sure you have a MemLayer API key:
pip install memlayer-py langgraph
Get your API key at memlayer.online. Keys follow the format ml_live_xxx.

The Pattern

Here is a complete LangGraph graph with MemLayer memory nodes wired around a central agent node.
import os
from memlayer import AsyncMemLayerClient
from langgraph.graph import StateGraph, MessagesState

# Initialise the async client once at module level
maas = AsyncMemLayerClient(api_key=os.environ["MEMLAYER_API_KEY"])


async def load_memory(state: MessagesState):
    """Load relevant memories before the agent responds."""
    last_message = state["messages"][-1].content

    memories = await maas.recall(
        query=last_message,
        user_id=state["user_id"],
        agent_id="my_agent",
        top_k=5,
    )

    memory_context = "\n".join(f"- {m.content}" for m in memories)
    state["memory_context"] = memory_context
    return state


async def save_memory(state: MessagesState):
    """Save what the agent learned after responding."""
    last_message = state["messages"][-1].content

    await maas.remember(
        content=last_message,
        user_id=state["user_id"],
        agent_id="my_agent",
        memory_type="episodic",
    )
    return state


# Wire into your graph
builder = StateGraph(MessagesState)
builder.add_node("load_memory", load_memory)
builder.add_node("agent", your_agent_node)
builder.add_node("save_memory", save_memory)

builder.add_edge("load_memory", "agent")
builder.add_edge("agent", "save_memory")

graph = builder.compile()
The load_memory node writes a memory_context string into the state. Your agent node reads it and uses it to build a context-aware system prompt. The save_memory node runs after the agent responds and persists the last message as an episodic memory.

Using context() at Session Start

For the very first message in a session, consider using context() instead of recall() in your load node. context() returns a broad snapshot of the user’s most important memories ranked by importance and recency — without needing a query.
async def load_memory(state: MessagesState):
    """Use context() for the first turn, recall() for subsequent turns."""
    messages = state["messages"]
    last_message = messages[-1].content

    # First turn: load broad context
    # Later turns: use the actual message as the search query
    if len(messages) == 1:
        result = await maas.context(
            user_id=state["user_id"],
            agent_id="my_agent",
            top_k=10,
            current_message=last_message,  # pass first message for smarter retrieval
        )
        memories = result.memories
    else:
        memories = await maas.recall(
            query=last_message,
            user_id=state["user_id"],
            agent_id="my_agent",
            top_k=5,
        )

    state["memory_context"] = "\n".join(f"- {m.content}" for m in memories)
    return state
This gives you the best of both approaches: a rich context snapshot at session start and targeted recall for follow-up queries.

Tips

Always use AsyncMemLayerClient with LangGraph. LangGraph executes nodes as coroutines. The sync MemLayerClient will block the event loop — use AsyncMemLayerClient and await every call.
Pass current_message to context() to enable semantic ranking instead of importance/recency ordering. For the first message in a session this dramatically improves the relevance of loaded memories.
Use importance scores to mark high-value memories. When saving a memory in save_memory, set importance=0.9 for critical facts (user escalations, confirmed account details) and leave the default 0.5 for routine conversation turns. High-importance memories rank higher in future retrievals.
# Example: detect a complaint and save it with elevated importance
last_message = state["messages"][-1].content
is_complaint = "frustrated" in last_message.lower() or "complaint" in last_message.lower()

await maas.remember(
    content=last_message,
    user_id=state["user_id"],
    agent_id="my_agent",
    memory_type="episodic",
    importance=0.9 if is_complaint else 0.5,
)