Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MASTRA-1183] Agent Memory Docs Update #1242

Merged
merged 6 commits into from
Jan 6, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
203 changes: 106 additions & 97 deletions docs/src/pages/docs/agents/01-agent-memory.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,183 +2,192 @@

Agents in Mastra have a memory that stores conversation history and contextual information. This memory allows agents to maintain state across interactions, enabling more coherent and context-aware responses.

There are three main ways to implement agent memory in Mastra:
There are two main ways to implement agent memory in Mastra:

1. **In-Memory Storage** (Default)
2. **Using Mastra Engine**
3. **Using External Storage (Redis or PostgreSQL)**
1. **Using KV Upstash**
2. **Using External Storage (Redis or PostgreSQL)**

## 1. Default In-Memory Storage
## 1. Using KV Upstash

Let's start by revisiting the example from the [overview](/guide/creating-agents/00-overview.mdx) page.
KV Upstash provides a serverless Redis-compatible key-value store that's perfect for agent memory storage. Here's how to set it up:

```typescript showLineNumbers filename="src/mastra/index.ts" copy
const response1 = await myAgent.generate("Which LLM model are you?", {
threadId: "thread_1",
});
First, install the necessary package:

await myAgent.memory.save("thread_1");
const memoryMessages = await myAgent.memory.getMessages({
threadId: "thread_1",
});
console.log("Agent Memory:", memoryMessages);
```bash
npm install @mastra/memory
```

This is the simplest way to use agent memory -- with the default in-memory storage. It's suitable for local development, testing, or backend processes outside the context of a user session and request/response cycle.

Especially if you're using `mastra dev` or otherwise running agents behind an API, you'll want to use a more persistent memory backend.

## 2. Using Mastra Engine

The Mastra engine is a Postgres database that you can install locally using the Mastra CLI. It's a helpful backend for agent memory during development because you can inspect agent memory more easily.

### Setting Up Mastra Engine for Agent Memory

1. **Install Mastra Engine**:
Create an Upstash account and database:

```bash npm2yarn copy
npm install @mastra/engine
```
1. Go to https://upstash.com/ and sign up for an account
2. Create a new database in your preferred region
3. Copy your REST URL and TOKEN from the database details page

2. **Configure Mastra**:
Then, configure your agent to use Upstash KV:

```typescript showLineNumbers
```typescript
// src/mastra/index.ts
import { Mastra } from "@mastra/core";
import { mastraEngine } from "@mastra/engine";
import { UpstashKVMemory } from "@mastra/memory";

import { myAgent } from "./agents";

// Create UpstashKVMemory
const upstashKVMemory = new UpstashKVMemory({
url: process.env.UPSTASH_REDIS_REST_URL!,
token: process.env.UPSTASH_REDIS_REST_TOKEN!,
});

export const mastra = new Mastra({
engine: mastraEngine,
memory: upstashKVMemory,
agents: { myAgent },
});
```

3. **Run Mastra Engine**:
Add your Upstash credentials to your environment variables:

```bash
mastra engine up
```env
# .env
UPSTASH_REDIS_REST_URL=https://your-url.upstash.io
UPSTASH_REDIS_REST_TOKEN=your_token
```

This command sets up the necessary infrastructure for Mastra Engine.
## 2. Using External Storage

## 3. Using External Storage
For production environments where you need persistent memory across restarts and scalability, you can use a external storage backend like PostgreSQL.

For production environments where you need persistent memory across restarts and scalability, you can use external storage backends like Redis or PostgreSQL.

### Using Redis for Agent Memory
### Using PostgreSQL for Agent Memory

First, install the necessary packages:

```bash
npm install @mastra/memory redis
```bash npm2yarn copy
npm install @mastra/memory
```

Then, configure your agent to use Redis for memory storage:
Then, configure your agent to use PostgreSQL for memory storage:

```typescript
// src/mastra/index.ts
import { Mastra } from "@mastra/core";
import { RedisMemory } from "@mastra/memory";
import { createClient } from "redis";
import { PostgresMemory } from "@mastra/memory";

import { myAgent } from "./agents";

// Create a Redis client
const redisClient = createClient({
url: process.env.REDIS_URL, // e.g., "redis://localhost:6379"
});

redisClient.connect();

const redisMemory = new RedisMemory({
client: redisClient,
// Create a PgMemory using connectionString
const pgMemory = new PgMemory({
connectionString: process.env.POSTGRES_CONNECTION_STRING!,
});

export const mastra = new Mastra({
memory: redisMemory,
memory: pgMemory,
agents: { myAgent },
});
```

Ensure you have your Redis URL set in your environment variables:
Ensure you have your PostgreSQL connection string set in your environment variables:

```env
# .env
REDIS_URL=redis://your_redis_server_url
POSTGRES_CONNECTION_STRING=postgresql://user:password@localhost:5432/your_database
```

### Using PostgreSQL for Agent Memory
## Managing Agent Memory

First, install the necessary packages:
Once your agent is configured with a memory backend, you can manage its memory using the following methods.

```bash
npm install @mastra/memory pg
```
### Creating a Thread

Then, configure your agent to use PostgreSQL for memory storage:
First, create a new conversation thread for your agent:

```typescript
// src/mastra/index.ts
import { Mastra } from "@mastra/core";
import { PostgresMemory } from "@mastra/memory";
import { Pool } from "pg";
const thread = await mastra.memory.createThread({
resourceId: "memory_id"
});
```

import { myAgent } from "./agents";
This creates a new thread and assigns it a unique identifier. The `resourceId` parameter helps identify which memory context this thread belongs to.

// Create a PostgreSQL pool
const pgPool = new Pool({
connectionString: process.env.POSTGRES_CONNECTION_STRING,
});
### Save Messages on Generate

const pgMemory = new PostgresMemory({
pool: pgPool,
Generate responses while maintaining conversation context.
The `threadId` parameter links messages to a specific conversation thread, while `resourceId` associates the conversation with a particular memory context or resource:

```typescript
const responseOne = await myAgent.generate("Tell me about the project requirements.", {
resourceId: "memory_id",
threadId: thread.id,
});

export const mastra = new Mastra({
memory: pgMemory,
agents: { myAgent },
const responseTwo = await myAgent.generate("What are the next steps?", {
resourceId: "memory_id",
threadId: thread.id,
});
```
Each generate call automatically preserves the conversation context in memory.

Ensure you have your PostgreSQL connection string set in your environment variables:
### Saving Messages to Memory

```env
# .env
POSTGRES_CONNECTION_STRING=postgresql://user:password@localhost:5432/your_database
```
You can explicitly save messages to the thread from the agent.

## Managing Agent Memory
```typescript
await myAgent.saveMemory({
threadId: thread.id,
resourceId: "memory_id",
userMessages: [
{
role: "user",
content: "What are the main performance bottlenecks?",
},
],
});
```

Once your agent is configured with a memory backend, you can manage its memory using the following methods.
This method enables you to manually preserve specific messages in the thread's memory.

### Saving the Agent's Memory
### Retrieving Messages From Memory

Save the agent's memory state with a unique identifier:
To check the current messages in memory at any point:

```typescript
await myAgent.memory.save("memory_id");
const messages = await mastra.memory.getMessages({
threadId: thread.id,
});
```

This persists the current memory state, allowing you to reload it later.
Retrieves all messages from the specified thread in chronological order.

### Retrieving Context Window

You can use memory to retrieve messages within a specific time range:

### Loading the Agent's Memory
```typescript
const messages = await mastra.memory.getContextWindow({
threadId: thread.id,
startDate: new Date('2024-01-01'),
endDate: new Date('2024-01-31'),
format: 'raw'
});
```

Load a previously saved memory state:
You can optionally limit the total tokens in the context window by configuring maxTokens in your memory:

```typescript
await myAgent.memory.load("memory_id");
const upstashKVMemory = new UpstashKVMemory({
url: process.env.UPSTASH_REDIS_REST_URL!,
token: process.env.UPSTASH_REDIS_REST_TOKEN!,
maxTokens: 4000 // Limit total tokens in context window
});
```

This replaces the agent's current memory with the saved state associated with `memory_id`.
When maxTokens is set, messages are filtered by date range and then processed from newest to oldest until the token limit is reached.
This maintains the context window size while preserving the most recent conversation history.

### Clearing the Agent's Memory
### Deleting a Thread

To clear the agent's memory, removing all stored messages and context:
To remove a thread and all its associated messages:

```typescript
await myAgent.memory.clear();
await mastra.memory.deleteThread(thread.id);
```

This resets the agent's memory to an empty state.
Permanently deletes the thread and its messages.