fleet-memory/memora-langmem/tutorial.ipynb
Nicolò Boschi 99a54aec90 more
2025-11-19 16:28:02 +01:00

280 lines
No EOL
12 KiB
Text

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Memora-LangMem: Drop-in Semantic Memory for LangGraph\n",
"\n",
"Replace your LangGraph memory store in one line and get advanced semantic capabilities."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## What is Memora-LangMem?\n",
"\n",
"`memora-langmem` implements LangGraph's `BaseStore` interface using Memora as the backend.\n",
"\n",
"### What You Get vs Standard LangGraph Memory\n",
"\n",
"| Feature | Standard Memory | Memora-LangMem |\n",
"|---------|-----------------|----------------|\n",
"| Basic Key-Value Storage | ✅ | ✅ |\n",
"| Semantic Search | ✅ Basic | ✅ **Enhanced with spreading activation** |\n",
"| Namespace Support | ✅ | ✅ |\n",
"| **Personality-Driven Retrieval** | ❌ | ✅ |\n",
"| **Automatic Fact Extraction** | ❌ | ✅ |\n",
"| **Entity Recognition** | ❌ | ✅ |\n",
"| **Temporal Reasoning** | ❌ | ✅ |\n",
"| **Opinion Formation** | ❌ | ✅ |\n",
"| **Background Knowledge** | ❌ | ✅ |\n",
"| **Thinking/Reasoning API** | ❌ | ✅ |\n",
"\n",
"### When to Use\n",
"- Conversational agents needing long-term memory\n",
"- Personalized AI with context-aware responses \n",
"- Multi-agent systems with distinct personalities\n",
"- Knowledge management with semantic search"
]
},
{
"cell_type": "markdown",
"source": "## Installation\n\nRun this cell to install dependencies:",
"metadata": {}
},
{
"cell_type": "code",
"source": "!pip install langgraph langmem",
"metadata": {},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": "Make sure Memora API is running at `http://localhost:8000`",
"metadata": {}
},
{
"cell_type": "markdown",
"source": "## Setup API Keys\n\nSet up your OpenAI API key and Memora URL:",
"metadata": {}
},
{
"cell_type": "code",
"source": "import os\nimport getpass\n\n# Set OpenAI API key\nif \"OPENAI_API_KEY\" not in os.environ:\n os.environ[\"OPENAI_API_KEY\"] = getpass.getpass(\"Enter your OpenAI API key: \")\n\n# Set Memora API URL\nif \"MEMORA_API_URL\" not in os.environ:\n os.environ[\"MEMORA_API_URL\"] = input(\"Enter Memora API URL (default: http://localhost:8000): \") or \"http://localhost:8000\"\n\nprint(\"✅ API keys configured\")",
"metadata": {},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## The Drop-in Replacement\n",
"\n"
]
},
{
"cell_type": "markdown",
"source": "### Before: Standard LangGraph Memory",
"metadata": {}
},
{
"cell_type": "code",
"source": "from langmem import create_manage_memory_tool, create_search_memory_tool\nfrom langgraph.prebuilt import create_react_agent\nfrom langgraph.store.memory import InMemoryStore\n\n# Standard store - basic key-value with optional vector search\nstore = InMemoryStore()\n\nagent = create_react_agent(\n \"openai:gpt-4o\",\n tools=[\n create_manage_memory_tool(namespace=(\"memories\",)),\n create_search_memory_tool(namespace=(\"memories\",)),\n ],\n store=store\n)",
"metadata": {},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": "### After: With Memora-LangMem\n\n**Just change one line!**",
"metadata": {},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"metadata": {},
"source": "import os\nfrom langmem import create_manage_memory_tool, create_search_memory_tool\nfrom langgraph.prebuilt import create_react_agent\nfrom memora_langmem import MemoraStore # ← Only import change!\n\n# Replace InMemoryStore with MemoraStore\nbase_url = os.getenv(\"MEMORA_API_URL\", \"http://localhost:8000\")\nstore = MemoraStore(base_url=base_url, default_agent_id=\"my_agent\") # ← One line change!\n\n# Everything else stays exactly the same\nagent = create_react_agent(\n \"openai:gpt-4o\", # ← Use OpenAI\n tools=[\n create_manage_memory_tool(namespace=(\"memories\",)),\n create_search_memory_tool(namespace=(\"memories\",)),\n ],\n store=store # ← Now using Memora with enhanced capabilities!\n)\n\nprint(\"✅ Agent created with Memora-powered memory\")"
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"ename": "ModuleNotFoundError",
"evalue": "No module named 'langmem'",
"output_type": "error",
"traceback": [
"\u001b[31m---------------------------------------------------------------------------\u001b[39m",
"\u001b[31mModuleNotFoundError\u001b[39m Traceback (most recent call last)",
"\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[1]\u001b[39m\u001b[32m, line 2\u001b[39m\n\u001b[32m 1\u001b[39m \u001b[38;5;28;01mimport\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mos\u001b[39;00m\n\u001b[32m----> \u001b[39m\u001b[32m2\u001b[39m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mlangmem\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m create_manage_memory_tool, create_search_memory_tool\n\u001b[32m 3\u001b[39m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mlanggraph\u001b[39;00m\u001b[34;01m.\u001b[39;00m\u001b[34;01mprebuilt\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m create_react_agent\n\u001b[32m 4\u001b[39m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mmemora_langmem\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m MemoraStore \u001b[38;5;66;03m# ← Only import change!\u001b[39;00m\n",
"\u001b[31mModuleNotFoundError\u001b[39m: No module named 'langmem'"
]
}
],
"source": [
"import os\n",
"from langmem import create_manage_memory_tool, create_search_memory_tool\n",
"from langgraph.prebuilt import create_react_agent\n",
"from memora_langmem import MemoraStore # ← Only import change!\n",
"\n",
"# Replace InMemoryStore with MemoraStore\n",
"base_url = os.getenv(\"MEMORA_API_URL\", \"http://localhost:8080\")\n",
"store = MemoraStore(base_url=base_url, default_agent_id=\"my_agent\") # ← One line change!\n",
"\n",
"# Everything else stays exactly the same\n",
"agent = create_react_agent(\n",
" \"anthropic:claude-3-5-sonnet-latest\",\n",
" tools=[\n",
" create_manage_memory_tool(namespace=(\"memories\",)),\n",
" create_search_memory_tool(namespace=(\"memories\",)),\n",
" ],\n",
" store=store # ← Now using Memora with enhanced capabilities!\n",
")\n",
"\n",
"print(\"✅ Agent created with Memora-powered memory\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Example: Conversational Memory in Action"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import time\n",
"\n",
"# Store information\n",
"result1 = agent.invoke({\n",
" \"messages\": [{\n",
" \"role\": \"user\",\n",
" \"content\": \"\"\"Remember: I'm David, a software engineer working on AI projects. \n",
" I love Python and machine learning. Currently building a chatbot with LangGraph.\"\"\"\n",
" }]\n",
"})\n",
"print(\"Agent:\", result1[\"messages\"][-1].content)\n",
"\n",
"time.sleep(2)\n",
"\n",
"# Recall information\n",
"result2 = agent.invoke({\n",
" \"messages\": [{\"role\": \"user\", \"content\": \"What do you remember about me?\"}]\n",
"})\n",
"print(\"\\nAgent:\", result2[\"messages\"][-1].content)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## What Happens Behind the Scenes\n",
"\n",
"When your agent stores memories with Memora, automatically:\n",
"\n",
"1. **Fact Extraction**: Natural language → structured facts\n",
"2. **Entity Recognition**: Identifies people, places, concepts\n",
"3. **Semantic Indexing**: Spreading activation for better retrieval\n",
"4. **Temporal Awareness**: Event dates tracked for time queries\n",
"5. **Opinion Formation**: Agent develops perspectives over time\n",
"6. **Personality Influence**: Memory retrieval shaped by personality traits\n",
"\n",
"**You use the standard LangGraph API - Memora does the rest!**"
]
},
{
"cell_type": "code",
"metadata": {},
"source": "# Different agents with different personalities\ncreative_store = MemoraStore(base_url=base_url, default_agent_id=\"creative_writer\")\nanalyst_store = MemoraStore(base_url=base_url, default_agent_id=\"data_analyst\")\n\ncreative_agent = create_react_agent(\n \"openai:gpt-4o\",\n tools=[\n create_manage_memory_tool(namespace=(\"creative\",)),\n create_search_memory_tool(namespace=(\"creative\",))\n ],\n store=creative_store\n)\n\nanalyst_agent = create_react_agent(\n \"openai:gpt-4o\",\n tools=[\n create_manage_memory_tool(namespace=(\"analysis\",)),\n create_search_memory_tool(namespace=(\"analysis\",))\n ],\n store=analyst_store\n)\n\nprint(\"✅ Two agents with isolated memories and distinct personalities\")"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Different agents with different personalities\n",
"creative_store = MemoraStore(base_url=base_url, default_agent_id=\"creative_writer\")\n",
"analyst_store = MemoraStore(base_url=base_url, default_agent_id=\"data_analyst\")\n",
"\n",
"creative_agent = create_react_agent(\n",
" \"anthropic:claude-3-5-sonnet-latest\",\n",
" tools=[\n",
" create_manage_memory_tool(namespace=(\"creative\",)),\n",
" create_search_memory_tool(namespace=(\"creative\",))\n",
" ],\n",
" store=creative_store\n",
")\n",
"\n",
"analyst_agent = create_react_agent(\n",
" \"anthropic:claude-3-5-sonnet-latest\",\n",
" tools=[\n",
" create_manage_memory_tool(namespace=(\"analysis\",)),\n",
" create_search_memory_tool(namespace=(\"analysis\",))\n",
" ],\n",
" store=analyst_store\n",
")\n",
"\n",
"print(\"✅ Two agents with isolated memories and distinct personalities\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Summary\n",
"\n",
"### The Change\n",
"```python\n",
"# Before\n",
"store = InMemoryStore()\n",
"\n",
"# After \n",
"store = MemoraStore(base_url=\"http://localhost:8000\", default_agent_id=\"my_agent\")\n",
"```\n",
"\n",
"### What You Get\n",
"- ✅ Semantic search with spreading activation\n",
"- ✅ Automatic fact extraction from conversations\n",
"- ✅ Entity recognition and linking\n",
"- ✅ Temporal reasoning (time-aware queries)\n",
"- ✅ Personality-driven memory retrieval\n",
"- ✅ Opinion formation over time\n",
"- ✅ Multi-agent support with isolated memories\n",
"\n",
"**Same LangGraph API. Smarter memory. Zero code changes (except the store line).**"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.10"
}
},
"nbformat": 4,
"nbformat_minor": 4
}