跳至主要內容

語義回憶

如果你問朋友上週末做過甚麼,他們會在記憶中搜尋與「上週末」相關的事件,然後告訴你做過甚麼。這大概就是 Mastra 語義回憶的運作方式。

📹 觀看影片

觀看 Mastra 語義回憶,了解 Agent 如何擷取過往對話中的相關訊息。

語義回憶的運作方式
語義回憶的運作方式 的直接連結

語義回憶是一種以 RAG 為基礎的搜尋功能。當訊息已不在近期訊息記錄中時,它可協助 Agent 在較長的互動中保持上下文。

它使用訊息的向量嵌入進行相似度搜尋,並與向量儲存整合,也可設定所擷取訊息前後的上下文視窗。

顯示 Mastra Memory 語義回憶的圖表

啟用後,新訊息會用於查詢向量資料庫,以找出語義相似的訊息。

LLM 回應後,所有新訊息(使用者、編程助手,以及 Tool 呼叫/結果)都會插入向量資料庫,以供日後互動回憶。

快速開始
快速開始 的直接連結

語義回憶預設為停用。要啟用此功能,請將 semanticRecall: true 設於 options 中,並提供 vector 儲存和 embedder

src/mastra/agents/index.ts
import { Agent } from '@mastra/core/agent'
import { Memory } from '@mastra/memory'
import { LibSQLStore, LibSQLVector } from '@mastra/libsql'
import { ModelRouterEmbeddingModel } from '@mastra/core/llm'

const agent = new Agent({
id: 'support-agent',
name: 'SupportAgent',
instructions: 'You are a helpful support agent.',
model: 'openai/gpt-5.6-sol',
memory: new Memory({
storage: new LibSQLStore({
id: 'agent-storage',
url: 'file:./local.db',
}),
vector: new LibSQLVector({
id: 'agent-vector',
url: 'file:./local.db',
}),
embedder: new ModelRouterEmbeddingModel('openai/text-embedding-3-small'),
options: {
semanticRecall: true,
},
}),
})

使用 recall() 方法
using-the-recall-method 的直接連結

listMessages 會透過執行緒 ID 和基本分頁功能擷取訊息,而 recall() 亦支援語義搜尋。如需按語義而非時間先後尋找訊息,請使用 recall(),並傳入 vectorSearchString

const memory = await agent.getMemory()

// Basic recall - similar to listMessages
const { messages } = await memory!.recall({
threadId: 'thread-123',
perPage: 50,
})

// Semantic recall - find messages by meaning
const { messages: relevantMessages } = await memory!.recall({
threadId: 'thread-123',
vectorSearchString: 'What did we discuss about the project deadline?',
threadConfig: {
semanticRecall: true,
},
})

儲存設定
儲存設定 的直接連結

語義回憶依賴儲存和向量資料庫來儲存訊息及其嵌入。

src/mastra/agents/index.ts
import { Memory } from '@mastra/memory'
import { Agent } from '@mastra/core/agent'
import { LibSQLStore, LibSQLVector } from '@mastra/libsql'

const agent = new Agent({
memory: new Memory({
// this is the default storage db if omitted
storage: new LibSQLStore({
id: 'agent-storage',
url: 'file:./local.db',
}),
// this is the default vector db if omitted
vector: new LibSQLVector({
id: 'agent-vector',
url: 'file:./local.db',
}),
options: {
semanticRecall: true,
},
}),
})

以下每個向量儲存頁面都包含安裝說明、設定參數和使用範例:

回憶設定
回憶設定 的直接連結

以下選項控制語義回憶的行為:

  1. topK:要擷取的相似訊息數目
  2. messageRange:每個相符結果前後要包含的訊息
  3. scope:搜尋目前執行緒,還是搜尋資源的所有執行緒
  4. filter:限制搜尋結果的中繼資料條件
const agent = new Agent({
id: 'agent',
memory: new Memory({
options: {
semanticRecall: {
topK: 3, // Retrieve 3 similar messages
messageRange: 2, // Include 2 messages before and after each match
scope: 'resource', // Search all threads for this resource
filter: { projectId: { $eq: 'project-a' } },
},
},
}),
})
備註

LibSQL、OracleDB、PostgreSQL、MongoDB 和 Upstash 儲存轉接器支援 scope: 'resource'

中繼資料篩選
中繼資料篩選 的直接連結

filter 選項會將語義回憶結果限制為執行緒中繼資料相符的訊息。

const agent = new Agent({
id: 'agent',
memory: new Memory({
options: {
semanticRecall: {
scope: 'resource',
filter: {
projectId: { $eq: 'project-a' },
category: { $in: ['work', 'personal'] },
},
},
},
}),
})

儲存訊息時,篩選條件會比對訊息嵌入所儲存的中繼資料。如果執行緒中繼資料其後有所變更,現有嵌入會保留先前的中繼資料,直至再次儲存或建立這些訊息的索引。

支援的篩選運算子:

  • $and:邏輯 AND
  • $eq:等於
  • $gt:大於
  • $gte:大於或等於
  • $in:在陣列中
  • $lt:小於
  • $lte:小於或等於
  • $ne:不等於
  • $nin:不在陣列中
  • $or:邏輯 OR

以下範例示範常見使用情境的中繼資料篩選條件:

// Filter by project
const options = {
semanticRecall: { filter: { projectId: { $eq: 'my-project' } } },
}

// Filter by multiple categories
const options = {
semanticRecall: { filter: { category: { $in: ['work', 'research'] } } },
}

// Filter by project and priority
const options = {
semanticRecall: {
filter: {
$and: [{ projectId: { $eq: 'project-a' } }, { priority: { $gte: 3 } }],
},
},
}

Embedder 設定
Embedder 設定 的直接連結

語義回憶依賴嵌入模型將訊息轉換成嵌入。Mastra 透過 model router 使用 provider/model 字串支援嵌入模型,你亦可使用任何與 AI SDK 兼容的嵌入模型

最簡單的方法是使用支援自動完成的 provider/model 字串:

src/mastra/agents/index.ts
import { Memory } from '@mastra/memory'
import { Agent } from '@mastra/core/agent'
import { ModelRouterEmbeddingModel } from '@mastra/core/llm'

const agent = new Agent({
id: 'agent',
memory: new Memory({
embedder: new ModelRouterEmbeddingModel('openai/text-embedding-3-small'),
options: {
semanticRecall: true,
},
}),
})

支援的嵌入模型:

  • OpenAItext-embedding-3-smalltext-embedding-3-largetext-embedding-ada-002
  • Googlegemini-embedding-001
  • OpenRouter:存取不同 Provider 的嵌入模型
import { Agent } from '@mastra/core/agent'
import { Memory } from '@mastra/memory'
import { ModelRouterEmbeddingModel } from '@mastra/core/llm'

const agent = new Agent({
id: 'agent',
memory: new Memory({
embedder: new ModelRouterEmbeddingModel({
providerId: 'openrouter',
modelId: 'openai/text-embedding-3-small',
}),
}),
})

Model router 會自動從環境變數(OPENAI_API_KEYGOOGLE_API_KEYOPENROUTER_API_KEY)偵測 API 金鑰。Google 模型亦會回退使用 GOOGLE_GENERATIVE_AI_API_KEY

使用 AI SDK 依賴套件
使用 AI SDK 依賴套件 的直接連結

你亦可直接使用 AI SDK 嵌入模型:

import { Memory } from '@mastra/memory'
import { Agent } from '@mastra/core/agent'
import { ModelRouterEmbeddingModel } from '@mastra/core/llm'

const agent = new Agent({
id: 'agent',
memory: new Memory({
embedder: new ModelRouterEmbeddingModel('openai/text-embedding-3-small'),
}),
})

使用 FastEmbed(本機)
使用 FastEmbed(本機) 的直接連結

要使用 FastEmbed(本機嵌入模型),請安裝 @mastra/fastembed

npm install @mastra/fastembed@latest

然後在 memory 中進行設定:

import { Memory } from '@mastra/memory'
import { Agent } from '@mastra/core/agent'
import { fastembed } from '@mastra/fastembed'

const agent = new Agent({
id: 'agent',
memory: new Memory({
embedder: fastembed,
}),
})

PostgreSQL 索引最佳化
PostgreSQL 索引最佳化 的直接連結

使用 PostgreSQL 作為向量儲存時,你可以設定向量索引,以改善語義回憶的效能。對於包含數以千計訊息的大型部署,這一點尤其重要。

PostgreSQL 同時支援 IVFFlat 和 HNSW 索引。Mastra 預設會建立 IVFFlat 索引,但 HNSW 索引通常效能更佳,尤其是使用內積距離的 OpenAI 嵌入。

import { Memory } from '@mastra/memory'
import { PgStore, PgVector } from '@mastra/pg'

const agent = new Agent({
memory: new Memory({
storage: new PgStore({
id: 'agent-storage',
connectionString: process.env.DATABASE_URL,
}),
vector: new PgVector({
id: 'agent-vector',
connectionString: process.env.DATABASE_URL,
}),
options: {
semanticRecall: {
topK: 5,
messageRange: 2,
indexConfig: {
type: 'hnsw', // Use HNSW for better performance
metric: 'dotproduct', // Best for OpenAI embeddings
m: 16, // Number of bi-directional links (default: 16)
efConstruction: 64, // Size of candidate list during construction (default: 64)
},
},
},
}),
})

如需索引設定選項和效能調校的詳細資料,請參閱 PgVector 設定指南

停用語義回憶
停用語義回憶 的直接連結

語義回憶預設為停用(semanticRecall: false)。每次呼叫都會增加延遲,因為新訊息會轉換成嵌入,並在 LLM 接收前用於查詢向量資料庫。

在以下情況下,請維持停用語義回憶:

  • 訊息記錄已為目前對話提供足夠的上下文。
  • 你正在建立對效能敏感的應用程式,例如即時雙向音訊,當中嵌入和向量查詢的延遲會較為明顯。

檢視回憶的訊息
檢視回憶的訊息 的直接連結

啟用 Trace 後,透過語義回憶擷取的任何訊息,都會連同近期訊息記錄(如已設定)顯示在 Agent 的 Trace 輸出中。