ワークフローの変数によるデータマッピング
Mastraのワークフロー変数は、ステップ間でデータをマッピングするための強力なメカニズムを提供し、動的なデータフローを作成して、あるステップから別のステップへ情報を渡すことができます。
ワークフロー変数を理解する
Mastraワークフローでは、変数は以下のような役割を果たします:
- トリガー入力からステップ入力へのデータマッピング
- あるステップの出力を別のステップの入力に渡す
- ステップ出力内のネストされたプロパティにアクセスする
- より柔軟で再利用可能なワークフローステップを作成する
ワークフロー変数を使用したデータマッピング
基本的な変数マッピング
variables
プロパティを使用して、ワークフローにステップを追加する際にステップ間でデータをマッピングできます:
src/mastra/workflows/index.ts
const workflow = new Workflow({
name: "data-mapping-workflow",
triggerSchema: z.object({
inputData: z.string(),
}),
});
workflow
.step(step1, {
variables: {
// トリガーデータをステップ入力にマッピング
inputData: { step: "trigger", path: "inputData" },
},
})
.then(step2, {
variables: {
// step1の出力をstep2の入力にマッピング
previousValue: { step: step1, path: "outputField" },
},
})
.commit();
// ワークフローをMastraに登録
export const mastra = new Mastra({
workflows: { workflow },
});
ネストされたプロパティへのアクセス
path
フィールドでドット表記を使用してネストされたプロパティにアクセスできます:
src/mastra/workflows/index.ts
workflow
.step(step1)
.then(step2, {
variables: {
// step1の出力からネストされたプロパティにアクセス
nestedValue: { step: step1, path: "nested.deeply.value" },
},
})
.commit();
オブジェクト全体のマッピング
パスとして.
を使用することで、オブジェクト全体をマッピングできます:
src/mastra/workflows/index.ts
workflow
.step(step1, {
variables: {
// トリガーデータオブジェクト全体をマッピング
triggerData: { step: "trigger", path: "." },
},
})
.commit();
ループ内の変数
変数はwhile
およびuntil
ループにも渡すことができます。これは反復間やステップ外からデータを渡す場合に便利です:
src/mastra/workflows/loop-variables.ts
// カウンターをインクリメントするステップ
const incrementStep = new Step({
id: "increment",
inputSchema: z.object({
// 前回の反復からの値
prevValue: z.number().optional(),
}),
outputSchema: z.object({
// 更新されたカウンター値
updatedCounter: z.number(),
}),
execute: async ({ context }) => {
const { prevValue = 0 } = context.inputData;
return { updatedCounter: prevValue + 1 };
},
});
const workflow = new Workflow({
name: "counter",
});
workflow.step(incrementStep).while(
async ({ context }) => {
// カウンターが10未満の間続ける
const result = context.getStepResult(incrementStep);
return (result?.updatedCounter ?? 0) < 10;
},
incrementStep,
{
// 前の値を次の反復に渡す
prevValue: {
step: incrementStep,
path: "updatedCounter",
},
},
);
変数の解決
ワークフローが実行されると、Mastraは以下の方法で実行時に変数を解決します:
step
プロパティで指定されたソースステップを識別する- そのステップからの出力を取得する
path
を使用して指定されたプロパティにナビゲートする- 解決された値をターゲットステップのコンテキストに
inputData
プロパティとして注入する
例
トリガーデータからのマッピング
この例では、ワークフローのトリガーからステップにデータをマッピングする方法を示しています:
src/mastra/workflows/trigger-mapping.ts
import { Step, Workflow, Mastra } from "@mastra/core";
import { z } from "zod";
// Define a step that needs user input
const processUserInput = new Step({
id: "processUserInput",
execute: async ({ context }) => {
// The inputData will be available in context because of the variable mapping
const { inputData } = context.inputData;
return {
processedData: `Processed: ${inputData}`,
};
},
});
// Create the workflow
const workflow = new Workflow({
name: "trigger-mapping",
triggerSchema: z.object({
inputData: z.string(),
}),
});
// Map the trigger data to the step
workflow
.step(processUserInput, {
variables: {
inputData: { step: "trigger", path: "inputData" },
},
})
.commit();
// Register the workflow with Mastra
export const mastra = new Mastra({
workflows: { workflow },
});
ステップ間のマッピング
この例では、あるステップから別のステップへのデータマッピングを示しています:
src/mastra/workflows/step-mapping.ts
import { Step, Workflow, Mastra } from "@mastra/core";
import { z } from "zod";
// Step 1: Generate data
const generateData = new Step({
id: "generateData",
outputSchema: z.object({
nested: z.object({
value: z.string(),
}),
}),
execute: async () => {
return {
nested: {
value: "step1-data",
},
};
},
});
// Step 2: Process the data from step 1
const processData = new Step({
id: "processData",
inputSchema: z.object({
previousValue: z.string(),
}),
execute: async ({ context }) => {
// previousValue will be available because of the variable mapping
const { previousValue } = context.inputData;
return {
result: `Processed: ${previousValue}`,
};
},
});
// Create the workflow
const workflow = new Workflow({
name: "step-mapping",
});
// Map data from step1 to step2
workflow
.step(generateData)
.then(processData, {
variables: {
// Map the nested.value property from generateData's output
previousValue: { step: generateData, path: "nested.value" },
},
})
.commit();
// Register the workflow with Mastra
export const mastra = new Mastra({
workflows: { workflow },
});
型安全性
Mastraは、TypeScriptを使用する際に変数マッピングの型安全性を提供します:
src/mastra/workflows/type-safe.ts
import { Step, Workflow, Mastra } from "@mastra/core";
import { z } from "zod";
// Define schemas for better type safety
const triggerSchema = z.object({
inputValue: z.string(),
});
type TriggerType = z.infer<typeof triggerSchema>;
// Step with typed context
const step1 = new Step({
id: "step1",
outputSchema: z.object({
nested: z.object({
value: z.string(),
}),
}),
execute: async ({ context }) => {
// TypeScript knows the shape of triggerData
const triggerData = context.getStepResult<TriggerType>("trigger");
return {
nested: {
value: `processed-${triggerData?.inputValue}`,
},
};
},
});
// Create the workflow with the schema
const workflow = new Workflow({
name: "type-safe-workflow",
triggerSchema,
});
workflow.step(step1).commit();
// Register the workflow with Mastra
export const mastra = new Mastra({
workflows: { workflow },
});
ベストプラクティス
-
入力と出力を検証する: データの一貫性を確保するために
inputSchema
とoutputSchema
を使用してください。 -
マッピングをシンプルに保つ: 可能な限り、過度に複雑なネストされたパスを避けてください。
-
デフォルト値を考慮する: マッピングされたデータが未定義の場合の処理を行ってください。
直接コンテキストアクセスとの比較
context.steps
を通じて前のステップの結果に直接アクセスすることもできますが、変数マッピングを使用すると以下のような利点があります:
機能 | 変数マッピング | 直接コンテキストアクセス |
---|---|---|
明確さ | 明示的なデータ依存関係 | 暗黙的な依存関係 |
再利用性 | ステップは異なるマッピングで再利用可能 | ステップは密接に結合している |
型安全性 | より良いTypeScript統合 | 手動での型アサーションが必要 |