Hierarchical Memory

Category: Architecture

Problem

Not all memories are equal. A user's name should persist forever, last week's conversation topics should fade gradually, and the current session's working context should be immediately available but ephemeral. Treating all memories with the same storage and decay strategy leads to either information overload or premature forgetting.

Architecture

This pattern uses three namespace tiers in Dakera — each with its own decay configuration. Short-term memory captures the active session and decays aggressively. Long-term memory holds durable facts and decays slowly. Permanent memory stores identity-level information with no decay at all.

Flow

Implementation

from dakera import Dakera

client = Dakera(base_url="http://localhost:3300", api_key="dk-...")

# Define the three memory tiers
TIERS = {
    "short_term": {
        "namespace_suffix": "stm",
        "decay_rate": 0.15,       # Aggressive: decays within hours
        "default_importance": 0.5
    },
    "long_term": {
        "namespace_suffix": "ltm",
        "decay_rate": 0.005,      # Slow: decays over weeks
        "default_importance": 0.75
    },
    "permanent": {
        "namespace_suffix": "perm",
        "decay_rate": 0.0,        # Never decays
        "default_importance": 1.0
    }
}

def store_hierarchical(user_id: str, content: str, tier: str):
    """Store a memory in the appropriate tier namespace."""
    config = TIERS[tier]
    namespace = f"user-{user_id}-{config['namespace_suffix']}"

    client.memory.store(
        content=content,
        namespace=namespace,
        metadata={
            "tier": tier,
            "importance": config["default_importance"]
        }
    )

def recall_all_tiers(user_id: str, query: str) -> list:
    """Recall from all memory tiers and merge results."""
    all_results = []

    for tier_name, config in TIERS.items():
        namespace = f"user-{user_id}-{config['namespace_suffix']}"
        results = client.memory.recall(
            query=query,
            namespace=namespace,
            top_k=5
        )
        for r in results["results"]:
            r["tier"] = tier_name
            all_results.append(r)

    # Sort by score, with permanent tier getting a boost
    all_results.sort(key=lambda x: x["score"] * (1.2 if x["tier"] == "permanent" else 1.0), reverse=True)
    return all_results[:10]

# Usage
store_hierarchical("alice", "User's name is Alice Chen", "permanent")
store_hierarchical("alice", "User is working on a React migration project", "long_term")
store_hierarchical("alice", "Currently debugging a useEffect hook", "short_term")

context = recall_all_tiers("alice", "Help with React hooks")
# Returns all relevant memories, prioritizing permanent identity facts

When to Use This Pattern

Key Considerations