Back to Blog
May 27, 2026

Deterministic Multi-Agent Orchestrations with Microsoft Agent Framework and .NET Durable Functions

Share

Deterministic Multi-Agent Orchestrations with Microsoft Agent Framework and .NET Durable Functions

Date: 2026-05-27

Discover how to build predictable, replayable multi-agent orchestrations using Microsoft Agent Framework with .NET Durable Functions — balancing AI autonomy and control for robust workflows.

Tags: ["Microsoft Agent Framework", "Durable Functions", "Azure Functions", "Multi-Agent Systems", "Deterministic Orchestration"]

Deterministic Multi-Agent Orchestrations with Microsoft Agent Framework and .NET Durable Functions

Multi-agent systems bring powerful flexibility to cloud-based AI workflows, but that flexibility often comes with unpredictability and complexity. When an orchestration routes dynamically between agents, divergent execution paths complicate auditing, retries, and debugging. In production-grade systems, deterministic workflows become crucial — ensuring the same inputs always trigger the same, replayable orchestration paths.

This post dives into how Microsoft Agent Framework leverages .NET Durable Functions to orchestrate multiple intelligent agents deterministically. We’ll explore a practical example coordinating a "weather-assessor" and an "itinerary-planner" agent to build weekend plans based on weather conditions. By embedding the orchestration logic in a Durable Functions orchestrator, you get a transparent, testable control plane that sequences smart agents reliably inside Azure Functions.

You’ll learn about designing these orchestrations, registering and resolving agents, managing deterministic branching, and even mixing AI-powered agents with traditional durable activities. Whether you’re building AI workflows in Azure or scaling multi-agent collaborations, understanding this pattern can improve maintainability and operational confidence dramatically.

Architecture Overview

┌────────────────────────────────────────────┐
│Architecture                                │
├────────────────────────────────────────────┤
│• Enterprise data sources                   │
│• Foundry platform                          │
│• AI applications                           │
└────────────────────────────────────────────┘

Key Technical Observations

  • Deterministic Orchestration Control Plane — Placing orchestration logic into Durable Functions allows replayable workflows where the same input deterministically follows the same path. This dramatically simplifies auditing and error handling over free-form agent routing.

  • Agent-as-Service Pattern — Each AI agent runs as a distinct, durable session with its own instructions and tools, encapsulated by DurableAIAgent. This architectural separation keeps AI functionality modular and testable.

  • Structured Agent Responses with Strong Typing — Using records like WeatherAssessment and WeekendItinerary for agent outputs enables compile-time guarantees and clean C# handling of AI results without fragile string parsing.

  • Seamless Blend of AI Agents and Traditional Activities — The orchestration mixes AI agent calls (via RunAsync) with standard Durable Function activities (via CallActivityAsync), enabling fallback or side branches without losing determinism.

  • Contextual Agent Resolution — The orchestrator dynamically resolves agents by name through context.GetAgent(name), supporting flexible agent composition without hardwired dependencies.

  • Session Lifecycle Management — Sessions created via CreateSessionAsync scope conversational context per orchestration run, enabling stateful dialogues with AI agents that are isolated and replayable.

How It Works

Defining Agent Names and Registration

Agents are referenced by constant strings to avoid magic values:

internal static class Agents
{
    public const string WeatherAssessor = "weather-assessor";
    public const string ItineraryPlanner = "itinerary-planner";
}

Each agent is registered with its associated AI model, instructions, and toolset at Azure Functions startup:

AIAgent weatherAssessor = projectClient.AsAIAgent(
    model: deploymentName,
    name: Agents.WeatherAssessor,
    instructions: @"
        You determine whether the weather in a given city is suitable for outdoor leisure activities this weekend.
        Use the available tools to check the weather and current date.
        Respond with a structured result: IsSuitableForOutdoors and a short Reason.",
    tools: new [] 
    {
        AIFunctionFactory.Create(Tools.GetWeather),
        AIFunctionFactory.Create(Tools.GetCurrentDate)
    });

AIAgent itineraryPlanner = projectClient.AsAIAgent(
    model: deploymentName,
    name: Agents.ItineraryPlanner,
    instructions: @"
        You build a weekend itinerary using the available activities for a given city.
        Include the date of the weekend in the itinerary.
        Respond with a structured result containing a Summary string.",
    tools: new []
    {
        AIFunctionFactory.Create(Tools.GetActivities),
        AIFunctionFactory.Create(Tools.GetCurrentDate)
    });

// Register both into Durable Agent options...

This approach encapsulates each agent’s domain knowledge and capabilities via specific instructions and tools while relying on the same client and authentication mechanism.

Orchestration Logic: Deterministic Control Flow

The core orchestration code executes a deterministic workflow coordinating the two agents:

public static async Task<string> WeekendPlanOrchestration(TaskOrchestrationContext context)
{
    WeekendRequest request = context.GetInput()!;

    // 1. Weather evaluation
    DurableAIAgent weatherAgent = context.GetAgent(Agents.WeatherAssessor);
    AgentSession weatherSession = await weatherAgent.CreateSessionAsync();
    AgentResponse weatherResponse = await weatherAgent.RunAsync(
        $"Is the weather in {request.City} suitable for outdoor activities this weekend?", 
        weatherSession);
    WeatherAssessment assessment = weatherResponse.Result;

    if (!assessment.IsSuitableForOutdoors)
    {
        // Bad weather branch: fallback activity
        return await context.CallActivityAsync<string>(nameof(NotifyIndoorPlan), assessment.Reason);
    }

    // 2. Build itinerary if weather is good
    DurableAIAgent plannerAgent = context.GetAgent(Agents.ItineraryPlanner);
    AgentSession plannerSession = await plannerAgent.CreateSessionAsync();
    AgentResponse plannerResponse = await plannerAgent.RunAsync(
        $"Create a weekend itinerary for {request.City}", plannerSession);
    return plannerResponse.Result.Summary;
}

The flow is simple yet powerful:

  • The orchestrator retrieves input.

  • Runs the weather assessor agent to get a structured weather assessment.

  • Checks the assessment to branch deterministically.

  • If the weather is bad, calls a traditional activity to suggest indoor plans.

  • Otherwise, calls the itinerary planner agent to generate a weekend plan.

  • Returns the final summary to the caller.

Because all branching decisions depend on durable agent results persisted and replayable by the Durable Task Scheduler, the entire orchestration behaves deterministically.

HTTP Starter to Launch Orchestration

Clients kick off the orchestration using a lightweight HTTP-triggered entry point:

[Function(nameof(StartWeekendPlan))]
public static async Task StartWeekendPlan(
    [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "weekend-plan")] HttpRequestData req,
    [DurableClient] DurableTaskClient client)
{
    var request = await req.ReadFromJsonAsync();
    if (request is null || string.IsNullOrWhiteSpace(request.City))
    {
        var badRequest = req.CreateResponse(HttpStatusCode.BadRequest);
        await badRequest.WriteStringAsync("Body must include a non-empty 'city'.");
        return badRequest;
    }

    string instanceId = await client.ScheduleNewOrchestrationInstanceAsync(nameof(WeekendPlanOrchestration), request);
    return await client.CreateCheckStatusResponseAsync(req, instanceId);
}

This endpoint validates input, schedules a new orchestration instance, and returns a status endpoint URL for clients to poll or await completion.

Quick Tips & Tricks

  1. Define Agent Names as Constants — Avoid magic strings by centralizing agent names in a static class for safer refactoring and clear intent.

  2. Use Strongly Typed Results — Always design your agents to return structured, typed outputs rather than free-form text. This keeps orchestrations robust and easy to reason about.

  3. Create Fresh Agent Sessions per Orchestration Run — Use CreateSessionAsync() at the start of the mission to scope agent conversations, preventing state bleed across instances.

  4. Leverage Durable Task Scheduler for Replayability — Durable Functions automatically replays orchestrations on replay, so keep the orchestration logic purely deterministic and side-effect free.

  5. Combine AI Agents and Standard Durable Activities — Use CallActivityAsync alongside agent calls to integrate traditional processing, notifications, or fallback logic for flexibility.

  6. Use AzureCliCredential Locally for Seamless Auth — During development, use AzureCliCredential to authenticate without managing credentials explicitly.

Conclusion

The combination of Microsoft Agent Framework with .NET Durable Functions unlocks a compelling pattern for building complex, multi-agent AI workflows underpinned by determinism and replayability. By moving orchestration logic out of the agents and into orchestrator code, you gain visibility, testability, and control—vital for production systems needing scalability and observability.

With this architecture, agents focus on domain-specific intelligence, while the orchestrator manages sequencing and branching reliably. The pattern elegantly balances agent autonomy with workflow predictability. Looking ahead, as AI agents pervade more enterprise workloads, such deterministic orchestration frameworks will be essential for operational excellence and compliance.

If you want to build maintainable AI workflows with confidence in Azure, combining Durable Functions and Microsoft Agent Framework is a potent approach worth adopting today.

References

  1. Microsoft Agent Framework: Deterministic Multi-Agent Orchestrations with .NET Durable Functions — Original blog post by Jaliya Udagedara explaining this approach in detail.

  2. Complete Source Code - maf-samples: Durable Orchestrator — Full sample repository demonstrating the orchestrations and agents.

  3. Microsoft Agent Framework Documentation — Official documentation covering the agent framework concepts and APIs.

  4. Durable Functions Orchestrations — Core concepts and guidance for Durable Functions orchestrations.

  5. Durable Task Scheduler Overview — Explanation of the DTS platform backing Durable Functions for state persistence and orchestration replay.