跳至主要內容

Memory.cloneThread()

.cloneThread() 方法會建立現有對話 thread 的副本,並包含其中所有訊息。它支援從對話中的指定位置建立不同的對話路徑。啟用 semantic recall 時,此方法亦會為 cloned message 建立 vector embedding。

使用範例
使用範例 的直接連結

以下範例會建立 Memory instance,並 clone 現有 thread。

import { Memory } from '@mastra/memory'
import { LibSQLStore } from '@mastra/libsql'

const memory = new Memory({
storage: new LibSQLStore({ id: 'memory-store', url: 'file:./memory.db' }),
})

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

參數
參數 的直接連結

sourceThreadId:

string
要 clone 的 thread ID

newThreadId?:

string
Cloned thread 的選用自訂 ID。如未提供,系統會自動產生。

resourceId?:

string
Cloned thread 的選用 resource ID。預設為 source thread 的 resourceId。

title?:

string
Cloned thread 的選用標題。如省略,而 source thread 有標題,clone 便會使用 Clone of ${sourceThread.title};否則標題為空白。

metadata?:

Record<string, unknown>
要與 source thread metadata 合併的選用 metadata。系統會自動加入 clone metadata。

options?:

CloneOptions
Clone 操作的選用篩選條件。
CloneOptions

messageLimit?:

number
要 clone 的訊息數目上限。設定後,會 clone 最新的 N 則訊息。

messageFilter?:

MessageFilter
用於選擇要 clone 哪些訊息的篩選條件。
MessageFilter

startDate?:

Date
只 clone 在此日期或之後建立的訊息。

endDate?:

Date
只 clone 在此日期或之前建立的訊息。

messageIds?:

string[]
只 clone 具有這些指定 ID 的訊息。

傳回值
傳回值 的直接連結

thread:

StorageThreadType
新建立並附有 clone metadata 的 cloned thread。

clonedMessages:

MastraDBMessage[]
已指派新 ID 並歸入新 thread 的 cloned message 陣列。

messageIdMap?:

Record<string, string>
Source message ID 與其對應 cloned message ID 之間的映射。

Clone metadata
Clone metadata 的直接連結

Cloned thread 的 metadata 包含一個 clone property,其中包括:

sourceThreadId:

string
被 clone 的原始 thread ID。

clonedAt:

Date
建立 clone 時的時間戳記。

lastMessageId?:

string
Clone 當刻 source thread 中最後一則訊息的 ID。

進階使用範例
進階使用範例 的直接連結

src/test-clone.ts
import { mastra } from './mastra'

const agent = mastra.getAgent('agent')
const memory = await agent.getMemory()

// Clone a thread with all messages
const { thread: fullClone } = await memory.cloneThread({
sourceThreadId: 'original-thread-123',
title: 'Alternative Conversation Path',
})

// Clone with a custom ID
const { thread: customIdClone } = await memory.cloneThread({
sourceThreadId: 'original-thread-123',
newThreadId: 'my-custom-clone-id',
})

// Clone only the last 5 messages
const { thread: partialClone, clonedMessages } = await memory.cloneThread({
sourceThreadId: 'original-thread-123',
options: {
messageLimit: 5,
},
})

// Clone messages from a specific date range
const { thread: dateFilteredClone } = await memory.cloneThread({
sourceThreadId: 'original-thread-123',
options: {
messageFilter: {
startDate: new Date('2024-01-01'),
endDate: new Date('2024-01-31'),
},
},
})

// Clone specific messages
const { thread: selectedMessagesClone } = await memory.cloneThread({
sourceThreadId: 'original-thread-123',
options: {
messageFilter: {
messageIds: ['message-1', 'message-2'],
},
},
})

// Continue conversation on the cloned thread
const response = await agent.generate('Try a different approach', {
memory: {
thread: fullClone.id,
resource: fullClone.resourceId,
},
})

將 cloned thread.idthread.resourceId 傳給 agent.generate(),即可從 cloned thread 繼續對話。

Vector embedding
Vector embedding 的直接連結

當 Memory instance 已啟用 semantic recall,並已設定 vector store 及 embedder 時,cloneThread() 會自動為所有 cloned message 建立 vector embedding,確保語意搜尋可在 cloned thread 上正常運作。

在此範例中,embeddingModel 是項目所設定的 embedding model。

import { Memory } from '@mastra/memory'
import { LibSQLStore, LibSQLVector } from '@mastra/libsql'

const memory = new Memory({
storage: new LibSQLStore({ id: 'memory-store', url: 'file:./memory.db' }),
vector: new LibSQLVector({ id: 'vector-store', url: 'file:./vector.db' }),
embedder: embeddingModel,
options: {
semanticRecall: true,
},
})

// Clone will also create embeddings for cloned messages
const { thread } = await memory.cloneThread({
sourceThreadId: 'original-thread',
})

// Semantic search works on the cloned thread
const results = await memory.recall({
threadId: thread.id,
vectorSearchString: 'search query',
})

Working memory
Working memory 的直接連結

啟用 working memory 後,cloneThread() 會根據 working memory scope 及 clone 的 resourceId 複製或共用 working memory:

  • Thread scope 的 working memory:Working memory 會複製至 cloned thread。
  • Resource scope 的 working memory,且 resourceId 相同:由於 source thread 與 cloned thread 屬於同一個 resource,因此會共用 working memory。
  • Resource scope 的 working memory,且 resourceId 不同:Working memory 會複製至 cloned thread 的 resource。

Observational Memory
Observational Memory 的直接連結

啟用 Observational Memory 後,cloneThread() 會自動 clone 與 source thread 相關的 OM 記錄。其行為視乎 OM scope:

  • Thread scope 的 OM:OM 記錄會 clone 至新 thread。所有內部訊息 ID 參照都會重新映射至 cloned message。
  • Resource scope 的 OM(resourceId 相同):由於 source thread 與 cloned thread 屬於同一個 resource,因此會共用 OM 記錄,不會建立副本。
  • Resource scope 的 OM(resourceId 不同):OM 記錄會 clone 至新 resource。訊息 ID 會重新映射,而 observation 中所有用於識別 thread 的 tag 都會更新為參照 cloned thread。

只會 clone 目前(最新)的 OM generation,不會複製較舊的歷史 generation。暫時性處理狀態(observation/reflection 進行中 flag)會在 cloned record 上重設。