AI

Durable Workflows nel Microsoft Agent Framework: da console app ad Azure Functions

Dario Fadda Maggio 11, 2026

Il Microsoft Agent Framework (MAF) è un framework open source multi-linguaggio pensato per costruire, orchestrare e distribuire agenti AI. Con le ultime versioni, il framework ha introdotto un modello di programmazione a workflow che permette di comporre più agenti e unità di lavoro in pipeline multi-step. In questo articolo vedremo come funziona questo modello, come aggiungere durabilità ai workflow e come fare il deploy su Azure Functions.

Il modello di programmazione a Workflow

Il sistema si basa su due concetti fondamentali: Executor e WorkflowBuilder.

Executor: l’unità di lavoro

Un Executor è la granularità minima del workflow. Riceve un input tipizzato, lo elabora e produce un output. Si crea estendendo Executor<TInput, TOutput>:

internal sealed class OrderLookup() : Executor<OrderCancelRequest, Order>("OrderLookup")
{
    public override async ValueTask<Order> HandleAsync(
        OrderCancelRequest message,
        IWorkflowContext context,
        CancellationToken cancellationToken = default)
    {
        await Task.Delay(TimeSpan.FromMilliseconds(100), cancellationToken);
        return new Order(
            Id: message.OrderId,
            OrderDate: DateTime.UtcNow.AddDays(-1),
            IsCancelled: false,
            CancelReason: message.Reason,
            Customer: new Customer(Name: "Mario", Email: "mario@example.com"));
    }
}

internal sealed class OrderCancel() : Executor<Order, Order>("OrderCancel")
{
    public override async ValueTask<Order> HandleAsync(
        Order message, IWorkflowContext context,
        CancellationToken cancellationToken = default)
    {
        await Task.Delay(TimeSpan.FromMilliseconds(200), cancellationToken);
        return message with { IsCancelled = true };
    }
}

internal sealed class SendEmail() : Executor<Order, string>("SendEmail")
{
    public override ValueTask<string> HandleAsync(
        Order message, IWorkflowContext context,
        CancellationToken cancellationToken = default)
    {
        return ValueTask.FromResult(
            $"Email di cancellazione inviata per l'ordine {message.Id} a {message.Customer.Email}.");
    }
}

I parametri di tipo definiscono il contratto: TInput è ciò che riceve dal passo precedente, TOutput è ciò che passa al passo successivo. Il framework verifica la compatibilità dei tipi a compile time.

WorkflowBuilder: il grafo di esecuzione

Il WorkflowBuilder collega gli executor in un grafo diretto. Si definiscono gli archi tra executor e si ottiene un oggetto Workflow immutabile:

OrderLookup orderLookup = new();
OrderCancel orderCancel = new();
SendEmail sendEmail = new();

Workflow cancelOrder = new WorkflowBuilder(orderLookup)
    .WithName("CancelOrder")
    .WithDescription("Cancella un ordine e notifica il cliente")
    .AddEdge(orderLookup, orderCancel)
    .AddEdge(orderCancel, sendEmail)
    .Build();

Esecuzione in-process

Per eseguire il workflow senza dipendenze esterne si usa InProcessExecution.RunStreamingAsync. Restituisce uno StreamingRun che emette eventi man mano che ogni step completa:

var cancelRequest = new OrderCancelRequest(OrderId: "123", Reason: "Colore errato");

await using StreamingRun run = await InProcessExecution.RunStreamingAsync(
    cancelOrder, input: cancelRequest);

await foreach (WorkflowEvent evt in run.WatchStreamAsync())
{
    if (evt is ExecutorCompletedEvent completed)
        Console.WriteLine($"{completed.ExecutorId}: {completed.Data}");
}

Bastano i pacchetti NuGet Microsoft.Agents.AI e Microsoft.Agents.AI.Workflows. Nessuna infrastruttura, nessun Docker, solo una console app .NET.

Aggiungere la durabilità con DurableTask

L’esecuzione in-process perde lo stato se il processo termina. Per workflow di produzione — che devono sopravvivere ai riavvii, girare per ore e rimanere osservabili — si aggiunge il pacchetto Microsoft.Agents.AI.DurableTask:

dotnet add package Microsoft.Agents.AI.DurableTask --prerelease
dotnet add package Microsoft.DurableTask.Client.AzureManaged
dotnet add package Microsoft.DurableTask.Worker.AzureManaged
dotnet add package Microsoft.Extensions.Hosting

Il runtime durable fornisce:

  • Esecuzione stateful e durabile: il workflow sopravvive ai riavvii del processo
  • Checkpointing automatico: il progresso viene salvato dopo ogni step
  • Esecuzione distribuita: gli executor possono girare su macchine diverse
  • Orchestrazioni long-running: i workflow possono durare minuti, ore o giorni
  • Osservabilità: dashboard integrata per monitorare e gestire le esecuzioni

Il punto chiave è che la definizione del workflow non cambia. Si usa lo stesso WorkflowBuilder, cambia solo l’hosting:

string dtsConnectionString = "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None";

IHost host = Host.CreateDefaultBuilder(args)
    .ConfigureServices(services =>
    {
        services.ConfigureDurableWorkflows(
            workflowOptions => workflowOptions.AddWorkflow(cancelOrder),
            workerBuilder: builder => builder.UseDurableTaskScheduler(dtsConnectionString),
            clientBuilder: builder => builder.UseDurableTaskScheduler(dtsConnectionString));
    })
    .Build();

await host.StartAsync();

IWorkflowClient workflowClient = host.Services.GetRequiredService<IWorkflowClient>();
IAwaitableWorkflowRun run = (IAwaitableWorkflowRun)await workflowClient
    .RunAsync(cancelOrder, new OrderCancelRequest("12345", "Colore errato"));

string? result = await run.WaitForCompletionAsync<string>();
Console.WriteLine($"Workflow completato: {result}");

Per lo sviluppo locale si avvia il DTS Emulator in Docker:

docker run -d --name dts-emulator   -p 8080:8080 -p 8082:8082   mcr.microsoft.com/dts/dts-emulator:latest

La dashboard è disponibile su http://localhost:8082 e mostra la timeline di ogni executor, gli input/output per ciascun step e lo stato delle esecuzioni.

Fan-Out / Fan-In con agenti AI

Uno dei pattern più potenti è il fan-out/fan-in: più agenti AI elaborano lo stesso input in parallelo, poi un executor aggrega i risultati. MAF supporta l’uso diretto di agenti AI come executor tramite il metodo estensione AsAIAgent:

AIAgent physicist = chatClient.AsAIAgent(
    "Sei un esperto di fisica. Rispondi in 2-3 frasi concise.", "Physicist");

AIAgent chemist = chatClient.AsAIAgent(
    "Sei un esperto di chimica. Rispondi in 2-3 frasi concise.", "Chemist");

Workflow workflow = new WorkflowBuilder(parseQuestion)
    .WithName("ExpertReview")
    .AddFanOutEdge(parseQuestion, [physicist, chemist])
    .AddFanInBarrierEdge([physicist, chemist], aggregator)
    .Build();

Con il runtime durable, il fisico potrebbe eseguire su una VM e il chimico su un’altra. Se il processo si riavvia a metà esecuzione, gli agenti già completati non vengono rieseguiti grazie al checkpointing.

Deploy su Azure Functions

Per il deploy serverless si aggiunge il pacchetto Microsoft.Agents.AI.Hosting.AzureFunctions. I vantaggi:

  • Scaling serverless: Azure Functions scala automaticamente in base al carico
  • HTTP endpoint automatici: ogni workflow registrato ottiene un HTTP trigger, senza scrivere controller o routing
  • Supporto MCP: i workflow possono essere esposti come MCP tool con un singolo flag, rendendoli scopribili da altri agenti AI
  • Zero boilerplate: il pacchetto genera orchestratori e activity function automaticamente

Conclusioni

Il Microsoft Agent Framework propone un’astrazione pulita per costruire workflow di agenti AI: si definisce il grafo una volta sola, e si sceglie il runtime — in-process per lo sviluppo, durable per la produzione, Azure Functions per il serverless. La separazione netta tra definizione del workflow e modalità di hosting è il punto di forza dell’approccio: consente di passare da un prototipo locale a un’orchestrazione distribuita con modifiche minime al codice.

Il framework è open source e in evoluzione rapida. Il codice di esempio completo è disponibile nella repository GitHub del Microsoft Agent Framework.

Fonte originale: Durable Workflows in the Microsoft Agent Framework — .NET Blog, Shyju Krishnankutty

💬 Unisciti alla discussione!


Questo è un blog del Fediverso: puoi trovare quindi questo articolo ovunque con @blog@spcnet.it e ogni commento/risposta apparirà qui sotto.

Se vuoi commentare su Durable Workflows nel Microsoft Agent Framework: da console app ad Azure Functions, utilizza la discussione sul Forum.
Condividi la tua esperienza, confrontati con altri professionisti e approfondisci i dettagli tecnici nel nostro 👉 forum community