|
| 1 | +--- |
| 2 | +title: Declarative Workflows - Overview |
| 3 | +description: Learn how to define workflows using YAML configuration files instead of programmatic code in Microsoft Agent Framework. |
| 4 | +zone_pivot_groups: programming-languages |
| 5 | +author: moonbox3 |
| 6 | +ms.topic: tutorial |
| 7 | +ms.author: evmattso |
| 8 | +ms.date: 1/12/2026 |
| 9 | +ms.service: agent-framework |
| 10 | +--- |
| 11 | + |
| 12 | +# Declarative Workflows - Overview |
| 13 | + |
| 14 | +Declarative workflows allow you to define workflow logic using YAML configuration files instead of writing programmatic code. This approach makes workflows easier to read, modify, and share across teams. |
| 15 | + |
| 16 | +## Overview |
| 17 | + |
| 18 | +With declarative workflows, you describe *what* your workflow should do rather than *how* to implement it. The framework handles the underlying execution, converting your YAML definitions into executable workflow graphs. |
| 19 | + |
| 20 | +**Key benefits:** |
| 21 | + |
| 22 | +- **Readable format**: YAML syntax is easy to understand, even for non-developers |
| 23 | +- **Portable**: Workflow definitions can be shared, versioned, and modified without code changes |
| 24 | +- **Rapid iteration**: Modify workflow behavior by editing configuration files |
| 25 | +- **Consistent structure**: Predefined action types ensure workflows follow best practices |
| 26 | + |
| 27 | +## When to Use Declarative vs. Programmatic Workflows |
| 28 | + |
| 29 | +| Scenario | Recommended Approach | |
| 30 | +|----------|---------------------| |
| 31 | +| Standard orchestration patterns | Declarative | |
| 32 | +| Workflows that change frequently | Declarative | |
| 33 | +| Non-developers need to modify workflows | Declarative | |
| 34 | +| Complex custom logic | Programmatic | |
| 35 | +| Maximum flexibility and control | Programmatic | |
| 36 | +| Integration with existing Python code | Programmatic | |
| 37 | + |
| 38 | +::: zone pivot="programming-language-csharp" |
| 39 | + |
| 40 | +> [!NOTE] |
| 41 | +> Documentation for declarative workflows in .NET is coming soon. Please check back for updates. |
| 42 | +
|
| 43 | +::: zone-end |
| 44 | + |
| 45 | +::: zone pivot="programming-language-python" |
| 46 | + |
| 47 | +## Prerequisites |
| 48 | + |
| 49 | +Before you begin, ensure you have: |
| 50 | + |
| 51 | +- Python 3.10 - 3.13 (Python 3.14 is not yet supported due to PowerFx compatibility) |
| 52 | +- The Agent Framework declarative package installed: |
| 53 | + |
| 54 | +```bash |
| 55 | +pip install agent-framework-declarative --pre |
| 56 | +``` |
| 57 | + |
| 58 | +This package pulls in the underlying `agent-framework-core` automatically. |
| 59 | + |
| 60 | +- Basic familiarity with YAML syntax |
| 61 | +- Understanding of [workflow concepts](./overview.md) |
| 62 | + |
| 63 | +## Basic YAML Structure |
| 64 | + |
| 65 | +A declarative workflow consists of a few key elements: |
| 66 | + |
| 67 | +```yaml |
| 68 | +name: my-workflow |
| 69 | +description: A brief description of what this workflow does |
| 70 | + |
| 71 | +inputs: |
| 72 | + parameterName: |
| 73 | + type: string |
| 74 | + description: Description of the parameter |
| 75 | + |
| 76 | +actions: |
| 77 | + - kind: ActionType |
| 78 | + id: unique_action_id |
| 79 | + displayName: Human readable name |
| 80 | + # Action-specific properties |
| 81 | +``` |
| 82 | + |
| 83 | +### Structure Elements |
| 84 | + |
| 85 | +| Element | Required | Description | |
| 86 | +|---------|----------|-------------| |
| 87 | +| `name` | Yes | Unique identifier for the workflow | |
| 88 | +| `description` | No | Human-readable description | |
| 89 | +| `inputs` | No | Input parameters the workflow accepts | |
| 90 | +| `actions` | Yes | List of actions to execute | |
| 91 | + |
| 92 | +## Your First Declarative Workflow |
| 93 | + |
| 94 | +Let's create a simple workflow that greets a user by name. |
| 95 | + |
| 96 | +### Step 1: Create the YAML File |
| 97 | + |
| 98 | +Create a file named `greeting-workflow.yaml`: |
| 99 | + |
| 100 | +```yaml |
| 101 | +name: greeting-workflow |
| 102 | +description: A simple workflow that greets the user |
| 103 | + |
| 104 | +inputs: |
| 105 | + name: |
| 106 | + type: string |
| 107 | + description: The name of the person to greet |
| 108 | + |
| 109 | +actions: |
| 110 | + # Set a greeting prefix |
| 111 | + - kind: SetVariable |
| 112 | + id: set_greeting |
| 113 | + displayName: Set greeting prefix |
| 114 | + variable: Local.greeting |
| 115 | + value: Hello |
| 116 | + |
| 117 | + # Build the full message using an expression |
| 118 | + - kind: SetVariable |
| 119 | + id: build_message |
| 120 | + displayName: Build greeting message |
| 121 | + variable: Local.message |
| 122 | + value: =Concat(Local.greeting, ", ", Workflow.Inputs.name, "!") |
| 123 | + |
| 124 | + # Send the greeting to the user |
| 125 | + - kind: SendActivity |
| 126 | + id: send_greeting |
| 127 | + displayName: Send greeting to user |
| 128 | + activity: |
| 129 | + text: =Local.message |
| 130 | + |
| 131 | + # Store the result in outputs |
| 132 | + - kind: SetVariable |
| 133 | + id: set_output |
| 134 | + displayName: Store result in outputs |
| 135 | + variable: Workflow.Outputs.greeting |
| 136 | + value: =Local.message |
| 137 | +``` |
| 138 | +
|
| 139 | +### Step 2: Load and Run the Workflow |
| 140 | +
|
| 141 | +Create a Python file to execute the workflow: |
| 142 | +
|
| 143 | +```python |
| 144 | +import asyncio |
| 145 | +from pathlib import Path |
| 146 | + |
| 147 | +from agent_framework.declarative import WorkflowFactory |
| 148 | + |
| 149 | + |
| 150 | +async def main() -> None: |
| 151 | + """Run the greeting workflow.""" |
| 152 | + # Create a workflow factory |
| 153 | + factory = WorkflowFactory() |
| 154 | + |
| 155 | + # Load the workflow from YAML |
| 156 | + workflow_path = Path(__file__).parent / "greeting-workflow.yaml" |
| 157 | + workflow = factory.create_workflow_from_yaml_path(workflow_path) |
| 158 | + |
| 159 | + print(f"Loaded workflow: {workflow.name}") |
| 160 | + print("-" * 40) |
| 161 | + |
| 162 | + # Run with a name input |
| 163 | + result = await workflow.run({"name": "Alice"}) |
| 164 | + for output in result.get_outputs(): |
| 165 | + print(f"Output: {output}") |
| 166 | + |
| 167 | + |
| 168 | +if __name__ == "__main__": |
| 169 | + asyncio.run(main()) |
| 170 | +``` |
| 171 | +
|
| 172 | +### Expected Output |
| 173 | +
|
| 174 | +``` |
| 175 | +Loaded workflow: greeting-workflow |
| 176 | +---------------------------------------- |
| 177 | +Output: Hello, Alice! |
| 178 | +``` |
| 179 | +
|
| 180 | +## Core Concepts |
| 181 | +
|
| 182 | +### Variable Namespaces |
| 183 | +
|
| 184 | +Declarative workflows use namespaced variables to organize state: |
| 185 | +
|
| 186 | +| Namespace | Description | Example | |
| 187 | +|-----------|-------------|---------| |
| 188 | +| `Local.*` | Variables local to the workflow | `Local.message` | |
| 189 | +| `Workflow.Inputs.*` | Input parameters | `Workflow.Inputs.name` | |
| 190 | +| `Workflow.Outputs.*` | Output values | `Workflow.Outputs.result` | |
| 191 | +| `System.*` | System-provided values | `System.ConversationId` | |
| 192 | + |
| 193 | +### Expression Language |
| 194 | + |
| 195 | +Values prefixed with `=` are evaluated as expressions: |
| 196 | + |
| 197 | +```yaml |
| 198 | +# Literal value (no evaluation) |
| 199 | +value: Hello |
| 200 | +
|
| 201 | +# Expression (evaluated at runtime) |
| 202 | +value: =Concat("Hello, ", Workflow.Inputs.name) |
| 203 | +``` |
| 204 | + |
| 205 | +Common functions include: |
| 206 | +- `Concat(str1, str2, ...)` - Concatenate strings |
| 207 | +- `If(condition, trueValue, falseValue)` - Conditional expression |
| 208 | +- `IsBlank(value)` - Check if value is empty |
| 209 | + |
| 210 | +### Action Types |
| 211 | + |
| 212 | +Declarative workflows support various action types: |
| 213 | + |
| 214 | +| Category | Actions | |
| 215 | +|----------|---------| |
| 216 | +| Variable Management | `SetVariable`, `AppendValue`, `ResetVariable` | |
| 217 | +| Control Flow | `If`, `ConditionGroup`, `Foreach`, `RepeatUntil` | |
| 218 | +| Output | `SendActivity`, `EmitEvent` | |
| 219 | +| Agent Invocation | `InvokeAzureAgent` | |
| 220 | +| Human-in-the-Loop | `Question`, `Confirmation`, `RequestExternalInput` | |
| 221 | +| Workflow Control | `EndWorkflow`, `EndConversation` | |
| 222 | + |
| 223 | +::: zone-end |
| 224 | + |
| 225 | +## Next Steps |
| 226 | + |
| 227 | +- [Expressions and Variables](./declarative-workflows/expressions.md) - Learn the expression language and variable namespaces |
| 228 | +- [Actions Reference](./declarative-workflows/actions-reference.md) - Complete reference for all action types |
| 229 | +- [Advanced Patterns](./declarative-workflows/advanced-patterns.md) - Multi-agent orchestration and complex scenarios |
| 230 | +- [Python Declarative Workflow Samples](https://github.com/microsoft/agent-framework/tree/main/python/samples/getting_started/workflows/declarative) - Explore complete working examples |
0 commit comments