orchestrate-durable-agents
Learn how to orchestrate multiple durable AI agents with fan-out/fan-in patterns for concurrent processing
$ npx -y skills add managedcode/dotnet-skills --agent claude-codeHow it fires
How this agent gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
Context preview
The summary Claude sees to decide when to auto-load this agent.
Learn how to orchestrate multiple durable AI agents with fan-out/fan-in patterns for concurrent processing
Agent definition
orchestrate-durable-agents.mdtitle: Orchestrate durable agents
description: Learn how to orchestrate multiple durable AI agents with fan-out/fan-in patterns for concurrent processing
zone_pivot_groups: programming-languages
author: anthonychu
ms.topic: tutorial
ms.author: antchu
ms.date: 11/07/2025
ms.service: agent-framework
Orchestrate durable agents
This tutorial shows you how to orchestrate multiple durable AI agents using the fan-out/fan-in patterns. You'll extend the durable agent from the [Create and run a durable agent](create-and-run-durable-agent.md) tutorial to create a multi-agent system that processes a user's question, then translates the response into multiple languages concurrently.
This orchestration pattern demonstrates how to:
- Reuse the durable agent from the first tutorial.
- Create additional durable agents for language translation.
- Fan out to multiple agents for concurrent processing.
- Fan in results and return them as structured JSON.
Prerequisites
Before you begin, you must complete the [Create and run a durable agent](create-and-run-durable-agent.md) tutorial. This tutorial extends the project created in that tutorial by adding orchestration capabilities.
Understanding the orchestration pattern
The orchestration you'll build follows this flow:
1. **User input** - A question or message from the user 2. **Main agent** - The `MyDurableAgent` from the first tutorial processes the question 3. **Fan-out** - The main agent's response is sent concurrently to both translation agents 4. **Translation agents** - Two specialized agents translate the response (French and Spanish) 5. **Fan-in** - Results are aggregated into a single JSON response with the original response and translations
This pattern enables concurrent processing, reducing total response time compared to sequential translation.
Register agents at startup
To properly use agents in durable orchestrations, register them at application startup. They can be used across orchestration executions.
::: zone pivot="programming-language-csharp"
Update your `Program.cs` to register the translation agents alongside the existing `MyDurableAgent`:
using System;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Hosting.AzureFunctions;
using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Extensions.Hosting;
using OpenAI;
using OpenAI.Chat;
// Get the Azure OpenAI configuration
string endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")
?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
string deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT")
?? "gpt-4o-mini";
// Create the Azure OpenAI client
AzureOpenAIClient client = new(new Uri(endpoint), new DefaultAzureCredential());
ChatClient chatClient = client.GetChatClient(deploymentName);
// Create the main agent from the first tutorial
AIAgent mainAgent = chatClient.AsAIAgent(
instructions: "You are a helpful assistant that can answer questions and provide information.",
name: "MyDurableAgent");
// Create translation agents
AIAgent frenchAgent = chatClient.AsAIAgent(
instructions: "You are a translator. Translate the following text to French. Return only the translation, no explanations.",
name: "FrenchTranslator");
AIAgent spanishAgent = chatClient.AsAIAgent(
instructions: "You are a translator. Translate the following text to Spanish. Return only the translation, no explanations.",
name: "SpanishTranslator");
// Build and configure the Functions host
using IHost app = FunctionsApplication
.CreateBuilder(args)
.ConfigureFunctionsWebApplication()
.ConfigureDurableAgents(options =>
{
// Register all agents for use in orchestrations and HTTP endpoints
options.AddAIAgent(mainAgent);
options.AddAIAgent(frenchAgent);
options.AddAIAgent(spanishAgent);
})
.Build();
app.Run();This setup:
- Keeps the original `MyDurableAgent` from the first tutorial.
- Creates two new translation agents (French and Spanish).
- Registers all three agents with the Durable Task framework using `options.AddAIAgent()`.
- Makes agents available throughout the application lifetime for individual interactions and orchestrations.
::: zone-end
::: zone pivot="programming-language-python"
Update your `function_app.py` to register the translation agents alongside the existing `MyDurableAgent`:
import os
from azure.identity import DefaultAzureCredential
from agent_framework.azure import AzureOpenAIChatClient, AgentFunctionApp
# Get the Azure OpenAI configuration
endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")
if not endpoint:
raise ValueError("AZURE_OPENAI_ENDPOINT is not set.")
deployment_name = os.getenv("AZURE_OPENAI_DEPLOYMENT", "gpt-4o-mini")
# Create the Azure OpenAI client
chat_client = AzureOpenAIChatClient(
endpoint=endpoint,
deployment_name=deployment_name,
credential=DefaultAzureCredential()
)
# Create the main agent from the first tutorial
main_agent = chat_client.as_agent(
instructions="You are a helpful assistant that can answer questions and provide information.",
name="MyDurableAgent"
)
# Create translation agents
french_agent = chat_client.as_agent(
instructions="You are a translator. Translate the following text to French. Return only the translation, no explanations.",
name="FrenchTranslator"
)
spanish_agent = chat_client.as_agent(
instructions="You are a translator. Translate the following text to Spanish. Return only the translation, no explanations.",
name="SpanishTranslator"
)
# Create the function app and register all agents
app = AgentFunctionApp(agents=[main_agent, french_agent, spanish_agent])This setup:
- Keeps the original `MyDurableAgent` from the first tutorial.
- Creates two new translation agents (French and Spanish).
- Registers all three agents with the Durable Task framewo
Read more
title: Orchestrate durable agents description: Learn how to orchestrate multiple durable AI agents with fan-out/fan-in patterns for concurrent processing zone_pivot_groups: programming-languages author: anthonychu ms.topic: tutorial ms.author: antchu ms.date: 11/07/2025 ms.service: agent-framework
Orchestrate durable agents
This tutorial shows you how to orchestrate multiple durable AI agents using the fan-out/fan-in patterns. You'll extend the durable agent from the [Create and run a durable agent](create-and-run-durable-agent.md) tutorial to create a multi-agent system that processes a user's question, then translates the response into multiple languages concurrently.
This orchestration pattern demonstrates how to:
- Reuse the durable agent from the first tutorial.
- Create additional durable agents for language translation.
- Fan out to multiple agents for concurrent processing.
- Fan in results and return them as structured JSON.
Prerequisites
Before you begin, you must complete the [Create and run a durable agent](create-and-run-durable-agent.md) tutorial. This tutorial extends the project created in that tutorial by adding orchestration capabilities.
Understanding the orchestration pattern
The orchestration you'll build follows this flow:
1. **User input** - A question or message from the user 2. **Main agent** - The `MyDurableAgent` from the first tutorial processes the question 3. **Fan-out** - The main agent's response is sent concurrently to both translation agents 4. **Translation agents** - Two specialized agents translate the response (French and Spanish) 5. **Fan-in** - Results are aggregated into a single JSON response with the original response and translations
This pattern enables concurrent processing, reducing total response time compared to sequential translation.
Register agents at startup
To properly use agents in durable orchestrations, register them at application startup. They can be used across orchestration executions.
::: zone pivot="programming-language-csharp"
Update your `Program.cs` to register the translation agents alongside the existing `MyDurableAgent`:
using System;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Hosting.AzureFunctions;
using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Extensions.Hosting;
using OpenAI;
using OpenAI.Chat;
// Get the Azure OpenAI configuration
string endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")
?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
string deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT")
?? "gpt-4o-mini";
// Create the Azure OpenAI client
AzureOpenAIClient client = new(new Uri(endpoint), new DefaultAzureCredential());
ChatClient chatClient = client.GetChatClient(deploymentName);
// Create the main agent from the first tutorial
AIAgent mainAgent = chatClient.AsAIAgent(
instructions: "You are a helpful assistant that can answer questions and provide information.",
name: "MyDurableAgent");
// Create translation agents
AIAgent frenchAgent = chatClient.AsAIAgent(
instructions: "You are a translator. Translate the following text to French. Return only the translation, no explanations.",
name: "FrenchTranslator");
AIAgent spanishAgent = chatClient.AsAIAgent(
instructions: "You are a translator. Translate the following text to Spanish. Return only the translation, no explanations.",
name: "SpanishTranslator");
// Build and configure the Functions host
using IHost app = FunctionsApplication
.CreateBuilder(args)
.ConfigureFunctionsWebApplication()
.ConfigureDurableAgents(options =>
{
// Register all agents for use in orchestrations and HTTP endpoints
options.AddAIAgent(mainAgent);
options.AddAIAgent(frenchAgent);
options.AddAIAgent(spanishAgent);
})
.Build();
app.Run();This setup:
- Keeps the original `MyDurableAgent` from the first tutorial.
- Creates two new translation agents (French and Spanish).
- Registers all three agents with the Durable Task framework using `options.AddAIAgent()`.
- Makes agents available throughout the application lifetime for individual interactions and orchestrations.
::: zone-end
::: zone pivot="programming-language-python"
Update your `function_app.py` to register the translation agents alongside the existing `MyDurableAgent`:
import os
from azure.identity import DefaultAzureCredential
from agent_framework.azure import AzureOpenAIChatClient, AgentFunctionApp
# Get the Azure OpenAI configuration
endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")
if not endpoint:
raise ValueError("AZURE_OPENAI_ENDPOINT is not set.")
deployment_name = os.getenv("AZURE_OPENAI_DEPLOYMENT", "gpt-4o-mini")
# Create the Azure OpenAI client
chat_client = AzureOpenAIChatClient(
endpoint=endpoint,
deployment_name=deployment_name,
credential=DefaultAzureCredential()
)
# Create the main agent from the first tutorial
main_agent = chat_client.as_agent(
instructions="You are a helpful assistant that can answer questions and provide information.",
name="MyDurableAgent"
)
# Create translation agents
french_agent = chat_client.as_agent(
instructions="You are a translator. Translate the following text to French. Return only the translation, no explanations.",
name="FrenchTranslator"
)
spanish_agent = chat_client.as_agent(
instructions="You are a translator. Translate the following text to Spanish. Return only the translation, no explanations.",
name="SpanishTranslator"
)
# Create the function app and register all agents
app = AgentFunctionApp(agents=[main_agent, french_agent, spanish_agent])This setup:
- Keeps the original `MyDurableAgent` from the first tutorial.
- Creates two new translation agents (French and Spanish).
- Registers all three agents with the Durable Task framewo
Stop explaining .NET to your AI. Start building. We've all been there: asking Claude to use Entity Framework, only to get EF6 patterns in a .NET 8 project. Explaining to Copilot that Blazor Server and Blazor WebAssembly aren't the same thing.
Repo: managedcode/dotnet-skills
Other agents on dotnet-skills.
- AGENT
Specialist orchestration agent for .NET Aspire work. Use when the problem is clearly about AppHost design, ServiceDefaults, first-party versus CommunityToolkit/Aspire integrations, dashboard and testing, `DistributedApplicationTestingBuilder`, `WebApplicationFactory`
Open agent - agent-as-function-tool
Legacy tutorial alias retained locally; the live Learn URL now resolves into the broader Function Tools surface
Open agent - agent-as-mcp-tool
Learn how to expose an agent as a tool over the MCP protocol
Open agent - create-and-run-durable-agent
Learn how to create and run a durable AI agent with Azure Functions and the durable task extension for Microsoft Agent Framework
Open agent - enable-observability
Enable OpenTelemetry for an agent so agent interactions are automatically logged
Open agent - function-tools-approvals
Learn how to use function tools with human in the loop approvals
Open agent

