Memory Management Guide
This guide covers best practices for managing memories in your application using the Papr Memory API. We'll explore strategies for organizing, updating, and maintaining your memory store effectively.
Memory Structure
A memory in Papr consists of:
interface Memory {
content: string; // The main content
type: "text" | "code_snippet" | "document"; // Content type
metadata?: {
topics?: string; // Comma-separated topics
hierarchical_structures?: string; // Navigation path (e.g., "Business/Planning/Product")
createdAt?: string; // ISO timestamp
location?: string; // Optional location context
"emoji tags"?: string; // Emoji representations
"emotion tags"?: string; // Emotional context
conversationId?: string; // For linking related memories
sourceUrl?: string; // Original source if applicable
};
context?: Array<{
role: "user" | "assistant";
content: string;
}>;
}
Organizing Memories
Using Metadata Effectively
- Topics
const memory = {
content: "Discussion about new feature requirements",
metadata: {
topics: "product development, feature planning, user feedback",
hierarchical_structures: "Product/Features/Requirements"
}
};
- Emotional Context
const memory = {
content: "Team celebration of successful launch",
metadata: {
"emoji tags": "🎉,🚀,🎯",
"emotion tags": "excited, accomplished, proud"
}
};
- Conversation Threading
const memory = {
content: "Follow-up on feature discussion",
metadata: {
conversationId: "feat-123-discussion",
sourceUrl: "https://meeting-notes.company.com/123"
}
};
Memory Lifecycle Management
1. Creating Memories
Always validate and format your content before creation:
function prepareMemory(content: string, type: string) {
return {
content: content.trim(),
type,
metadata: {
createdAt: new Date().toISOString(),
topics: extractTopics(content), // Your topic extraction logic
hierarchical_structures: determineHierarchy(content) // Your hierarchy logic
}
};
}
const memory = prepareMemory("Meeting notes...", "text");
const response = await fetch('https://memory.papr.ai/v1/memory', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': '<your-api-key>',
'X-Client-Type': 'your_app_name',
'Accept-Encoding': 'gzip'
},
body: JSON.stringify(memory)
});
2. Updating Memories
Keep track of memory changes:
const updateMemory = async (memoryId: string, updates: Partial<Memory>) => {
const response = await fetch(`https://memory.papr.ai/v1/memory/${memoryId}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'X-API-Key': '<your-api-key>',
'X-Client-Type': 'your_app_name',
'Accept-Encoding': 'gzip'
},
body: JSON.stringify({
...updates,
metadata: {
...updates.metadata,
updatedAt: new Date().toISOString()
}
})
});
return response.json();
};
3. Batch Processing
Group related memories for efficient processing:
const batchAddMemories = async (memories: Memory[]) => {
// Group memories by type
const groupedMemories = memories.reduce((acc, memory) => {
acc[memory.type] = acc[memory.type] || [];
acc[memory.type].push(memory);
return acc;
}, {});
// Process each group
for (const [type, typeMemories] of Object.entries(groupedMemories)) {
const response = await fetch('https://memory.papr.ai/v1/memory/batch', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': '<your-api-key>',
'X-Client-Type': 'your_app_name',
'Accept-Encoding': 'gzip'
},
body: JSON.stringify({
memories: typeMemories,
batch_size: 10
})
});
const result = await response.json();
handleBatchResults(result); // Your result handling logic
}
};
Search and Retrieval Strategies
1. Semantic Search
Write detailed queries for better results:
const searchMemories = async (topic: string, context: string) => {
const response = await fetch('https://memory.papr.ai/v1/memory/search', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': '<your-api-key>',
'X-Client-Type': 'your_app_name',
'Accept-Encoding': 'gzip'
},
body: JSON.stringify({
query: `Find detailed discussions about ${topic} that include ${context}. Focus on items with specific examples or decisions made.`
})
});
return response.json();
};
2. Result Processing
Handle search results effectively:
interface SearchResult {
memories: Memory[];
nodes: Node[]; // Graph nodes if available
}
function processSearchResults(results: SearchResult) {
// Group by hierarchical structure
const groupedResults = results.memories.reduce((acc, memory) => {
const hierarchy = memory.metadata?.hierarchical_structures || 'Uncategorized';
acc[hierarchy] = acc[hierarchy] || [];
acc[hierarchy].push(memory);
return acc;
}, {});
// Sort within each group by date
for (const hierarchy in groupedResults) {
groupedResults[hierarchy].sort((a, b) => {
return new Date(b.metadata.createdAt) - new Date(a.metadata.createdAt);
});
}
return groupedResults;
}
Error Handling and Monitoring
Implement robust error handling:
async function safeMemoryOperation<T>(operation: () => Promise<T>): Promise<T> {
const maxRetries = 3;
let lastError: Error;
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await operation();
} catch (error) {
lastError = error;
if (error.status === 429) { // Rate limit
const retryAfter = parseInt(error.headers.get('Retry-After') || '5');
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
continue;
}
if (error.status >= 500) { // Server error
await new Promise(resolve => setTimeout(resolve, attempt * 1000));
continue;
}
throw error; // Client error or other - don't retry
}
}
throw lastError;
}
// Usage
const memory = await safeMemoryOperation(() =>
fetch('https://memory.papr.ai/v1/memory/123')
.then(res => res.json())
);
Best Practices Summary
Content Organization
- Use consistent hierarchical structures
- Apply relevant emoji and emotion tags
- Link related memories with conversationId
Performance Optimization
- Use batch operations for multiple memories
- Enable gzip compression for searches
- Monitor and handle rate limits
Data Quality
- Validate content before storage
- Keep metadata consistent and updated
- Use meaningful topics and hierarchies
Error Handling
- Implement retry logic for transient errors
- Handle rate limits gracefully
- Log and monitor error patterns
Search Optimization
- Write detailed, context-rich queries
- Process and group results meaningfully
- Cache frequently accessed memories
Next Steps
- Explore our API Reference for detailed endpoint documentation
- Check out our Context Handling Guide for advanced context management
- View our Retrieval Guide for advanced search techniques