人類參與(HITL)
部分 Workflow 需要暫停以等候人類輸入,然後才繼續執行。當 Workflow 被暫停時,可傳回訊息,說明暫停原因及繼續執行所需的資料。之後,Workflow 可根據收到的輸入選擇恢復執行,或提早結束。這種方式很適合用於人工批准、拒絕、設有條件限制的決策,或任何需要人類監督的步驟。
暫停 Workflow 以等候人類輸入暫停 Workflow 以等候人類輸入 的直接連結
人類參與輸入的運作方式,與使用 suspend() 暫停 Workflow 十分相似。主要分別是需要人類輸入時,你可透過 suspend() 傳回 payload,為用戶提供背景資料或指引,說明如何繼續。

src/mastra/workflows/test-workflow.ts
import { createWorkflow, createStep } from '@mastra/core/workflows'
import { z } from 'zod'
const step1 = createStep({
id: 'step-1',
inputSchema: z.object({
userEmail: z.string(),
}),
outputSchema: z.object({
output: z.string(),
}),
resumeSchema: z.object({
approved: z.boolean(),
}),
suspendSchema: z.object({
reason: z.string(),
}),
execute: async ({ inputData, resumeData, suspend }) => {
const { userEmail } = inputData
const { approved } = resumeData ?? {}
if (!approved) {
return await suspend({
reason: 'Human approval required.',
})
}
return {
output: `Email sent to ${userEmail}`,
}
},
})
export const testWorkflow = createWorkflow({
id: 'test-workflow',
inputSchema: z.object({
userEmail: z.string(),
}),
outputSchema: z.object({
output: z.string(),
}),
})
.then(step1)
.commit()
向用戶提供回饋向用戶提供回饋 的直接連結
Workflow 暫停時,你可存取 suspend() 傳回的 payload,方法是找出已暫停的步驟,並讀取其 suspendPayload。
src/test-workflow.ts
const workflow = mastra.getWorkflow('testWorkflow')
const run = await workflow.createRun()
const result = await run.start({
inputData: {
userEmail: 'alex@example.com',
},
})
if (result.status === 'suspended') {
const suspendStep = result.suspended[0]
const suspendedPayload = result.steps[suspendStep[0]].suspendPayload
console.log(suspendedPayload)
}
輸出範例輸出範例 的直接連結
步驟傳回的資料可包含原因,協助用戶了解恢復執行 Workflow 所需的操作。
{
reason: 'Confirm to send email.'
}
使用人類輸入恢復執行 Workflow使用人類輸入恢復執行 Workflow 的直接連結
與重新啟動 Workflow一樣,收到人類輸入後,使用 resume() 並傳入 resumeData,即可繼續執行 Workflow。Workflow 會從暫停的步驟恢復執行。

const workflow = mastra.getWorkflow('testWorkflow')
const run = await workflow.createRun()
await run.start({
inputData: {
userEmail: 'alex@example.com',
},
})
const handleResume = async () => {
const result = await run.resume({
step: 'step-1',
resumeData: { approved: true },
})
}
使用 bail() 處理人類拒絕handling-human-rejection-with-bail 的直接連結
使用 bail() 可在某個步驟停止執行 Workflow,而不會觸發錯誤。當人類明確拒絕某項操作時,這會很有用。Workflow 會以 success 狀態完成,而呼叫 bail() 之後的所有邏輯均會略過。
const step1 = createStep({
execute: async ({ inputData, resumeData, suspend, bail }) => {
const { userEmail } = inputData
const { approved } = resumeData ?? {}
if (approved === false) {
return bail({
reason: 'User rejected the request.',
})
}
if (!approved) {
return await suspend({
reason: 'Human approval required.',
})
}
return {
message: `Email sent to ${userEmail}`,
}
},
})
多輪人類輸入多輪人類輸入 的直接連結
對於需要在多個階段取得輸入的 Workflow,暫停模式維持不變。每個步驟都會定義 resumeSchema 和 suspendSchema;後者通常包含一個原因,以便向用戶提供回饋。
src/mastra/workflows/test-workflow.ts
const step1 = createStep({...});
const step2 = createStep({
id: "step-2",
inputSchema: z.object({
message: z.string()
}),
outputSchema: z.object({
output: z.string()
}),
resumeSchema: z.object({
approved: z.boolean()
}),
suspendSchema: z.object({
reason: z.string()
}),
execute: async ({ inputData, resumeData, suspend }) => {
const { message } = inputData;
const { approved } = resumeData ?? {};
if (!approved) {
return await suspend({
reason: "Human approval required."
});
}
return {
output: `${message} - Deleted`
};
}
});
export const testWorkflow = createWorkflow({
id: "test-workflow",
inputSchema: z.object({
userEmail: z.string()
}),
outputSchema: z.object({
output: z.string()
})
})
.then(step1)
.then(step2)
.commit();
每個步驟都必須按順序恢復執行,並為每個已暫停的步驟分別呼叫一次 resume()。這種方式有助管理多步驟批准流程,在每個階段提供一致的 UI 回饋,並清晰處理輸入。
const handleResume = async () => {
const result = await run.resume({
step: 'step-1',
resumeData: { approved: true },
})
}
const handleDelete = async () => {
const result = await run.resume({
step: 'step-2',
resumeData: { approved: true },
})
}