Skip to main content

存储

🌐 Storage

为了让代理记住之前的互动,Mastra 需要一个数据库。请为其中一个支持的数据库使用存储适配器,并将其传递给你的 Mastra 实例。

🌐 For agents to remember previous interactions, Mastra needs a database. Use a storage adapter for one of the supported databases and pass it to your Mastra instance.

src/mastra/index.ts
import { Mastra } from "@mastra/core";
import { LibSQLStore } from "@mastra/libsql";

export const mastra = new Mastra({
storage: new LibSQLStore({
id: 'mastra-storage',
url: "file:./mastra.db",
}),
});

This configures instance-level storage, which all agents share by default. You can also configure agent-level storage for isolated data boundaries.

Mastra 会在第一次交互时自动创建必要的表。有关创建的内容详情,请参见 核心架构,包括消息、线程、资源、工作流、跟踪和评估数据集的表。

🌐 Mastra automatically creates the necessary tables on first interaction. See the core schema for details on what gets created, including tables for messages, threads, resources, workflows, traces, and evaluation datasets.

支持的提供商
Direct link to 支持的提供商

🌐 Supported providers

每个提供商页面都包括安装说明、配置参数和使用示例:

🌐 Each provider page includes installation instructions, configuration parameters, and usage examples:

tip

libSQL 是最容易上手的方式,因为它不需要运行独立的数据库服务器。

配置范围
Direct link to 配置范围

🌐 Configuration scope

存储可以在实例级别(由所有代理共享)或代理级别(仅针对特定代理隔离)进行配置。

🌐 Storage can be configured at the instance level (shared by all agents) or at the agent level (isolated to a specific agent).

实例级存储
Direct link to 实例级存储

🌐 Instance-level storage

为你的 Mastra 实例添加存储,以便所有代理、工作流、可观测性追踪和评分共享相同的内存提供商:

🌐 Add storage to your Mastra instance so all agents, workflows, observability traces and scores share the same memory provider:

src/mastra/index.ts
import { Mastra } from "@mastra/core";
import { PostgresStore } from "@mastra/pg";

export const mastra = new Mastra({
storage: new PostgresStore({
id: 'mastra-storage',
connectionString: process.env.DATABASE_URL,
}),
});

// Both agents inherit storage from the Mastra instance above
const agent1 = new Agent({ id: "agent-1", memory: new Memory() });
const agent2 = new Agent({ id: "agent-2", memory: new Memory() });

当所有原语共享相同的存储后端并且具有类似的性能、扩展性和操作需求时,这会非常有用。

🌐 This is useful when all primitives share the same storage backend and have similar performance, scaling, and operational requirements.

复合存储
Direct link to 复合存储

🌐 Composite storage

复合存储 是配置实例级存储的另一种方法。使用 MastraCompositeStorememory 域(以及你需要的任何其他 )设置为不同的存储提供商。

src/mastra/index.ts
import { Mastra } from "@mastra/core";
import { MastraCompositeStore } from "@mastra/core/storage";
import { MemoryLibSQL } from "@mastra/libsql";
import { WorkflowsPG } from "@mastra/pg";
import { ObservabilityStorageClickhouse } from "@mastra/clickhouse";

export const mastra = new Mastra({
storage: new MastraCompositeStore({
id: "composite",
domains: {
memory: new MemoryLibSQL({ url: "file:./memory.db" }),
workflows: new WorkflowsPG({ connectionString: process.env.DATABASE_URL }),
observability: new ObservabilityStorageClickhouse({
url: process.env.CLICKHOUSE_URL,
username: process.env.CLICKHOUSE_USERNAME,
password: process.env.CLICKHOUSE_PASSWORD,
}),
},
}),
});

当不同类型的数据有不同的性能或操作要求时,这非常有用,例如用于内存的低延迟存储、用于工作流的持久存储以及用于可观测性的高吞吐量存储。

🌐 This is useful when different types of data have different performance or operational requirements, such as low-latency storage for memory, durable storage for workflows, and high-throughput storage for observability.

代理级存储
Direct link to 代理级存储

🌐 Agent-level storage

代理级别的存储会覆盖实例级别配置的存储。当你需要数据边界或合规性要求时,可以为特定代理添加存储:

🌐 Agent-level storage overrides storage configured at the instance level. Add storage to a specific agent when you need data boundaries or compliance requirements:

src/mastra/agents/your-agent.ts
import { Agent } from "@mastra/core/agent";
import { Memory } from "@mastra/memory";
import { PostgresStore } from "@mastra/pg";

export const agent = new Agent({
id: "agent",
memory: new Memory({
storage: new PostgresStore({
id: 'agent-storage',
connectionString: process.env.AGENT_DATABASE_URL,
}),
}),
});
warning

Mastra Cloud Store 不支持代理级存储。

线程和资源
Direct link to 线程和资源

🌐 Threads and resources

Mastra 使用两个标识符来组织对话:

🌐 Mastra organizes conversations using two identifiers:

  • 线程 - 包含一系列消息的会话。
  • 资源 - 拥有线程的实体,例如用户、组织、项目或应用中的任何其他字段实体。

存储信息时,代理需要两个标识符:

🌐 Both identifiers are required for agents to store information:

const response = await agent.generate("hello", {
memory: {
thread: "conversation-abc-123",
resource: "user_123",
},
});
note

Studio 会自动为你生成线程和资源 ID。当你自己调用 stream()generate() 时,请记得显式提供这些标识符。

主题标题生成
Direct link to 主题标题生成

🌐 Thread title generation

当启用 generateTitle 时,Mastra 可以根据用户的第一条消息自动生成描述性主题标题。

🌐 Mastra can automatically generate descriptive thread titles based on the user's first message when generateTitle is enabled.

在实现类似 ChatGPT 的聊天界面时使用此选项,以在会话列表中为每个线程呈现标题(例如,在侧边栏中),标题由线程的初始用户消息生成。

🌐 Use this option when implementing a ChatGPT-style chat interface to render a title alongside each thread in the conversation list (for example, in a sidebar) derived from the thread’s initial user message.

src/mastra/agents/my-agent.ts
export const agent = new Agent({
id: "agent",
memory: new Memory({
options: {
generateTitle: true,
},
}),
});

标题生成在代理响应后异步进行,并且不影响响应时间。

🌐 Title generation runs asynchronously after the agent responds and does not affect response time.

为了优化成本或行为,请提供较小的 model 和自定义 instructions

🌐 To optimize cost or behavior, provide a smaller model and custom instructions:

src/mastra/agents/my-agent.ts
export const agent = new Agent({
id: "agent",
memory: new Memory({
options: {
generateTitle: {
model: "openai/gpt-4o-mini",
instructions: "Generate a 1 word title",
},
},
}),
});

语义回忆
Direct link to 语义回忆

🌐 Semantic recall

语义检索有不同的存储要求——它除了需要标准存储适配器之外,还需要一个向量数据库。有关设置和支持的向量提供商,请参见语义检索

🌐 Semantic recall has different storage requirements - it needs a vector database in addition to the standard storage adapter. See Semantic recall for setup and supported vector providers.

处理大型附件
Direct link to 处理大型附件

🌐 Handling large attachments

一些存储提供商会强制执行记录大小限制,而 base64 编码的文件附件(如图片)可能会超出这个限制:

🌐 Some storage providers enforce record size limits that base64-encoded file attachments (such as images) can exceed:

提供商记录大小限制
DynamoDB400 KB
Convex1 MiB
Cloudflare D11 MiB

PostgreSQL、MongoDB 和 libSQL 的限制更高,通常不受影响。

🌐 PostgreSQL, MongoDB, and libSQL have higher limits and are generally unaffected.

为避免这种情况,请使用输入处理器将附件上传到外部存储(S3、R2、GCS、Convex 文件存储 等),并在保存之前将其替换为 URL 引用。

🌐 To avoid this, use an input processor to upload attachments to external storage (S3, R2, GCS, Convex file storage, etc.) and replace them with URL references before persistence.

src/mastra/processors/attachment-uploader.ts
import type { Processor } from "@mastra/core/processors";
import type { MastraDBMessage } from "@mastra/core/memory";

export class AttachmentUploader implements Processor {
id = "attachment-uploader";

async processInput({ messages }: { messages: MastraDBMessage[] }) {
return Promise.all(messages.map((msg) => this.processMessage(msg)));
}

async processMessage(msg: MastraDBMessage) {
const attachments = msg.content.experimental_attachments;
if (!attachments?.length) return msg;

const uploaded = await Promise.all(
attachments.map(async (att) => {
// Skip if already a URL
if (!att.url?.startsWith("data:")) return att;

// Upload base64 data and replace with URL
const url = await this.upload(att.url, att.contentType);
return { ...att, url };
})
);

return { ...msg, content: { ...msg.content, experimental_attachments: uploaded } };
}

async upload(dataUri: string, contentType?: string): Promise<string> {
const base64 = dataUri.split(",")[1];
const buffer = Buffer.from(base64, "base64");

// Replace with your storage provider (S3, R2, GCS, Convex, etc.)
// return await s3.upload(buffer, contentType);
throw new Error("Implement upload() with your storage provider");
}
}

将处理器与你的代理一起使用:

🌐 Use the processor with your agent:

import { Agent } from "@mastra/core/agent";
import { Memory } from "@mastra/memory";
import { AttachmentUploader } from "./processors/attachment-uploader";

const agent = new Agent({
id: "my-agent",
memory: new Memory({ storage: yourStorage }),
inputProcessors: [new AttachmentUploader()],
});