technology
February 8, 2026Context Management and Memory Systems
title: "Context Management and Memory Systems" description: "Research on long-term state, cross-session persistence, and context window optimization" date: 2026-02-06 topics: [context, memory, state-management, persistence] sources: 0 status: initial
Context Management and Memory Systems
Overview
Effective agentic systems require sophisticated context management to maintain state across long-running workflows, sessions, and interactions. This research covers memory architectures, state persistence, and context optimization strategies.
Types of Memory
1. Working Memory
Short-term, high-fidelity context
typescriptinterface WorkingMemory { // Current conversation/task context currentTask: Task; conversationHistory: Message[]; recentActions: Action[]; // Temporary calculations scratchpad: string; // Active tool results toolOutputs: Map<ToolId, Output>; // Limited by context window maxTokens: number; async add(item: MemoryItem): Promise<void> { // Check capacity if (this.willExceedCapacity(item)) { await this.compressOrEvict(); } this.items.push(item); } }
2. Episodic Memory
Specific experiences and events
typescriptinterface EpisodicMemory { // Store an experience async recordEpisode(episode: Episode): Promise<void> { await this.store({ type: 'episode', timestamp: episode.timestamp, context: episode.context, action: episode.action, outcome: episode.outcome, emotions: episode.emotions, // success/failure intensity embeddings: await this.embed(episode) }); } // Retrieve similar experiences async recallSimilar( currentContext: Context, k: number = 5 ): Promise<Episode[]> { const queryEmbedding = await this.embed(currentContext); return this.vectorSearch({ embedding: queryEmbedding, filter: { type: 'episode' }, topK: k }); } }
3. Semantic Memory
Generalized knowledge and facts
typescriptinterface SemanticMemory { // Concepts and relationships concepts: Map<ConceptId, Concept>; // Learned patterns patterns: Pattern[]; // Best practices bestPractices: Map<Domain, Practice[]>; // Facts facts: Fact[]; async learnConcept(examples: Example[]): Promise<Concept> { // Generalize from examples const concept = await this.generalize(examples); // Store with relationships await this.storeConcept(concept); await this.updateRelationships(concept); return concept; } }
4. Procedural Memory
How to do things (skills and strategies)
typescriptinterface ProceduralMemory { // Task-specific procedures procedures: Map<TaskType, Procedure>; // Tool usage patterns toolStrategies: Map<Tool, Strategy>; // Successful approaches successfulApproaches: Approach[]; async learnProcedure( taskType: string, execution: Execution ): Promise<void> { if (execution.success) { await this.storeProcedure({ taskType, steps: execution.steps, successRate: 1.0, avgTime: execution.duration }); } } }
Memory Architecture
1. Hierarchical Memory
┌─────────────────────────────────────┐
│ Working Memory │ <-- Fast, limited, volatile
│ (Context window, ~128K tokens) │
└──────────────┬──────────────────────┘
│
┌──────────────▼──────────────────────┐
│ Episodic Buffer │ <-- Recent episodes, compressed
│ (Last N sessions/days) │
└──────────────┬──────────────────────┘
│
┌──────────────▼──────────────────────┐
│ Long-term Storage │ <-- Persistent, indexed
│ (Vector DB + Structured Store) │
└─────────────────────────────────────┘
2. Memory Access Patterns
typescriptinterface MemoryAccess { // Read path async recall(query: Query): Promise<Memory[]> { // 1. Check working memory (fastest) const working = this.workingMemory.search(query); if (working.length > 0) return working; // 2. Check episodic buffer const episodic = await this.episodicBuffer.search(query); if (episodic.length > 0) return episodic; // 3. Query long-term storage (slowest) return this.longTermStorage.search(query); } // Write path async store(memory: Memory): Promise<void> { // Always store in working memory this.workingMemory.add(memory); // Important memories -> episodic if (memory.importance > EPISODIC_THRESHOLD) { await this.episodicBuffer.add(memory); } // Very important -> long-term if (memory.importance > LONG_TERM_THRESHOLD) { await this.longTermStorage.store(memory); } } }
Context Compression
1. Summarization Strategies
typescriptinterface ContextCompressor { async compress(context: Context): Promise<CompressedContext> { // Identify key information const keyPoints = await this.extractKeyPoints(context); // Summarize conversations const conversationSummary = await this.summarize( context.conversationHistory ); // Compress tool outputs const toolSummaries = await Promise.all( context.toolOutputs.map(t => this.summarizeToolOutput(t)) ); return { summary: keyPoints, conversation: conversationSummary, tools: toolSummaries, originalTokens: context.tokenCount, compressedTokens: this.estimateTokens(keyPoints, conversationSummary, toolSummaries) }; } }
2. Selective Retention
typescriptinterface SelectiveRetention { async selectWhatToKeep( context: Context, budget: number ): Promise<RetainedContext> { // Score each item const scored = context.items.map(item => ({ item, score: this.calculateImportance(item) })); // Sort by importance scored.sort((a, b) => b.score - a.score); // Select top items within budget const retained = []; let tokens = 0; for (const { item } of scored) { if (tokens + item.tokens <= budget) { retained.push(item); tokens += item.tokens; } else { // Summarize or discard const summary = await this.summarize(item); if (tokens + summary.tokens <= budget) { retained.push(summary); tokens += summary.tokens; } } } return { items: retained, totalTokens: tokens }; } }
Cross-Session Persistence
1. Session State Management
typescriptinterface SessionManager { async saveSession(session: Session): Promise<SessionId> { const checkpoint = { id: generateId(), timestamp: new Date(), workingMemory: session.workingMemory, taskStack: session.taskStack, pendingActions: session.pendingActions, context: session.context }; await this.persistence.store(checkpoint); return checkpoint.id; } async resumeSession(sessionId: SessionId): Promise<Session> { const checkpoint = await this.persistence.load(sessionId); // Rehydrate session return { workingMemory: checkpoint.workingMemory, taskStack: checkpoint.taskStack, pendingActions: checkpoint.pendingActions, context: { ...checkpoint.context, resumedAt: new Date() } }; } }
2. Long-Running Workflow State
typescriptinterface WorkflowState { workflowId: string; currentPhase: Phase; completedPhases: Phase[]; artifacts: Map<Phase, Artifact>; decisions: Decision[]; pendingApprovals: ApprovalRequest[]; async checkpoint(): Promise<void> { await this.persistence.store({ workflowId: this.workflowId, state: this.toJSON(), timestamp: new Date() }); } async restore(): Promise<WorkflowState> { const saved = await this.persistence.loadLatest(this.workflowId); return WorkflowState.fromJSON(saved.state); } }
Context Window Optimization
1. Smart Context Building
typescriptinterface SmartContextBuilder { async buildContext( task: Task, availableContext: Context[], maxTokens: number ): Promise<Context> { // Always include task description let context = [task.description]; let tokens = countTokens(task.description); // Add relevant memories const relevantMemories = await this.findRelevantMemories(task); for (const memory of relevantMemories) { if (tokens + memory.tokens <= maxTokens * 0.6) { context.push(memory); tokens += memory.tokens; } } // Add recent conversation (compressed) const recentChat = await this.getCompressedRecentChat( maxTokens * 0.3 ); context.push(recentChat); // Add current environment state const envState = await this.getEnvironmentState(); if (tokens + envState.tokens <= maxTokens * 0.1) { context.push(envState); } return this.compileContext(context); } }
2. Dynamic Window Allocation
typescriptinterface DynamicWindowAllocation { allocateWindow(task: Task): WindowAllocation { const totalWindow = this.model.contextWindow; // Reserve space for output const outputReserve = totalWindow * 0.2; // Available for input const available = totalWindow - outputReserve; // Allocate based on task needs return { systemPrompt: available * 0.1, conversation: available * 0.3, memories: available * 0.4, scratchpad: available * 0.2 }; } }
Memory Consistency
1. Conflict Resolution
typescriptinterface MemoryConsistency { async resolveConflicts(memories: Memory[]): Promise<Memory[]> { const conflicts = this.findConflicts(memories); for (const conflict of conflicts) { // Temporal: newer wins if (conflict.type === 'temporal') { this.resolveByTimestamp(conflict); } // Authority: higher confidence wins if (conflict.type === 'authority') { this.resolveByConfidence(conflict); } // Semantic: merge if possible if (conflict.type === 'semantic') { await this.mergeOrFlag(conflict); } } return memories; } }
2. Garbage Collection
typescriptinterface MemoryGarbageCollector { async collectGarbage(): Promise<void> { // Find stale memories const stale = await this.findStaleMemories(); // Archive instead of delete for (const memory of stale) { if (memory.importance > ARCHIVE_THRESHOLD) { await this.archive(memory); } else { await this.delete(memory); } } // Consolidate fragmented memories const fragments = await this.findFragments(); await this.consolidate(fragments); } }
Implementation Patterns
1. Memory as a Service
typescriptinterface MemoryService { // Store async store(memory: Memory, options: StoreOptions): Promise<MemoryId>; // Retrieve async retrieve(query: Query): Promise<Memory[]>; async recallSimilar(context: Context, k: number): Promise<Memory[]>; // Manage async update(id: MemoryId, memory: Partial<Memory>): Promise<void>; async delete(id: MemoryId): Promise<void>; // Maintenance async compact(): Promise<void>; async backup(): Promise<Backup>; }
2. Event Sourcing for State
typescriptinterface EventSourcedMemory { events: Event[]; async applyEvent(event: Event): Promise<void> { this.events.push(event); await this.projection.update(event); } async getState(): Promise<State> { return this.projection.getCurrentState(); } async replay(events: Event[]): Promise<State> { let state = this.initialState; for (const event of events) { state = this.reducer(state, event); } return state; } }
Observability
1. Memory Metrics
typescriptinterface MemoryMetrics { // Capacity workingMemoryUtilization: number; episodicBufferUtilization: number; longTermStorageSize: number; // Performance recallAccuracy: number; retrievalLatency: Histogram; compressionRatio: number; // Quality memoryRelevance: number; staleMemoryRatio: number; conflictRate: number; }
2. Context Debugging
typescriptinterface ContextDebugger { async traceContextUsage( request: Request ): Promise<ContextTrace> { return { originalContext: request.context, selectedMemories: request.selectedMemories, compressionApplied: request.compression, tokensUsed: request.tokensUsed, relevanceScores: request.relevanceScores }; } }
Open Questions
- Optimal memory hierarchy depth?
- When to forget vs. compress?
- How to handle contradictory memories?
- Cross-agent memory sharing?
- Privacy and sensitive data in memory?