Memory for an AI agent
TeselaDB
TeselaDB team
25 minIntermediate
Store what an agent learns about each user with its vector and recall the closest memories to the current conversation.
An agent that remembers each user stores short sentences, such as a preference or a fact about their project, and in each conversation recalls the ones closest to what is being discussed. In TeselaDB, those memories are documents with their vector, a vector index with a filter by user and a TTL index that forgets them after a while.
What you will build
A memories collection in the agent database with a vector index filtered by userId and a query that returns a
user's two memories closest to the conversation. Memories older than 90 days are deleted on their own.
Requirements
mongoshand a user withreadWriteon theagentdatabase.- An embedding model for your texts. The examples use three-dimension vectors written by hand so you see the exact
result; with a real model,
numDimensionsis the size of its vectors.
1. Store the memories
Each memory carries the user, the text, its vector and the date. Two of them belong to Ana and one to Luis, whose vector is close to one of Ana's, so later you can check that a search for one user never returns the memories of the other:
db.memories.insertMany([
{ userId: "ana", text: "Prefers answers in Spanish", embedding: [0.9, 0.1, 0.0], createdAt: new Date() },
{ userId: "ana", text: "Works with a three-node cluster", embedding: [0.1, 0.9, 0.1], createdAt: new Date() },
{ userId: "luis", text: "Prefers short answers", embedding: [0.8, 0.2, 0.1], createdAt: new Date() },
]);2. Create the vector index
The userId field goes in as a filter, so a search never mixes the memories of two users. The loop waits until the
index can be queried:
db.memories.createSearchIndex({
name: "memory",
type: "vectorSearch",
definition: {
fields: [
{ type: "vector", path: "embedding", numDimensions: 3, similarity: "cosine" },
{ type: "filter", path: "userId" },
],
},
});
while (!db.memories.getSearchIndexes("memory")[0]?.queryable) sleep(100);3. Forget what is old
A TTL index on createdAt deletes each memory 90 days after it was stored:
db.memories.createIndex({ createdAt: 1 }, { expireAfterSeconds: 60 * 60 * 24 * 90 });Try it
Look for Ana's two memories closest to the conversation's vector, [1, 0, 0] in this example. With exact: true the
search compares with every vector and gives the same result on any replica. The filter keeps it inside Ana's memories:
db.memories.aggregate([
{
$vectorSearch: {
index: "memory",
path: "embedding",
queryVector: [1, 0, 0],
exact: true,
limit: 2,
filter: { userId: "ana" },
},
},
{ $project: { _id: 0, text: 1 } },
]);[
{ text: 'Prefers answers in Spanish' },
{ text: 'Works with a three-node cluster' }
]Luis's memories do not show up even though his vector is close, because the filter leaves the other users out. If
your agent uses MCP, the aggregate tool of the MCP server runs this same query.
Clean up
db.memories.drop();Dropping the test collection also drops its two indexes, the vector one and the TTL one.
Next steps
- Vector search, with approximate search and its options.
- Connect an AI agent with MCP, to give the agent access to its memories.