{ "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 }