Deterministic, policy-driven memory management for AI agents
Project description
๐ง Memoric
Policy-Driven, Deterministic Memory Framework for AI Agents
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.
โจ Key Features
๐ 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 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
๐ 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
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - 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:
- Muthanna Al-Faris โ Creator & Lead Developer
- Part of Nuzum Technologies's open AI infrastructure initiative
Support
- ๐ Documentation: docs.memoric.dev
- ๐ฌ Discussions: GitHub Discussions
- ๐ Issues: GitHub Issues
- ๐ง Email: support@memoric.dev
โญ 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
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ee52a7f83f9b92d23982437b4f3ef4198c8f0be514ec1ce1639e49f49031b07c
|
|
| MD5 |
c4cbd3f83c7e40a59f746d47c9eecfe1
|
|
| BLAKE2b-256 |
bb1c1c60c2d3da92bb708a05b2b909d0f3824bbfb84fab17ac88115279abfacf
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eea587862d78cf94396ed7b0d5f664dfcd7e66306204a3d046c52eb125defaf3
|
|
| MD5 |
c59015c2345084c76fcb357b0d78771a
|
|
| BLAKE2b-256 |
c9f5ace909466b0dcf2bcd9fd42a00fedec4bb7d20319c56b8b6d099f08e10b0
|