Ontomem
Self-consolidating semantic memory for AI agents with Pydantic schemas, intelligent deduplication, and FAISS vector search.
Install / Use
npx skills add yifanfeng97/ontomemInstalls into whichever agent you are using.
README
🧠 OntoMem: The Self-Consolidating Memory
<div align="center"> </div>OntoMem is built on the concept of Ontology Memory—structured, coherent knowledge representation for AI systems.
<p align="center"> <img src="docs/assets/fw.png" alt="OntoMem Framework Diagram" width="800" /> </p> <div align="center">Give your AI agent a "coherent" memory, not just "fragmented" retrieval.
<a href="https://pypi.org/project/ontomem/"><img src="https://img.shields.io/pypi/v/ontomem.svg" alt="PyPI version"></a> <a href="https://www.python.org/"><img src="https://img.shields.io/badge/python-3.11%2B-blue" alt="Python 3.11+"></a> <a href="https://opensource.org/licenses/Apache-2.0"><img src="https://img.shields.io/badge/License-Apache%202.0-blue.svg" alt="License: Apache 2.0"></a> <a href="https://pypi.org/project/ontomem/"><img src="https://img.shields.io/pypi/dm/ontomem.svg" alt="PyPI downloads"></a> <a href="https://yifanfeng97.github.io/ontomem/"><img src="https://img.shields.io/badge/docs-latest-green" alt="Documentation"></a>
</div>Traditional RAG (Retrieval-Augmented Generation) systems retrieve text fragments. OntoMem maintains structured entities using Pydantic schemas and intelligent merging algorithms.
It excels at Time-Series Consolidation: effortlessly merging streaming observations (like logs or chat turns) into coherent "Daily Snapshots" or "Session Summaries" simply by defining a composite key (e.g., user_id + date).
It doesn't just store data—it continuously "digests" and "organizes" it.
📰 News
<details> <summary>Details</summary>-
[2026-01-28] 🎉 v0.2.0: Lookups Feature Released:
- Multi-dimensional Indexing: Create O(1) secondary indices for fast queries by custom keys (name, location, time, etc.)
- Auto-maintained: Indices automatically update when items merge or are removed
- Memory Efficient: Stores only references (primary keys), not data copies
- Example: Build a time-series database where primary key includes timestamp, but query by character name using Lookups!
- Learn more → | 中文
-
[2026-01-21] v0.1.5 Released:
- 🎯 Production Safety: Added
max_workersparameter to control LLM batch processing concurrency - ⚡ Rate Limit Protection: Prevents hitting API rate limits from providers like OpenAI, preventing account throttling
- 🔧 Fine-Grained Control: Customize concurrency per merge strategy (default: 5 workers)
- Learn more →
- 🎯 Production Safety: Added
-
[2026-01-19] v0.1.4 Released:
- API Improvement: Renamed
merge_strategyparameter tostrategy_or_mergerfor better clarity and flexibility - Enhancement: Added
**kwargssupport to directly pass merger-specific parameters (likeruleanddynamic_ruleforCUSTOM_RULE) throughOMemwithout pre-configuration - Benefit: Cleaner API and more intuitive usage patterns for advanced merging scenarios
- Learn more →
- API Improvement: Renamed
-
[2026-01-19] v0.1.3 Released:
- New Feature: Added
MergeStrategy.LLM.CUSTOM_RULEstrategy for user-defined merge logic. Inject static rules and dynamic context (via functions) directly into the LLM merger! - Breaking Change: Renamed legacy strategies for clarity:
KEEP_OLD→KEEP_EXISTINGKEEP_NEW→KEEP_INCOMINGFIELD_MERGE→MERGE_FIELD
- Learn more about Custom Rules
- New Feature: Added
✨ Why OntoMem?
🧩 Schema-First & Type-Safe
Built on Pydantic. All memories are strongly-typed objects. Say goodbye to {"unknown": "dict"} hell and embrace IDE autocomplete and type checking.
⏱️ Temporal Consolidation (Time-Slicing)
OntoMem isn't just about ID deduplication. By using Composite Keys (e.g., lambda x: f"{x.user}_{x.date}"), you can automatically aggregate a day's worth of fragmented events into a Single Daily Record.
- Input: 1,000 fragmented logs/observations throughout the day.
- Output: 1 structured, LLM-synthesized "Daily Summary" object.
🔄 Auto-Evolution
When you insert new data about an existing entity, OntoMem doesn't create duplicates. It intelligently merges them into a Golden Record using configurable strategies (Conflict Resolution, List Appending, or LLM-powered Synthesis).
🔍 Hybrid Search
- Key-Value Lookup: O(1) exact access (e.g., "Get me Alice's summary for 2024-01-01").
- Vector Search: Semantic similarity search across your entire timeline (e.g., "When was Alice frustrated?").
🔎 Multi-Dimensional Lookups
Create secondary indices for ultra-fast queries across custom dimensions without vector overhead. Perfect for time-series data where you need both temporal and cross-sectional queries.
<details> <summary><b>Learn more about Lookups →</b></summary>Problem: If your primary key includes timestamp (for time-series), how do you query by character name?
Solution: Use Lookups for O(1) exact-match queries on any field!
# Create lookups for different dimensions
memory.create_lookup("by_character", lambda x: x.char_name)
memory.create_lookup("by_location", lambda x: x.location)
# Query - automatic sync with merges
character_events = memory.get_by_lookup("by_character", "Alice")
location_events = memory.get_by_lookup("by_location", "Kitchen")
Key Features:
- ✨ Auto-maintained: Lookups update when items merge or are removed
- ✨ Memory efficient: Stores only references, not data copies
- ✨ Consistent: Merge operations automatically sync lookups
💾 Stateful & Persistent
Save your complete memory state (structured data + vector indices) to disk and restore it in seconds on next startup.
🧠 OntoMem vs. Other Memory Systems
Most memory libraries store Raw Text or Chat History. OntoMem stores Consolidated Knowledge.
| Feature | OntoMem 🧠 | Mem0 / Zep | LangChain Memory | Vector DBs (Pinecone/Chroma) | | :--- | :--- | :--- | :--- | :--- | | Core Storage Unit | ✅ Structured Objects (Pydantic) | Text Chunks + Metadata | Raw Chat Logs | Embedding Vectors | | Data "Digestion" | ✅ Auto-Consolidation & merging | Simple Extraction | ❌ Append-only | ❌ Append-only | | Time Awareness | ✅ Time-Slicing (Daily/Session Aggregation) | ❌ Timestamp metadata only | ❌ Sequential only | ❌ Metadata filtering only | | Conflict Resolution| ✅ LLM Logic (Synthesize/Prioritize) | ❌ Last-write-wins | ❌ None | ❌ None | | Type Safety | ✅ Strict Schema | ⚠️ Loose JSON | ❌ String only | ❌ None | | Ideal For | Long-term Agent Profiles, Knowledge Graphs | Simple RAG, Search | Chatbots, Context Window | Semantic Search |
💡 The "Consolidation" Advantage
- Traditional RAG: Stores 50 chunks of "Alice likes apples", "Alice likes bananas". Search returns 50 fragments.
- OntoMem: Merges them into 1 object:
User(name="Alice", likes=["apples", "bananas"]). Search returns one complete truth.
🚀 Quick Start
Build a structured memory store in 30 seconds.
1. Define & Initialize
from pydantic import BaseModel
from ontomem import OMem
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
# 1. Define your memory schema
class UserProfile(BaseModel):
name: str
skills: list[str]
last_seen: str
# 2. Initialize with LLM merging and concurrency control (v0.1.5+)
memory = OMem(
memory_schema=UserProfile,
key_extractor=lambda x: x.name,
llm_client=ChatOpenAI(model="gpt-4o"),
embedder=OpenAIEmbeddings(),
max_workers=3 # 🆕 Control LLM batch concurrency to prevent rate limits
)
2. Add & Merge (Auto-Consolidation)
OntoMem automatically merges data for the same ID.
# First observation
memory.add(UserProfile(name="Alice", skills=["Python"], last_seen="10:00"))
# Later observation (New skill added, time updated)
memory.add(UserProfile(name="Alice", skills=["Docker"], last_seen="11:00"))
# Retrieve the consolidated "Golden Record"
alice = memory.get("Alice")
print(alice.skills) # ['Python', 'Docker'] (Lists merged!)
print(alice.last_seen) # "11:00" (Updated!)
3. Search & Retrieve
# Exact retrieval
profile = memory.get("Alice")
# All keys in memory
all_keys = memory.keys
# Clear or remove
memory.remove("Alice")
💡 Advanced Examples
<details> <summary><b>Example 1: The "Self-Improving" Debugger (Logic Evolution)</b></summary>An AI agent that doesn't just store errors—it synthesizes debugging wisdom over time using LLM.BALANCED strategy.
from ontomem import OMem, MergeStrategy
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
class BugFixExperience(BaseModel):
error_signature: str
solutions: list[str]
prevention_tips: str
memory = OMem(
memory_schema=BugFixExperience,
key_extractor=lambda x: x.error_signature,
llm_client=ChatOpenAI(model="gpt-4o"),
embedder=OpenAIEmbeddings(),
strategy_or_merger=MergeStrategy.LLM.BALANCED
)
# Day 1: Pip install
memory.add(BugFixExperience(
error_signature="ModuleNotFoundError: pandas",
solutions=["pip install pandas"],
prevention_tips="Check requirements.txt"
))
# Day 2: Docker container (Different solution!)
memory.add(BugFixExperience(
error_signature="ModuleNotFoundError: pandas",
solutions=["apt-get install python3-pandas"], # Added to list!
prevention_tips="Use system packages in containers" # LLM merges both tips
))
# Result: Single record with merged solutions + synthesized advice
guidance = memory.get("ModuleNotFoundError: pandas")
print(guidance.prevention_tips)
# >>> "In standard environments, check requirements.txt.
#
Related Skills
node-connect
385.5kDiagnose OpenClaw Android, iOS, or macOS node pairing, QR/setup code, route, auth, and connection failures.
blender-python-addon
40.5kBlender Python add-on rules for operators, panels, properties, registration, testing, and API-safe scripting
flutter-development-guidelines-cursorrules-prompt-file
40.5kCursor rules for Flutter development with MVVM architecture, Riverpod state management, Material widgets, and Dart style guidelines.
commit-push-pr
140.6kCommit, push, and open a PR
