Rediger

Dynamic workflows in Azure Functions hosted skills

Dynamic workflows are a feature of Azure Functions hosted skills. They let a hosted skill start a durable, multistep workflow of tool calls and waits without you writing Durable Functions orchestration code.

For the most up-to-date and comprehensive runtime documentation, see Dynamic workflows in Azure Functions Agents Runtime.

Important

Azure Functions hosted skills is currently in preview. Features, configuration names, and supported connectors can change before general availability.

Instead of calling tools one at a time through the conversation loop, dynamic workflows let the AI model generate a structured plan of tool calls. The runtime executes the plan as a Durable Functions orchestration that can fan out, wait, survive restarts, and remain observable without adding each intermediate tool result to the hosted skill's context during execution.

Why dynamic workflows

There are four basic limitations to hosted skills calling tools directly in the model loop:

  • Token cost. Every intermediate tool result is added to the model's context. A multistep plan can spend tokens on raw data that the model only needs to summarize.
  • Latency. Each direct tool call is another model round trip. Long or branchy work runs serially through the model loop instead of running independent work in parallel.
  • Durability. Inline work can be lost if the worker restarts, and there's no first-class way to sleep on a timer or wait for a long-running external signal.
  • Observability. Operators can't easily list, inspect, or cancel in-flight work without going through the chat session.

Dynamic workflows address these limitations by moving plan execution into a durable orchestration. The hosted skill starts the workflow, receives a workflow ID, and can end its turn. The orchestrator runs workflow-safe tools and durable timers. The built-in chat UI and operations surfaces can track the workflow independently.

How dynamic workflows relate to programmatic tool calling

Dynamic workflows are similar in shape to Anthropic's programmatic tool calling pattern. In that pattern, the model creates a structured tool plan and the runtime executes it outside the normal tool-by-tool chat loop. This approach can reduce token use and latency because intermediate results stay outside the model context during execution, and one model-authored plan can represent multiple tool calls.

Dynamic workflows apply that pattern to Azure Functions and add a durability and operations layer:

Capability Programmatic tool calling pattern Dynamic workflows
Plan-shaped tool calls Yes Yes
Lower token use and latency for multi-tool work Yes Yes
Durable execution across worker restarts No Yes, by using Durable Functions
Durable waits and timers No Yes
Outside-the-loop list, inspect, cancel, and terminate No Yes
Operator visibility in Durable Task Scheduler No Yes, when configured

When to use dynamic workflows

Use dynamic workflows when a hosted skill needs to run work that's larger than a single chat turn or direct tool call. Good fits include:

  • Fan-out/fan-in patterns that gather evidence from several independent sources in parallel, such as logs, metrics, and deployment history.
  • Running isolated specialist hosted skills in parallel and combining their responses.
  • Running a multistep plan where later steps depend on earlier tool results.
  • Waiting for a durable timer without keeping a worker busy.
  • Keeping large intermediate results out of the hosted skill's conversation context until a final result or summary is available.
  • Tracking and controlling long-running work from outside the model loop.

Tip

If the work can finish in a single tool call or needs an immediate user response at every step, use direct tool calling instead of a dynamic workflow.

How a workflow runs

The following diagram shows the main components in the dynamic workflow architecture:

Diagram showing a hosted skill starting a dynamic workflow that runs tool activities, timers, and subagents through a Durable orchestrator.

A dynamic workflow runs through this sequence:

  1. An event triggers the hosted skill, or a user sends a request through the chat UI.
  2. The hosted skill calls fhs_start_workflow with a workflow plan generated by the AI model.
  3. The runtime starts the plan as a Durable Functions orchestration and returns a workflow ID immediately.
  4. The orchestrator runs ready tool activities in parallel and creates durable timers for wait steps. It can also delegate work to subagent hosted skills, each running in an isolated, stateless session.
  5. In the built-in chat UI, the UI polls workflow status. When the workflow reaches a terminal state, the UI notifies the hosted skill, which calls fhs_get_workflow_status and summarizes the final output.

For workflows started by an explicit Functions trigger, add a final tool task that delivers the result to a queue, database, or notification service. The trigger doesn't automatically resume the hosted skill.

Intermediate results stay in the workflow store during execution. For a completed workflow, output.results includes each task's result, including any continued failures. Keep task results small and end the workflow with a summary task when needed. The hosted skill doesn't poll while the workflow runs.

Workflow management tools

When you enable workflows, the runtime adds these tools to the hosted skill:

Tool Purpose
fhs_start_workflow Starts a validated workflow plan and returns a workflow ID immediately.
fhs_get_workflow_status Gets the current status and final output for a workflow.
fhs_list_workflows Lists workflows owned by the current hosted skill and session.
fhs_cancel_workflow Requests cooperative cancellation.
fhs_terminate_workflow Terminates the workflow instance abruptly.

The hosted skill calls these tools. Users don't call them directly in application code.

Workflow subagents

A workflow-enabled hosted skill can grant access to specialist hosted skills in its workflows.subagents configuration. Each specialist is another .agent.md file in the same hosted skills app.

The following front matter lets the coordinator use two specialists:

---
name: PR Status Portfolio Coordinator
description: Reviews pull requests and produces an actionable report.
workflows:
  enabled: true
  subagents:
    - agent: pr_status_analyst
      when: Review one pull request and summarize its current status
    - agent: actionable_report_writer
      when: Combine pull-request summaries into an actionable portfolio report
---

The agent value is the specialist's file-name slug. For example, pr_status_analyst refers to pr_status_analyst.agent.md. The optional when value helps the model decide when to use the specialist. The runtime validates each specialist against this explicit grant before scheduling the workflow.

The model can generate a sub_agent workflow task with id, agent, and a self-contained task. A subagent task can also use depends_on, when, and for_each.

{
  "id": "analyze_pr",
  "type": "sub_agent",
  "agent": "pr_status_analyst",
  "task": "Review the supplied pull request and summarize its current status."
}

Each subagent invocation is stateless and isolated:

  • The specialist uses its own model, instructions, tools, MCP servers, skills, and timeout.
  • The specialist doesn't receive the coordinator's conversation history, sandbox, workflow-management tools, or chat-time delegation tools.
  • By default, a specialist failure or timeout fails the parent workflow. Set execution.continue_on_error to true to pass a failure result to later tasks instead. Authorization and tool-contract errors still fail the workflow.
  • Specialist tools should tolerate re-execution because a worker failure can cause a subagent to run more than once.

For an end-to-end example that runs parallel PR analyst tasks and combines their summaries into a report, see the workflow subagents sample.

Storage backend

Dynamic workflows use Durable Functions internally and support the same storage backends. By default, workflows use the Azure Storage account that your function app already has. For production workloads, you can switch to Durable Task Scheduler (DTS), which provides a dashboard with per-instance task state, retry history, and controls for in-flight work. The how-to guide covers both options.

Considerations

Keep these considerations in mind when you use dynamic workflows:

  • Workflow-safe tool handlers can be synchronous or asynchronous and must return JSON-serializable values.
  • The AI model generates the workflow plan at run time. You can't define static workflow templates in YAML or Markdown.
  • Tool and subagent tasks support execution.retry, execution.timeout, and execution.continue_on_error. Wait tasks don't support these settings.
  • A workflow supports up to 50 task instances and 10 parallel tasks. Each wait can last up to 24 hours.
  • Large-output handling and MCP Tasks integration aren't available.

Next steps

Configure workflow-safe tools and run your workflow locally: