Skip to main content

Deterministic, policy-driven memory management for AI agents

Project description

๐Ÿง  Memoric

Policy-Driven, Deterministic Memory Framework for AI Agents

Python Version License Status Code Quality Security

Give your AI agents structured, explainable, and persistent memory โ€” without the black box.

Features โ€ข Installation โ€ข Quick Start โ€ข Documentation โ€ข Architecture โ€ข Security


๐ŸŽฏ Overview

Memoric is an open-source Python framework that provides a robust, deterministic memory layer for AI agents. It helps AI teams deploy agents with long-term, rule-based memory, structured by metadata, organized by tiers, and retrievable through policy-driven scoring.

Instead of relying solely on vector embeddings or opaque similarity searches, Memoric focuses on structure, transparency, and control. Every stored memory is traceable, explainable, and policy-governed โ€” enabling predictable, high-relevance recall for any AI system.

๐Ÿ† Production Ready Score: 8.95/10


โœจ Key Features

๐ŸŽฏ Deterministic Retrieval

Retrieve memories using metadata, recency, and importance โ€” not fuzzy vector magic. Every decision is explainable.

๐Ÿ”„ Multi-Tier Memory

Short-term, mid-term, and long-term tiers evolve your memory over time automatically with policy-driven transitions.

๐Ÿงต Multi-Threaded Isolation

Maintain separate memory threads (e.g., different chat topics) under one user while preserving cross-thread relevance.

๐Ÿ”’ Enterprise Security

JWT authentication, RBAC, encryption at rest, comprehensive audit logging, and compliance support (SOC2, GDPR, HIPAA).

๐Ÿค– AI-Powered Metadata

Automatic metadata extraction (topics, categories, entities, sentiment, importance) via integrated LLM agent.

๐Ÿ“‹ Policy-Driven YAML

Define memory rules, expiry, routing, and scoring in one clean, version-controlled YAML file.

๐Ÿ˜ PostgreSQL Backend

Proven, efficient, and enterprise-grade database with ready-to-use schemas and indexes.

๐Ÿ”— Framework-Agnostic

Works seamlessly with LangChain, LlamaIndex, or any custom LLM pipeline. Drop-in integration.


๐Ÿš€ Installation

Option 1: Install from PyPI (Recommended)

pip install memoric

Option 2: Install from Source

# Clone the repository
git clone https://github.com/cyberbeamhq/memoric.git
cd memoric

# Install in development mode
pip install -e .

Option 3: Install with Extras

# All optional dependencies
pip install memoric[all]

# Specific extras
pip install memoric[llm]      # OpenAI integration
pip install memoric[metrics]  # Prometheus metrics
pip install memoric[dev]      # Development tools

Requirements

  • Python 3.9+
  • PostgreSQL 12+ (recommended) or SQLite (development)

โšก Quick Start

1๏ธโƒฃ Create Configuration File (Optional)

Create a config.yaml file to customize behavior:

# Storage configuration
storage:
  tiers:
    - name: short_term
      backend: sqlite
      dsn: "sqlite:///memoric_short.db"
      expiry_days: 7
    - name: mid_term
      backend: sqlite
      dsn: "sqlite:///memoric_mid.db"
      expiry_days: 90
    - name: long_term
      backend: postgres
      dsn: "postgresql://user:pass@localhost/memoric"
      expiry_days: 365

# Metadata enrichment (requires OpenAI API key)
metadata:
  enrichment:
    model: gpt-4o-mini
    enabled: true

# Memory retrieval settings
recall:
  scope: thread  # Options: thread | topic | user | global
  default_top_k: 10
  fallback_order: [thread, topic, user]

# Scoring weights
scoring:
  importance_weight: 0.6
  recency_weight: 0.3
  repetition_weight: 0.1

# Privacy settings
privacy:
  enforce_user_scope: true
  allow_shared_namespace: false

Note: Memoric works out-of-the-box with SQLite. The config file is optional for customization.

2๏ธโƒฃ Initialize Memoric

from memoric import Memoric

# Initialize with config
mem = Memoric(config_path="config.yaml")

# Or use environment variables
mem = Memoric()

3๏ธโƒฃ Store Memories

# Save a user message with automatic metadata extraction
memory_id = mem.save(
    user_id="U-123",
    thread_id="T-Refunds",
    content="I still haven't received my refund for order #1049.",
    session_id="S-456"
)
print(f"Memory saved with ID: {memory_id}")

What happens automatically:

  • ๐Ÿค– Content enriched with AI-extracted metadata (topic, category, entities, importance)
  • ๐Ÿ“Š Routed to appropriate tier based on policies (e.g., short_term)
  • ๐Ÿ’พ Stored in PostgreSQL with all metadata
  • ๐Ÿ” Indexed for fast retrieval

4๏ธโƒฃ Retrieve Memories

# Retrieve relevant memories
memories = mem.retrieve(
    user_id="U-123",
    thread_id="T-Refunds",
    top_k=10
)

# Display results
for memory in memories:
    print(f"Score: {memory['_score']}, Content: {memory['content']}")

Example Output:

[
    {
        "id": 42,
        "user_id": "U-123",
        "thread_id": "T-Refunds",
        "content": "I still haven't received my refund for order #1049.",
        "metadata": {
            "topic": "refunds",
            "category": "customer_support",
            "importance": "high",
            "entities": ["order #1049"]
        },
        "tier": "short_term",
        "_score": 85.3,
        "created_at": "2025-10-30T10:30:00Z"
    },
    # ... more memories
]

The list of memories can be formatted and injected into your LLM's context window.


๐Ÿ—๏ธ Architecture

graph TD
    A[User/AI Agent] --> B[Metadata Agent]
    B --> C[Memory Router]
    C --> D[PostgreSQL Store]
    D --> E[Retriever + Scorer]
    E --> F[LLM/Agent]

    style A fill:#e1f5ff
    style B fill:#fff4e1
    style C fill:#ffe1f5
    style D fill:#e1ffe1
    style E fill:#f5e1ff
    style F fill:#ffe1e1

Core Components

Component Purpose Technology
Metadata Agent AI-powered metadata extraction OpenAI API / Custom LLM
Memory Router Policy-driven tier assignment Rule engine (YAML config)
PostgreSQL Store Persistent, indexed storage PostgreSQL + SQLAlchemy
Retriever Deterministic memory search Metadata filtering + scoring
Scorer Rank memories by importance/recency Configurable scoring engine

Each layer is modular, configurable, and easy to extend.


๐Ÿงฑ Multi-Tier Memory System

Memoric organizes memories into tiers, each with its own lifecycle:

Tier Lifetime Behavior Purpose
Short-Term Days Raw, recent data Immediate recall
Mid-Term Weeksโ€“Months Trimmed, compact Ongoing relevance
Long-Term Monthsโ€“Years Clustered, summarized Historical continuity

Memory Evolution Example

Day 1   โ†’ ๐Ÿ’พ Stored in short_term (full detail)
Day 8   โ†’ ๐Ÿ”„ Moved to mid_term (trimmed)
Day 100 โ†’ ๐Ÿ“š Moved to long_term (clustered by topic)

Tier transitions are deterministic and follow your YAML policy.


๐Ÿงต Multi-Threaded Memory

Memoric natively supports multi-threaded memory โ€” ideal for agents handling multiple topics or chat sessions with the same user.

Thread Hierarchy

User: U-123
 โ”œโ”€โ”€ Thread: T-Refunds
 โ”‚    โ”œโ”€โ”€ Message 1: "Where's my refund?"
 โ”‚    โ”œโ”€โ”€ Message 2: "It's been two weeks."
 โ”‚    โ””โ”€โ”€ Message 3: "Still waiting..."
 โ”œโ”€โ”€ Thread: T-Shipping
 โ”‚    โ”œโ”€โ”€ Message 1: "When will my package arrive?"
 โ”‚    โ””โ”€โ”€ Message 2: "Is it shipped yet?"
 โ””โ”€โ”€ Thread: T-Technical
      โ””โ”€โ”€ Message 1: "How do I reset my password?"

Thread Features

Feature Description
Thread Isolation Each conversation has its own memory timeline
Thread Linking Link threads with related topics or entities
Cross-Thread Recall Optionally fetch related past experiences
Thread Summarization Old threads summarized and archived
Concurrent Safety PostgreSQL ensures thread-safe operations

Thread Management Example

# Save messages in different threads
mem.save(user_id="U-123", thread_id="T-Refunds",
         message="Still no refund yet.")
mem.save(user_id="U-123", thread_id="T-Shipping",
         message="When will my package arrive?")

# Retrieve thread-specific memory
refund_context = mem.retrieve(user_id="U-123", thread_id="T-Refunds")
shipping_context = mem.retrieve(user_id="U-123", thread_id="T-Shipping")

๐Ÿงฎ Scoring System

Each memory is ranked deterministically using configurable weights:

score = (importance ร— 0.6) + (recency ร— 0.3) + (repetition ร— 0.1)

Customizable Weights

retrieval:
  scoring:
    importance: 0.6   # How critical is this memory?
    recency: 0.3      # How recent is it?
    repetition: 0.1   # How often is it mentioned?

All scoring formulas are fully transparent and adjustable.


๐Ÿ”’ Security Features

๐Ÿ† Security Score: 8/10 (Production Grade)

๐Ÿ” Authentication & Authorization

  • โœ… JWT-based authentication (HS256)
  • โœ… Role-Based Access Control (RBAC)
  • โœ… Secure password hashing (Bcrypt)
  • โœ… API key management
  • โœ… Token refresh & revocation

๐Ÿ›ก๏ธ Data Protection

  • โœ… Encryption at rest (Fernet/AES-128)
  • โœ… Encrypted sensitive fields
  • โœ… SQL injection protection (SQLAlchemy ORM)
  • โœ… XSS protection (Pydantic validation)

๐Ÿ“ Audit & Compliance

  • โœ… Comprehensive audit logging (30+ event types)
  • โœ… Compliance support (SOC2, GDPR, HIPAA, PCI-DSS)
  • โœ… IP address & user agent tracking
  • โœ… Before/after state capture
  • โœ… Security event detection

๐Ÿฅ Health Monitoring

  • โœ… Liveness probes (Kubernetes-ready)
  • โœ… Readiness probes
  • โœ… Resource monitoring (CPU, memory, disk)
  • โœ… Database health checks

Security Quick Start

from memoric.api import create_app

# Create secure API with authentication
app = create_app(
    enable_auth=True,      # JWT authentication
    enable_audit=True,     # Audit logging
    secret_key="your-secret-key"
)

See SECURITY_IMPLEMENTATION_COMPLETE.md for full details.


๐Ÿ”Œ Framework Integration

LangChain Integration

from memoric.integrations.langchain.memory import MemoricMemory
from langchain.agents import AgentExecutor

# Use Memoric as LangChain memory backend
memory = MemoricMemory(
    user_id="user-123",
    thread_id="conversation-1",
    k=10  # Number of memories to retrieve
)

agent = AgentExecutor(
    llm=your_llm,
    memory=memory,
    # ... other config
)

Custom Integration

# Direct API usage
from memoric import Memoric

class MyAgent:
    def __init__(self, user_id: str, thread_id: str):
        self.memory = Memoric()
        self.user_id = user_id
        self.thread_id = thread_id

    def process(self, user_input: str):
        # Retrieve relevant memories
        memories = self.memory.retrieve(
            user_id=self.user_id,
            thread_id=self.thread_id,
            top_k=10
        )

        # Format context for LLM
        context = "\n".join([m["content"] for m in memories])

        # Generate response with context
        response = self.llm.generate(f"Context:\n{context}\n\nQuery: {user_input}")

        # Store the interaction
        self.memory.save(
            user_id=self.user_id,
            thread_id=self.thread_id,
            content=user_input
        )

        return response

Framework-Agnostic Pattern

from memoric import Memoric

mem = Memoric()

# Save memories
mem.save(user_id="user-1", thread_id="chat-1", content="User question")
mem.save(user_id="user-1", thread_id="chat-1", content="Agent response")

# Retrieve for context
memories = mem.retrieve(user_id="user-1", thread_id="chat-1", top_k=5)

# Use with any LLM framework (OpenAI, Anthropic, etc.)
context = "\n".join([m["content"] for m in memories])

๐Ÿงฐ Developer API

Core Methods

Method Description Example
mem.save() Store a memory mem.save(user_id="U-1", content="Hello")
mem.retrieve() Retrieve memories mem.retrieve(user_id="U-1", top_k=10)
mem.run_policies() Execute tier transitions mem.run_policies()
mem.inspect() Debug memory system mem.inspect()
mem.rebuild_clusters() Rebuild topic clusters mem.rebuild_clusters(user_id="U-1")
mem.get_topic_clusters() Get topic clusters mem.get_topic_clusters(user_id="U-1")

API Reference

save() - Store a Memory

memory_id = mem.save(
    user_id="user-123",           # Required: User identifier
    content="Meeting notes...",   # Required: Memory content
    thread_id="thread-abc",       # Optional: Thread/conversation ID
    session_id="session-xyz",     # Optional: Session identifier
    metadata={"custom": "data"},  # Optional: Additional metadata
    namespace="team-alpha"        # Optional: Namespace for multi-tenancy
)
# Returns: int (memory ID)

retrieve() - Get Memories

memories = mem.retrieve(
    user_id="user-123",                    # Filter by user
    thread_id="thread-abc",                # Filter by thread
    metadata_filter={"topic": "refunds"},  # Filter by metadata
    scope="thread",                        # Scope: thread|topic|user|global
    top_k=10,                              # Max results
    namespace="team-alpha"                 # Filter by namespace
)
# Returns: List[Dict[str, Any]]

Other Methods

# Run policy-based tier transitions
mem.run_policies()

# Inspect memory system state
info = mem.inspect()
# Returns: {"config": {...}, "db_table": "memories", "counts_by_tier": {...}}

# Rebuild topic clusters for a user
cluster_count = mem.rebuild_clusters(user_id="user-123")

# Get topic clusters
clusters = mem.get_topic_clusters(
    user_id="user-123",
    topic="sales",      # Optional filter
    category="meeting", # Optional filter
    limit=100
)

๐Ÿ“Š Database Schema

Memory Table

CREATE TABLE memories (
    id SERIAL PRIMARY KEY,
    user_id TEXT NOT NULL,
    thread_id TEXT,
    session_id TEXT,
    content TEXT NOT NULL,
    metadata JSONB,
    tier TEXT DEFAULT 'short_term',
    importance_score FLOAT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_memories_user_thread ON memories(user_id, thread_id);
CREATE INDEX idx_memories_tier ON memories(tier);
CREATE INDEX idx_memories_created ON memories(created_at DESC);

Cluster Table

CREATE TABLE memory_clusters (
    id SERIAL PRIMARY KEY,
    user_id TEXT NOT NULL,
    topic TEXT NOT NULL,
    entities JSONB,
    summary TEXT,
    memory_ids JSONB,
    occurrences INT DEFAULT 0,
    first_seen TIMESTAMP,
    last_seen TIMESTAMP,
    UNIQUE(user_id, topic, category)
);

Full schema: memoric/db/schema.py


๐ŸŽจ Design Philosophy

โœ… Core Principles

  • Deterministic by Default โ€“ Every action is explainable
  • Metadata-First Design โ€“ Structure before embeddings
  • Policy-Driven Logic โ€“ YAML-defined behavior
  • Simple, Composable Python โ€“ No bloat
  • Thread-Safe & Scalable โ€“ PostgreSQL transactions

๐ŸŽฏ Design Goals

  • Transparency over black boxes
  • Explainability for all decisions
  • Enterprise-grade reliability
  • Developer-friendly APIs
  • Production-ready from day one

๐Ÿ“š Documentation

Document Description
AUTHENTICATION_GUIDE.md Complete JWT & RBAC guide
AUDIT_LOGGING_COMPLETE.md Audit system documentation
SECURITY_IMPLEMENTATION_COMPLETE.md Security features overview
COMPREHENSIVE_REVIEW.md Full system review (8.95/10)
INSTALLATION.md Detailed setup instructions

๐Ÿงช Testing

Run Tests

# Install dev dependencies
pip install memoric[dev]

# Run all tests
pytest

# Run with coverage
pytest --cov=memoric --cov-report=html

# Run specific test suite
pytest tests/test_authentication.py
pytest tests/test_audit_logging.py

Test Coverage

โœ… Unit Tests: 100+ tests
โœ… Integration Tests: 15/15 passed
โœ… Security Tests: All passed
โœ… Database Tests: All passed
โœ… API Tests: All passed

๐Ÿšฆ Production Checklist

Before Deploying

  • Set production secrets (JWT, encryption keys)
  • Configure PostgreSQL database
  • Enable HTTPS (nginx/Caddy)
  • Set CORS origins
  • Configure environment variables
  • Set up monitoring (Prometheus)
  • Configure audit log retention
  • Review security settings

Environment Variables

# Required
export MEMORIC_DB_HOST="your-db-host"
export MEMORIC_DB_USER="memoric"
export MEMORIC_DB_PASSWORD="your-secure-password"
export MEMORIC_JWT_SECRET="$(python -c 'import secrets; print(secrets.token_hex(64))')"
export MEMORIC_ENCRYPTION_KEY="$(python -c 'from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())')"

# Optional
export MEMORIC_LOG_LEVEL="INFO"
export MEMORIC_CORS_ORIGINS="https://yourdomain.com"
export MEMORIC_RATE_LIMIT="100/minute"

๐Ÿค Contributing

We welcome contributions from AI engineers, researchers, and developers!

How to Contribute

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Development Setup

# Clone your fork
git clone https://github.com/YOUR_USERNAME/memoric.git
cd memoric

# Install in editable mode with dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Format code
black memoric tests

Contribution Guidelines

  • Follow PEP 8 style guide
  • Add tests for new features
  • Update documentation
  • Write clear commit messages

๐Ÿ“ˆ Roadmap

Version 0.2.0 (Q4 2025)

  • Async database support (asyncpg)
  • Redis caching layer
  • Rate limiting middleware
  • Email verification
  • Password reset flow

Version 0.3.0 (Q1 2026)

  • OAuth integration
  • Multi-factor authentication
  • Admin dashboard
  • Performance optimization
  • Multi-database support

Version 1.0.0 (Q2 2026)

  • Enterprise features
  • Advanced analytics
  • Custom embedding models
  • Distributed deployment
  • Cloud-native features

๐Ÿ›ก๏ธ License

Apache License 2.0 โ€“ Free for personal, commercial, and research use.

See LICENSE file for details.


๐Ÿ‘ฅ Team & Support

Maintainers

Built with โค๏ธ by:

Support


โญ Show Your Support

If you find Memoric useful, please consider:

  • โญ Starring the repository
  • ๐Ÿ› Reporting bugs
  • ๐Ÿ’ก Suggesting features
  • ๐Ÿ“– Improving documentation
  • ๐Ÿค Contributing code

๐Ÿš€ Memoric โ€” Bring Structure, Persistence, and Reasoning to Your AI's Memory

Get Started โ€ข View Docs โ€ข Join Community


Made with ๐Ÿง  by the Memoric Team | Website | GitHub

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

memoric-0.1.0.tar.gz (105.2 kB view details)

Uploaded Source

Built Distribution

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

memoric-0.1.0-py3-none-any.whl (90.6 kB view details)

Uploaded Python 3

File details

Details for the file memoric-0.1.0.tar.gz.

File metadata

  • Download URL: memoric-0.1.0.tar.gz
  • Upload date:
  • Size: 105.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.12

File hashes

Hashes for memoric-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ee52a7f83f9b92d23982437b4f3ef4198c8f0be514ec1ce1639e49f49031b07c
MD5 c4cbd3f83c7e40a59f746d47c9eecfe1
BLAKE2b-256 bb1c1c60c2d3da92bb708a05b2b909d0f3824bbfb84fab17ac88115279abfacf

See more details on using hashes here.

File details

Details for the file memoric-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: memoric-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 90.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.12

File hashes

Hashes for memoric-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 eea587862d78cf94396ed7b0d5f664dfcd7e66306204a3d046c52eb125defaf3
MD5 c59015c2345084c76fcb357b0d78771a
BLAKE2b-256 c9f5ace909466b0dcf2bcd9fd42a00fedec4bb7d20319c56b8b6d099f08e10b0

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