{"id":5678,"date":"2026-07-23T11:13:24","date_gmt":"2026-07-23T18:13:24","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/agent-framework\/?p=5678"},"modified":"2026-07-23T11:13:24","modified_gmt":"2026-07-23T18:13:24","slug":"move-agent-orchestration-workflows-out-of-code-with-agent-framework-declarative-workflows-1-0","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/agent-framework\/move-agent-orchestration-workflows-out-of-code-with-agent-framework-declarative-workflows-1-0\/","title":{"rendered":"Move Agent Orchestration\/Workflows out of Code with Agent Framework Declarative Workflows 1.0"},"content":{"rendered":"<p class=\"wp-block-paragraph\">Most multi-agent apps wire every flow in application code: the sequence of steps, branching, and handoffs between agents all live inside the program, making the orchestration harder to review, version, and change.<\/p>\n<p class=\"wp-block-paragraph\">Declarative workflows make that orchestration explicit. In YAML, you define how agents coordinate, how state changes, where execution branches, and when people step in. Agent Framework loads the definition into a standard workflow you can run, stream, and compose with code.<\/p>\n<p class=\"wp-block-paragraph\">Today, declarative workflows reach 1.0 across both Agent Framework SDKs. Python&#8217;s <code>agent-framework-declarative<\/code> package is now 1.0.0, joining the already-stable .NET <code>Microsoft.Agents.AI.Workflows.Declarative<\/code> package.<\/p>\n<h2 class=\"wp-block-heading\">Why teams choose declarative workflows<\/h2>\n<div>\n<div>Declarative workflows separate orchestration from application logic, and that separation pays off well beyond cleaner code. Because the workflow is a document rather than a call graph, product owners, solution architects, and developers can review how a workflow behaves without reading framework code. Updating an approval step, adding a new agent handoff, or changing branching logic often becomes a YAML change rather than a code change; something you can diff, review, and ship on its own.<\/div>\n<\/div>\n<div>\n<div>\u00a0<\/div>\n<div>You give up nothing at runtime. A declarative workflow loads into the same <code>Workflow<\/code> type as a code-first one, so it runs, streams, and composes just the same.<\/div>\n<\/div>\n<h2 class=\"wp-block-heading\">Author in YAML, run as an ordinary workflow<\/h2>\n<div>\n<div>Consider a support desk that routes each incoming request to the right specialist. The entire orchestration is a short, readable list of steps: a triage agent classifies the request, and a condition routes it to the billing, sales, or support agent.<\/div>\n<div>\u00a0<\/div>\n<\/div>\n<pre class=\"prettyprint language-json\"><code class=\"language-json\">kind: Workflow\r\ntrigger:\r\n  kind: OnConversationStart\r\n  id: support_router\r\n  actions:\r\n\r\n    # A triage agent classifies the incoming request.\r\n    - kind: InvokeAzureAgent\r\n      id: triage\r\n      conversationId: =System.ConversationId\r\n      agent:\r\n        name: TriageAgent\r\n      output:\r\n        responseObject: Local.Triage\r\n\r\n    # Route to the specialist that matches the category.\r\n    - kind: If\r\n      id: route\r\n      condition: =Local.Triage.Category = \"Billing\"\r\n      then:\r\n        - kind: InvokeAzureAgent\r\n          id: billing\r\n          agent:\r\n            name: BillingAgent\r\n      else:\r\n        - kind: If\r\n          condition: =Local.Triage.Category = \"Sales\"\r\n          then:\r\n            - kind: InvokeAzureAgent\r\n              id: sales\r\n              agent:\r\n                name: SalesAgent\r\n          else:\r\n            - kind: InvokeAzureAgent\r\n              id: support\r\n              agent:\r\n                name: SupportAgent<\/code><\/pre>\n<div>\n<div>The routing lives in the definition, not in application control flow. To add a category or reorder the checks, you edit the list; no executors to rewire.<\/div>\n<div>\u00a0<\/div>\n<\/div>\n<p class=\"wp-block-paragraph\">In <strong>Python<\/strong>, use <code>WorkflowFactory<\/code> to load the YAML definition and create a <code>Workflow<\/code> instance:<\/p>\n<pre class=\"wp-block-code\"><code class=\"language-python\">from agent_framework.declarative import WorkflowFactory\r\n\r\nfactory = WorkflowFactory()\r\nworkflow = factory.create_workflow_from_yaml_path(\"support_router.yaml\")\r\n<br \/># workflow is a standard Workflow - run, stream or compose it like any other.<br \/># The agents it names (TriageAgent, BillingAgent, ...) live in your Foundry project.<\/code><\/pre>\n<p class=\"wp-block-paragraph\">In <strong>.NET<\/strong>, use <code>DeclarativeWorkflowBuilder<\/code> to load the workflow definition and create a <code>Workflow<\/code> instance:<\/p>\n<pre class=\"wp-block-code\"><code class=\"language-csharp\">using Microsoft.Agents.AI.Workflows;\r\nusing Microsoft.Agents.AI.Workflows.Declarative;\r\n\r\n\/\/ options carries your agent provider and configuration; see the sample for setup.\r\nWorkflow workflow = DeclarativeWorkflowBuilder.Build&lt;string&gt;(\"CustomerSupport.yaml\", options);\r\n\r\n\/\/ From here, run or stream `workflow` like any other workflow.<\/code><\/pre>\n<p class=\"wp-block-paragraph\">These snippets focus on loading the workflow definition. For the full, runnable version of this pattern (with ticketing, escalation, and a human handoff); see the customer support sample (<a href=\"https:\/\/github.com\/microsoft\/agent-framework\/tree\/main\/python\/samples\/03-workflows\/declarative\/customer_support\">Python<\/a>,\u00a0<a href=\"https:\/\/github.com\/microsoft\/agent-framework\/tree\/main\/dotnet\/samples\/03-workflows\/Declarative\/CustomerSupport\">.Net<\/a>).<\/p>\n<h2 class=\"wp-block-heading\">What you can build<\/h2>\n<p class=\"wp-block-paragraph\">The router workflow above is intentionally small, but the same building blocks carry real multi-agent work. Each capability has a runnable sample in the repository:<\/p>\n<ul class=\"wp-block-list\">\n<li><strong>State and expressions<\/strong>: Store values in workflow state and compute new values with Power Fx expressions, such as <code>=If(IsBlank(inputs.name), \"World\", inputs.name)<\/code> (<a href=\"https:\/\/github.com\/microsoft\/agent-framework\/tree\/main\/python\/samples\/03-workflows\/declarative\/simple_workflow\">sample<\/a>).<\/li>\n<li><strong>Control flow<\/strong>: Branch on workflow state or agent results using conditions, loops, and jumps (<a href=\"https:\/\/github.com\/microsoft\/agent-framework\/tree\/main\/python\/samples\/03-workflows\/declarative\/conditional_workflow\">sample<\/a>).<\/li>\n<li><strong>Agent invocation<\/strong>: Invoke agents and route their responses, from sequential pipelines (<a href=\"https:\/\/github.com\/microsoft\/agent-framework\/tree\/main\/python\/samples\/03-workflows\/declarative\/marketing\">marketing<\/a>) to conditional routing (<a href=\"https:\/\/github.com\/microsoft\/agent-framework\/tree\/main\/python\/samples\/03-workflows\/declarative\/customer_support\">customer support<\/a>).<\/li>\n<li><strong>Function, MCP, and HTTP tools<\/strong>: Call application code (<a href=\"https:\/\/github.com\/microsoft\/agent-framework\/tree\/main\/python\/samples\/03-workflows\/declarative\/invoke_function_tool\">function tools<\/a>, <a href=\"https:\/\/github.com\/microsoft\/agent-framework\/tree\/main\/python\/samples\/03-workflows\/declarative\/invoke_mcp_tool\">MCP<\/a>, <a href=\"https:\/\/github.com\/microsoft\/agent-framework\/tree\/main\/python\/samples\/03-workflows\/declarative\/invoke_http_request\">HTTP<\/a>) from a step.<\/li>\n<li><strong>Human-in-the-loop<\/strong>: Pause for input or approval and continue when the person responds (<a href=\"https:\/\/github.com\/microsoft\/agent-framework\/tree\/main\/python\/samples\/03-workflows\/declarative\/human_in_loop\">sample<\/a>).<\/li>\n<li><strong>Checkpoint and resume<\/strong>: Persist workflow state and resume execution later (<a href=\"https:\/\/github.com\/microsoft\/agent-framework\/tree\/main\/dotnet\/samples\/03-workflows\/Declarative\/AotCheckpointing\">sample<\/a>).<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\">Declarative definitions load as standard <code>Workflow<\/code> instances, so you can run and compose them with code-first workflows. Use YAML where it fits and the lower-level APIs when you need custom behavior.<\/p>\n<h2 class=\"wp-block-heading\">Get started<\/h2>\n<p class=\"wp-block-paragraph\">Install the package for your SDK:<\/p>\n<pre class=\"wp-block-code\"><code class=\"language-bash\">pip install agent-framework-declarative\r\n\r\ndotnet add package Microsoft.Agents.AI.Workflows.Declarative<\/code><\/pre>\n<h2>Key takeaways<\/h2>\n<div>\n<div>Declarative workflows give you a way to define orchestration as data rather than code. Author workflows in YAML, review them like configuration, version them with your application, and execute them using the same runtime that powers code-first workflows. With 1.0 now available across Python and .NET, you can confidently build production multi-agent orchestrations while choosing the authoring style that best fits your team.<\/div>\n<div>\u00a0<\/div>\n<\/div>\n<p class=\"wp-block-paragraph\">Explore the documentation and runnable samples:<\/p>\n<ul class=\"wp-block-list\">\n<li><strong>Docs<\/strong>: <a href=\"https:\/\/learn.microsoft.com\/en-us\/agent-framework\/workflows\/declarative\">Declarative workflows overview<\/a><\/li>\n<li><strong>Python samples<\/strong>: <a href=\"https:\/\/github.com\/microsoft\/agent-framework\/tree\/main\/python\/samples\/03-workflows\/declarative\">python\/samples\/03-workflows\/declarative<\/a><\/li>\n<li><strong>.NET samples<\/strong>: <a href=\"https:\/\/github.com\/microsoft\/agent-framework\/tree\/main\/dotnet\/samples\/03-workflows\/Declarative\">dotnet\/samples\/03-workflows\/Declarative<\/a><\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\">Try a declarative workflow for an orchestration you would otherwise implement in code, then show us what you build. If you have ideas for what should come next, <a href=\"https:\/\/github.com\/microsoft\/agent-framework\/issues\">open an issue on GitHub<\/a>. Thanks for building with us.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Most multi-agent apps wire every flow in application code: the sequence of steps, branching, and handoffs between agents all live inside the program, making the orchestration harder to review, version, and change. Declarative workflows make that orchestration explicit. In YAML, you define how agents coordinate, how state changes, where execution branches, and when people step [&hellip;]<\/p>\n","protected":false},"author":208980,"featured_media":5475,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143,47],"tags":[79,161,155,157,53,158],"class_list":["post-5678","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-agent-framework","category-announcement","tag-net","tag-declarative","tag-multi-agent","tag-orchestration","tag-python","tag-workflows"],"acf":[],"blog_post_summary":"<p>Most multi-agent apps wire every flow in application code: the sequence of steps, branching, and handoffs between agents all live inside the program, making the orchestration harder to review, version, and change. Declarative workflows make that orchestration explicit. In YAML, you define how agents coordinate, how state changes, where execution branches, and when people step [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts\/5678","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/users\/208980"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/comments?post=5678"}],"version-history":[{"count":3,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts\/5678\/revisions"}],"predecessor-version":[{"id":5751,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts\/5678\/revisions\/5751"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/media\/5475"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/media?parent=5678"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/categories?post=5678"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/tags?post=5678"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}