> Discover all available pages from the documentation index: https://mastra.zisheng.pro/zh-HK/llms.txt # 訊息記錄 訊息記錄是最基本也最重要的記憶形式。它讓 LLM 可在上下文視窗中查看近期訊息,使 Agent 能夠參考較早前的交流並連貫地回應。 你亦可擷取訊息記錄,在 UI 中顯示過往對話。 > **資訊:** 每則訊息都屬於一個 thread(對話)和一個 resource(與其關聯的使用者或實體)。詳情請參閱 [Thread 與 resource](#threads-and-resources)。 > **注意:** 當你在客戶端應用程式中使用記憶時,客戶端應**只傳送新訊息**,而非完整的對話記錄。 > > 傳送完整記錄是多餘的,因為 Mastra 會從儲存空間載入訊息;此外,當客戶端時間戳記與已儲存的時間戳記有衝突時,這樣做亦可能導致訊息排序錯誤。 > > 如需 AI SDK 範例,請參閱[使用 Mastra Memory](https://mastra.zisheng.pro/zh-HK/guides/build-your-ui/ai-sdk-ui)。 ## Thread 與 resource Mastra 使用兩個識別碼來組織對話: - **Thread**:包含一連串訊息的對話工作階段。 - **Resource**:擁有該 thread 的實體,例如使用者、機構、項目,或應用程式中的其他領域實體。 Studio 會自動為你產生 thread 和 resource ID。自行呼叫 `stream()` 或 `generate()` 時,請明確提供這些識別碼。 ## 開始使用 安裝 Mastra memory 模組,以及供資料庫使用的[儲存適配器](https://mastra.zisheng.pro/zh-HK/docs/storage/overview)。以下範例使用 `@mastra/libsql`,它會將資料儲存在本機的 `mastra.db` 檔案中。 **npm**: ```bash npm install @mastra/memory@latest @mastra/libsql@latest ``` **pnpm**: ```bash pnpm add @mastra/memory@latest @mastra/libsql@latest ``` **Yarn**: ```bash yarn add @mastra/memory@latest @mastra/libsql@latest ``` **Bun**: ```bash bun add @mastra/memory@latest @mastra/libsql@latest ``` 訊息記錄需要儲存適配器來持久保存對話。如尚未設定,請在 Mastra 執行個體上設定儲存空間: ```typescript 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`](https://mastra.zisheng.pro/zh-HK/reference/memory/memory-class) 執行個體: ```typescript 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 時,訊息會自動儲存至資料庫。你可以指定 `threadId`、`resourceId` 和選填的 `metadata`: **.generate()**: ```typescript await agent.generate('Hello', { memory: { thread: { id: 'thread-123', title: 'Support conversation', metadata: { category: 'billing' }, }, resource: 'user-456', }, }) ``` **.stream()**: ```typescript await agent.stream('Hello', { memory: { thread: { id: 'thread-123', title: 'Support conversation', metadata: { category: 'billing' }, }, resource: 'user-456', }, }) ``` > **資訊:** 呼叫 `agent.generate()` 或 `agent.stream()` 時,系統會自動建立 thread 和訊息;你亦可使用 [`createThread()`](https://mastra.zisheng.pro/zh-HK/reference/memory/createThread) 和 [`saveMessages()`](https://mastra.zisheng.pro/zh-HK/reference/memory/memory-class) 手動建立。 你可以透過兩種方式使用此記錄: - **自動加入**:Mastra 會自動擷取近期訊息,並將其加入上下文視窗。預設會加入最近 10 則訊息,讓 Agent 的回應以對話內容為依據。你可以透過 `lastMessages` 調整此數目,但大多數情況下毋須特別處理。 - [**手動查詢**](#querying):如需更精細的控制,可使用 `recall()` 函式直接查詢 thread 和訊息。這讓你能夠準確選擇要在上下文視窗中加入哪些記憶,或擷取訊息以在 UI 中呈現對話記錄。 > **提示:** 啟用記憶後,[Studio](https://mastra.zisheng.pro/zh-HK/docs/studio/overview) 會使用訊息記錄,在聊天側邊欄顯示過往對話。 ## 產生 thread 標題 啟用 `generateTitle` 後,Mastra 可根據對話文字記錄自動產生具描述性的 thread 標題。當你建立的聊天介面會在 thread 清單或側邊欄顯示對話標題時,可使用此選項。 ```typescript 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`](https://mastra.zisheng.pro/zh-HK/models) 和自訂 `instructions`: ```typescript 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()`: ```typescript const agent = mastra.getAgentById('test-agent') const memory = await agent.getMemory() ``` `Memory` 執行個體讓你可以使用列出 thread 和回想訊息的函式,亦可複製對話等。 ## 查詢 使用以下方法擷取 thread 和訊息,以便在 UI 中顯示對話記錄,或用於自訂的記憶擷取邏輯。 > **注意:** 記憶系統不會強制執行存取控制。執行任何查詢前,請在應用程式邏輯中確認目前使用者獲授權存取要查詢的 `resourceId`。 ### Thread 使用 [`listThreads()`](https://mastra.zisheng.pro/zh-HK/reference/memory/listThreads) 擷取某個 resource 的 thread: ```typescript const result = await memory.listThreads({ filter: { resourceId: 'user-123' }, perPage: false, }) ``` 以分頁方式瀏覽 thread: ```typescript 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 篩選並控制排序次序: ```typescript const result = await memory.listThreads({ filter: { resourceId: 'user-123', metadata: { status: 'active' }, }, orderBy: { field: 'createdAt', direction: 'DESC' }, }) ``` 如要按 ID 擷取單一 thread,請使用 [`getThreadById()`](https://mastra.zisheng.pro/zh-HK/reference/memory/getThreadById): ```typescript const thread = await memory.getThreadById({ threadId: 'thread-123' }) ``` ### 訊息 取得 thread 後,使用 [`recall()`](https://mastra.zisheng.pro/zh-HK/reference/memory/recall) 擷取其中的訊息。此方法支援分頁、日期篩選和[語意搜尋](https://mastra.zisheng.pro/zh-HK/docs/memory/semantic-recall)。 基本回想會傳回 thread 中的所有訊息: ```typescript const { messages } = await memory.recall({ threadId: 'thread-123', perPage: false, }) ``` 以分頁方式瀏覽訊息: ```typescript const { messages } = await memory.recall({ threadId: 'thread-123', page: 0, perPage: 50, }) ``` 按日期範圍篩選: ```typescript const { messages } = await memory.recall({ threadId: 'thread-123', filter: { dateRange: { start: new Date('2025-01-01'), end: new Date('2025-06-01'), }, }, }) ``` 按訊息的淺層 metadata 篩選: ```typescript const { messages } = await memory.recall({ threadId: 'thread-123', filter: { metadata: { category: 'billing', escalated: true, priority: 2, archivedAt: null, }, }, }) ``` Metadata 篩選條件只會比對淺層純量值:`string`、有限的 `number`、`boolean` 和 `null`。 所有指定的 metadata key 均使用 AND 語意。`null` 篩選條件只會比對明確的 `null` 值;缺少的 metadata key 不會構成相符結果。 Metadata key 必須以字母或底線開頭,且只能包含英數字元。長度不得超過 128 個字元,亦不可使用 `__proto__`、`constructor` 或 `prototype` 等保留的 prototype key。 效能取決於儲存後端。部分後端可將部分篩選條件推送至資料庫,其他後端則會在套用 thread、resource 和日期限制後、分頁前掃描候選訊息。 按 ID 擷取單一訊息: ```typescript const { messages } = await memory.recall({ threadId: 'thread-123', include: [{ id: 'msg-123' }], }) ``` 按 ID 擷取多則訊息及其周邊上下文: ```typescript const { messages } = await memory.recall({ threadId: 'thread-123', include: [ { id: 'msg-123' }, { id: 'msg-456', withPreviousMessages: 3, withNextMessages: 1, }, ], }) ``` 按意思搜尋(設定方法請參閱[語意回想](https://mastra.zisheng.pro/zh-HK/docs/memory/semantic-recall)): ```typescript const { messages } = await memory.recall({ threadId: 'thread-123', vectorSearchString: 'project deadline discussion', threadConfig: { semanticRecall: true, }, }) ``` ### UI 格式 訊息查詢會傳回 `MastraDBMessage[]` 格式。如要在前端顯示訊息,你可能需要將訊息轉換成 UI 程式庫預期的格式。例如,[`toAISdkV5Messages`](https://mastra.zisheng.pro/zh-HK/reference/ai-sdk/to-ai-sdk-v5-messages) 可將訊息轉換成 AI SDK UI 格式。 ## 複製 thread 複製 thread 會建立現有 thread 及其訊息的副本。這適合用於建立對話分支、在可能具破壞性的操作前建立檢查點,或測試對話的不同變化。 ```typescript const { thread, clonedMessages } = await memory.cloneThread({ sourceThreadId: 'thread-123', title: 'Branched conversation', }) ``` 你可以篩選要複製的訊息(按數量或日期範圍)、指定自訂 thread ID,並使用實用方法檢查複製關係。 如需完整 API,請參閱 [`cloneThread()`](https://mastra.zisheng.pro/zh-HK/reference/memory/cloneThread) 和[複製實用工具](https://mastra.zisheng.pro/zh-HK/reference/memory/clone-utilities)。 ## 刪除訊息 如要從 thread 移除訊息,請使用 [`deleteMessages()`](https://mastra.zisheng.pro/zh-HK/reference/memory/deleteMessages)。你可以按訊息 ID 刪除訊息,或清除 thread 中的所有訊息。