AI SDK

Memory

Multi-tier memory system with automatic consolidation

Multi-Tier Memory

4-level memory system with automatic consolidation and importance scoring.

WorkingShort-termLong-termEpisodic

Memory Tiers

  1. Working Memory - Current context (5-10 items)
  2. Short-term Memory - Recent interactions (1 hour TTL)
  3. Long-term Memory - Important information (persistent)
  4. Episodic Memory - Significant events (timestamped)

Basic Usage

memory := sdk.NewMemoryManager(
    vectorStore,
    logger,
    metrics,
    sdk.MemoryConfig{
        WorkingCapacity:   5,
        ShortTermTTL:      1 * time.Hour,
        LongTermThreshold: 0.8,  // Importance score
    },
)

// Store memory
memory.Store(ctx, &sdk.Memory{
    Content:    "User prefers dark mode",
    Importance: 0.9,
    Tags:       []string{"preference", "ui"},
})

// Recall memories
memories, _ := memory.Recall(ctx, "ui preferences", 5)

Storage

Automatic Tier Assignment

// High importance → Long-term
memory.Store(ctx, &sdk.Memory{
    Content:    "User's email: user@example.com",
    Importance: 0.95,  // Automatically goes to long-term
})

// Medium importance → Short-term
memory.Store(ctx, &sdk.Memory{
    Content:    "User asked about pricing",
    Importance: 0.6,   // Goes to short-term
})

// Low importance → Working
memory.Store(ctx, &sdk.Memory{
    Content:    "User said hello",
    Importance: 0.3,   // Stays in working memory
})

Explicit Tier

memory.StoreInTier(ctx, &sdk.Memory{
    Content: "Critical user data",
}, sdk.LongTerm)

With Metadata

memory.Store(ctx, &sdk.Memory{
    Content:    "User completed onboarding",
    Importance: 0.8,
    Tags:       []string{"milestone", "onboarding"},
    Metadata: map[string]interface{}{
        "timestamp":  time.Now(),
        "user_id":    "12345",
        "completion": "100%",
    },
})

Retrieval

// Find related memories
memories, err := memory.Recall(ctx, "user preferences", 5)

for _, mem := range memories {
    fmt.Printf("%s (score: %.2f)\n", mem.Content, mem.Importance)
}

By Tier

// Get all working memories
working := memory.GetByTier(ctx, sdk.Working)

// Get long-term memories
longTerm := memory.GetByTier(ctx, sdk.LongTerm)

By Tags

// Filter by tags
preferences := memory.GetByTags(ctx, []string{"preference"})
milestones := memory.GetByTags(ctx, []string{"milestone"})

Time-based

// Get recent memories
since := time.Now().Add(-24 * time.Hour)
recent := memory.GetSince(ctx, since)

// Get episodic memories in range
start := time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC)
end := time.Date(2024, 1, 31, 23, 59, 59, 0, time.UTC)
january := memory.GetEpisodicRange(ctx, start, end)

Consolidation

Automatic

Memories are automatically consolidated:

// Working memory fills up → consolidates to short-term
// Short-term TTL expires → moves to long-term (if important)
// Low importance expires → removed

memory := sdk.NewMemoryManager(vectorStore, logger, metrics,
    sdk.MemoryConfig{
        WorkingCapacity:      5,     // Auto-consolidate at 5 items
        ShortTermTTL:         1h,    // Expire after 1 hour
        LongTermThreshold:    0.8,   // Only important to long-term
        ConsolidationInterval: 5m,   // Check every 5 minutes
    },
)

Manual

// Force consolidation
memory.Consolidate(ctx)

// Consolidate specific tier
memory.ConsolidateWorking(ctx)
memory.ConsolidateShortTerm(ctx)

Promotion

Manually promote important memories:

// Promote to higher tier
memory.Promote(ctx, memoryID, sdk.LongTerm)

// Demote to lower tier
memory.Demote(ctx, memoryID, sdk.ShortTerm)

Memory Statistics

stats := memory.GetStats()

fmt.Printf("Working: %d/%d\n", stats.Working, stats.WorkingCapacity)
fmt.Printf("Short-term: %d\n", stats.ShortTerm)
fmt.Printf("Long-term: %d\n", stats.LongTerm)
fmt.Printf("Episodic: %d\n", stats.Episodic)
fmt.Printf("Total: %d\n", stats.Total)
fmt.Printf("Avg Importance: %.2f\n", stats.AverageImportance)

Real-World Examples

User Profile Agent

type ProfileAgent struct {
    agent  *sdk.Agent
    memory *sdk.MemoryManager
}

func (p *ProfileAgent) Chat(ctx context.Context, message string) (string, error) {
    // Recall relevant context
    context, _ := p.memory.Recall(ctx, message, 5)
    
    // Build prompt with context
    prompt := fmt.Sprintf(`
        User context:
        %s
        
        User message: %s
    `, formatMemories(context), message)
    
    // Generate response
    result, err := p.agent.Execute(ctx, prompt)
    
    // Store new memory
    p.memory.Store(ctx, &sdk.Memory{
        Content:    message,
        Importance: calculateImportance(message),
        Tags:       extractTags(message),
    })
    
    return result.Content, err
}

Learning System

func createLearningAgent() *sdk.Agent {
    memory := sdk.NewMemoryManager(vectorStore, logger, metrics,
        sdk.MemoryConfig{
            WorkingCapacity:   10,
            ShortTermTTL:      2 * time.Hour,
            LongTermThreshold: 0.75,
        },
    )
    
    agent := sdk.NewAgent("learner", llm, logger, metrics, nil)
    
    // Store lessons learned
    agent.OnComplete(func(result *sdk.Result) {
        memory.Store(ctx, &sdk.Memory{
            Content:    result.Content,
            Importance: 0.8,
            Tags:       []string{"lesson"},
        })
    })
    
    // Recall past lessons
    agent.OnStart(func() {
        lessons, _ := memory.GetByTags(ctx, []string{"lesson"})
        agent.SetContext(formatLessons(lessons))
    })
    
    return agent
}

Session Manager

type SessionManager struct {
    memory   *sdk.MemoryManager
    sessions map[string]*sdk.Agent
}

func (s *SessionManager) GetOrCreate(userID string) *sdk.Agent {
    if agent, ok := s.sessions[userID]; ok {
        return agent
    }
    
    agent := sdk.NewAgent(userID, llm, logger, metrics, nil)
    
    // Load user's long-term memories
    memories, _ := s.memory.GetByTier(ctx, sdk.LongTerm)
    for _, mem := range memories {
        if mem.Metadata["user_id"] == userID {
            agent.AddContext(mem.Content)
        }
    }
    
    s.sessions[userID] = agent
    return agent
}

Configuration

type MemoryConfig struct {
    // Working memory
    WorkingCapacity int
    
    // Short-term memory
    ShortTermTTL      time.Duration
    ShortTermCapacity int  // 0 = unlimited
    
    // Long-term memory
    LongTermThreshold float64  // Importance score
    
    // Episodic memory
    EnableEpisodic bool
    
    // Consolidation
    ConsolidationInterval time.Duration
    AutoConsolidate       bool
    
    // Embeddings
    EmbeddingModel string
    EmbeddingDim   int
}

Best Practices

Set Appropriate Thresholds

memory := sdk.NewMemoryManager(vectorStore, logger, metrics,
    sdk.MemoryConfig{
        WorkingCapacity:   5,    // Small for current context
        LongTermThreshold: 0.8,  // High bar for persistence
    },
)

Tag Meaningfully

memory.Store(ctx, &sdk.Memory{
    Content: "User changed email",
    Tags:    []string{"profile", "email", "change"},
    // Easy to find with any of these tags
})

Use Metadata

memory.Store(ctx, &sdk.Memory{
    Content: "Purchase completed",
    Tags:    []string{"transaction"},
    Metadata: map[string]interface{}{
        "amount":     99.99,
        "product_id": "SKU123",
        "timestamp":  time.Now(),
    },
})

Monitor Statistics

// Regular health checks
ticker := time.NewTicker(5 * time.Minute)
go func() {
    for range ticker.C {
        stats := memory.GetStats()
        metrics.Gauge("memory.working").Set(float64(stats.Working))
        metrics.Gauge("memory.long_term").Set(float64(stats.LongTerm))
        
        if stats.Working == stats.WorkingCapacity {
            logger.Warn("working memory full")
        }
    }
}()

Debugging

// Enable verbose logging
memory.SetVerbose(true)

// Inspect specific memory
mem, _ := memory.Get(ctx, memoryID)
fmt.Printf("Content: %s\n", mem.Content)
fmt.Printf("Tier: %s\n", mem.Tier)
fmt.Printf("Importance: %.2f\n", mem.Importance)
fmt.Printf("Created: %s\n", mem.CreatedAt)
fmt.Printf("Accessed: %d times\n", mem.AccessCount)

// View consolidation history
history := memory.GetConsolidationHistory()
for _, event := range history {
    fmt.Printf("%s: %d memories consolidated\n", 
        event.Timestamp, event.Count)
}

Next Steps

  • Agents - Memory-enabled agents
  • RAG - Combine RAG with memory
  • Examples - Memory examples

How is this guide?

Last updated on