跳至主要內容

訊息記錄

訊息記錄是最基本也最重要的記憶形式。它讓 LLM 可在上下文視窗中查看近期訊息,使 Agent 能夠參考較早前的交流並連貫地回應。

你亦可擷取訊息記錄,在 UI 中顯示過往對話。

資訊

每則訊息都屬於一個 thread(對話)和一個 resource(與其關聯的使用者或實體)。詳情請參閱 Thread 與 resource

注意

當你在客戶端應用程式中使用記憶時,客戶端應只傳送新訊息,而非完整的對話記錄。

傳送完整記錄是多餘的,因為 Mastra 會從儲存空間載入訊息;此外,當客戶端時間戳記與已儲存的時間戳記有衝突時,這樣做亦可能導致訊息排序錯誤。

如需 AI SDK 範例,請參閱使用 Mastra Memory

Thread 與 resource
Thread 與 resource 的直接連結

Mastra 使用兩個識別碼來組織對話:

  • Thread:包含一連串訊息的對話工作階段。
  • Resource:擁有該 thread 的實體,例如使用者、機構、項目,或應用程式中的其他領域實體。

Studio 會自動為你產生 thread 和 resource ID。自行呼叫 stream()generate() 時,請明確提供這些識別碼。

開始使用
開始使用 的直接連結

安裝 Mastra memory 模組,以及供資料庫使用的儲存適配器。以下範例使用 @mastra/libsql,它會將資料儲存在本機的 mastra.db 檔案中。

npm install @mastra/memory@latest @mastra/libsql@latest

訊息記錄需要儲存適配器來持久保存對話。如尚未設定,請在 Mastra 執行個體上設定儲存空間:

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',
}),
})

在 Agent 中建立 Memory 執行個體:

src/mastra/agents/test-agent.ts
import { Memory } from '@mastra/memory'
import { Agent } from '@mastra/core/agent'

export const agent = new Agent({
id: 'test-agent',
memory: new Memory({
options: {
lastMessages: 10,
},
}),
})

呼叫 Agent 時,訊息會自動儲存至資料庫。你可以指定 threadIdresourceId 和選填的 metadata

await agent.generate('Hello', {
memory: {
thread: {
id: 'thread-123',
title: 'Support conversation',
metadata: { category: 'billing' },
},
resource: 'user-456',
},
})
資訊

呼叫 agent.generate()agent.stream() 時,系統會自動建立 thread 和訊息;你亦可使用 createThread()saveMessages() 手動建立。

你可以透過兩種方式使用此記錄:

  • 自動加入:Mastra 會自動擷取近期訊息,並將其加入上下文視窗。預設會加入最近 10 則訊息,讓 Agent 的回應以對話內容為依據。你可以透過 lastMessages 調整此數目,但大多數情況下毋須特別處理。
  • 手動查詢:如需更精細的控制,可使用 recall() 函式直接查詢 thread 和訊息。這讓你能夠準確選擇要在上下文視窗中加入哪些記憶,或擷取訊息以在 UI 中呈現對話記錄。
提示

啟用記憶後,Studio 會使用訊息記錄,在聊天側邊欄顯示過往對話。

產生 thread 標題
產生 thread 標題 的直接連結

啟用 generateTitle 後,Mastra 可根據對話文字記錄自動產生具描述性的 thread 標題。當你建立的聊天介面會在 thread 清單或側邊欄顯示對話標題時,可使用此選項。

src/mastra/agents/support-agent.ts
import { Agent } from '@mastra/core/agent'
import { Memory } from '@mastra/memory'

export const supportAgent = new Agent({
id: 'support-agent',
name: 'Support agent',
instructions: 'Answer customer support questions.',
model: 'openai/gpt-5.6-sol',
memory: new Memory({
options: {
generateTitle: true,
},
}),
})

Agent 回應後,標題產生程序會以非同步方式執行,不會影響回應時間。

如要最佳化成本或行為,請提供較小型的 model 和自訂 instructions

src/mastra/agents/support-agent.ts
import { Agent } from '@mastra/core/agent'
import { Memory } from '@mastra/memory'

export const supportAgent = new Agent({
id: 'support-agent',
name: 'Support agent',
instructions: 'Answer customer support questions.',
model: 'openai/gpt-5.6-sol',
memory: new Memory({
options: {
generateTitle: {
model: 'openai/gpt-5-mini',
instructions: 'Generate a one-word title.',
},
},
}),
})

存取記憶
存取記憶 的直接連結

如要存取用於查詢、複製或刪除 thread 和訊息的記憶函式,請在 Agent 上呼叫 getMemory()

const agent = mastra.getAgentById('test-agent')
const memory = await agent.getMemory()

Memory 執行個體讓你可以使用列出 thread 和回想訊息的函式,亦可複製對話等。

查詢
查詢 的直接連結

使用以下方法擷取 thread 和訊息,以便在 UI 中顯示對話記錄,或用於自訂的記憶擷取邏輯。

注意

記憶系統不會強制執行存取控制。執行任何查詢前,請在應用程式邏輯中確認目前使用者獲授權存取要查詢的 resourceId

Thread
Thread 的直接連結

使用 listThreads() 擷取某個 resource 的 thread:

const result = await memory.listThreads({
filter: { resourceId: 'user-123' },
perPage: false,
})

以分頁方式瀏覽 thread:

const result = await memory.listThreads({
filter: { resourceId: 'user-123' },
page: 0,
perPage: 10,
})

console.log(result.threads) // thread objects
console.log(result.hasMore) // more pages available?

你亦可按 metadata 篩選並控制排序次序:

const result = await memory.listThreads({
filter: {
resourceId: 'user-123',
metadata: { status: 'active' },
},
orderBy: { field: 'createdAt', direction: 'DESC' },
})

如要按 ID 擷取單一 thread,請使用 getThreadById()

const thread = await memory.getThreadById({ threadId: 'thread-123' })

訊息
訊息 的直接連結

取得 thread 後,使用 recall() 擷取其中的訊息。此方法支援分頁、日期篩選和語意搜尋

基本回想會傳回 thread 中的所有訊息:

const { messages } = await memory.recall({
threadId: 'thread-123',
perPage: false,
})

以分頁方式瀏覽訊息:

const { messages } = await memory.recall({
threadId: 'thread-123',
page: 0,
perPage: 50,
})

按日期範圍篩選:

const { messages } = await memory.recall({
threadId: 'thread-123',
filter: {
dateRange: {
start: new Date('2025-01-01'),
end: new Date('2025-06-01'),
},
},
})

按訊息的淺層 metadata 篩選:

const { messages } = await memory.recall({
threadId: 'thread-123',
filter: {
metadata: {
category: 'billing',
escalated: true,
priority: 2,
archivedAt: null,
},
},
})

Metadata 篩選條件只會比對淺層純量值:string、有限的 numberbooleannull

所有指定的 metadata key 均使用 AND 語意。null 篩選條件只會比對明確的 null 值;缺少的 metadata key 不會構成相符結果。

Metadata key 必須以字母或底線開頭,且只能包含英數字元。長度不得超過 128 個字元,亦不可使用 __proto__constructorprototype 等保留的 prototype key。

效能取決於儲存後端。部分後端可將部分篩選條件推送至資料庫,其他後端則會在套用 thread、resource 和日期限制後、分頁前掃描候選訊息。

按 ID 擷取單一訊息:

const { messages } = await memory.recall({
threadId: 'thread-123',
include: [{ id: 'msg-123' }],
})

按 ID 擷取多則訊息及其周邊上下文:

const { messages } = await memory.recall({
threadId: 'thread-123',
include: [
{ id: 'msg-123' },
{
id: 'msg-456',
withPreviousMessages: 3,
withNextMessages: 1,
},
],
})

按意思搜尋(設定方法請參閱語意回想):

const { messages } = await memory.recall({
threadId: 'thread-123',
vectorSearchString: 'project deadline discussion',
threadConfig: {
semanticRecall: true,
},
})

UI 格式
UI 格式 的直接連結

訊息查詢會傳回 MastraDBMessage[] 格式。如要在前端顯示訊息,你可能需要將訊息轉換成 UI 程式庫預期的格式。例如,toAISdkV5Messages 可將訊息轉換成 AI SDK UI 格式。

複製 thread
複製 thread 的直接連結

複製 thread 會建立現有 thread 及其訊息的副本。這適合用於建立對話分支、在可能具破壞性的操作前建立檢查點,或測試對話的不同變化。

const { thread, clonedMessages } = await memory.cloneThread({
sourceThreadId: 'thread-123',
title: 'Branched conversation',
})

你可以篩選要複製的訊息(按數量或日期範圍)、指定自訂 thread ID,並使用實用方法檢查複製關係。

如需完整 API,請參閱 cloneThread()複製實用工具

刪除訊息
刪除訊息 的直接連結

如要從 thread 移除訊息,請使用 deleteMessages()。你可以按訊息 ID 刪除訊息,或清除 thread 中的所有訊息。