本集换一条赛道:前面四集都是「单个 Agent 怎么用」,这一集看「多个步骤怎么串成一条流水线」。MAF 的 Workflows 子库让你用 executor(执行单元)+ edge(边) 把处理步骤组合起来,像搭积木一样编排流程。
本集不调用任何大模型、不需要
DEEPSEEK_API_KEY,完全在本地运行,所以可以放心跑、随便改。
本集能学到什么
- 什么是 executor、什么是 edge;
- 两种创建 executor 的方式(lambda 包一层 / 继承基类自定义);
- 用
WorkflowBuilder把步骤串成工作流并运行; - 怎么从事件流里读出每一步的结果。
这个示例在做什么
流程只有两步,纯文本变换:
"Hello, World!"
│ UppercaseExecutor(转大写)
▼
"HELLO, WORLD!"
│ ReverseTextExecutor(反转)
▼
"!DLROW ,OLLEH"
输入 "Hello, World!",先被转成大写,再被反转,最终得到 "!DLROW ,OLLEH"。运行后在控制台会看到两行:
UppercaseExecutor: HELLO, WORLD!
ReverseTextExecutor: !DLROW ,OLLEH
核心概念
Executor —— 执行单元
executor 是工作流里最小的处理单元:吃进一个输入,吐出一个输出。两种写法:
方式一:把现成的方法包成 executor(适合一行就能写完的逻辑):
Func<string, string> uppercaseFunc = s => s.ToUpperInvariant();
var uppercase = uppercaseFunc.BindAsExecutor("UppercaseExecutor");
方式二:继承 Executor<TIn, TOut> 自定义(适合逻辑较复杂的步骤)。重写 HandleAsync,返回值就是该单元的输出:
internal sealed class ReverseTextExecutor() : Executor<string, string>("ReverseTextExecutor")
{
public override ValueTask<string> HandleAsync(string message, IWorkflowContext context, CancellationToken cancellationToken = default)
=> ValueTask.FromResult(string.Concat(message.Reverse()));
}
Edge —— 边(数据流)
edge 决定数据怎么从一个 executor 流到下一个。AddEdge(A, B) 表示「A 的输出接到 B 的输入」;.WithOutputFrom(B) 声明整个工作流的最终产出来自 B:
WorkflowBuilder builder = new(uppercase);
builder.AddEdge(uppercase, reverse).WithOutputFrom(reverse);
var workflow = builder.Build();
运行与读结果
InProcessExecution.RunAsync(workflow, 输入) 在进程内执行,返回 Run。通过 run.NewEvents 遍历事件,再筛选出 ExecutorCompletedEvent 就能拿到每一步的输出:
await using Run run = await InProcessExecution.RunAsync(workflow, "Hello, World!");
foreach (WorkflowEvent evt in run.NewEvents)
{
if (evt is ExecutorCompletedEvent done)
Console.WriteLine($"{done.ExecutorId}: {done.Data}");
}
动手改造:加一个步骤
把工作流从「两步」扩成「三步」,感受一下编排有多轻量。新增一个给文本加方括号的执行单元,插在反转之后:
internal sealed class BracketExecutor() : Executor<string, string>("BracketExecutor")
{
public override ValueTask<string> HandleAsync(string message, IWorkflowContext context, CancellationToken cancellationToken = default)
=> ValueTask.FromResult($"【{message}】");
}
串联时多加一条边即可:
WorkflowBuilder builder = new(uppercase);
builder.AddEdge(uppercase, reverse);
builder.AddEdge(reverse, bracket).WithOutputFrom(bracket); // 最终输出来自 bracket
var workflow = builder.Build();
输入 "Hello, World!" 现在会依次产出:
UppercaseExecutor: HELLO, WORLD!
ReverseTextExecutor: !DLROW ,OLLEH
BracketExecutor: 【!DLROW ,OLLEH】
要点:加步骤 = 写一个新 executor + 加一条 AddEdge,原有逻辑一行都不用改。
小结
- 工作流 = executor(做什么)+ edge(怎么流),与「是否用大模型」无关;
- executor 既能从 lambda 快速包出来,也能继承基类写复杂逻辑;
WorkflowBuilder负责串线,InProcessExecution.RunAsync负责跑,事件流负责暴露中间结果;- 这是把前面「单个 Agent」升级成「多步骤流水线」的基石——下一阶段你完全可以把某个 executor 内部换成调用一个 Agent。
系列总览
| 集 | 主题 | 关键 API |
|---|---|---|
| 1 | 单轮 Agent | AsAIAgent / RunAsync |
| 2 | 工具调用 | AIFunctionFactory.Create |
| 3 | 多轮对话 | AgentSession / CreateSessionAsync |
| 4 | 记忆 | 记忆持久化 |
| 5 | 工作流编排 | Executor / WorkflowBuilder / AddEdge |
参考资料
- 本集源码:
05_first_workflow/Program.cs - MAF Workflows 命名空间:
Microsoft.Agents.AI.Workflows - 上一集:第 4 集 · 记忆