How to Integrate memU with LangGraph for Agent Workflows
memU provides a native LangGraph adapter that exposes save_memory and search_memory tools through the MemULangGraphTools class, allowing agents to persist and retrieve long-term memories via a MemoryService instance.
The NevaMind-AI/memU repository offers a purpose-built integration layer for LangGraph that transforms its vector memory service into LangChain-compatible tools. When you integrate memU with LangGraph for agent workflows, you gain persistent memory capabilities without writing custom storage logic or tool wrappers.
Architecture Overview
The integration centers on three components working together to provide persistent memory in agent graphs.
MemoryService – The core memU component implemented in src/memu/app/service.py that handles embeddings, vector-store lookups, and metadata management through its memorize and retrieve methods.
MemULangGraphTools – The adapter class defined in src/memu/integrations/langgraph.py that wraps a MemoryService instance and constructs two StructuredTool instances: save_memory and search_memory.
LangGraph ToolNode – The standard LangGraph mechanism for tool execution. The memU tools integrate directly with ToolNode, allowing agents to invoke memory operations as part of their state graph workflow.
Prerequisites and Installation
The LangGraph integration requires optional dependencies beyond memU's core package. Install these using your preferred package manager:
uv add langgraph langchain-core
Or with pip:
pip install langgraph langchain-core
Ensure your environment includes the necessary configuration for memU's core functionality, specifically MEMU_DATABASE_URL for the vector store connection and OPENAI_API_KEY for embeddings generation.
The memU LangGraph Integration Layer
The MemULangGraphTools class creates two specialized tools that bridge memU's storage capabilities with LangGraph's execution model.
save_memory Tool
The save_memory tool persists arbitrary text as a memory item associated with a specific user_id. According to the source code in src/memu/integrations/langgraph.py (lines 76-92), the _save method implements this by:
- Creating a temporary file containing the content
- Calling
MemoryService.memorizewith the file path and metadata - Cleaning up the temporary file in a
finallyblock to prevent leaks
This approach allows memU's file-based ingestion pipeline to process the content while maintaining a clean interface for text-based agent interactions.
search_memory Tool
The search_memory tool retrieves relevant memories using natural language queries. Implemented in the _search method (lines 25-55) of src/memu/integrations/langgraph.py, this tool:
- Accepts a
querystring,user_id, and optionallimitparameter - Builds a LangChain-style query list compatible with
MemoryService.retrieve - Returns the most semantically similar memory items from the vector store
Both tools are defined as async coroutines, requiring await tool.ainvoke({...}) when called within LangGraph nodes.
Step-by-Step Integration Guide
Follow these steps to add memU memory capabilities to your LangGraph agent.
-
Initialize the MemoryService
Create a service instance that handles the underlying storage and embedding operations:
from memu.app.service import MemoryService service = MemoryService() -
Instantiate the LangGraph Adapter
Wrap the service with
MemULangGraphToolsto generate LangChain-compatible tools:from memu.integrations.langgraph import MemULangGraphTools tools_adapter = MemULangGraphTools(service) tools = tools_adapter.tools() # Returns List[BaseTool] -
Register Tools with Your StateGraph
Add the tools to a
ToolNodewithin your LangGraph workflow:from langgraph.graph import StateGraph, ToolNode workflow = StateGraph(state_schema={"user_id": str, "messages": list}) workflow.add_node("tools", ToolNode(tools)) -
Invoke Tools in Agent Steps
Use async invocation to save and retrieve memories during agent execution:
async def agent_step(state): # Save a memory save_tool = next(t for t in tools if t.name == "save_memory") await save_tool.ainvoke({ "content": "User prefers Python over JavaScript", "user_id": state["user_id"], "metadata": {"source": "preference_extraction"} }) # Retrieve memories search_tool = next(t for t in tools if t.name == "search_memory") result = await search_tool.ainvoke({ "query": "What programming language does the user prefer?", "user_id": state["user_id"], "limit": 3 }) return {"context": result} -
Compile and Execute
Compile your graph and run it as usual; the tools will handle persistence automatically through memU's storage layer.
Complete Working Example
The repository includes a full demonstration in examples/langgraph_demo.py that shows async initialization, tool usage, and proper error handling. This implementation initializes the infrastructure, saves user preferences, and performs semantic retrieval:
import asyncio, logging, os, sys
try:
import langgraph
from langchain_core.tools import BaseTool
from memu.app.service import MemoryService
from memu.integrations.langgraph import MemULangGraphTools
except ImportError:
print("Missing dependencies. Run: uv add langgraph langchain-core")
sys.exit(1)
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("langgraph_demo")
async def initialize_infrastructure() -> MemULangGraphTools:
if not os.getenv("OPENAI_API_KEY"):
logger.warning("OPENAI_API_KEY not set – embeddings may fail.")
service = MemoryService()
return MemULangGraphTools(service)
async def process_conversation(tools: list[BaseTool], user_id: str):
save_tool = next(t for t in tools if t.name == "save_memory")
await save_tool.ainvoke({
"content": "The user prefers dark mode and likes Python programming.",
"user_id": user_id,
"metadata": {"source": "demo_script"},
})
logger.info("Memory saved.")
async def process_retrieval(tools: list[BaseTool], user_id: str):
search_tool = next(t for t in tools if t.name == "search_memory")
result = await search_tool.ainvoke({
"query": "What are the user's preferences?",
"user_id": user_id,
"limit": 3,
})
logger.info("Search result:\n%s", result)
async def main():
logger.info("Starting LangGraph demo.")
adapter = await initialize_infrastructure()
tools = adapter.tools()
user_id = "demo_user_123"
await process_conversation(tools, user_id)
await process_retrieval(tools, user_id)
logger.info("Demo completed.")
if __name__ == "__main__":
asyncio.run(main())
Using Tools with ToolNode
For standard LangGraph tool-calling patterns, pass the tools list directly to ToolNode. This configuration allows language models to decide when to save or retrieve memories based on the conversation context:
from langgraph.graph import StateGraph, ToolNode
from memu.app.service import MemoryService
from memu.integrations.langgraph import MemULangGraphTools
service = MemoryService()
adapter = MemULangGraphTools(service)
tools = adapter.tools()
graph = StateGraph(state_schema={"user_id": str, "messages": list})
graph.add_node("tools", ToolNode(tools))
# Connect nodes to create agent loop
graph.add_edge("agent", "tools")
graph.add_edge("tools", "agent")
Summary
- MemULangGraphTools in
src/memu/integrations/langgraph.pyprovides the bridge between memU's storage layer and LangGraph's execution environment. - The adapter exposes two tools:
save_memoryfor persisting content andsearch_memoryfor semantic retrieval, both implemented as async coroutines. - Temporary file handling in the save operation ensures content is processed through memU's pipeline without leaving orphaned files.
- The integration requires
langgraphandlangchain-coreas optional dependencies and operates through standardToolNodeconfigurations. - Reference implementation exists in
examples/langgraph_demo.py, demonstrating end-to-end async usage with proper initialization patterns.
Frequently Asked Questions
What dependencies are required to integrate memU with LangGraph?
You must install langgraph and langchain-core alongside memU. These are optional dependencies not included in the base package. Install them via uv add langgraph langchain-core or pip install langgraph langchain-core before importing from memu.integrations.langgraph.
How does the save_memory tool handle content storage?
The tool writes content to a temporary file before calling MemoryService.memorize, then deletes the file in a finally block. This approach leverages memU's file-based ingestion pipeline while presenting a simple text interface to the agent. The implementation in src/memu/integrations/langgraph.py lines 76-92 ensures no temporary files persist after the operation completes.
Is the memU LangGraph integration synchronous or asynchronous?
The integration is async-first. Both _save and _search methods are async coroutines, requiring you to use await tool.ainvoke({...}) when calling them inside LangGraph nodes. This design aligns with LangGraph's async execution model and prevents blocking during vector store operations.
Where can I find the source code for the integration?
The core adapter code resides in src/memu/integrations/langgraph.py, containing the MemULangGraphTools class and tool definitions. Additional documentation is available in docs/langgraph_integration.md, and a complete working example is provided in examples/langgraph_demo.py within the NevaMind-AI/memU repository.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →