Project 10: Mem0g Memory Layer
Build a Mem0-compatible memory layer with graph extensions, supporting the Mem0 API while adding relationship tracking and temporal awareness.
Quick Reference
| Attribute | Value |
|---|---|
| Difficulty | Level 3: Advanced |
| Time Estimate | 2 weeks (25-35 hours) |
| Language | Python (Alternatives: TypeScript) |
| Prerequisites | Projects 1-7, REST API design, async Python |
| Key Topics | Mem0 API, memory CRUD, hybrid storage, multi-user isolation, REST API design |
1. Learning Objectives
By completing this project, you will:
- Understand Mem0’s memory model and API design.
- Build a compatible API with extended graph capabilities.
- Implement multi-user memory isolation.
- Add relationship tracking beyond Mem0’s core features.
- Design for API compatibility and extensibility.
2. Theoretical Foundation
2.1 Core Concepts
-
Mem0: Open-source memory layer for LLM applications. Stores user/agent/session memories with vector search.
- Memory Types:
- User memory: Facts about specific users
- Agent memory: What the agent has learned
- Session memory: Context within a conversation
-
Memory CRUD: Create, read, update, delete with search capabilities.
- Mem0g Extension: Adding graph relationships to Mem0’s vector-first approach.
2.2 Why This Matters
Mem0 is widely adopted but vector-only. By building a compatible layer with graph extensions:
- Drop-in replacement for existing Mem0 users
- Graph relationships for richer memory
- Temporal tracking not in base Mem0
2.3 Common Misconceptions
- “Mem0 is graph-based.” Core Mem0 is vector store + metadata.
- “Just use Mem0.” Production needs often require graph relationships.
- “APIs are trivial.” Proper multi-tenancy and auth are complex.
2.4 ASCII Diagram: Mem0g Architecture
MEM0 COMPATIBLE API + GRAPH EXTENSIONS
══════════════════════════════════════════════════════════════
CLIENT REQUEST
│
▼
┌─────────────────────────────────────────────────────────────┐
│ REST API LAYER │
│ │
│ POST /v1/memories GET /v1/memories/search │
│ PUT /v1/memories/{id} GET /v1/memories/{id} │
│ DELETE /v1/memories/{id} │
│ │
│ GRAPH EXTENSIONS: │
│ POST /v1/memories/{id}/relationships │
│ GET /v1/memories/{id}/related │
│ GET /v1/memories/graph │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ MEMORY SERVICE │
│ │
│ ┌────────────────────┐ ┌────────────────────┐ │
│ │ Memory Manager │ │ Graph Manager │ │
│ │ │ │ │ │
│ │ • CRUD ops │◄──▶│ • Relationships │ │
│ │ • Deduplication │ │ • Traversal │ │
│ │ • Versioning │ │ • Temporal edges │ │
│ └────────────────────┘ └────────────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌────────────────────┐ ┌────────────────────┐ │
│ │ Vector Store │ │ Graph Store │ │
│ │ (ChromaDB) │ │ (Neo4j/SQLite) │ │
│ └────────────────────┘ └────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
MEMORY DATA MODEL
═════════════════
Standard Mem0 Memory:
┌─────────────────────────────────────────────────────────────┐
│ Memory │
│ id: "mem_abc123" │
│ content: "User prefers dark mode" │
│ user_id: "user_456" │
│ agent_id: "assistant" │
│ metadata: {"category": "preference", "confidence": 0.9} │
│ created_at: "2024-12-15T10:00:00Z" │
│ updated_at: "2024-12-15T10:00:00Z" │
│ embedding: [0.12, 0.45, ...] │
└─────────────────────────────────────────────────────────────┘
Mem0g Extension (Graph Relationships):
┌─────────────────────────────────────────────────────────────┐
│ Memory: "User prefers dark mode" │
│ │ │
│ ├──[RELATES_TO]──► Memory: "User uses VSCode" │
│ │ relationship: "applies_to" │
│ │ │
│ └──[SUPERSEDES]──► Memory: "User prefers light mode" │
│ valid_from: 2024-01-01 │
│ valid_to: 2024-12-15 │
└─────────────────────────────────────────────────────────────┘
MULTI-USER ISOLATION
════════════════════
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ User A │ │ User B │ │ User C │
│ │ │ │ │ │
│ ┌─────────────┐ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │
│ │ Memories │ │ │ │ Memories │ │ │ │ Memories │ │
│ │ - Prefs │ │ │ │ - Prefs │ │ │ │ - Prefs │ │
│ │ - History │ │ │ │ - History │ │ │ │ - History │ │
│ │ - Graph │ │ │ │ - Graph │ │ │ │ - Graph │ │
│ └─────────────┘ │ │ └─────────────┘ │ │ └─────────────┘ │
│ │ │ │ │ │
│ ISOLATED │ │ ISOLATED │ │ ISOLATED │
└─────────────────┘ └─────────────────┘ └─────────────────┘
3. Project Specification
3.1 What You Will Build
A REST API service that:
- Implements Mem0-compatible memory CRUD
- Adds graph relationship extensions
- Supports multi-user isolation
- Provides temporal memory queries
3.2 Functional Requirements
Mem0 Compatible:
- Add memory:
POST /v1/memories→ Memory - Get memory:
GET /v1/memories/{id}→ Memory - Update memory:
PUT /v1/memories/{id}→ Memory - Delete memory:
DELETE /v1/memories/{id}→ void - Search:
POST /v1/memories/search→ List[Memory] - List all:
GET /v1/memories→ List[Memory]
Graph Extensions:
- Add relationship:
POST /v1/memories/{id}/relationships→ Relationship - Get related:
GET /v1/memories/{id}/related→ List[Memory] - Get graph:
GET /v1/memories/graph→ Graph
3.3 Example Usage / Output
import httpx
# Mem0-compatible API
client = httpx.Client(base_url="http://localhost:8000")
# Add memory
response = client.post("/v1/memories", json={
"content": "User prefers Python for scripting",
"user_id": "user_123",
"metadata": {"category": "language_preference", "confidence": 0.9}
})
memory = response.json()
print(memory)
# {"id": "mem_abc", "content": "...", "created_at": "...", ...}
# Search memories
response = client.post("/v1/memories/search", json={
"query": "programming language preferences",
"user_id": "user_123",
"limit": 5
})
results = response.json()
for mem in results["memories"]:
print(f"[{mem['score']:.2f}] {mem['content']}")
# [0.92] User prefers Python for scripting
# [0.78] User knows JavaScript
# Graph extension: Add relationship
response = client.post(f"/v1/memories/{memory['id']}/relationships", json={
"target_id": "mem_xyz",
"relation": "related_to",
"metadata": {"context": "both about coding preferences"}
})
# Graph extension: Get related memories
response = client.get(f"/v1/memories/{memory['id']}/related", params={
"depth": 2,
"relation": "related_to"
})
related = response.json()
for mem in related["memories"]:
print(f" → {mem['content']} (via {mem['relation']})")
# Graph extension: Get memory graph
response = client.get("/v1/memories/graph", params={
"user_id": "user_123",
"limit": 100
})
graph = response.json()
print(f"Nodes: {len(graph['nodes'])}, Edges: {len(graph['edges'])}")
4. Solution Architecture
4.1 High-Level Design
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ FastAPI │────▶│ Memory │────▶│ Storage │
│ Router │ │ Service │ │ Layer │
└───────────────┘ └───────────────┘ └───────────────┘
│ │ │
│ │ ┌──────┴──────┐
│ │ │ │
│ │ ▼ ▼
│ │ ┌─────────┐ ┌─────────┐
│ │ │ Vector │ │ Graph │
│ │ │ Store │ │ Store │
│ │ └─────────┘ └─────────┘
│ │
▼ ▼
┌───────────────┐ ┌───────────────┐
│ Auth │ │ Embedder │
│ Middleware │ │ │
└───────────────┘ └───────────────┘
4.2 Key Components
| Component | Responsibility | Technology |
|---|---|---|
| FastAPI Router | HTTP endpoints | FastAPI |
| Auth Middleware | API key validation, user isolation | Custom |
| Memory Service | CRUD operations, deduplication | Python class |
| Graph Service | Relationship management | Python class |
| Vector Store | Embedding storage and search | ChromaDB |
| Graph Store | Relationship storage | SQLite (can upgrade to Neo4j) |
| Embedder | Text → vector | sentence-transformers |
4.3 Data Models
from pydantic import BaseModel
from datetime import datetime
from typing import Literal
class MemoryCreate(BaseModel):
content: str
user_id: str
agent_id: str | None = None
session_id: str | None = None
metadata: dict = {}
class Memory(BaseModel):
id: str
content: str
user_id: str
agent_id: str | None
session_id: str | None
metadata: dict
created_at: datetime
updated_at: datetime
class MemorySearchRequest(BaseModel):
query: str
user_id: str
limit: int = 10
threshold: float = 0.7
class RelationshipCreate(BaseModel):
target_id: str
relation: str
metadata: dict = {}
valid_from: datetime | None = None
valid_to: datetime | None = None
class GraphResponse(BaseModel):
nodes: list[Memory]
edges: list[dict]
5. Implementation Guide
5.1 Development Environment Setup
mkdir mem0g-service && cd mem0g-service
python -m venv .venv && source .venv/bin/activate
pip install fastapi uvicorn chromadb sentence-transformers pydantic sqlalchemy
5.2 Project Structure
mem0g-service/
├── src/
│ ├── main.py # FastAPI app
│ ├── routers/
│ │ ├── memories.py # Memory CRUD endpoints
│ │ └── graph.py # Graph extension endpoints
│ ├── services/
│ │ ├── memory.py # Memory service
│ │ └── graph.py # Graph service
│ ├── storage/
│ │ ├── vector.py # ChromaDB wrapper
│ │ └── graph.py # SQLite graph store
│ ├── models.py # Pydantic models
│ └── auth.py # API key middleware
├── tests/
│ ├── test_memories.py
│ └── test_graph.py
├── docker-compose.yml
└── README.md
5.3 Implementation Phases
Phase 1: Mem0-Compatible CRUD (8-10h)
Goals:
- Basic memory CRUD working
- Vector search implemented
Tasks:
- Set up FastAPI with router structure
- Implement ChromaDB vector store
- Build memory service with CRUD
- Add search endpoint with similarity
Checkpoint: Can create, read, search memories.
Phase 2: Multi-User and Auth (6-8h)
Goals:
- User isolation enforced
- API key authentication
Tasks:
- Add auth middleware
- Implement user_id filtering
- Add rate limiting
- Test isolation between users
Checkpoint: Users cannot access each other’s memories.
Phase 3: Graph Extensions (8-10h)
Goals:
- Relationship CRUD working
- Graph queries implemented
Tasks:
- Build SQLite graph store
- Implement relationship endpoints
- Add graph traversal queries
- Build graph export endpoint
Checkpoint: Full graph functionality alongside Mem0 API.
6. Testing Strategy
6.1 Test Categories
| Category | Purpose | Examples |
|---|---|---|
| Unit | Test services | Memory CRUD logic |
| Integration | Test API endpoints | HTTP request/response |
| Security | Test isolation | Cross-user access attempts |
6.2 Critical Test Cases
- CRUD cycle: Create → Read → Update → Delete
- Search accuracy: Query returns relevant memories
- User isolation: User A cannot see User B’s memories
- Graph integrity: Relationships survive memory updates
7. Common Pitfalls & Debugging
| Pitfall | Symptom | Solution |
|---|---|---|
| Missing user_id filter | Cross-user data leak | Add to ALL queries |
| Embedding mismatch | Search returns wrong results | Check embedder consistency |
| Orphan relationships | Deleted memory has dangling edges | Cascade delete relationships |
| Slow search | High latency | Add vector index, limit results |
8. Extensions & Challenges
8.1 Beginner Extensions
- Add memory categories/tags
- Implement memory export/import
8.2 Intermediate Extensions
- Add memory deduplication
- Implement temporal decay
8.3 Advanced Extensions
- Add real-time sync (WebSocket)
- Implement distributed storage
9. Real-World Connections
9.1 Industry Applications
- Mem0 Cloud: The production Mem0 service
- Custom Assistants: Memory layer for any LLM app
- Multi-tenant SaaS: Per-user knowledge storage
9.2 Interview Relevance
- Explain vector vs graph storage tradeoffs
- Discuss multi-tenant isolation strategies
- Describe API versioning and compatibility
10. Resources
10.1 Essential Reading
- Mem0 Documentation — https://docs.mem0.ai
- FastAPI Documentation — API design patterns
- ChromaDB Documentation — Vector storage
10.2 Related Projects
- Previous: Project 9 (Graphiti Integration)
- Next: Project 11 (MemGPT Virtual Context)
11. Self-Assessment Checklist
- I can implement Mem0-compatible API endpoints
- I understand multi-tenant data isolation
- I can extend the API with graph capabilities
- I know how to test API security
12. Submission / Completion Criteria
Minimum Viable Completion:
- Mem0-compatible CRUD endpoints
- Vector search working
- User isolation enforced
Full Completion:
- Graph relationship extensions
- API key authentication
- Full test coverage
Excellence:
- Memory deduplication
- Temporal queries
- Production deployment ready