跳至主要內容

時間旅行

時間旅行可使用已儲存的快照資料或你提供的自訂情境,從任何特定步驟開始重新執行 Workflow。

此功能適合用來偵錯失敗的 Workflow、以不同輸入測試個別步驟,或在不重新執行整個 Workflow 的情況下從錯誤中復原。你也可以使用時間旅行,從任意特定步驟開始執行尚未執行過的 Workflow。

時間旅行的運作方式
「時間旅行的運作方式」的直接連結

對 Workflow 執行呼叫 timeTravel() 時:

  1. Workflow 會從儲存空間載入現有快照(若有)
  2. 系統會依快照或提供的情境,重建目標步驟之前的步驟結果
  3. 使用提供或重建的輸入資料,從指定步驟開始執行
  4. Workflow 會從該處繼續執行至完成

時間旅行依賴持久保存的 Workflow 快照,因此必須設定儲存空間。

基本用法
「基本用法」的直接連結

使用 run.timeTravel() 從特定步驟重新執行 Workflow:

import { mastra } from './mastra'

const workflow = mastra.getWorkflow('myWorkflow')
const run = await workflow.createRun()

const result = await run.timeTravel({
step: 'step2',
inputData: { previousStepResult: 'custom value' },
})

指定目標步驟
「指定目標步驟」的直接連結

你可以使用步驟參照或步驟 ID 指定目標步驟:

使用步驟參照
「使用步驟參照」的直接連結

const result = await run.timeTravel({
step: step2,
inputData: { value: 10 },
})

使用步驟 ID
「使用步驟 ID」的直接連結

const result = await run.timeTravel({
step: 'step2',
inputData: { value: 10 },
})

巢狀 Workflow 步驟
「巢狀 Workflow 步驟」的直接連結

對於巢狀 Workflow 內的步驟,請使用點號表示法、步驟 ID 陣列或步驟參照陣列:

// Using dot notation
const result = await run.timeTravel({
step: 'nestedWorkflow.step3',
inputData: { value: 10 },
})

// Using array of step IDs
const result = await run.timeTravel({
step: ['nestedWorkflow', 'step3'],
inputData: { value: 10 },
})

// Using array of step references
const result = await run.timeTravel({
step: [nestedWorkflow, step3],
inputData: { value: 10 },
})

提供執行情境
「提供執行情境」的直接連結

進行時間旅行時,可提供情境來指定先前步驟的狀態:

const result = await run.timeTravel({
step: 'step2',
context: {
step1: {
status: 'success',
payload: { value: 0 },
output: { step1Result: 2 },
startedAt: Date.now(),
endedAt: Date.now(),
},
},
})

情境物件包含以步驟 ID 為鍵的步驟結果。每個步驟結果包括:

  • status:步驟的執行狀態(successfailedsuspended
  • payload:傳給步驟的輸入資料
  • output:步驟的輸出資料(適用於成功的步驟)
  • startedAt:步驟開始時的時間戳記
  • endedAt:步驟結束時的時間戳記(適用於已完成的步驟)
  • suspendPayload:傳給 suspend() 的資料(適用於暫停的步驟)
  • resumePayload:傳給 resume() 的資料(適用於已繼續的步驟)

重新執行失敗的 Workflow
「重新執行失敗的 Workflow」的直接連結

時間旅行特別適合用來偵錯失敗的 Workflow 執行並從中復原:

const workflow = mastra.getWorkflow('myWorkflow')
const run = await workflow.createRun()

// Initial run fails at step2
const failedResult = await run.start({
inputData: { value: 1 },
})

if (failedResult.status === 'failed') {
// Re-run from step2 with corrected input
const recoveredResult = await run.timeTravel({
step: 'step2',
inputData: { step1Result: 5 }, // Provide corrected input
})
}

對暫停的 Workflow 進行時間旅行
「對暫停的 Workflow 進行時間旅行」的直接連結

你可以透過時間旅行,從較早的步驟繼續暫停的 Workflow:

const run = await workflow.createRun()

// Start workflow - suspends at promptAgent step
const initialResult = await run.start({
inputData: { input: 'test' },
})

if (initialResult.status === 'suspended') {
// Time travel back to an earlier step with resume data
const result = await run.timeTravel({
step: 'getUserInput',
resumeData: {
userInput: 'corrected input',
},
})
}

串流傳送時間旅行結果
「串流傳送時間旅行結果」的直接連結

使用 timeTravelStream() 接收時間旅行執行期間的串流事件:

const run = await workflow.createRun()

const stream = run.timeTravelStream({
step: 'step2',
inputData: { value: 10 },
})

for await (const event of stream.fullStream) {
console.log(event.type, event.payload)
}

const result = await stream.result

if (result.status === 'success') {
console.log(result.result)
}

使用初始狀態進行時間旅行
「使用初始狀態進行時間旅行」的直接連結

進行時間旅行時,可提供初始狀態以設定 Workflow 層級狀態:

const result = await run.timeTravel({
step: 'step2',
inputData: { value: 10 },
initialState: {
counter: 5,
metadata: { source: 'time-travel' },
},
})

錯誤處理
「錯誤處理」的直接連結

時間旅行會在特定情況下擲回錯誤:

執行中的 Workflow
「執行中的 Workflow」的直接連結

你無法對目前正在執行的 Workflow 進行時間旅行:

try {
await run.timeTravel({ step: 'step2' })
} catch (error) {
// "This workflow run is still running, cannot time travel"
}

無效的步驟 ID
「無效的步驟 ID」的直接連結

若 Workflow 中不存在目標步驟,時間旅行會擲回錯誤:

try {
await run.timeTravel({ step: 'nonExistentStep' })
} catch (error) {
// "Time travel target step not found in execution graph: 'nonExistentStep'. Verify the step id/path."
}

無效的輸入資料
「無效的輸入資料」的直接連結

啟用 validateInputs 時,時間旅行會依步驟的 schema 驗證輸入資料:

try {
await run.timeTravel({
step: 'step2',
inputData: { invalidField: 'value' },
})
} catch (error) {
// "Invalid inputData: \n- step1Result: Required"
}

巢狀 Workflow 情境
「巢狀 Workflow 情境」的直接連結

對巢狀 Workflow 進行時間旅行時,可同時提供父層與巢狀 Workflow 步驟的情境:

const result = await run.timeTravel({
step: 'nestedWorkflow.step3',
context: {
step1: {
status: 'success',
payload: { value: 0 },
output: { step1Result: 2 },
startedAt: Date.now(),
endedAt: Date.now(),
},
nestedWorkflow: {
status: 'running',
payload: { step1Result: 2 },
startedAt: Date.now(),
},
},
nestedStepsContext: {
nestedWorkflow: {
step2: {
status: 'success',
payload: { step1Result: 2 },
output: { step2Result: 3 },
startedAt: Date.now(),
endedAt: Date.now(),
},
},
},
})

使用案例
「使用案例」的直接連結

偵錯失敗的步驟
「偵錯失敗的步驟」的直接連結

以相同或修改後的輸入重新執行失敗步驟,以診斷問題:

const result = await run.timeTravel({
step: failedStepId,
context: originalContext, // Use context from the failed run
})

在新的 Workflow 執行中測試步驟邏輯
「在新的 Workflow 執行中測試步驟邏輯」的直接連結

在新的 Workflow 執行中使用特定輸入測試個別步驟,適合用來測試步驟邏輯,而不必從頭開始執行 Workflow。

const result = await run.timeTravel({
step: 'processData',
inputData: { testData: 'specific test case' },
})

從暫時性失敗中復原
「從暫時性失敗中復原」的直接連結

重新執行因暫時性問題(網路錯誤、速率限制)而失敗的步驟:

// After fixing the external service issue
const result = await run.timeTravel({
step: 'callExternalApi',
inputData: savedInputData,
})