Chapter 7 · Workflow Basics and .then()
Chapter goals: Understand the division of labor between Workflow and Agent, master createStep / createWorkflow / .then() to build serial pipelines.
7.1 Agent vs Workflow: When to Use Which
| Agent | Workflow | |
|---|---|---|
| Execution path | Model decides autonomously, unpredictable | Explicitly defined, deterministic graph structure |
| Suitable tasks | Open-ended questions ("help me write a plan") | Deterministic flows ("scrape → clean → store") |
| Reliability | Depends on prompts and model capability | Step schemas provide strong constraints, predictable results |
| Debugging | View the full Trace reasoning process | Graphical view of each step's input/output |
Rule of thumb: use Workflow for predictable paths, embed Agents only where model judgment is needed. The two are often used in combination.
7.2 createStep: Defining Steps
Steps are the building blocks of a Workflow. Each step declares input/output schemas with Zod, forming a type-safe pipeline interface:
// src/mastra/workflows/article-workflow.ts
import { createStep } from '@mastra/core/workflows';
import { z } from 'zod';
// Step 1: receive topic, produce an outline
const outlineStep = createStep({
id: 'outline',
inputSchema: z.object({
topic: z.string().describe('Article topic'),
}),
outputSchema: z.object({
outline: z.string(),
topic: z.string(), // passthrough to downstream
}),
// execute's inputData type is auto-derived from inputSchema
execute: async ({ inputData }) => {
const { topic } = inputData;
// In production, call an LLM, API, or any function here
return {
outline: `Three-part outline for "${topic}": Background → Analysis → Conclusion`,
topic,
};
},
});7.3 createWorkflow + .then(): Chaining Execution
// Same file: step 2 consumes upstream output
const draftStep = createStep({
id: 'draft',
inputSchema: z.object({
outline: z.string(),
topic: z.string(),
}),
outputSchema: z.object({
article: z.string(),
}),
execute: async ({ inputData }) => ({
article: `《${inputData.topic}》\n\nBased on the outline, draft the body: ${inputData.outline}`,
}),
});
// Assemble the workflow: declare overall input/output → link steps → commit
export const articleWorkflow = createWorkflow({
id: 'article-workflow',
inputSchema: z.object({ topic: z.string() }),
outputSchema: z.object({ article: z.string() }),
})
.then(outlineStep) // Run outlineStep first
.then(draftStep) // Its output auto-becomes the next step's input
.commit(); // Must call — locks the flow definitionKey mechanism: .then() passes the previous step's outputSchema as the next step's validated input — if the two steps' schemas don't match, it errors at assembly time. This is the value of "schema as contract."
7.4 Registration and Triggering
// src/mastra/index.ts —— register the workflow
import { Mastra } from '@mastra/core';
import { articleWorkflow } from './workflows/article-workflow';
export const mastra = new Mastra({
workflows: { articleWorkflow },
});// Trigger method 1: create a run instance directly in code
const run = await mastra.getWorkflow('articleWorkflow').createRun();
const result = await run.start({ inputData: { topic: 'Large Language Models' } });
console.log(result.results); // Each step's outputYou can also manually fill trigger parameters in Studio's Workflows tab and observe each step's flow graphically.
7.5 Chapter Summary
- Open-ended tasks go to Agents; deterministic flows go to Workflows; complex systems combine both;
createStepuses Zod to bidirectionally declare input/output; execute only writes business logic;.then()chains serially and auto-checks schema compatibility;.commit()locks the flow;- Workflows also need to be registered on the Mastra instance; supports both code createRun and Studio manual trigger.
🧪 随堂测验
点击你认为正确的选项。答错时会展示正确答案与原因解析。
1. Which type of task is best suited for Workflow over Agent?
2. When linking steps with .then(), how does the framework ensure step compatibility?
3. After defining a createWorkflow, which method must be called last?
4. How does a workflow step's execute function correctly access upstream data?
🛠️ Hands-On Exercises
- Add a third step reviewStep to articleWorkflow: takes the draft as input, outputs a scored structure.
- Intentionally mismatch draftStep's outputSchema with reviewStep's inputSchema fields; observe the assembly-time error message.
- Open your workflow in Studio; screenshot the Graph view and compare it against the .then() order in code.