Yesterday, I created a minimal .NET project with DevUI and registered a couple of standalone agents. That gets you surprisingly far for interactive testing. But real business scenarios quickly outgrow a single agent: you need data flowing through multiple specialized steps, decisions being made along the way, and a clear picture of the whole pipeline.
That's what workflows are for. In this post, we'll build a content review pipeline as a concrete example — a Writer agent drafts a response, a Reviewer agent critiques it, and a deterministic formatting step finalizes the output. All of it visualized in DevUI.
Agents vs Workflows — the key distinction
The Agent Framework docs put it cleanly: an agent is LLM-driven and dynamic — it decides which tools to call and in what order, based on the conversation. A workflow is a predefined graph of operations, some of which may be AI agents, but the topology is explicit and deterministic. You decide exactly what runs after what.
When should you choose a workflow over a single agent with tools? A few signals:
- You need multiple agents with different system prompts to collaborate in a fixed order
- You have deterministic steps (validation, formatting, API calls) interleaved with LLM steps
- You need checkpointing, fault tolerance, or human-in-the-loop approval between steps
- You want type-safe message contracts between pipeline stages
Remark: The key message is to remain pragmatic: if you can write a regular function to handle the task, do that. Use an agent when you need LLM reasoning. Use a workflow when you need explicit control over a multi-step process.
Core Workflow concepts
Three concepts make up the mental model:
Executors are the processing nodes. Each executor receives typed messages, does work (LLM call, API call, data transform), and emits typed output messages. The recommended way to define one is a partial class that inherits from Executor, with handler methods marked [MessageHandler]. The partial keyword enables compile-time source generation for handler registration.
Edges define the connections between executors — which executor's output feeds which other executor's input. They can be simple direct connections, or conditional branches that route based on message content.
WorkflowBuilder ties executors and edges into a directed graph. Once built, you execute it with InProcessExecution.RunStreamingAsync() or RunAsync().
What we're building
A content review pipeline with three stages:
1. Writer executor (AI agent) — takes a topic prompt and drafts a short paragraph
2. Reviewer executor (AI agent) — receives the draft and returns concise actionable feedback
3. Formatter executor (deterministic) — wraps the final output in a structured response envelope
The data flow looks like this:
Step 1: Install extra packages
On top of the packages from the previous post, you need the workflows package:
dotnet add package Microsoft.Agents.AI.Hosting --prerelease
dotnet add package Microsoft.Agents.AI.DevUI --prerelease
dotnet add package Microsoft.Agents.AI.Workflows --prerelease
dotnet add package OllamaSharp
Step 2: Define the Executors
WriterExecutor.cs
The Writer executor is a thin wrapper around a ChatClientAgent. It receives a string (the user's topic), runs the agent, and returns the draft as a string that gets forwarded to the next executor automatically.
ReviewerExecutor.cs
The Reviewer receives the draft string and returns a string containing its feedback. Same pattern, different agent instructions.
FormatterExecutor.cs
The Formatter is a purely deterministic executor — no AI, just C# code. It calls context.YieldOutputAsync() to emit the final result back to the workflow caller.
Step 3: Wire it up in Program.cs
Now the workflow is assembled in Program.cs alongside the DevUI registration. The key difference from the single-agent setup is that instead of calling builder.AddAIAgent(), we construct agents manually so we can pass them into executor instances, then hand the workflow to the hosting layer.
Step 3 — Run and Explore in DevUI
dotnet run
In the DevUI sidebar you'll now see ContentReviewPipeline listed as a workflow entry rather than an agent. Click on Configure and run, type a topic — "the benefits of electric vehicles" works well — and hit Run workflow.
Unfortunately, that didn't work and resulted in an error. It turns out that using mixed workflows in C# doesn't work yet in DevUI.
However, an agent only workflow does work. So, let's update our example and change it into an agent only workflow:
Restart the application, click on Configure and run again, type a topic — "the benefits of electric vehicles" — and hit Run workflow.
You'll see each executor fire in sequence. Because agents are wrapped as executors in the workflow, the reasoning trail shows the Writer's output, then the Reviewer's feedback, the full chain of thought, step by step.
Tip: DevUI's workflow visualization is one of its strongest features. Unlike the single-agent view, you can see the executor graph on the left and watch messages propagate through it in real time, which makes it easy to spot where in the pipeline things are going wrong.
Calling the workflow programmatically
If you want to call the workflow directly from code (outside of DevUI), you can use the RunAsync method:
Conclusion
Switching from a single agent to a workflow in the Agent Framework is mostly additive. You keep the same setup from part one and add executor classes plus a WorkflowBuilder call.
Unfortunately, the DevUI backend part for ASP.NET Core can’t handle all type of workflows yet, so we’ll have to wait for an update. When that happens, I’ll write a follow-up post. Pinky promise!
Meanwhile, you can explore my working end-to-end example here: wullemsb/DevUIExample at workflows
More information
Microsoft Agent Framework Workflows | Microsoft Learn
Microsoft Agent Framework Workflows - Executors | Microsoft Learn
wullemsb/DevUIExample at workflows