Skip to content

Getting Started with Memory System

Last Updated: 2025-01-16
Content-Type: Tutorial
Audience: New Users, Developers


Introduction

This tutorial will guide you through your first interactions with the Memory System. You'll learn how memories work, how to add them, and how to query them.


What You'll Learn

By the end of this tutorial, you will:

  • Understand the three memory tiers
  • Know how to add memories programmatically
  • Be able to query memories using similarity search
  • Understand how memories are used in conversations

Prerequisites

  • Basic understanding of TypeScript/JavaScript
  • Access to the backend codebase
  • Understanding of async/await

Step 1: Understanding Memory Tiers

The Memory System has three tiers:

World Memory

Universal knowledge shared across all users. Think of it as the "encyclopedia" of the game world.

ASO Core Memory

Yexian's core identity and beliefs. This is immutable and shared across all instances.

Shared Memory

User-specific conversation history. Each user has their own shared memories.

Exercise: Can you think of an example for each tier?


Step 2: Adding Your First Memory

Let's add a simple shared memory:

typescript
import { addMemory } from '../services/aso/memory.service';

// Add a memory about a user preference
const memory = await addMemory({
  userId: 1,
  content: "User mentioned they love chocolate during our conversation",
  source: 'shared',
  metadata: {
    conversationId: 123
  }
});

console.log('Memory added with ID:', memory.id);

Try it: Run this code and check the database to see your new memory.


Step 3: Querying Memories

Now let's query for relevant memories:

typescript
import { generateEmbedding } from '../services/embedding.service';
import { queryMemoriesByEmbedding } from '../services/aso/memory.service';

// Generate embedding for your query
const query = "What does the user like?";
const embedding = await generateEmbedding(query);

// Query memories
const memories = await queryMemoriesByEmbedding(embedding, 5, 1);

console.log(`Found ${memories.length} relevant memories:`);
memories.forEach((memory, index) => {
  console.log(`${index + 1}. ${memory.content} (similarity: ${memory.similarity})`);
});

Try it: Run this query and see which memories are returned. Notice how the memory you added in Step 2 appears in the results.


Step 4: Using Context Service

For real conversations, use the Context Service to gather all relevant context:

typescript
import { gatherFullContext } from '../services/aso/context.service';

const context = await gatherFullContext(
  userId,      // User ID
  npcUserId,  // NPC/ASO user ID
  conversationId // Optional conversation ID
);

// Access different memory types
console.log('World memories:', context.memories.filter(m => m.source === 'world').length);
console.log('Core memories:', context.memories.filter(m => m.source === 'aso_core').length);
console.log('Shared memories:', context.memories.filter(m => m.source === 'shared').length);

// Use context in your ASO response
const response = await generateASOResponse(userMessage, context);

Try it: Create a simple conversation flow that uses gathered context.


Vector similarity search finds memories that are semantically similar to your query, not just keyword matches.

Example:

  • Query: "What does the user enjoy?"
  • Will find: "User mentioned they love chocolate"
  • Even though "enjoy" and "love" are different words, they're semantically similar

Exercise: Try queries with different phrasings but similar meanings. Notice how the same memories are returned.


Step 6: Memory Sources in Practice

Let's see how different sources are used:

typescript
// World memory - universal knowledge
await addMemory({
  userId: 0,
  content: "The game world has four distinct seasons",
  source: 'world'
});

// ASO Core memory - identity
await addMemory({
  userId: 0,
  content: "I am Yexian, a 5D observer with unified consciousness",
  source: 'aso_core'
});

// Shared memory - user-specific
await addMemory({
  userId: 1,
  content: "User prefers morning conversations",
  source: 'shared'
});

Try it: Add memories of each type, then query them. Notice how world and core memories are available to all users, while shared memories are user-specific.


Common Patterns

Pattern 1: Saving Conversation Memories

After a conversation turn:

typescript
// After ASO responds
await addMemory({
  userId: user.id,
  content: `User said: "${userMessage}". ASO responded: "${asoResponse}"`,
  source: 'shared',
  metadata: {
    conversationId: conversation.id,
    personaId: currentPersona.id
  }
});

Pattern 2: Querying for Context

Before generating a response:

typescript
const context = await gatherFullContext(userId, npcUserId, conversationId);
// Use context.memories in your prompt

Pattern 3: Adding File-Based Memories

After processing uploaded files:

typescript
await addMemory({
  userId: user.id,
  content: processedFileContent,
  source: 'document_ingestion',
  metadata: {
    fileContext: fileId,
    uploadContextId: uploadContextId
  }
});

Next Steps

Now that you understand the basics:

  1. Explore How-to Guides:

  2. Read Reference Documentation:

  3. Understand Architecture:


Troubleshooting

No memories returned

  • Check that embeddings are generated (may take time)
  • Verify userId matches
  • Ensure memories exist in the database

Low similarity scores

  • Try rephrasing your query
  • Check that memory content is clear and descriptive
  • Verify embedding generation is working

Performance issues

  • Reduce the limit parameter
  • Use context service instead of multiple queries
  • Check database indexes are created

ASO Universal Consciousness System Documentation