A lightweight, Zettelkasten-inspired memory framework for AI Agents.
Project description
Zettel-Memory
"Building the Agent's Second Brain."
Zettel-Memory is a lightweight, organic memory framework for AI Agents, inspired by the Niklas Luhmann's Zettelkasten method. Unlike traditional RAG (which acts like a static file cabinet), Zettel-Memory functions as a living organism—it grows, connects, forgets, and dreams.
Core Philosophy
- Atomicity: Memories are automatically split into atomic concepts.
- Connectivity: Notes are auto-linked via an internal graph (NetworkX).
- Organic Life:
- Dreaming: Background compaction of memories into insights.
- Forgetting: Automatic pruning of irrelevant/unused memories over time.
- Resurfacing: Proactive retrieval of old but relevant memories.
Installation
Prerequisites
- Python 3.9+
- A Google Gemini API Key
Steps
-
Clone and Install
git clone https://github.com/your-username/project-zettel-memory.git cd project-zettel-memory python3 -m venv .venv source .venv/bin/activate pip install .
-
Configuration Create a
.envfile in the root directory:GOOGLE_API_KEY=your_gemini_api_key_here MODEL_NAME=gemini-2.0-flash-exp
Quick Start
import asyncio
from zettel_memory.core.brain import ZettelBrain
async def main():
# Initialize the Brain
brain = ZettelBrain()
# 1. Add Memory (Auto-atomized & Auto-linked)
await brain.add_memory("""
The Zettelkasten method emphasizes connecting ideas rather than just collecting them.
It was popularized by Niklas Luhmann.
""")
# 2. Retrieve (Hybrid: Vector + Graph)
results = await brain.retrieve("How should I organize notes?")
print("Retrieval Results:", results)
# 3. Resurfacing (Proactive Contextual Recall)
# Surfaces old relevant memories while ignoring what you just discussed
surfaced = await brain.resurfacer.resurface("Tell me about knowledge management systems.")
print("Resurfaced Memories:", [n.content for n in surfaced])
if __name__ == "__main__":
asyncio.run(main())
Integration Patterns (Agentic Workflows)
Zettel-Memory is designed to be the Hippocampus (Long-term Memory) of your agent system. In a workflow (like LangGraph or CrewAI), it shouldn't be used by every node, but rather by specific roles:
- Planner / Manager Node:
- Queries
brain.retrieve(task_context)at the start to load relevant history. - Decides direction based on past learnings.
- Queries
- Writer / Executor Node:
- Queries specific details when generating content.
- Observer / Critic Node:
- Calls
brain.add_memory(observation)to store new findings after an action is completed.
- Calls
Multi-tenancy (Serving Multiple Users)
If your system serves multiple users (e.g., a SaaS platform), you MUST isolate their memories. The implementation requires creating a separate brain instance (pointing to a separate path) for each user.
def get_user_brain(user_id: str) -> ZettelBrain:
# Each user gets their own isolated folder
return ZettelBrain(storage_path=f"./brain_data/users/{user_id}")
Why?
- Privacy: User A should never traverse User B's graph.
- Safety: Isolating NetworkX graphs prevents in-memory cross-contamination.
Best Practice: Treat ZettelBrain as a Shared Singleton passed to these nodes.
Why Shared? The power of Zettelkasten comes from "Cross-pollination". If the Planner has a separate database from the Reflector, the Planner will never learn from the Reflector's insights. They should share the same
storage_pathso that one node's output becomes another node's retrieval context.
Architecture
| Component | Responsibility | Tech Stack |
|---|---|---|
| ZettelBrain | Main Interface & Orchestrator | Python (Async) |
| Storage | Vector Embedding Storage | ChromaDB |
| Graph | Knowledge Graph & Links | NetworkX |
| Cortex | Background Intelligence (Dream/Forget/Resurface) | Background Tasks |
Development & Testing
Run the test suite to verify the installation:
# Run all tests with coverage
pytest --cov=zettel_memory --cov-report=term-missing tests/
Build & Distribution
If you want to build a distribution package or use this library in other local projects without publishing to PyPI.
1. Build Package
pip install build twine
python -m build
# Generates ./dist/zettel_memory-0.1.0.tar.gz and .whl
2. Local Integration (Editable Install)
Recommended for development. Allows you to use Zettel-Memory in another project while keeping the code editable.
# In your other project's directory:
pip install -e /path/to/project-zettel-memory
3. Deploy to PyPI
twine upload dist/*
License
MIT License. Created by Arthur & Gemini.
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
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 zettel_memory-0.1.0.tar.gz.
File metadata
- Download URL: zettel_memory-0.1.0.tar.gz
- Upload date:
- Size: 11.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
93e8a13d11d29b7881e38f6b0b53d7addaad43033129d839d68bc65526fef2bd
|
|
| MD5 |
2c0c36f93ab1c8639eef87a0e4c8d68a
|
|
| BLAKE2b-256 |
03ea92746904b9111873fd7c9c47e786070251f92496831be2c558ecfa4cc14c
|
File details
Details for the file zettel_memory-0.1.0-py3-none-any.whl.
File metadata
- Download URL: zettel_memory-0.1.0-py3-none-any.whl
- Upload date:
- Size: 4.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e254d5f3ae8495e15e1f359508c81934168090277ffc19d3b302d9e64bb45e9a
|
|
| MD5 |
732a29797e3e79dcb0472c82e6a75eb0
|
|
| BLAKE2b-256 |
34eadbf2e05e8a02835e67aa99ae56c52d9743956b3e5fb06eb06ce7aefea0f6
|