Skip to main content

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

  1. Install from PyPI (Recommended)

    pip install zettel-memory
    
  2. Or Clone and Install (For development)

    git clone https://github.com/AppantasyArthurLai/project-zettel-memory.git
    cd project-zettel-memory
    python3 -m venv .venv
    source .venv/bin/activate
    pip install .
    
  3. Configuration Create a .env file 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.
  • 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.

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_path so 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

Technical Implementation Details

  • Embedding Model: We use Google Gemini text-embedding-004 by default.
    • Why? Better semantic understanding for complex queries compared to local models (e.g., all-MiniLM).
    • Note: This incurs a small API cost and latency.
  • Graph Persistence: While NetworkX operates in-memory, the graph state is automatically saved to disk (graph.graphml) after every modification (add_node / add_edge). It is ACID-compliant enough for single-user file locking but not for concurrent writes.

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

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

zettel_memory-0.1.3.tar.gz (11.6 kB view details)

Uploaded Source

Built Distribution

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

zettel_memory-0.1.3-py3-none-any.whl (5.2 kB view details)

Uploaded Python 3

File details

Details for the file zettel_memory-0.1.3.tar.gz.

File metadata

  • Download URL: zettel_memory-0.1.3.tar.gz
  • Upload date:
  • Size: 11.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for zettel_memory-0.1.3.tar.gz
Algorithm Hash digest
SHA256 4e07e9be6af08fadc015097d14745372813844108f6f9cc6daf8e4863bf9f529
MD5 458b7344bec1bdcfb00d7081dc5601d3
BLAKE2b-256 41166ddbe2a930afd53e0114375ad522efffb5641e1e421b17d9940fefbb8cc9

See more details on using hashes here.

File details

Details for the file zettel_memory-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: zettel_memory-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 5.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for zettel_memory-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 b47b1fa26f2eee8115cc37ef2e36b6e1b014a3270b32a1956ce3a08046c8fcc9
MD5 21684fc30115421de75ccb85d7920865
BLAKE2b-256 2a2b98190e061b7319a986543e97e89f8181ff8aaa90aa784540d2c71239ab21

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