Advanced Memory and Context Techniques for Claude Code
As AI applications grow more complex, traditional context management approaches reach their limits. This guide explores cutting-edge memory architectures and context techniques that enable Claude Code to maintain coherent understanding across extended interactions, multiple sessions, and complex knowledge domains.
Table of Contents
- Semantic Memory Layers and Knowledge Graphs
- Hierarchical Context Management
- Dynamic Context Pruning
- Cross-Session Memory Transfer
- Episodic Memory Systems
- Production Memory Architectures
- Performance and Optimization
- Implementation Examples
Semantic Memory Layers and Knowledge Graphs
Semantic memory provides structured, interconnected knowledge that enhances Claude’s understanding and reasoning capabilities. By organizing information in knowledge graphs, we create queryable, expandable memory systems.
Building a Knowledge Graph Memory System
interface KnowledgeNode {
id: string
type: 'entity' | 'concept' | 'relationship' | 'event'
name: string
properties: Map<string, any>
embeddings: number[]
lastAccessed: Date
accessCount: number
}
interface KnowledgeEdge {
id: string
source: string
target: string
relationship: string
weight: number
metadata: Map<string, any>
}
class SemanticMemoryLayer {
private graph: KnowledgeGraph
private embedder: EmbeddingService
private reasoner: GraphReasoner
async addKnowledge(
content: string,
context: Context
): Promise<KnowledgeNode[]> {
// Extract entities and relationships
const extraction = await this.extractStructured(content)
// Disambiguate entities (USA/US/United States → single node)
const disambiguated = await this.disambiguate(extraction.entities)
// Create or update nodes
const nodes = await Promise.all(
disambiguated.map(entity => this.upsertNode(entity))
)
// Create relationships
const edges = await this.createEdges(extraction.relationships, nodes)
// Update graph
await this.graph.addNodesAndEdges(nodes, edges)
return nodes
}
private async extractStructured(content: string): Promise<Extraction> {
const prompt = `
Extract entities and relationships from the following text.
Return as JSON with schema:
{
"entities": [
{
"name": "string",
"type": "person|organization|concept|technology",
"properties": {}
}
],
"relationships": [
{
"source": "entity_name",
"target": "entity_name",
"type": "relationship_type"
}
]
}
Text: ${content}
`
const response = await this.claudeClient.sendMessage({
messages: [{ role: 'user', content: prompt }],
response_format: { type: 'json_object' }
})
return JSON.parse(response.content)
}
async query(
question: string,
maxHops: number = 2
): Promise<GraphQueryResult> {
// Convert question to graph query
const graphQuery = await this.questionToQuery(question)
// Execute multi-hop reasoning
const subgraph = await this.graph.traverse(
graphQuery.startNodes,
graphQuery.constraints,
maxHops
)
// Reason over subgraph
const answer = await this.reasoner.reason(subgraph, question)
return {
answer,
evidence: subgraph,
confidence: this.calculateConfidence(subgraph)
}
}
}HybridRAG Implementation
Combine vector search with graph reasoning for optimal results:
class HybridRAGMemory {
private vectorStore: VectorStore
private graphMemory: SemanticMemoryLayer
private router: QueryRouter
async retrieve(query: string): Promise<MemoryContext> {
// Determine best retrieval strategy
const strategy = await this.router.route(query)
switch (strategy) {
case 'vector':
// Simple factual queries
return await this.vectorRetrieval(query)
case 'graph':
// Complex reasoning queries
return await this.graphRetrieval(query)
case 'hybrid':
// Combine both approaches
return await this.hybridRetrieval(query)
}
}
private async hybridRetrieval(query: string): Promise<MemoryContext> {
// Parallel retrieval
const [vectorResults, graphResults] = await Promise.all([
this.vectorStore.search(query, 10),
this.graphMemory.query(query, 3)
])
// Re-rank combined results
const combined = await this.reranker.rank(
query,
[...vectorResults, ...graphResults.evidence]
)
// Build context with both sources
return {
primary: combined.slice(0, 5),
supporting: graphResults.answer,
confidence: this.mergeConfidence(vectorResults, graphResults)
}
}
}Hierarchical Context Management
Organize context in hierarchical layers for efficient access and management:
Multi-Level Context Architecture
class HierarchicalContextManager {
private levels: ContextLevel[]
constructor() {
this.levels = [
new ImmediateContext(1000), // Current turn
new ConversationContext(10000), // Current conversation
new SessionContext(50000), // Current session
new UserContext(100000), // User preferences
new GlobalContext(Infinity) // Persistent knowledge
]
}
async buildContext(input: string): Promise<HierarchicalContext> {
const context = new HierarchicalContext()
// Start with most specific level
for (const level of this.levels) {
const levelContext = await level.getRelevant(input)
context.addLevel(level.name, levelContext)
// Check token budget
if (context.totalTokens() >= this.TOKEN_BUDGET) {
break
}
}
// Consolidate overlapping information
return this.consolidate(context)
}
private consolidate(context: HierarchicalContext): HierarchicalContext {
// Remove redundancy across levels
const consolidated = new HierarchicalContext()
const seen = new Set<string>()
// Process from most specific to least
for (const level of context.getLevels()) {
const unique = level.items.filter(item => {
const hash = this.contentHash(item)
if (seen.has(hash)) return false
seen.add(hash)
return true
})
consolidated.addLevel(level.name, unique)
}
return consolidated
}
}Context Compression Strategies
class ContextCompressor {
private summarizer: Summarizer
private encoder: Encoder
async compress(
context: Context,
targetTokens: number
): Promise<CompressedContext> {
const currentTokens = this.countTokens(context)
if (currentTokens <= targetTokens) {
return { content: context, compressionRatio: 1.0 }
}
// Try different compression strategies
const strategies = [
this.removeRedundancy.bind(this),
this.abstractiveCompression.bind(this),
this.selectiveRetention.bind(this)
]
for (const strategy of strategies) {
const compressed = await strategy(context, targetTokens)
if (this.countTokens(compressed) <= targetTokens) {
return {
content: compressed,
compressionRatio: currentTokens / this.countTokens(compressed)
}
}
}
// Fall back to aggressive summarization
return await this.aggressiveSummarize(context, targetTokens)
}
private async abstractiveCompression(
context: Context,
targetTokens: number
): Promise<Context> {
const chunks = this.chunkByImportance(context)
const compressed = []
for (const chunk of chunks) {
if (chunk.importance > 0.8) {
// Keep high-importance content as-is
compressed.push(chunk.content)
} else {
// Summarize lower importance content
const summary = await this.summarizer.summarize(
chunk.content,
Math.floor(targetTokens * chunk.importance)
)
compressed.push(summary)
}
}
return new Context(compressed.join('\n'))
}
}Dynamic Context Pruning
Intelligently select and prune context based on relevance and importance:
LazyLLM-Inspired Token Selection
class DynamicContextPruner {
private importanceScorer: ImportanceScorer
private tokenizer: Tokenizer
async pruneContext(
fullContext: string,
query: string,
maxTokens: number
): Promise<PrunedContext> {
// Tokenize and score each token
const tokens = this.tokenizer.tokenize(fullContext)
const scores = await this.importanceScorer.score(tokens, query)
// Dynamic programming for optimal selection
const selected = this.selectOptimalTokens(tokens, scores, maxTokens)
// Reconstruct coherent text
const reconstructed = this.reconstruct(selected)
return {
content: reconstructed,
retainedTokens: selected.length,
totalTokens: tokens.length,
compressionRatio: selected.length / tokens.length
}
}
private selectOptimalTokens(
tokens: Token[],
scores: number[],
budget: number
): Token[] {
// PREMISE-inspired gradient optimization
const selected = new Set<number>()
const gradient = new Array(tokens.length).fill(0)
// Initialize with high-importance tokens
tokens.forEach((token, i) => {
if (scores[i] > 0.9) {
selected.add(i)
}
})
// Iteratively add tokens based on gradient
while (selected.size < budget) {
// Calculate gradient based on context coherence
this.updateGradient(gradient, selected, tokens)
// Select token with highest gradient
const best = this.argmax(gradient, selected)
if (gradient[best] <= 0) break
selected.add(best)
}
return Array.from(selected)
.sort((a, b) => a - b)
.map(i => tokens[i])
}
}Intelligent Context Windows
class IntelligentContextWindow {
private readonly CONTEXT_LIMIT = 100000
private readonly SAFETY_BUFFER = 5000
async optimizeWindow(
conversation: Conversation,
currentQuery: string
): Promise<OptimizedWindow> {
const sections = this.identifySections(conversation)
// Score each section's relevance
const scoredSections = await Promise.all(
sections.map(async section => ({
section,
relevance: await this.scoreRelevance(section, currentQuery),
tokens: this.countTokens(section)
}))
)
// Optimize selection with constraints
const selected = this.optimizeSelection(
scoredSections,
this.CONTEXT_LIMIT - this.SAFETY_BUFFER
)
// Add connecting context for coherence
const withConnections = this.addConnections(selected)
return {
content: withConnections,
metadata: {
totalSections: sections.length,
selectedSections: selected.length,
tokenUsage: this.countTokens(withConnections)
}
}
}
}Cross-Session Memory Transfer
Enable knowledge and patterns to persist across sessions:
Memory Transfer System
interface TransferableMemory {
patterns: Pattern[]
insights: Insight[]
preferences: Preference[]
relationships: Relationship[]
}
class CrossSessionMemoryTransfer {
private memoryStore: PersistentMemoryStore
private transferOptimizer: TransferOptimizer
async extractTransferableMemory(
session: Session
): Promise<TransferableMemory> {
// Extract reusable patterns
const patterns = await this.extractPatterns(session)
// Identify key insights
const insights = await this.extractInsights(session)
// Learn user preferences
const preferences = await this.extractPreferences(session)
// Map entity relationships
const relationships = await this.extractRelationships(session)
return {
patterns: this.filterHighConfidence(patterns),
insights: this.deduplicate(insights),
preferences: this.consolidate(preferences),
relationships: this.validate(relationships)
}
}
async transferToNewSession(
memory: TransferableMemory,
targetContext: Context
): Promise<void> {
// Adapt patterns to new context
const adaptedPatterns = await this.adaptPatterns(
memory.patterns,
targetContext
)
// Initialize new session with transferred knowledge
await this.initializeSession({
patterns: adaptedPatterns,
insights: memory.insights,
preferences: memory.preferences,
relationships: memory.relationships
})
}
private async adaptPatterns(
patterns: Pattern[],
context: Context
): Promise<Pattern[]> {
return Promise.all(
patterns.map(async pattern => {
// Check applicability in new context
const applicable = await this.checkApplicability(pattern, context)
if (!applicable) return null
// Adjust confidence based on context similarity
const similarity = await this.contextSimilarity(
pattern.originalContext,
context
)
return {
...pattern,
confidence: pattern.confidence * similarity,
adapted: true
}
})
).then(results => results.filter(Boolean))
}
}Experience Consolidation
class ExperienceConsolidator {
async consolidateExperiences(
sessions: Session[]
): Promise<ConsolidatedKnowledge> {
// Group similar experiences
const clusters = await this.clusterExperiences(sessions)
// Extract common patterns
const patterns = await Promise.all(
clusters.map(cluster => this.extractCommonPatterns(cluster))
)
// Build generalized knowledge
const generalizations = await this.generalize(patterns)
// Create transferable knowledge base
return {
patterns: generalizations.patterns,
rules: generalizations.rules,
heuristics: generalizations.heuristics,
metadata: {
sessionCount: sessions.length,
clusterCount: clusters.length,
confidence: this.calculateOverallConfidence(generalizations)
}
}
}
}Episodic Memory Systems
Implement human-inspired episodic memory for better context retention:
EM-LLM Architecture Implementation
class EpisodicMemorySystem {
private hippocampus: HippocampalMemory // Short-term episodic storage
private neocortex: NeocorticalMemory // Long-term semantic storage
private consolidator: MemoryConsolidator
async recordEpisode(interaction: Interaction): Promise<void> {
// Create episodic memory trace
const episode: Episode = {
id: generateId(),
timestamp: new Date(),
content: interaction.content,
context: interaction.context,
outcome: interaction.outcome,
salience: await this.calculateSalience(interaction)
}
// Store in hippocampus (short-term)
await this.hippocampus.store(episode)
// Schedule for consolidation
this.scheduleConsolidation(episode)
}
async recall(cue: string): Promise<RecalledMemories> {
// Pattern completion in hippocampus
const recentEpisodes = await this.hippocampus.patternComplete(cue)
// Semantic search in neocortex
const semanticMemories = await this.neocortex.search(cue)
// Combine and rank by relevance
const combined = await this.rankByRelevance(
[...recentEpisodes, ...semanticMemories],
cue
)
return {
episodes: combined.filter(m => m.type === 'episodic'),
semantic: combined.filter(m => m.type === 'semantic'),
totalRecalled: combined.length
}
}
private async scheduleConsolidation(episode: Episode): Promise<void> {
// Consolidate high-salience episodes immediately
if (episode.salience > 0.8) {
await this.consolidateEpisode(episode)
} else {
// Schedule for sleep consolidation
this.consolidator.schedule(episode, this.CONSOLIDATION_DELAY)
}
}
private async consolidateEpisode(episode: Episode): Promise<void> {
// Extract semantic knowledge
const semanticKnowledge = await this.extractSemantics(episode)
// Update neocortical memory
await this.neocortex.integrate(semanticKnowledge)
// Optionally forget episodic details
if (episode.salience < 0.5) {
await this.hippocampus.forget(episode.id)
}
}
}Experience Replay System
class ExperienceReplaySystem {
private replayBuffer: PrioritizedReplayBuffer
private dreamGenerator: DreamGenerator
async addExperience(experience: Experience): Promise<void> {
// Calculate priority based on surprise and relevance
const priority = await this.calculatePriority(experience)
await this.replayBuffer.add(experience, priority)
}
async replayForLearning(
currentContext: Context
): Promise<ReplayedExperiences> {
// Sample experiences based on priority and relevance
const samples = await this.replayBuffer.sample(
this.REPLAY_BATCH_SIZE,
currentContext
)
// Generate synthetic variations (dreams)
const dreams = await this.dreamGenerator.generate(samples)
// Combine real and synthetic experiences
return {
real: samples,
synthetic: dreams,
totalExperiences: samples.length + dreams.length
}
}
async consolidateLearning(
experiences: ReplayedExperiences
): Promise<void> {
// Update importance weights
for (const exp of experiences.real) {
const newPriority = await this.recalculatePriority(exp)
await this.replayBuffer.updatePriority(exp.id, newPriority)
}
// Prune low-value experiences
await this.replayBuffer.prune(this.RETENTION_THRESHOLD)
}
}Production Memory Architectures
Mem0-Inspired Scalable Architecture
class ScalableMemoryArchitecture {
private graphDB: Neo4jConnection
private vectorDB: ChromaDB
private llm: ClaudeClient
private cache: RedisCache
async initialize(config: MemoryConfig): Promise<void> {
// Set up graph schema
await this.graphDB.createSchema({
nodes: ['User', 'Memory', 'Entity', 'Relationship'],
relationships: ['REMEMBERS', 'RELATES_TO', 'MENTIONED_IN']
})
// Initialize vector collections
await this.vectorDB.createCollection('memories', {
dimension: 1536,
metric: 'cosine'
})
// Set up caching layer
await this.cache.configure({
ttl: 3600,
maxSize: 10000
})
}
async addMemory(
userId: string,
content: string,
metadata: Metadata
): Promise<string> {
// Extract structured information
const extracted = await this.llm.extract({
content,
schema: this.EXTRACTION_SCHEMA
})
// Create graph nodes
const memoryNode = await this.graphDB.createNode('Memory', {
id: generateId(),
content,
timestamp: new Date(),
...metadata
})
// Link to user
await this.graphDB.createRelationship(
userId,
memoryNode.id,
'REMEMBERS'
)
// Create entity nodes and relationships
for (const entity of extracted.entities) {
const entityNode = await this.graphDB.upsertNode('Entity', entity)
await this.graphDB.createRelationship(
memoryNode.id,
entityNode.id,
'MENTIONED_IN'
)
}
// Generate and store embeddings
const embedding = await this.llm.embed(content)
await this.vectorDB.upsert({
id: memoryNode.id,
vector: embedding,
metadata: { userId, ...metadata }
})
return memoryNode.id
}
async queryMemories(
userId: string,
query: string,
options: QueryOptions = {}
): Promise<Memory[]> {
// Check cache first
const cacheKey = `${userId}:${query}:${JSON.stringify(options)}`
const cached = await this.cache.get(cacheKey)
if (cached) return cached
// Hybrid search
const [graphResults, vectorResults] = await Promise.all([
this.graphSearch(userId, query, options),
this.vectorSearch(userId, query, options)
])
// Merge and rank
const merged = this.mergeResults(graphResults, vectorResults)
const ranked = await this.rerank(query, merged)
// Cache results
await this.cache.set(cacheKey, ranked)
return ranked
}
}MemGPT-Style Virtual Context
class VirtualContextManager {
private mainContext: FixedContext
private recursiveSummary: RecursiveSummary
private externalMemory: ExternalMemory
constructor(contextLimit: number = 8000) {
this.mainContext = new FixedContext(contextLimit)
this.recursiveSummary = new RecursiveSummary()
this.externalMemory = new ExternalMemory()
}
async processMessage(message: string): Promise<Response> {
// Update recursive summary
await this.recursiveSummary.update(message)
// Determine if context swap needed
if (this.shouldSwapContext(message)) {
await this.swapContext(message)
}
// Build effective context
const context = {
system: this.buildSystemPrompt(),
summary: this.recursiveSummary.get(),
active: this.mainContext.get(),
relevant: await this.externalMemory.retrieve(message)
}
// Process with LLM
const response = await this.llm.process(context, message)
// Update memories
await this.updateMemories(message, response)
return response
}
private buildSystemPrompt(): string {
return `You are MemGPT, with virtual context management.
Core Memory (limited): ${this.mainContext.usage()}/${this.mainContext.limit()} tokens
Recursive Summary: Available
External Memory: ${this.externalMemory.size()} items
Available functions:
- core_memory_append: Add to core memory
- core_memory_replace: Replace in core memory
- recall_memory_search: Search external memory
- archival_memory_insert: Add to long-term storage
- archival_memory_search: Search long-term storage
Manage your memory actively to maintain context within limits.`
}
}Performance and Optimization
Memory Access Optimization
class MemoryAccessOptimizer {
private accessPatterns: AccessPatternAnalyzer
private prefetcher: MemoryPrefetcher
private indexer: MemoryIndexer
async optimizeAccess(workload: Workload): Promise<OptimizationPlan> {
// Analyze access patterns
const patterns = await this.accessPatterns.analyze(workload)
// Build optimization plan
const plan: OptimizationPlan = {
indexes: this.recommendIndexes(patterns),
caching: this.recommendCaching(patterns),
prefetching: this.recommendPrefetching(patterns),
partitioning: this.recommendPartitioning(patterns)
}
return plan
}
async implementOptimizations(plan: OptimizationPlan): Promise<void> {
// Create recommended indexes
for (const index of plan.indexes) {
await this.indexer.createIndex(index)
}
// Configure prefetching
this.prefetcher.configure(plan.prefetching)
// Set up intelligent caching
await this.setupCaching(plan.caching)
}
}Token-Efficient Memory Encoding
class TokenEfficientEncoder {
private compressor: SemanticCompressor
private abbreviator: Abbreviator
async encode(memory: Memory): Promise<EncodedMemory> {
// Remove redundancy
const deduplicated = this.removeRedundancy(memory)
// Abbreviate common patterns
const abbreviated = await this.abbreviator.abbreviate(deduplicated)
// Semantic compression
const compressed = await this.compressor.compress(abbreviated, {
preserveKeys: ['entities', 'relationships', 'outcomes'],
targetReduction: 0.5
})
return {
encoded: compressed,
originalTokens: this.countTokens(memory),
encodedTokens: this.countTokens(compressed),
compressionRatio: this.countTokens(compressed) / this.countTokens(memory)
}
}
}Implementation Examples
Multi-Domain Knowledge Assistant
class MultiDomainKnowledgeAssistant {
private domainMemories: Map<string, DomainMemory>
private crossDomainLinker: CrossDomainLinker
async processQuery(query: string, userId: string): Promise<Response> {
// Identify relevant domains
const domains = await this.identifyDomains(query)
// Retrieve domain-specific memories
const domainContexts = await Promise.all(
domains.map(domain =>
this.domainMemories.get(domain)?.retrieve(query, userId)
)
)
// Find cross-domain connections
const connections = await this.crossDomainLinker.findConnections(
domainContexts,
query
)
// Build integrated context
const integratedContext = this.integrateContexts(
domainContexts,
connections
)
// Generate response with full context
return await this.generateResponse(query, integratedContext)
}
}Collaborative Memory System
class CollaborativeMemorySystem {
private userMemories: Map<string, UserMemory>
private sharedMemory: SharedMemory
private privacyManager: PrivacyManager
async shareInsight(
insight: Insight,
sourceUserId: string,
targetUserIds: string[]
): Promise<void> {
// Check privacy permissions
const shareable = await this.privacyManager.canShare(
insight,
sourceUserId,
targetUserIds
)
if (!shareable) {
throw new Error('Privacy restrictions prevent sharing')
}
// Anonymize if needed
const processed = await this.privacyManager.processForSharing(insight)
// Add to shared memory with attribution
await this.sharedMemory.add({
...processed,
sharedBy: sourceUserId,
sharedWith: targetUserIds,
timestamp: new Date()
})
// Notify target users
for (const userId of targetUserIds) {
await this.notifyUser(userId, processed)
}
}
}Best Practices
- Design for Scale: Use hierarchical structures that can grow efficiently
- Prioritize Relevance: Not all memories are equally important
- Implement Forgetting: Prune low-value memories to maintain performance
- Version Memory Schemas: Enable backward compatibility as systems evolve
- Monitor Memory Health: Track access patterns and optimize accordingly
- Respect Privacy: Implement strong boundaries for user-specific memories
- Test Retrieval Quality: Regularly evaluate memory system effectiveness
Related Resources
- State Management for Long-Running Tasks
- Context Management Guide
- Vector Database Integration
- Graph Database Patterns
- Prompt Caching Strategies
Next Steps
- Implement Task Decomposition Strategies
- Explore Error Recovery Patterns
- Study Production Implementation Examples
Memory and context techniques are rapidly evolving. This guide reflects best practices as of January 2025. Regular updates recommended as new research emerges.