動的 Workflow 定義
動的 Workflow はベータ版です。API が安定するまでは、メジャーバージョンを上げずに破壊的変更が加わる場合があります。
動的 Workflow 定義は、Mastra.addDynamicWorkflow()、保存済み Workflow のサーバールート、および Client SDK の Workflows API が受け取る JSON 互換の DynamicWorkflowGraph です。
セットアップと使用方法の完全な例については、動的 Workflowを参照してください。
定義フィールド定義フィールドへの直接リンク
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
id | string | はい | 一意の Workflow ID。Workflow の取得と実行にもこの ID を使用します。 |
description | string | いいえ | 人が読める説明 |
inputSchema | JsonSchema | はい | Workflow 入力の JSON Schema |
outputSchema | JsonSchema | はい | Workflow 出力の JSON Schema |
stateSchema | JsonSchema | いいえ | 共有 Workflow state の JSON Schema |
requestContextSchema | JsonSchema | いいえ | request context から読み取る値の JSON Schema |
metadata | Record<string, unknown> | いいえ | Storage で保持される任意の JSON metadata |
graph | SerializedStepFlowEntry[] | はい | Workflow を構成するステップエントリ |
定義を JSON として往復変換できるように、スキーマには Zod ではなく JSON Schema を使用します。Mastra は Workflow の登録時に各スキーマを Zod に変換します。
{
"id": "greeting-workflow",
"description": "Returns a greeting for the supplied name",
"inputSchema": {
"type": "object",
"properties": { "name": { "type": "string" } },
"required": ["name"]
},
"outputSchema": {
"type": "object",
"properties": { "message": { "type": "string" } },
"required": ["message"]
},
"graph": [
{
"type": "mapping",
"id": "create-greeting",
"mapConfig": "{\"message\":{\"template\":\"Hello, ${initData.name}!\"}}"
}
]
}
グラフエントリグラフエントリへの直接リンク
graph 内のエントリは順番に実行されます。各エントリは直前のエントリの出力を受け取り、最初のエントリは Workflow の入力を受け取ります。
| エントリタイプ | 説明 |
|---|---|
agent | 登録済み Agent を呼び出します |
tool | 登録済み Tool を呼び出します |
mapping | ステップ間でデータの形を変換します |
workflow | 登録済み Workflow をネストされたステップとして呼び出します |
parallel | 複数のステップを並行実行し、出力をマージします |
conditional | 述語が true になるすべての分岐を並行実行します |
foreach | 配列入力の項目ごとに 1 つのステップを実行します |
loop | 述語が成立している間、または成立するまでステップを繰り返します |
sleep | 一定時間一時停止します |
sleepUntil | 指定した日時まで一時停止します |
.agent() と .tool() を使用するコード定義の Workflow も、シリアライズ時には同じ宣言的エントリを生成します。
Agent ステップAgent ステップへの直接リンク
agent エントリは、登録済み Agent を ID で呼び出します。Agent ステップは入力として { prompt: string } を受け取り、デフォルトでは { text: string } を返します。
{
"type": "agent",
"id": "summarize",
"agentId": "support-agent"
}
id は、Workflow 内でこの呼び出し位置を識別します。後続のステップは、Agent 自体の ID にかかわらず、結果を stepResults.summarize として参照します。
Agent に構造化出力を要求するには、outputSchema を追加します。
{
"type": "agent",
"id": "extract-subtopics",
"agentId": "support-agent",
"outputSchema": {
"type": "array",
"items": {
"type": "object",
"properties": { "title": { "type": "string" } },
"required": ["title"]
}
}
}
Agent の前に mapping エントリを置くと、Workflow データから { prompt } 入力を構築できます。
Agent エントリは、任意の description と options オブジェクトを受け取ります。
{
"type": "agent",
"id": "summarize",
"agentId": "support-agent",
"description": "Summarize the incoming request",
"options": { "retries": 2, "metadata": { "team": "support" } }
}
永続化されるのは retries と metadata だけです。コード定義の Workflow を保存するとき、onFinish や関数値の toolChoice など、値が関数のオプションは拒否されます。その他の Agent 呼び出しオプションも永続化されません。
Tool ステップTool ステップへの直接リンク
tool エントリは、Mastra の tools オブジェクトにある登録キーで Tool を呼び出します。Mastra は Workflow の登録時に、レジストリから Tool の入力スキーマと出力スキーマを解決します。
{
"type": "tool",
"id": "lookup",
"toolId": "lookup-customer"
}
Tool エントリは、Agent エントリと同じ任意の description フィールドと options フィールドを受け取ります。永続化されるのは retries と metadata だけです。
Mapping ステップMapping ステップへの直接リンク
mapping エントリはデータの形を変換します。mapConfig はオブジェクトをエンコードした JSON 文字列です。各キーはステップ出力のキーになり、各 descriptor は 1 つのソースを定義します。
| Descriptor | 説明 |
|---|---|
{ "value": ... } | 定数の JSON 値 |
{ "template": "..." } | ${...} プレースホルダーから構築される文字列 |
{ "initData": true, "path": "a.b" } | Workflow 入力から取得する値 |
{ "step": "step-id", "path": "a.b" } | 先行ステップの出力から取得する値 |
{ "requestContextPath": "a.b" } | request context から取得する値 |
step ソースにはステップ ID の配列も指定できます。
{ "step": ["escalate", "auto-reply"], "path": "text" }
一覧内で最初に空でない結果を持つステップが値を提供します。conditional エントリの後で、実行された分岐を選択するために使用できます。
テンプレートは、initData、inputData、state、requestContext、stepResults.<step-id> に対してプレースホルダーを解決します。
{
"type": "mapping",
"id": "build-prompt",
"mapConfig": "{\"prompt\":{\"template\":\"Summarize this request: ${initData.request}\"}}"
}
テンプレートで解決されたオブジェクトと配列は、JSON 文字列に変換されます。存在する結果内の null 値は空文字列としてレンダリングされます。正常な出力がないステップをテンプレートから参照すると、Run は失敗します。
Mapping エントリは、トップレベルのグラフエントリである必要があります。parallel、conditional、foreach、loop のコンテナ内には配置できません。
ネストされた Workflow ステップネストされた Workflow ステップへの直接リンク
workflow エントリは、別の登録済み Workflow を呼び出します。対象にはコード定義または保存済みの Workflow を指定できます。
{
"type": "workflow",
"id": "lookup-first",
"workflowId": "lookup-customer-workflow"
}
id は呼び出し位置を識別します。同じネストされた Workflow を異なる呼び出し位置の ID で複数回配置でき、後続のステップは各結果を stepResults.<id> として参照します。workflow エントリは、任意の description も受け取ります。
Parallel エントリParallel エントリへの直接リンク
parallel エントリは、複数の単一ステップを並行実行し、ステップ ID をキーとするオブジェクトに出力をマージします。
{
"type": "parallel",
"steps": [
{ "type": "tool", "id": "first", "toolId": "lookup-customer" },
{ "type": "tool", "id": "second", "toolId": "lookup-customer" }
]
}
各子要素は agent、tool、workflow のいずれかのエントリである必要があります。すべての子要素は、parallel エントリの入力を直接受け取ります。
Conditional エントリConditional エントリへの直接リンク
conditional エントリは、各ステップと宣言的な述語を組み合わせ、述語が true になるすべての分岐を実行します。
{
"type": "conditional",
"steps": [
{ "type": "agent", "id": "escalate", "agentId": "support-agent" },
{ "type": "agent", "id": "auto-reply", "agentId": "support-agent" }
],
"predicates": [
{ "op": "eq", "left": { "path": "inputData.priority" }, "right": { "literal": "urgent" } },
{ "op": "ne", "left": { "path": "inputData.priority" }, "right": { "literal": "urgent" } }
]
}
各子要素は agent、tool、workflow のいずれかのエントリである必要があり、それぞれに述語が必要です。すべての子要素は、conditional エントリの入力を直接受け取ります。
述語述語への直接リンク
Conditional エントリと loop は JSON の述語 DSL を使用します。operand は { "path": "..." } 参照または { "literal": ... } 値です。パスは initData、inputData、stepResults、state に対して解決されます。
| 演算子 | 形式 |
|---|---|
eq, ne, lt, lte, gt, gte | { "op": "eq", "left": ..., "right": ... } |
in, notIn | { "op": "in", "value": ..., "set": [...] } |
exists, notExists | { "op": "exists", "path": "..." } |
truthy, falsy | { "op": "truthy", "value": ... } |
and, or | { "op": "and", "args": [...] } |
not | { "op": "not", "arg": ... } |
存在しないパスでも例外はスローされません。パスベースの演算子は、パスを解決できない場合に false を返します。値が存在しない場合と falsy な値を区別するには、exists または notExists を使用します。
Foreach エントリForeach エントリへの直接リンク
foreach エントリは、配列入力の各項目に対して本体を 1 回実行します。直前のエントリは生の配列を生成する必要があります。結果では入力順が維持され、並行数のデフォルトは 1 です。
{
"type": "foreach",
"step": { "type": "workflow", "id": "write-blurb", "workflowId": "blurb-workflow" },
"opts": { "concurrency": 3 }
}
本体には agent、tool、workflow のいずれかのエントリを指定できますが、mapping エントリは指定できません。
Loop エントリLoop エントリへの直接リンク
loop は、述語が成立している間(dowhile)、または成立するまで(dountil)、1 つのステップを繰り返します。
{
"type": "loop",
"loopType": "dountil",
"step": { "type": "tool", "id": "poll", "toolId": "check-status" },
"predicate": {
"op": "eq",
"left": { "path": "inputData.status" },
"right": { "literal": "done" }
}
}
loop の本体は単一のステップである必要があり、保存される loop には宣言的な述語が必要です。
Sleep エントリSleep エントリへの直接リンク
sleep エントリは、指定したミリ秒だけ一時停止します。sleepUntil エントリは、ISO 日付文字列で表された指定日時まで一時停止します。保存される定義にはリテラル値が必要です。
{ "type": "sleep", "id": "wait", "duration": 5000 }
{ "type": "sleepUntil", "id": "wait-for-launch", "date": "2027-01-01T00:00:00.000Z" }
実行時に期間または日時を計算する必要がある場合は、コード定義の Workflow を使用します。
検証検証への直接リンク
Mastra は、定義を永続化または登録する前に検証します。
- 構造: トップレベルにのみ配置できる mapping などの配置規則を含む、エントリの形式と必須フィールド。
- 参照: 各
agentIdとworkflowIdは、稼働中のレジストリまたは同じ bundle に対して解決できる必要があります。toolIdは Tool の登録キーと一致する必要があります。 - スキーマフロー: 推論された mapping 出力を含め、各エントリの入力が直前の出力と互換性を持つ必要があります。
検証エラーには、無効なエントリを示す graph.2.steps.0 のようなドット区切りのパスが含まれます。