Skip to main content

Semantic memory layer for AI applications with vector storage and LLM-based extraction

Project description

Longterm AI Memory

A semantic longeterm AI memory layer for Agentic AI applications that remembers context across conversations.

PyPI version Python 3.8+ License: MIT


What It Does

Most AI assistants forget everything between sessions. This SDK solves that by extracting factual information from conversations, storing it as searchable vector embeddings, and retrieving relevant context when needed.

Your AI can reference things users mentioned weeks ago without them repeating themselves.

Example:

from longterm_ai_memory import Memory

memory = Memory(user_id="user-123")

# Store information
memory.add("My name is Sarah and I work at Google")
memory.add("I'm allergic to shellfish")

# Search later
results = memory.search("what are my dietary restrictions?")
# Returns: "User is allergic to shellfish"

Installation

pip install longterm_ai_memory

Requirements:

  • Python 3.8+
  • Pinecone account (free tier available)
  • OpenRouter API key (for cloud LLM) OR Ollama installed (for local LLM)

Quick Start

1. Set Up Environment

Create a .env file:

PINECONE_API_KEY=your_pinecone_key_here
OPENROUTER_API_KEY=your_openrouter_key  # only if using cloud LLM

2. Basic Usage

from longterm_ai_memory import Memory
import os
from dotenv import load_dotenv

load_dotenv()

# Initialize with cloud LLM (OpenRouter)
memory = Memory(
    user_id="demo-user",
    pinecone_api_key=os.getenv("PINECONE_API_KEY"),
    openrouter_api_key=os.getenv("OPENROUTER_API_KEY"),
    use_local_llm=False
)

# OR initialize with local LLM (Ollama - free)
memory = Memory(
    user_id="demo-user",
    pinecone_api_key=os.getenv("PINECONE_API_KEY"),
    use_local_llm=True
)

# Add memories
memory.add("My name is Alex and I work at Microsoft")
memory.add("I love playing tennis on weekends")

# Search memories
results = memory.search("what's my name?")
for result in results:
    print(f"{result['metadata']['memory']} (score: {result['score']:.2f})")

# Get all memories
all_memories = memory.get_all()

# Delete all memories
memory.delete_all()

How It Works

User Message → LLM Extraction → Vector Embedding → Pinecone Storage
                    ↓                    ↓                ↓
          Filters noise,        multilingual-e5    Namespaced
          converts to 3rd person                    by user_id
            
Search Query → Vector Embedding → Semantic Search → Ranked Results

Key Features:

  • Automatic fact extraction - LLM converts conversations to factual statements
  • Semantic search - Find memories by meaning, not just keywords
  • Multi-tenant - Each user gets isolated storage namespace
  • Noise filtering - Ignores "okay", "cool", conversational filler
  • Local or cloud LLM - Use free Ollama or pay-per-use OpenRouter
  • Category auto-assignment - Memories tagged with relevant categories

API Reference

Initialization

Memory(
    user_id: str,                    # Required: unique user identifier
    pinecone_api_key: str,           # Required: Pinecone API key
    openrouter_api_key: str = None,  # Required if use_local_llm=False
    use_local_llm: bool = True,      # True=Ollama, False=OpenRouter
    local_llm_model: str = "phi3:mini",  # Ollama model name
    skip_health_check: bool = False  # Skip startup validation
)

add(user_message, categories=None)

Store a new memory from user message.

result = memory.add("My favorite food is sushi")
# Returns: {"id": "...", "memory": "User's favorite food is sushi", "metadata": {...}}

# Noise filtered → returns None
result = memory.add("okay cool")  # None

Parameters:

  • user_message (str): User's message to extract memory from
  • categories (list, optional): Manual category override (not recommended)

Returns: Dict with memory data or None if no factual content found.

search(query, top_k=5, filter=None)

Search for relevant memories using semantic similarity.

results = memory.search("what do I like to eat?", top_k=3)

# With category filter
results = memory.search("work info", filter={"categories": "work"})

Parameters:

  • query (str): Natural language search query
  • top_k (int): Maximum results to return (1-20, default: 5)
  • filter (dict, optional): Metadata filter

Returns: List of dicts with id, score, and metadata fields, sorted by relevance.

get_all(filter=None)

Retrieve all memories for the current user.

all_memories = memory.get_all()

# With filter
work_memories = memory.get_all(filter={"categories": "work"})

Returns: List of all memories (up to 10,000).

list(limit=100)

Quick way to get recent memories.

recent = memory.list(limit=20)

delete_all()

Delete all memories for the current user.

success = memory.delete_all()  # Returns True if successful

Warning: No undo. Use with caution.


Local LLM Setup (Free Alternative)

Install Ollama for free local LLM inference:

# macOS/Linux
curl -fsSL https://ollama.com/install.sh | sh

# Pull a model
ollama pull phi3:mini

# Start server (runs in background)
ollama serve

Supported models:

  • phi3:mini (recommended, 3.8GB)
  • gemma2:2b (lightweight, 1.6GB)
  • llama3:8b (more capable, 4.7GB)

Then initialize with use_local_llm=True.


Configuration

Customize behavior by modifying config.py:

# Search similarity threshold (0.0-1.0)
SEARCH_CONFIG = {
    "similarity_threshold": 0.7,  # Higher = stricter matching
    "default_top_k": 5
}

# Memory categories (auto-assigned by LLM)
MEMORY_CATEGORIES = [
    "work", "personal", "health", "preferences",
    "family", "education", "hobbies", "misc"
]

# LLM models
LOCAL_LLM_CONFIG = {
    "extraction_model": "phi3:mini",
    "base_url": "http://localhost:11434"
}

OPENROUTER_CONFIG = {
    "extraction_model": "google/gemma-2-9b-it:free"
}

Use Cases

Chatbot with Memory

def chatbot_with_memory(user_message):
    # 1. Search for relevant context
    context = memory.search(user_message, top_k=3)
    
    # 2. Build prompt with context
    context_text = " | ".join([m['metadata']['memory'] for m in context])
    prompt = f"Context: {context_text}\n\nUser: {user_message}"
    
    # 3. Generate response with your LLM
    response = your_llm.generate(prompt)
    
    # 4. Store new information
    memory.add(user_message)
    
    return response

Personal Assistant

# Store user preferences
memory.add("I prefer emails over phone calls")
memory.add("My meetings are usually in the mornings")

# Later, retrieve context for scheduling
prefs = memory.search("communication and scheduling preferences")

Customer Support

# Store customer information
memory.add("Customer is on enterprise plan")
memory.add("Customer's primary use case is data analytics")

# Retrieve during support conversations
customer_info = memory.search("plan and use case")

Architecture

Components:

  • Memory (core) - Main orchestrator, handles all operations
  • MemoryExtractor - LLM-based extraction (Ollama or OpenRouter)
  • VectorStore - Pinecone backend with namespace isolation
  • EmbeddingProvider - Pinecone inference API for embeddings
  • MetadataGenerator - Temporal + categorical metadata

Storage:

  • Each user gets isolated namespace in Pinecone
  • Embeddings: 1024-dimensional vectors (multilingual-e5-large)
  • Metadata: categories, timestamps, temporal fields (day, month, quarter, etc.)

Advanced Features

Time-Based Filtering

from datetime import datetime

# Get memories from this year
all_memories = memory.get_all()
this_year = datetime.now().year
recent = [m for m in all_memories if m['metadata']['year'] == this_year]

# Weekend memories
weekend = [m for m in all_memories if m['metadata']['is_weekend']]

Batch Operations

messages = [
    "I graduated from Stanford in 2020",
    "My favorite food is sushi",
    "I have two cats named Luna and Mochi"
]

for msg in messages:
    result = memory.add(msg)
    if result:
        print(f"Stored: {result['memory']}")

Error Handling

from longterm_ai_memory import ValidationError, MemoryError

try:
    result = memory.add(user_message)
except ValidationError as e:
    print(f"Invalid input: {e}")
except MemoryError as e:
    print(f"Operation failed: {e}")

Limitations

  • Memory updates require delete + add (no direct update operation)
  • Conversation threading not implemented
  • Storage backend limited to Pinecone (no ChromaDB/Qdrant support yet)
  • Batch operations not optimized for high-volume scenarios
  • Maximum 10,000 memories per user via get_all() (pagination needed for more)

Roadmap

Planned improvements:

  • Additional storage backends (ChromaDB, Qdrant, Weaviate)
  • Conversation context tracking
  • Enhanced category inference
  • Memory importance scoring
  • Temporal decay for older memories

Contributing

Contributions welcome! Areas needing work:

  • Additional storage backends
  • Better category inference
  • Memory deduplication
  • Conversation threading
  • Performance optimization

License

MIT License - See LICENSE for details.


Links


Questions or feedback? Open an issue on GitHub or reach out on LinkedIn.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

longterm_ai_memory-0.1.2.tar.gz (21.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

longterm_ai_memory-0.1.2-py3-none-any.whl (22.7 kB view details)

Uploaded Python 3

File details

Details for the file longterm_ai_memory-0.1.2.tar.gz.

File metadata

  • Download URL: longterm_ai_memory-0.1.2.tar.gz
  • Upload date:
  • Size: 21.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for longterm_ai_memory-0.1.2.tar.gz
Algorithm Hash digest
SHA256 3d295a06843fbb6e08310157425f3d9b25be5a7f47b39479e3a3aeac97c37a2c
MD5 a243e5a166fc9c7d51d6ca1f90ca16ab
BLAKE2b-256 1d2e16fd5c28ebdcde23372e03117af33aeaeecf4ba58dfb2ef93b6b0a26c586

See more details on using hashes here.

File details

Details for the file longterm_ai_memory-0.1.2-py3-none-any.whl.

File metadata

File hashes

Hashes for longterm_ai_memory-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 7d74e65cb7377c83dc5336f928c47b794213a4cd978813dca07c5868e52a2e23
MD5 61bc5994b7f8384a6735924289b44e0c
BLAKE2b-256 7aed2f5d46c9818116759cab6345e612e8a5c69169508aa6351d3a93aa559a45

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page