MemorySync
Integrations

LangChain Tools

Five structured memory tools that let a LangChain agent store, search, list, update and delete memories — with scoping, idempotent writes, and failures that never abort an agent run.

The agent calls five scoped structured tools; failures return readable strings instead of aborting the run.

The tool set

ToolArgumentsReturns
add_memorytext (required), tags, importance 0–1Stored memory m_123. — or Already stored as m_123 on a repeat, or guidance when nothing durable was found.
search_memoryquery (required), k 1–50, default 5Ranked lines with ids and relevance scores, or No relevant memories found.
list_memorieslimit 1–200, default 20Newest-first lines with ids, or No memories stored yet.
update_memorymemory_id (required), tags, importanceUpdated memory m_123. Memory text is immutable — replace a fact by delete plus add.
delete_memorymemory_id (required)Deleted memory m_123. — or a not-found sentence when it is already gone.

Create the tools

from langchain.agents import create_agent
from langchain_memorysync import create_memorysync_tools
tools = create_memorysync_tools(end_user_id="user-123")
agent = create_agent(model, tools=tools)
agent.invoke({"messages": [{"role": "user", "content": "Remember that I'm allergic to peanuts."}]})

The factory also works with LangGraph’s create_react_agent and the legacy AgentExecutor on 0.3.x — the tools are plain structured tools, nothing framework-version specific.

Scope to the right user

Pass end_user_id whenever the key belongs to an organisation. It is what keeps one customer’s memories out of another’s session: every tool call is isolated to that user, and a delete cannot reach another user’s memory even by id.

tools = create_memorysync_tools(
end_user_id="user-123",
read_only=True, # only search_memory and list_memories
)

Write behaviour worth knowing

  • add_memory derives an idempotency key from the content, so an agent that repeats "remember X" gets "already stored" instead of a duplicate.
  • Extraction judges what is durable: transient chit-chat comes back as "nothing stored" with guidance to rephrase, not as a memory.
  • Memory text is immutable by design — the update tool changes tags and importance, and replacing a fact is delete plus add, which keeps history auditable.
  • Over-quota writes degrade silently server-side; the agent sees a normal response rather than a billing error to narrate to the end user.

Complete example: an agent that stores, then recalls

The whole loop in one program: the first invocation stores facts the user states, and a later invocation — a different process, days later — searches memory before answering. The tool return strings are exactly what the model sees.

from langchain.agents import create_agent
from langchain_openai import ChatOpenAI
from langchain_memorysync import create_memorysync_tools
tools = create_memorysync_tools(end_user_id="customer-7")
agent = create_agent(ChatOpenAI(model="your-model"), tools=tools)
# Run 1 — the user states facts; the agent calls add_memory twice.
agent.invoke({"messages": [{
"role": "user",
"content": "Remember that I'm vegetarian and I'm allergic to peanuts.",
}]})
# Tool results the model saw:
# Stored memory m_101.
# Stored memory m_102.
# Run 2 — a fresh process. The agent calls search_memory before answering.
result = agent.invoke({"messages": [{
"role": "user",
"content": "Pick a restaurant for my team dinner on Friday.",
}]})
print(result["messages"][-1].content)
# Tool result the model saw first:
# - m_101 (relevance 0.89): The user is vegetarian.
# - m_102 (relevance 0.87): The user is allergic to peanuts.

Where to go next

Was this page helpful?