metadata
license: mit
library_name: mnemo
tags:
- mnemo
- memory
- ai-memory
- llm-memory
- semantic-memory
- rag
- retrieval
- langchain
- llamaindex
- mcp
- agent-memory
- chatbot-memory
- mem0
- vector-search
- knowledge-graph
- smart-injection
- context-check
pipeline_tag: feature-extraction
π§ Mnemo - AI Memory System
Open-source memory for LLMs, chatbots, and AI agents
21x faster than mem0 β’ Smart memory injection β’ Real embeddings β’ No API keys
β¨ What's New in v2.0
- π― Smart Memory Injection - Context-check algorithm with 90% accuracy decides WHEN to inject memory
- 𧬠Real Embeddings - sentence-transformers support (with hash fallback)
- π Benchmark Tested - Validated on medical AI bias detection tasks
π¦ Install
pip install mnemo-memory
Or with all features:
pip install mnemo-memory[all] # Includes sentence-transformers, faiss-cpu
π Quick Start
from mnemo import Mnemo
memory = Mnemo()
memory.add("User prefers Python and dark mode")
memory.add("Project deadline is March 15th")
# Search memories
results = memory.search("user preferences")
print(results[0].content) # "User prefers Python and dark mode"
π― Smart Memory Injection (NEW!)
Don't inject memory blindly - use context-check to decide when it helps:
from mnemo import Mnemo
m = Mnemo()
m.add("Previous analysis showed gender bias patterns")
m.add("Framework has 5 checkpoints for detection")
# Check if query needs memory
query1 = "What is machine learning?"
query2 = "Based on your previous analysis, explain the patterns"
m.should_inject(query1) # False - standalone question
m.should_inject(query2) # True - references prior context
# Get formatted context for injection
if m.should_inject(query2):
context = m.get_context("previous analysis")
prompt = f"{context}\n\nQuestion: {query2}"
When Memory Helps vs Hurts
| Query Type | Example | Action |
|---|---|---|
| References prior | "Based on your previous analysis..." | β Inject |
| Comparison | "Compare this to earlier findings" | β Inject |
| Synthesis | "Synthesize all the patterns" | β Inject |
| Standalone | "What is Python?" | β Skip |
| New topic | "This is a NEW problem..." | β Skip |
π¬ Benchmark Results
Tested on NRA-19 Medical AI Bias Detection benchmark:
Memory Injection Strategy Comparison
| Strategy | Score | Decision Accuracy |
|---|---|---|
| Always inject | 47/100 | 70% |
| Context-check | 46/100 | 90% |
| Never inject | 41/100 | 30% |
| Similarity only | 37/100 | 50% |
Embedding Comparison
| Type | Score | vs Baseline |
|---|---|---|
| No memory | 77/100 | β |
| Hash embeddings | 65/100 | -12 pts β |
| Real embeddings | 74/100 | -3 pts |
Key finding: Real embeddings are 9 points better than hash embeddings.
π§ MCP Server (for Claude)
Add to your Claude config:
{
"mcpServers": {
"mnemo": {
"command": "uvx",
"args": ["mnemo-memory"]
}
}
}
MCP Tools
| Tool | Description |
|---|---|
add_memory |
Store a new memory |
search_memory |
Search stored memories |
should_inject |
Check if memory should be used |
get_context |
Get formatted context for injection |
get_stats |
Get system statistics |
π Benchmarks vs mem0
| Metric | mem0 | Mnemo |
|---|---|---|
| Search latency | 5.73ms | 0.27ms |
| API keys required | Yes | No |
| Works offline | No | Yes |
| Smart injection | No | Yes |
| Embedding options | API only | Local + API |
ποΈ Architecture
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Mnemo β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β βββββββββββββββ βββββββββββββββ βββββββββββββββ β
β β Semantic β β BM25 β β Graph β β
β β Search β β Search β β Search β β
β β (FAISS) β β (Keywords) β β (NetworkX) β β
β ββββββββ¬βββββββ ββββββββ¬βββββββ ββββββββ¬βββββββ β
β β β β β
β ββββββββββββββββββ΄βββββββββββββββββ β
β β β
β ββββββββ΄βββββββ β
β β Ranker β β Feedback Learning β
β ββββββββ¬βββββββ β
β β β
β βββββββββββββ΄ββββββββββββ β
β β Smart Injection β β
β β (Context-Check) β β
β βββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π API Reference
Mnemo Class
class Mnemo:
def __init__(
self,
embedding_model: str = "all-MiniLM-L6-v2",
embedding_dim: int = 384,
semantic_weight: float = 0.5,
bm25_weight: float = 0.3,
graph_weight: float = 0.2,
use_real_embeddings: bool = True
)
def add(content: str, metadata: dict = None) -> str
def search(query: str, top_k: int = 5) -> List[SearchResult]
def should_inject(query: str, context: str = "") -> bool
def get_context(query: str, top_k: int = 3) -> str
def feedback(query: str, memory_id: str, relevance: float)
def get_stats() -> dict
def clear()
SearchResult
@dataclass
class SearchResult:
id: str
content: str
score: float
strategy_scores: Dict[str, float]
metadata: Dict
π Links
π License
MIT License - Use freely in your projects!
Built with β€οΈ for the AI community