跳到主要内容

Memory.cloneThread()

.cloneThread() 方法创建现有对话线程的副本,其中包括该线程的所有消息。它支持从对话中的特定位置创建不同的对话路径。启用语义召回后,该方法还会为克隆的消息创建向量嵌入。

用法示例
用法示例的直接链接

以下示例创建一个 Memory 实例并克隆现有线程。

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
要克隆的线程 ID

newThreadId?:

string
克隆线程的可选自定义 ID。如果未提供,则会自动生成。

resourceId?:

string
克隆线程的可选资源 ID。默认为源线程的 resourceId。

title?:

string
克隆线程的可选标题。如果省略,当源线程有标题时,克隆线程使用 Clone of ${sourceThread.title};否则标题为空。

metadata?:

Record<string, unknown>
与源线程元数据合并的可选元数据。系统会自动添加克隆元数据。

options?:

CloneOptions
克隆操作的可选筛选选项。
CloneOptions

messageLimit?:

number
要克隆的最大消息数。设置后,将克隆最近的 N 条消息。

messageFilter?:

MessageFilter
用于选择要克隆消息的筛选条件。
MessageFilter

startDate?:

Date
仅克隆在此日期或之后创建的消息。

endDate?:

Date
仅克隆在此日期或之前创建的消息。

messageIds?:

string[]
仅克隆具有这些指定 ID 的消息。

返回值
返回值的直接链接

thread:

StorageThreadType
新创建且包含克隆元数据的克隆线程。

clonedMessages:

MastraDBMessage[]
克隆消息的数组;这些消息已分配新 ID 并归属于新线程。

messageIdMap?:

Record<string, string>
源消息 ID 与其对应的克隆消息 ID 之间的映射。

克隆元数据
克隆元数据的直接链接

克隆线程的元数据包含一个 clone 属性,其中包括:

sourceThreadId:

string
被克隆的原始线程 ID。

clonedAt:

Date
克隆的创建时间戳。

lastMessageId?:

string
克隆时源线程中最后一条消息的 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,
},
})

将克隆线程的 thread.idthread.resourceId 传递给 agent.generate(),即可从该克隆线程继续对话。

向量嵌入
向量嵌入的直接链接

当 Memory 实例已启用语义召回,并配置了向量存储和 embedder 时,cloneThread() 会自动为所有克隆消息创建向量嵌入。这可确保语义搜索在克隆线程上正常工作。

在此示例中,embeddingModel 是为项目配置的嵌入模型。

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

工作内存
工作内存的直接链接

启用工作内存后,cloneThread() 会根据工作内存的作用域和克隆线程的 resourceId 复制或共享工作内存:

  • 线程作用域的工作内存:工作内存会复制到克隆线程中。
  • 资源作用域的工作内存(使用相同的 resourceId:源线程和克隆线程属于同一资源,因此会共享工作内存。
  • 资源作用域的工作内存(使用不同的 resourceId:工作内存会复制到克隆线程的资源中。

Observational Memory
Observational Memory的直接链接

启用 Observational Memory 后,cloneThread() 会自动克隆与源线程关联的 OM 记录。具体行为取决于 OM 的作用域:

  • 线程作用域的 OM:OM 记录会克隆到新线程。所有内部消息 ID 引用都会重新映射到克隆后的消息。
  • 资源作用域的 OM(使用相同的 resourceId:源线程和克隆线程属于同一资源,因此会共享 OM 记录,不会创建副本。
  • 资源作用域的 OM(使用不同的 resourceId:OM 记录会克隆到新资源。消息 ID 会重新映射,observations 中所有用于标识线程的标签也会更新为引用克隆后的线程。

只会克隆当前(最近一代)的 OM。较早的历史 generation 不会被复制。临时处理状态(正在进行 observation/reflection 的标志)会在克隆记录上重置。