Duurzame extensie

De Durable Extension voor Microsoft Agent Framework brengt duurzame uitvoering naar agents, indelingen met meerdere agents en Microsoft Agent Framework-werkstromen. U kunt deze gebruiken om agentsessies, controlepuntindeling en werkstroomvoortgang te behouden, fouten te herstellen en werk op gedistribueerde hosts te schalen zonder de logica van uw kernagent te wijzigen.

De extensie ondersteunt twee hostingmodellen in C# en Python:

  • Azure Functions voor beheerde, serverloze hosting met het Azure Functions programmeermodel.
  • Bring-your-own-compute/zelf-hostend voor het uitvoeren van duurzame agents en werkstromen in uw eigen werkproces, service, container, Kubernetes-omgeving of bestaande app-infrastructuur.

Overview

Duurzame agents combineren het Agent Framework-programmeermodel met een Durable Task-infrastructuur, zoals de Durable Task Scheduler, om agents te maken die:

  • Status automatisch behouden voor aanvragen en werkroluitvoeringen
  • Hervatten na fouten zonder gesprekscontext te verliezen of voltooid werk te herhalen
  • Schalen over gedistribueerde, staatloze werknemers op basis van vraag
  • Werkstromen met meerdere agents organiseren met betrouwbare uitvoeringsgaranties
  • Checkpoint Agent Framework-werkstromen die zijn gebouwd met het werkstroommodel op basis van grafieken
  • Onderbreken voor menselijke invoer of externe gebeurtenissen zonder reken- of modeltokens te gebruiken tijdens het wachten
  • Reacties op een betrouwbare manier streamen wanneer ze zijn geconfigureerd met een betrouwbare streambroker, zoals Redis
  • Sessielevenscyclus beheren met sessie time-to-live (TTL) opschonen en bewaking op basis van dashboards

Wanneer duurzame agents gebruiken

Kies duurzame agents wanneer u het volgende nodig hebt:

  • Permanente gespreksstatus: Agentsessies overleven procescrashes, opnieuw opstarten en uitschalen
  • Complexe indelingen: meerdere agents coördineren met deterministische, betrouwbare werkstromen die dagen of weken kunnen worden uitgevoerd
  • Gebeurtenisgestuurde indeling: integreren met triggers, wachtrijen, webhooks, timers of bestaande toepassingsgebeurtenissen
  • Automatische gespreksstatus: de gespreksgeschiedenis van de agent wordt automatisch beheerd en persistent zonder expliciete statusafhandeling in uw code
  • Urable Agent Framework-werkstromen: Maak op grafieken gebaseerde Microsoft Agent Framework-werkstromen duurzaam, zodat elke stap kan worden gecontroleerd en hervat
  • Langdurige sessies: Houd nuttige gesprekken beschikbaar tijdens het opschonen van sessietime-to-live (TTL) om niet-actieve sessies automatisch te verwijderen
  • Betrouwbare realtime antwoorden: Stream-tokenuitvoer duurzaam voor toepassingen die realtime UX nodig hebben met leveringsgaranties

Deze hostingbenadering verschilt van hosting op basis van beheerde serviceagenten (zoals Foundry Agent Service), die volledig beheerde infrastructuur biedt zonder dat u werkhosts hoeft te implementeren of beheren. Duurzame agents zijn ideaal wanneer u de flexibiliteit van code-first-implementatie nodig hebt in combinatie met duurzaam statusbeheer.

Een hostingmodel kiezen

Hostingmodel Kies deze wanneer u dat nodig hebt
Azure Functions Een beheerd, serverloos hostingmodel; ingebouwde uitschalen en naar nul schalen; Azure Functions triggers en bindingen; HTTP-eindpunten die zijn gegenereerd door het Functions-programmeermodel; de MCP-servertrigger; en minimaal beheer van hostinfrastructuur.
Bring-your-own-compute /zelf-hostend Meer controle over het hostproces, de implementatieomgeving, de runtimelevenscyclus, infrastructuur, netwerken, verificatie of integratie met een bestaande app of service. Gebruik dit model voor containers, Kubernetes, langlopende werkrollen, console-apps, aangepaste services of niet-Functions-hostingomgevingen.

Wanneer agents worden gehost in het Azure Functions Flex Consumption-hostingabonnement , kunnen agents worden geschaald naar duizenden exemplaren of naar nul exemplaren wanneer ze niet in gebruik zijn, zodat u alleen betaalt voor de rekenkracht die u nodig hebt. In zelf-hostende scenario's beheert uw eigen host de levensduur, schaalaanpassing, netwerken en implementatie.

Aan de slag

Kies in een .NET project het pakket dat is ingesteld voor uw hostingmodel.

Voeg voor Azure Functions hosting het Azure Functions-integratiepakket en de Functions-werkpakketten toe.

dotnet add package Azure.AI.Projects --prerelease
dotnet add package Azure.Identity
dotnet add package Microsoft.Agents.AI.Foundry --prerelease
dotnet add package Microsoft.Agents.AI.Hosting.AzureFunctions --prerelease

Note

Zorg er naast deze pakketten ook voor dat uw project versie 2.2.0 of hoger van het Microsoft.Azure.Functions.Worker-pakket gebruikt.

Voor bring-your-own-compute-hosting voegt u het basispakket voor Durable Task Integration en de Durable Task Scheduler-werkrol-/clientpakketten toe die door uw host worden gebruikt:

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

Kies in een Python project het pakket voor uw hostingmodel.

Installeer het Azure Functions-integratiepakket voor Azure Functions hosting.

pip install azure-identity
pip install agent-framework-azurefunctions --pre

Installeer het Durable Task-integratiepakket voor bring-your-own-compute-hosting.

pip install azure-identity
pip install agent-framework-durabletask --pre

Azure Functions hosting

Met de Durable Extension kunt u agents voor Microsoft Agent Framework implementeren en hosten in Azure Functions met ingebouwde HTTP-eindpunten en op indeling gebaseerde aanroep. Azure Functions biedt een gebeurtenisgestuurd prijsmodel op basis van aanroep, met automatische schaalvergroting en minimaal infrastructuurbeheer.

Wanneer u een duurzame agent in Azure Functions configureert, maakt de extensie automatisch HTTP-eindpunten voor uw agent en beheert de onderliggende infrastructuur voor het opslaan van de gespreksstatus, het verwerken van gelijktijdige aanvragen en het coördineren van werkstromen met meerdere agents. De Azure Functions hostingintegratie biedt ook functiesspecifieke voorzieningen, zoals gegenereerde REST API's voor het verzenden van berichten, het controleren van de status en het beheren van sessies, plus triggers zoals de MCP-servertrigger voor het hosten van agents als MCP-servers zonder triggerlijm te schrijven.

using System;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Hosting.AzureFunctions;
using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Extensions.Hosting;

var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT");
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT") ?? "gpt-4o-mini";

// Create an AI agent following the standard Microsoft Agent Framework pattern
AIAgent agent = new AIProjectClient(new Uri(endpoint), new DefaultAzureCredential())
    .AsAIAgent(
        model: deploymentName,
        instructions: "You are good at telling jokes.",
        name: "Joker");

// Configure the function app to host the agent with durable thread management
// This automatically creates HTTP endpoints and manages state persistence
using IHost app = FunctionsApplication
    .CreateBuilder(args)
    .ConfigureFunctionsWebApplication()
    .ConfigureDurableAgents(options =>
        options.AddAIAgent(agent)
    )
    .Build();
app.Run();

Warning

DefaultAzureCredential is handig voor ontwikkeling, maar vereist zorgvuldige overwegingen in de productieomgeving. Overweeg in productie een specifieke referentie te gebruiken (bijvoorbeeld ManagedIdentityCredential) om latentieproblemen, onbedoelde referentieprobing en potentiële beveiligingsrisico's van terugvalmechanismen te voorkomen.

import os
from agent_framework.azure import AgentFunctionApp
from agent_framework.openai import OpenAIChatCompletionClient
from azure.identity import DefaultAzureCredential

endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")
deployment_name = os.getenv("AZURE_OPENAI_CHAT_COMPLETION_MODEL", "gpt-4o-mini")
api_version = os.getenv("AZURE_OPENAI_API_VERSION")

# Create an AI agent following the standard Microsoft Agent Framework pattern
agent = OpenAIChatCompletionClient(
    azure_endpoint=endpoint,
    model=deployment_name,
    api_version=api_version,
    credential=DefaultAzureCredential()
).as_agent(
    instructions="You are good at telling jokes.",
    name="Joker"
)

# Configure the function app to host the agent with durable thread management
# This automatically creates HTTP endpoints and manages state persistence
app = AgentFunctionApp(agents=[agent])

Bring-your-own-compute/zelf-hostende hosting

Gebruik bring-your-own-compute-hosting wanneer u de durable extension-mogelijkheden wilt gebruiken zonder het Azure Functions programmeermodel te gebruiken. In dit model start uw proces een Durable Task Worker, registreert u duurzame agents of werkstromen en maakt u verbinding met een Durable Task Scheduler-back-end. Clientcode kan in hetzelfde proces of in een afzonderlijke service worden uitgevoerd.

Zelf-hostende werknemers gebruiken dezelfde kernmogelijkheden voor Durable Extension als Azure Functions hosting: controlepunten en hervatting, deterministische agentindeling, durable Agent Framework-werkstromen, wachttijden voor human-in-the-loop, betrouwbare streaming, opschoning van niet-actieve sessies, zichtbaarheid van dashboards en gedistribueerde uitvoering over stateless werkrolexemplaren. Uw host is verantwoordelijk voor het weergeven van zijn eigen API's, levenscyclusbeheer, netwerken, verificatie en implementatiemodel.

Configureer uw host met het duurzame basispakket voor taakintegratie. Gebruik ConfigureDurableAgents voor duurzame agents en ConfigureDurableWorkflows voor Microsoft Agent Framework-werkstromen op basis van grafieken.

string connectionString = Environment.GetEnvironmentVariable("DURABLE_TASK_SCHEDULER_CONNECTION_STRING")
    ?? "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None";

IHost host = Host.CreateDefaultBuilder(args)
    .ConfigureServices(services =>
    {
        services.ConfigureDurableAgents(
            options => options.AddAIAgent(agent),
            workerBuilder: builder => builder.UseDurableTaskScheduler(connectionString),
            clientBuilder: builder => builder.UseDurableTaskScheduler(connectionString));
    })
    .Build();

await host.StartAsync();

Zie de .NET Durable Agents-consolevoorbeelden en .NET Durable Workflows-consolevoorbeelden voor runnable zelf-hostende voorbeelden.

Gebruik het Durable Task-integratiepakket om een werkproces uit te voeren dat agents registreert en luistert naar aanvragen. Clientcode kan verbinding maken met dezelfde Durable Task Scheduler-taakhub vanuit een ander proces.

from agent_framework.azure import DurableAIAgentWorker
from durabletask.azuremanaged.worker import DurableTaskSchedulerWorker

worker = DurableTaskSchedulerWorker(
    host_address="http://localhost:8080",
    secure_channel=False,
    taskhub="default",
)

agent_worker = DurableAIAgentWorker(worker)
agent_worker.add_agent(agent)

worker.start()

Zie de voorbeelden van Python Durable Task voor werkrolclientvoorbeelden, waaronder hosting van één agent, routering met meerdere agents, betrouwbare streaming, indelingsketens, gelijktijdigheid, voorwaarden en patronen voor menselijke in-the-loop.

Durable Agent Framework-werkstromen

Duurzaamheid is niet beperkt tot duurzame indelingen. Microsoft Agent Framework-werkstromen die zijn gebouwd met het werkstroommodel op basis van grafieken, kunnen ook duurzaam worden gemaakt. De uitvoering van de durable Extension-controlepunten voor werkstromen, zodat voltooide uitvoerders en agentstappen niet worden herhaald nadat een proces opnieuw is opgestart of mislukt.

Gebruik duurzame indelingen als u imperatieve coördinatie wilt met vertakking op basis van code, timers, activiteiten en externe gebeurtenissen. Gebruik durable Agent Framework-werkstromen als u een declaratieve grafiek wilt van uitvoerders en agents met getypte routering, fan-out/fan-in, voorwaardelijke randen, werkstroomgebeurtenissen, gedeelde status, subwerkstromen of poorten voor aanvragen voor human-in-the-loop.

Note

Durable Agent Framework-werkstromen verschillen van controlepuntopslag in standaardwerkstromen. Controlepuntopslag helpt bij het hervatten van een werkstroomuitvoering in de Agent Framework-runtime. De Durable Extension voert de werkstroom uit op de duurzame taakinfrastructuur, zodat de voortgang van de werkstroom wordt gecontroleerd en hersteld voor gedistribueerde duurzame werknemers. Zie Controlepunten en hervatten voor standaardwerkstroomcontrolepunten.

Registreer op grafieken gebaseerde werkstromen bij ConfigureDurableWorkflows voor zelf-hostende apps of ConfigureDurableWorkflows in de opbouwfunctie voor Functions-apps voor Azure Functions hosting.

Zie de .NET Durable Workflows Azure Functions voorbeelden en .NET Durable Workflows-consolevoorbeelden.

Voorbeelden van duurzame werkstromen zijn beschikbaar voor Azure Functions hosting, waaronder gedeelde status, geen gedeelde status, parallelle werkstroomuitvoering en werkstromen voor mensen in de lus.

Zie de voorbeelden van Python Azure Functions voor duurzame agent,indeling, MCP-server en werkstroomvoorbeelden.

Samples

Language Hostingmodel Samples
C# Azure Functions .NET Durable Agents - Azure Functions, .NET Durable Workflows - Azure Functions
C# Bring-your-own-compute /zelf-hostend .NET Durable Agents - Console-apps, .NET Durable Workflows - Console-apps
Python Azure Functions Python Azure Functions voorbeelden
Python Bring-your-own-compute /zelf-hostend Python voorbeelden van duurzame taken

Stateful agentthreads met gespreksgeschiedenis

Agenten onderhouden doorlopende threads die meerdere interacties doorstaan. Elke thread wordt geïdentificeerd door een unieke thread-id en slaat de volledige gespreksgeschiedenis op in duurzame opslag die wordt beheerd door de Durable Task-infrastructuur, zoals de Durable Task Scheduler.

Dit patroon maakt gesprekscontinuïteit mogelijk waarbij de status van de agent behouden blijft door procescrashes en opnieuw op te starten, zodat de volledige gespreksgeschiedenis kan worden onderhouden in gebruikersthreads. De duurzame opslag zorgt ervoor dat zelfs als een hostproces opnieuw wordt opgestart of het werk wordt hervat op een ander werkrolexemplaren, het gesprek naadloos doorgaat vanaf waar het was gebleven.

Gebruik time-to-live -opschoning (TTL) van sessies voor workloads die duurzame continuïteit nodig hebben tijdens actief gebruik, maar moet automatisch niet-actieve gesprekken opschonen. Op TTL gebaseerde opschoning voorkomt dat ongebruikte sessies en gespreksgeschiedenis voor onbepaalde tijd accumuleren terwijl de actieve sessiestatus behouden blijft.

In het volgende Azure Functions voorbeeld ziet u meerdere HTTP-aanvragen voor dezelfde thread, waarin wordt getoond hoe de gesprekscontext zich blijft voordoen. Gebruik in zelf-hostende apps de Durable Task-client-API's van uw eigen proces of service.

# First interaction - start a new thread
curl -X POST https://your-function-app.azurewebsites.net/api/agents/Joker/run \
  -H "Content-Type: text/plain" \
  -d "Tell me a joke about pirates"

# Response includes thread ID in x-ms-thread-id header and joke as plain text
# HTTP/1.1 200 OK
# Content-Type: text/plain
# x-ms-thread-id: @dafx-joker@263fa373-fa01-4705-abf2-5a114c2bb87d
#
# Why don't pirates shower before they walk the plank? Because they'll just wash up on shore later!

# Second interaction - continue the same thread with context
curl -X POST "https://your-function-app.azurewebsites.net/api/agents/Joker/run?thread_id=@dafx-joker@263fa373-fa01-4705-abf2-5a114c2bb87d" \
  -H "Content-Type: text/plain" \
  -d "Tell me another one about the same topic"

# Agent remembers the pirate context from the first message and responds with plain text
# What's a pirate's favorite letter? You'd think it's R, but it's actually the C!

De staat van de agent wordt behouden in persistente opslag, wat gedistribueerde uitvoeringen mogelijk maakt voor meerdere instanties. Elke instantie kan de uitvoering van een agent hervatten na onderbrekingen of storingen, waardoor continue bewerkingen worden gegarandeerd.

Betrouwbare streaming

De Durable Extension ondersteunt betrouwbare streaming voor toepassingen die realtime tokenlevering met duurzame leveringsgaranties nodig hebben. Streaming kan worden gebruikt met de kernextensie in beide hostingmodellen, maar gedistribueerde hosts hebben een betrouwbare streambroker nodig, zoals Redis, zodat tokenstromen consistent kunnen worden geleverd bij het opnieuw opstarten van processen, opnieuw verbinding maken of werkrolwijzigingen.

Gebruik betrouwbare streaming wanneer de gebruikerservaring afhankelijk is van incrementele antwoorden, maar de workload heeft nog steeds semantiek voor duurzame uitvoering nodig. Zie de voorbeelden van Python Durable Task, waaronder betrouwbare streamingpatronen voor runnable voorbeelden.

Deterministische indelingen met meerdere agents

De Durable Extension ondersteunt het bouwen van deterministische werkstromen die meerdere agents coördineren met behulp van Durable Task-indelingen. In Azure Functions gebruiken deze Durable Functions indelingen; in bring-your-own-compute-hosts worden ze uitgevoerd via de Durable Task Worker en client die u configureert.

Indelingen zijn op code gebaseerde werkstromen die meerdere bewerkingen (zoals agent-aanroepen, externe API-aanroepen of timers) op een betrouwbare manier coördineren. Deterministisch betekent dat de orkestratiecode op dezelfde manier wordt uitgevoerd wanneer deze na een fout opnieuw wordt afgespeeld, waardoor werkstromen betrouwbaar zijn en eenvoudiger te debuggen. Wanneer u de geschiedenis van een orkestratie opnieuw afspeelt, kunt u precies zien wat er in elke stap is gebeurd.

Orchestrationen worden betrouwbaar uitgevoerd, overleven fouten tussen agentaanroepen en bieden voorspelbare en herhaalbare processen. Dit maakt ze ideaal voor complexe scenario's met meerdere agents waarbij u gegarandeerde uitvoeringsvolgorde en fouttolerantie nodig hebt.

Sequentiële indelingen

In het sequentiële patroon met meerdere agenten worden gespecialiseerde agenten uitgevoerd in een specifieke volgorde, waarbij de uitvoer van elke agent invloed kan hebben op de uitvoering van de volgende agent. Dit patroon ondersteunt voorwaardelijke logica en vertakking op basis van agentreacties.

Wanneer u agents in orkestraties gebruikt, moet u de context.GetAgent() API gebruiken om een DurableAIAgent instantie te verkrijgen. Dit is een speciale subklasse van het standaardtype AIAgent die een van uw geregistreerde agents omsluit. De DurableAIAgent wrapper zorgt ervoor dat agent-aanroepen correct worden bijgehouden en gecontroleerd door het durable orchestration-framework.

using Microsoft.Azure.Functions.Worker;
using Microsoft.DurableTask;
using Microsoft.Agents.AI.DurableTask;

[Function(nameof(SpamDetectionOrchestration))]
public static async Task<string> SpamDetectionOrchestration(
    [OrchestrationTrigger] TaskOrchestrationContext context)
{
    Email email = context.GetInput<Email>();

    // Check if the email is spam
    DurableAIAgent spamDetectionAgent = context.GetAgent("SpamDetectionAgent");
    AgentSession spamSession = await spamDetectionAgent.CreateSessionAsync();

    AgentResponse<DetectionResult> spamDetectionResponse = await spamDetectionAgent.RunAsync<DetectionResult>(
        message: $"Analyze this email for spam: {email.EmailContent}",
        session: spamSession);
    DetectionResult result = spamDetectionResponse.Result;

    if (result.IsSpam)
    {
        return await context.CallActivityAsync<string>(nameof(HandleSpamEmail), result.Reason);
    }

    // Generate response for legitimate email
    DurableAIAgent emailAssistantAgent = context.GetAgent("EmailAssistantAgent");
    AgentSession emailSession = await emailAssistantAgent.CreateSessionAsync();

    AgentResponse<EmailResponse> emailAssistantResponse = await emailAssistantAgent.RunAsync<EmailResponse>(
        message: $"Draft a professional response to: {email.EmailContent}",
        session: emailSession);

    return await context.CallActivityAsync<string>(nameof(SendEmail), emailAssistantResponse.Result.Response);
}

Wanneer u agents in orkestraties gebruikt, moet u de app.get_agent()-methode gebruiken om een duurzaam agent-exemplaar op te halen, wat een speciale wrapper is rond een van uw geregistreerde agents. De duurzame agent wrapper zorgt ervoor dat agent-aanroepen correct worden bijgehouden en gecontroleerd door het betrouwbare orchestration-framework.

import azure.durable_functions as df
from typing import cast
from agent_framework.azure import AgentFunctionApp
from pydantic import BaseModel

class SpamDetectionResult(BaseModel):
    is_spam: bool
    reason: str

class EmailResponse(BaseModel):
    response: str

app = AgentFunctionApp(agents=[spam_detection_agent, email_assistant_agent])

@app.orchestration_trigger(context_name="context")
def spam_detection_orchestration(context: df.DurableOrchestrationContext):
    email = context.get_input()

    # Check if the email is spam
    spam_agent = app.get_agent(context, "SpamDetectionAgent")
    spam_thread = spam_agent.create_session()

    spam_result_raw = yield spam_agent.run(
        messages=f"Analyze this email for spam: {email['content']}",
        session=spam_thread,
        response_format=SpamDetectionResult
    )
    spam_result = cast(SpamDetectionResult, spam_result_raw.get("structured_response"))

    if spam_result.is_spam:
        result = yield context.call_activity("handle_spam_email", spam_result.reason)
        return result

    # Generate response for legitimate email
    email_agent = app.get_agent(context, "EmailAssistantAgent")
    email_thread = email_agent.create_session()

    email_response_raw = yield email_agent.run(
        messages=f"Draft a professional response to: {email['content']}",
        session=email_thread,
        response_format=EmailResponse
    )
    email_response = cast(EmailResponse, email_response_raw.get("structured_response"))

    result = yield context.call_activity("send_email", email_response.response)
    return result

Orkestraties coördineren het werk tussen meerdere agents en vangen storingen tussen agentoproepen op. De orkestratiecontext biedt methoden voor het ophalen en interactie met gehoste agents binnen orkestraties.

Parallelle indelingen

In het parallelle patroon met meerdere agents voert u meerdere agents gelijktijdig uit en voegt u vervolgens de resultaten samen. Dit patroon is handig voor het verzamelen van diverse perspectieven of het gelijktijdig verwerken van onafhankelijke subtaken.

using Microsoft.Azure.Functions.Worker;
using Microsoft.DurableTask;
using Microsoft.Agents.AI.DurableTask;

[Function(nameof(ResearchOrchestration))]
public static async Task<string> ResearchOrchestration(
    [OrchestrationTrigger] TaskOrchestrationContext context)
{
    string topic = context.GetInput<string>();

    // Execute multiple research agents in parallel
    DurableAIAgent technicalAgent = context.GetAgent("TechnicalResearchAgent");
    DurableAIAgent marketAgent = context.GetAgent("MarketResearchAgent");
    DurableAIAgent competitorAgent = context.GetAgent("CompetitorResearchAgent");

    // Start all agent runs concurrently
    Task<AgentResponse<TextResponse>> technicalTask = 
        technicalAgent.RunAsync<TextResponse>($"Research technical aspects of {topic}");
    Task<AgentResponse<TextResponse>> marketTask = 
        marketAgent.RunAsync<TextResponse>($"Research market trends for {topic}");
    Task<AgentResponse<TextResponse>> competitorTask = 
        competitorAgent.RunAsync<TextResponse>($"Research competitors in {topic}");

    // Wait for all tasks to complete
    await Task.WhenAll(technicalTask, marketTask, competitorTask);

    // Aggregate results
    string allResearch = string.Join("\n\n", 
        technicalTask.Result.Result.Text,
        marketTask.Result.Result.Text,
        competitorTask.Result.Result.Text);

    DurableAIAgent summaryAgent = context.GetAgent("SummaryAgent");
    AgentResponse<TextResponse> summaryResponse = 
        await summaryAgent.RunAsync<TextResponse>($"Summarize this research:\n{allResearch}");

    return summaryResponse.Result.Text;
}
import azure.durable_functions as df
from agent_framework.azure import AgentFunctionApp

app = AgentFunctionApp(agents=[technical_agent, market_agent, competitor_agent, summary_agent])

@app.orchestration_trigger(context_name="context")
def research_orchestration(context: df.DurableOrchestrationContext):
    topic = context.get_input()

    # Execute multiple research agents in parallel
    technical_agent = app.get_agent(context, "TechnicalResearchAgent")
    market_agent = app.get_agent(context, "MarketResearchAgent")
    competitor_agent = app.get_agent(context, "CompetitorResearchAgent")

    technical_task = technical_agent.run(messages=f"Research technical aspects of {topic}")
    market_task = market_agent.run(messages=f"Research market trends for {topic}")
    competitor_task = competitor_agent.run(messages=f"Research competitors in {topic}")

    # Wait for all tasks to complete
    results = yield context.task_all([technical_task, market_task, competitor_task])

    # Aggregate results
    all_research = "\n\n".join([r.get('response', '') for r in results])

    summary_agent = app.get_agent(context, "SummaryAgent")
    summary = yield summary_agent.run(messages=f"Summarize this research:\n{all_research}")

    return summary.get('response', '')

De parallelle uitvoering wordt bijgehouden met behulp van een lijst met taken. Automatische controlepunten zorgen ervoor dat voltooide agentprocessen niet worden herhaald of verloren gaan als er een fout optreedt tijdens de aggregatie.

Human-in-the-loop orchestrations

Deterministische agentorkestraties kunnen worden gepauzeerd voor menselijke invoer, goedkeuring of beoordeling zonder computercapaciteit te gebruiken. Met duurzame uitvoering kunnen orkestraties dagen of zelfs weken wachten op menselijke reacties. In combinatie met serverloze hosting worden alle rekenresources tijdens de wachttijd uitgeschakeld, waardoor de rekenkosten worden geëlimineerd totdat de mens de invoer levert.

using Microsoft.Azure.Functions.Worker;
using Microsoft.DurableTask;
using Microsoft.Agents.AI.DurableTask;

[Function(nameof(ContentApprovalWorkflow))]
public static async Task<string> ContentApprovalWorkflow(
    [OrchestrationTrigger] TaskOrchestrationContext context)
{
    string topic = context.GetInput<string>();

    // Generate content using an agent
    DurableAIAgent contentAgent = context.GetAgent("ContentGenerationAgent");
    AgentResponse<GeneratedContent> contentResponse = 
        await contentAgent.RunAsync<GeneratedContent>($"Write an article about {topic}");
    GeneratedContent draftContent = contentResponse.Result;

    // Send for human review
    await context.CallActivityAsync(nameof(NotifyReviewer), draftContent);

    // Wait for approval with timeout
    HumanApprovalResponse approvalResponse;
    try
    {
        approvalResponse = await context.WaitForExternalEvent<HumanApprovalResponse>(
            eventName: "ApprovalDecision",
            timeout: TimeSpan.FromHours(24));
    }
    catch (OperationCanceledException)
    {
        // Timeout occurred - escalate for review
        return await context.CallActivityAsync<string>(nameof(EscalateForReview), draftContent);
    }

    if (approvalResponse.Approved)
    {
        return await context.CallActivityAsync<string>(nameof(PublishContent), draftContent);
    }

    return "Content rejected";
}
import azure.durable_functions as df
from datetime import timedelta
from agent_framework.azure import AgentFunctionApp

app = AgentFunctionApp(agents=[content_agent])

@app.orchestration_trigger(context_name="context")
def content_approval_workflow(context: df.DurableOrchestrationContext):
    topic = context.get_input()

    # Generate content using an agent
    content_agent = app.get_agent(context, "ContentGenerationAgent")
    draft_content = yield content_agent.run(
        messages=f"Write an article about {topic}"
    )

    # Send for human review
    yield context.call_activity("notify_reviewer", draft_content)

    # Wait for approval with timeout
    approval_task = context.wait_for_external_event("ApprovalDecision")
    timeout_task = context.create_timer(
        context.current_utc_datetime + timedelta(hours=24)
    )

    winner = yield context.task_any([approval_task, timeout_task])

    if winner == approval_task:
        timeout_task.cancel()
        approval_data = approval_task.result
        if approval_data.get("approved"):
            result = yield context.call_activity("publish_content", draft_content)
            return result
        return "Content rejected"

    # Timeout occurred - escalate for review
    result = yield context.call_activity("escalate_for_review", draft_content)
    return result

Deterministische agentorkestraties kunnen wachten op externe gebeurtenissen, hun status duurzaam behouden terwijl ze wachten op menselijke feedback, fouten overleven, herstarten en uitgebreide wachttijden. Wanneer het menselijke antwoord binnenkomt, wordt de coördinatie automatisch hervat waarbij de volledige gesprekscontext en de uitvoeringstoestand intact blijven.

Menselijke invoer leveren

Als u goedkeuring of invoer wilt verzenden naar een wachtindeling, dient u een externe gebeurtenis in bij het indelingsexemplaar met behulp van de Durable Task-client-SDK of de Azure Functions Eindpunten van durable-extensies. Een revisor kan bijvoorbeeld inhoud goedkeuren via een webformulier dat aanroept:

await client.RaiseEventAsync(instanceId, "ApprovalDecision", new HumanApprovalResponse 
{ 
    Approved = true,
    Feedback = "Looks great!"
});
approval_data = {
    "approved": True,
    "feedback": "Looks great!"
}
await client.raise_event(instance_id, "ApprovalDecision", approval_data)

Kostenefficiëntie

Human-in-the-loop-werkstromen met duurzame agents zijn uiterst rendabel wanneer ze worden gehost in het Azure Functions Flex Consumption-abonnement. Voor een werkstroom die 24 uur wacht op goedkeuring, betaalt u slechts voor een paar seconden uitvoeringstijd (de tijd voor het genereren van inhoud, het verzenden van meldingen en het verwerken van het antwoord), en niet voor de 24 uur wachten. Tijdens de wachttijd worden er geen rekenresources verbruikt.

Waarneembaarheid met duurzame taakplanner

De Durable Task Scheduler (DTS) is de aanbevolen duurzame back-end voor uw duurzame agents, met de beste prestaties, volledig beheerde infrastructuur en ingebouwde waarneembaarheid via een UI-dashboard. Azure Functions apps kunnen andere back-ends voor opslag (zoals Azure Storage) gebruiken, maar DTS is speciaal geoptimaliseerd voor duurzame workloads en biedt superieure prestaties en bewakingsmogelijkheden. Zelf-hostende werknemers maken ook gebruik van DTS voor duurzame planning, status en zichtbaarheid van dashboards.

Inzichten in agentsessies

  • Gespreksgeschiedenis: Bekijk de volledige chatgeschiedenis voor elke agentsessie, inclusief alle berichten, toolaanroepen en gesprekscontext op elk gewenst moment
  • Tijdsinstellingen voor taken: controleren hoe lang het duurt voordat specifieke taken en agentinteracties zijn voltooid

Schermopname van het Durable Task Scheduler-dashboard met de chatgeschiedenis van de agent met gespreksthreads en berichten.

Indelingsinzichten

  • Visualisatie van meerdere agents: bekijk de uitvoeringsstroom bij het aanroepen van meerdere gespecialiseerde agents met visuele weergave van parallelle uitvoeringen en voorwaardelijke vertakking
  • Uitvoeringsgeschiedenis: gedetailleerde uitvoeringslogboeken openen
  • Realtime monitoring: houd actieve orkestraties, geplande werkitems en agentstatussen bij in uw implementatie
  • Metrische gegevens over prestaties: reactietijden van agents, tokengebruik en indelingsduur bewaken

Schermopname van het Durable Task Scheduler-dashboard met indelingsvisualisatie met meerdere agentinteracties en werkstroomuitvoering.

Mogelijkheden voor foutopsporing

  • Gestructureerde uitvoer van agent en resultaten van het aanroepen van tools weergeven
  • Aanroepen van hulpprogramma's en hun resultaten traceren
  • Externe gebeurtenisafhandeling bewaken voor human-in-the-loop-scenario's

Met het dashboard kunt u precies begrijpen wat uw agents doen, snel problemen diagnosticeren en prestaties optimaliseren op basis van echte uitvoeringsgegevens.

Zelfstudie: Een duurzame agent maken en uitvoeren met Azure Functions

Deze zelfstudie laat zien hoe u een duurzame AI-agent maakt en uitvoert met behulp van het Azure Functions hostingmodel voor de Durable Extension. U bouwt een Azure Functions-app die als host fungeert voor een stateful agent met ingebouwde HTTP-eindpunten en leert hoe u deze bewaakt met behulp van het Durable Task Scheduler-dashboard. Zie de voorbeelden voor zelf-hostende agents.

Prerequisites

Zorg ervoor dat u aan de volgende vereisten voldoet voordat u begint:

Note

Microsoft Agent Framework wordt ondersteund met alle actief ondersteunde versies van .NET. Voor dit voorbeeld raden we de .NET 9 SDK of een latere versie aan.

Het snelstartproject downloaden

Gebruik Azure Developer CLI om een nieuw project te initialiseren op basis van de quickstartsjabloon voor durable agents.

  1. Maak een nieuwe map voor uw project en navigeer ernaartoe:

    mkdir MyDurableAgent
    cd MyDurableAgent
    

  1. Initialiseer het project op basis van de sjabloon:

    azd init --template durable-agents-quickstart-dotnet
    

    Wanneer u wordt gevraagd om een omgevingsnaam, voert u een naam in, zoals my-durable-agent.

Hiermee downloadt u het quickstartproject met alle benodigde bestanden, waaronder de Azure Functions-configuratie, agentcode en infrastructuur als codesjablonen.

  1. Maak een nieuwe map voor uw project en navigeer ernaartoe:

    mkdir MyDurableAgent
    cd MyDurableAgent
    

  1. Initialiseer het project op basis van de sjabloon:

    azd init --template durable-agents-quickstart-python
    

    Wanneer u wordt gevraagd om een omgevingsnaam, voert u een naam in, zoals my-durable-agent.

  2. Een virtuele omgeving maken en activeren:

    uv venv .venv
    source .venv/bin/activate
    

Note

python3 -m venv .venv werkt ook, maar kan voor onbepaalde tijd hangen op Windows met Microsoft Store Python vanwege een bekend probleem met ensurepip. Gebruik uv venv .venv dit om dit te voorkomen.

  1. Installeer de vereiste pakketten:

    python -m pip install -r requirements.txt
    

Hiermee downloadt u het quickstartproject met alle benodigde bestanden, waaronder de Azure Functions-configuratie, agentcode en infrastructuur als codesjablonen. Er wordt ook een virtuele omgeving voorbereid met de vereiste afhankelijkheden.

Azure-resources inrichten

Gebruik Azure Developer CLI om de vereiste Azure-resources voor uw duurzame agent te maken.

  1. De infrastructuur inrichten:

    azd provision
    

    Met deze opdracht maakt u:

    • Een Azure OpenAI-service met een gpt-4o-mini-implementatie
    • Een Azure Functions-app met Flex Consumption-hostingabonnement
    • Een Azure Storage-account voor de Azure Functions-runtime en duurzame opslag
    • Een Durable Task Scheduler-exemplaar (verbruiksabonnement) voor het beheren van de agentstatus
    • Benodigde netwerk- en identiteitsconfiguraties
  2. Wanneer u hierom wordt gevraagd, selecteert u uw Azure-abonnement en kiest u een locatie voor de resources.

Het provisioningproces duurt een paar minuten. Zodra het is voltooid, slaat azd de gemaakte resource-informatie op in uw omgeving.

De agentcode controleren

Laten we nu de code bekijken die uw duurzame agent definieert.

Open Program.cs om de agentconfiguratie weer te geven:

using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Hosting.AzureFunctions;
using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Extensions.Hosting;

var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") 
    ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT environment variable is not set");
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT") ?? "gpt-4o-mini";

// Create an AI agent following the standard Microsoft Agent Framework pattern
AIAgent agent = new AIProjectClient(new Uri(endpoint), new DefaultAzureCredential())
    .AsAIAgent(
        model: deploymentName,
        instructions: "You are a helpful assistant that can answer questions and provide information.",
        name: "MyDurableAgent");

using IHost app = FunctionsApplication
    .CreateBuilder(args)
    .ConfigureFunctionsWebApplication()
    .ConfigureDurableAgents(options => options.AddAIAgent(agent))
    .Build();
app.Run();

Deze code:

  1. Haalt uw Azure OpenAI-configuratie op uit omgevingsvariabelen.
  2. Hiermee maakt u een Azure OpenAI-client met behulp van Azure-referenties.
  3. Hiermee maakt u een AI-agent met instructies en een naam.
  4. Hiermee configureert u de Azure Functions-app om de agent te hosten met duurzaam threadbeheer.

Open function_app.py om de agentconfiguratie weer te geven:

import os
from agent_framework.azure import AgentFunctionApp
from agent_framework.openai import OpenAIChatCompletionClient
from azure.identity import DefaultAzureCredential

endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")
if not endpoint:
    raise ValueError("AZURE_OPENAI_ENDPOINT is not set.")
deployment_name = os.getenv("AZURE_OPENAI_CHAT_COMPLETION_MODEL", "gpt-4o-mini")
api_version = os.getenv("AZURE_OPENAI_API_VERSION")

# Create an AI agent following the standard Microsoft Agent Framework pattern
agent = OpenAIChatCompletionClient(
    azure_endpoint=endpoint,
    model=deployment_name,
    api_version=api_version,
    credential=DefaultAzureCredential()
).as_agent(
    instructions="You are a helpful assistant that can answer questions and provide information.",
    name="MyDurableAgent"
)

# Configure the function app to host the agent with durable thread management
app = AgentFunctionApp(agents=[agent])

Deze code:

  • Haalt uw Azure OpenAI-configuratie op uit omgevingsvariabelen.
  • Hiermee maakt u een Azure OpenAI-client met behulp van Azure-referenties.
  • Hiermee maakt u een AI-agent met instructies en een naam.
  • Hiermee configureert u de Azure Functions-app om de agent te hosten met duurzaam threadbeheer.

De agent is nu klaar om te worden gehost in Azure Functions. De duurzame taakextensie maakt automatisch HTTP-eindpunten voor interactie met uw agent en beheert de gespreksstatus over meerdere aanvragen.

Lokale instellingen configureren

Maak een local.settings.json bestand voor lokale ontwikkeling op basis van het voorbeeldbestand dat in het project is opgenomen.

  1. Kopieer het voorbeeldinstellingenbestand:

    cp local.settings.sample.json local.settings.json
    

  1. Haal uw Azure OpenAI-eindpunt op uit de ingestelde bronnen.

    azd env get-value AZURE_OPENAI_ENDPOINT
    
  2. Open local.settings.json en vervang <your-resource-name> in de waarde van AZURE_OPENAI_ENDPOINT door het eindpunt uit de vorige opdracht.

Uw local.settings.json moet er als volgt uitzien:

{
  "IsEncrypted": false,
  "Values": {
    // ... other settings ...
    "AZURE_OPENAI_ENDPOINT": "https://your-openai-resource.openai.azure.com",
    "AZURE_OPENAI_DEPLOYMENT": "gpt-4o-mini",
    "TASKHUB_NAME": "default"
  }
}

Note

Het local.settings.json bestand wordt alleen gebruikt voor lokale ontwikkeling en wordt niet geïmplementeerd in Azure. Voor productie-implementaties worden deze instellingen automatisch geconfigureerd in uw Azure Functions-app door de infrastructuursjablonen.

Lokale ontwikkelingsafhankelijkheden starten

Als u duurzame agents lokaal wilt uitvoeren, moet u twee diensten starten:

  • Azurite: Emuleert de Azure Storage-services (door Azure Functions gebruikt voor het beheren van triggers en interne status).
  • DTS-emulator (Durable Task Scheduler): beheert duurzame status (gespreksgeschiedenis, indelingsstatus) en planning voor uw agents

Start Azurite

Azurite emuleert Azure Storage-services lokaal. De Azure Functions gebruikt deze voor het beheren van de interne status. U moet dit uitvoeren in een nieuw terminalvenster en deze blijven uitvoeren terwijl u uw duurzame agent ontwikkelt en test.

  1. Open een nieuw terminalvenster en haal de Docker-image van Azurite op.

    docker pull mcr.microsoft.com/azure-storage/azurite
    
  2. Start Azurite in een terminalvenster:

    docker run -p 10000:10000 -p 10001:10001 -p 10002:10002 mcr.microsoft.com/azure-storage/azurite
    

    Azurite start en luistert op de standaardpoorten voor blobservices (10000), wachtrij (10001) en tabelservices (10002).

Houd dit terminalvenster open terwijl u uw duurzame agent ontwikkelt en test.

Tip

Voor meer informatie over Azurite, inclusief alternatieve installatiemethoden, raadpleegt u De Emulator van Azurite gebruiken voor lokale Azure Storage-ontwikkeling.

De Durable Task Scheduler-emulator starten

De DTS-emulator biedt de betrouwbare backend voor het beheren van agentstatus en orkestraties. Het slaat de gespreksgeschiedenis op en zorgt ervoor dat de status van uw agent behouden blijft tijdens het opnieuw opstarten. Het activeert ook duurzame orkestraties en agents. U moet dit uitvoeren in een afzonderlijk nieuw terminalvenster en deze blijven uitvoeren terwijl u uw duurzame agent ontwikkelt en test.

  1. Open nog een nieuw terminalvenster en haal de Docker-installatiekopie van de DTS-emulator op:

    docker pull mcr.microsoft.com/dts/dts-emulator:latest
    
  2. Voer de DTS-emulator uit:

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

    Met deze opdracht wordt de emulator gestart en wordt het volgende weergegeven:

    • Poort 8080: het gRPC-eindpunt voor de Durable Task Scheduler (gebruikt door uw Functions-app)
    • Poort 8082: Het beheerdashboard
  3. Het dashboard is beschikbaar op http://localhost:8082.

Houd dit terminalvenster open terwijl u uw duurzame agent ontwikkelt en test.

Tip

Zie Ontwikkelen met Durable Task Scheduler voor meer informatie over de DTS-emulator, waaronder het configureren van meerdere taakhubs en het openen van het dashboard.

De functie-app uitvoeren

U bent nu klaar om uw Azure Functions-app uit te voeren met de duurzame agent.

  1. Navigeer in een nieuw terminalvenster (waarbij zowel Azurite als de DTS-emulator in afzonderlijke vensters worden uitgevoerd) naar uw projectmap.

  2. Start de Azure Functions-runtime:

    func start
    
  3. U ziet uitvoer die aangeeft dat uw functie-app wordt uitgevoerd, inclusief de HTTP-eindpunten voor uw agent:

    Functions:
         http-MyDurableAgent: [POST] http://localhost:7071/api/agents/MyDurableAgent/run
         dafx-MyDurableAgent: entityTrigger
    

Met deze eindpunten wordt de gespreksstatus automatisch beheerd. U hoeft geen threadobjecten zelf te maken of te beheren.

De agent lokaal testen

U kunt nu communiceren met uw duurzame agent met behulp van HTTP-aanvragen. De agent onderhoudt de gespreksstatus over meerdere verzoeken, waardoor gesprekken met meerdere rondes mogelijk zijn.

Start een nieuw gesprek

Maak een nieuwe thread en verzend uw eerste bericht:

curl -i -X POST http://localhost:7071/api/agents/MyDurableAgent/run \
  -H "Content-Type: text/plain" \
  -d "What are three popular programming languages?"

Voorbeeldantwoord (let op: de x-ms-thread-id header bevat de thread-id):

HTTP/1.1 200 OK
Content-Type: text/plain
x-ms-thread-id: @dafx-mydurableagent@263fa373-fa01-4705-abf2-5a114c2bb87d
Content-Length: 189

Three popular programming languages are Python, JavaScript, and Java. Python is known for its simplicity and readability, JavaScript powers web interactivity, and Java is widely used in enterprise applications.

Sla de thread-id op uit de x-ms-thread-id header (bijvoorbeeld @dafx-mydurableagent@263fa373-fa01-4705-abf2-5a114c2bb87d) voor de volgende aanvraag.

Doorgaan met het gesprek

Verzend een opvolgingsbericht naar dezelfde thread door de thread-id op te geven als een queryparameter:

curl -X POST "http://localhost:7071/api/agents/MyDurableAgent/run?thread_id=@dafx-mydurableagent@263fa373-fa01-4705-abf2-5a114c2bb87d" \
  -H "Content-Type: text/plain" \
  -d "Which one is best for beginners?"

Vervang @dafx-mydurableagent@263fa373-fa01-4705-abf2-5a114c2bb87d door de werkelijke thread-id uit de header van x-ms-thread-id het vorige antwoord.

Voorbeeldantwoord:

Python is often considered the best choice for beginners among those three. Its clean syntax reads almost like English, making it easier to learn programming concepts without getting overwhelmed by complex syntax. It's also versatile and widely used in education.

U ziet dat de agent de context van het vorige bericht (de drie programmeertalen) onthoudt zonder dat u deze opnieuw hoeft op te geven. Omdat de gespreksstatus duurzaam wordt opgeslagen door de Durable Task Scheduler, blijft deze geschiedenis behouden, zelfs als u de functie-app opnieuw start of het gesprek wordt hervat door een ander exemplaar.

Bewaken met het durable Task Scheduler-dashboard

De Durable Task Scheduler biedt een ingebouwd dashboard voor het bewaken en debuggen van uw durable agents. Het dashboard biedt uitgebreide inzicht in agentbewerkingen, gespreksgeschiedenis en uitvoeringsstroom.

Het dashboard openen

  1. Open het dashboard voor uw lokale DTS-emulator http://localhost:8082 in uw webbrowser.

  2. Selecteer de standaardtaakhub in de lijst om de details ervan weer te geven.

  3. Selecteer het tandwielpictogram in de rechterbovenhoek om de instellingen te openen en zorg ervoor dat de optie Agent-pagina's inschakelen onder Preview-functies is geselecteerd.

Agentgesprekken bekijken

  1. Navigeer in het dashboard naar het tabblad Agents .

  2. Selecteer uw durable agent-thread (bijvoorbeeld mydurableagent - 263fa373-fa01-4705-abf2-5a114c2bb87d) in de lijst.

    U ziet een gedetailleerde weergave van de agentthread, inclusief de volledige gespreksgeschiedenis met alle berichten en antwoorden.

    Schermopname van het Durable Task Scheduler-dashboard met de gespreksgeschiedenis van een agentthread.

Het dashboard biedt een tijdlijnweergave om u inzicht te geven in de stroom van het gesprek. Belangrijke informatie zijn onder andere:

  • Tijdstempels en duur voor elke interactie
  • Inhoud van opdrachten en reacties
  • Aantal gebruikte tokens

Tip

Het DTS-dashboard biedt realtime updates, zodat u het gedrag van uw agent kunt bekijken terwijl u ermee communiceert via de HTTP-eindpunten.

Implementeren in Azure

Nu u uw duurzame agent lokaal hebt getest, implementeert u deze in Azure.

  1. De toepassing implementeren:

    azd deploy
    

    Met deze opdracht wordt uw toepassing verpakt en geïmplementeerd in de Azure Functions-app die tijdens het inrichten is gemaakt.

  2. Wacht tot de implementatie is voltooid. De uitvoer zal bevestigen wanneer uw agent in Azure draait.

De gedeployeerde agent testen

Test na de implementatie de agent die draait in Azure.

De functietoets ophalen

Azure Functions vereist een API-sleutel voor door HTTP geactiveerde functies in productie:

API_KEY=`az functionapp function keys list --name $(azd env get-value AZURE_FUNCTION_NAME) --resource-group $(azd env get-value AZURE_RESOURCE_GROUP) --function-name http-MyDurableAgent --query default -o tsv`

Een nieuw gesprek starten in Azure

Maak een nieuwe thread en verzend uw eerste bericht naar de geïmplementeerde agent:

curl -i -X POST "https://$(azd env get-value AZURE_FUNCTION_NAME).azurewebsites.net/api/agents/MyDurableAgent/run?code=$API_KEY" \
  -H "Content-Type: text/plain" \
  -d "What are three popular programming languages?"

Noteer de thread-id die wordt geretourneerd in de x-ms-thread-id antwoordheader.

Doorgaan met het gesprek in Azure

Verzend een opvolgingsbericht in dezelfde thread. Vervang <thread-id> door de thread-id uit het vorige antwoord:

THREAD_ID="<thread-id>"
curl -X POST "https://$(azd env get-value AZURE_FUNCTION_NAME).azurewebsites.net/api/agents/MyDurableAgent/run?code=$API_KEY&thread_id=$THREAD_ID" \
  -H "Content-Type: text/plain" \
  -d "Which is easiest to learn?"

De agent onderhoudt de gesprekscontext in Azure net zoals lokaal, wat de duurzaamheid van de agentstatus aangeeft.

De geïmplementeerde agent bewaken

U kunt uw geïmplementeerde agent bewaken met behulp van het Durable Task Scheduler-dashboard in Azure.

  1. Haal de naam op van uw Durable Task Scheduler-exemplaar:

    azd env get-value DTS_NAME
    
  2. Open Azure Portal en zoek de naam van de Durable Task Scheduler uit de vorige stap.

  3. Selecteer in het overzichtblad van de Durable Task Scheduler-resource de standaard taakhub in de lijst.

  4. Selecteer Dashboard openen boven aan de pagina van de taakhub om het bewakingsdashboard te openen.

  5. Bekijk de gesprekken van uw agent net zoals u hebt gedaan met de lokale emulator.

Het door Azure gehoste dashboard biedt dezelfde mogelijkheden voor foutopsporing en bewaking als de lokale emulator, zodat u de gespreksgeschiedenis kunt inspecteren, hulpprogrammaaanroepen kunt traceren en prestaties in uw productieomgeving kunt analyseren.

Zelfstudie: Duurzame agents organiseren met Azure Functions

In deze zelfstudie leert u hoe u meerdere duurzame AI-agents kunt organiseren met behulp van het Azure Functions hostingmodel en het fan-out-/fan-in-patroon. U gaat de duurzame agent uit de vorige zelfstudie uitbreiden om een systeem met meerdere agents te maken dat de vraag van een gebruiker verwerkt en het antwoord vervolgens in meerdere talen tegelijk vertaalt. Zie de voorbeelden voor zelf-hostende indelingen.

Inzicht in het orchestratiepatroon

De orkestratie die u gaat bouwen, volgt deze werkwijze:

  1. Gebruikersinvoer : een vraag of bericht van de gebruiker
  2. Hoofdagent - de MyDurableAgent van de eerste handleiding verwerkt de vraag
  3. Fan-out : het antwoord van de hoofdagent wordt gelijktijdig naar beide vertaalagenten verzonden
  4. Vertaalagenten - Twee gespecialiseerde agenten vertalen het antwoord (Frans en Spaans)
  5. Fan-in : resultaten worden samengevoegd in één JSON-antwoord met het oorspronkelijke antwoord en de vertalingen

Dit patroon maakt gelijktijdige verwerking mogelijk, waardoor de totale reactietijd wordt verminderd ten opzichte van sequentiële vertaling.

Agents registreren bij het opstarten

Als u agents in duurzame orkestraties goed wilt gebruiken, registreert u deze bij het opstarten van de toepassing. Ze kunnen worden gebruikt voor orkestraties.

Werk uw Program.cs bij om de vertaalagenten naast het bestaande MyDurableAgentte registreren:

using System;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Hosting.AzureFunctions;
using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Extensions.Hosting;

// 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 Microsoft Foundry client
AIProjectClient client = new(new Uri(endpoint), new DefaultAzureCredential());

// Create the main agent from the first tutorial
AIAgent mainAgent = client.AsAIAgent(
    model: deploymentName,
    instructions: "You are a helpful assistant that can answer questions and provide information.",
    name: "MyDurableAgent");

// Create translation agents
AIAgent frenchAgent = client.AsAIAgent(
    model: deploymentName,
    instructions: "You are a translator. Translate the following text to French. Return only the translation, no explanations.",
    name: "FrenchTranslator");

AIAgent spanishAgent = client.AsAIAgent(
    model: deploymentName,
    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();

Werk uw function_app.py bij om de vertaalagenten naast het bestaande MyDurableAgentte registreren:

import os
from azure.identity import DefaultAzureCredential
from agent_framework.azure import AgentFunctionApp
from agent_framework.openai import OpenAIChatCompletionClient

# 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_CHAT_COMPLETION_MODEL", "gpt-4o-mini")
api_version = os.getenv("AZURE_OPENAI_API_VERSION")

# Create the Azure OpenAI client
chat_client = OpenAIChatCompletionClient(
    azure_endpoint=endpoint,
    model=deployment_name,
    api_version=api_version,
    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])

Een orkestratiefunctie maken

Een indelingsfunctie coördineert de werkstroom over meerdere agents. Het haalt geregistreerde agents op uit de duurzame context en organiseert de uitvoering, waarbij eerst de hoofdagent wordt aangeroepen en vervolgens gelijktijdig wordt uitgewaaid naar vertaalagenten.

Maak een nieuw bestand met de naam AgentOrchestration.cs in de projectmap:

using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.DurableTask;
using Microsoft.Azure.Functions.Worker;
using Microsoft.DurableTask;

namespace MyDurableAgent;

public static class AgentOrchestration
{
    // Define a strongly-typed response structure for agent outputs
    public sealed record TextResponse(string Text);

    [Function("agent_orchestration_workflow")]
    public static async Task<Dictionary<string, string>> AgentOrchestrationWorkflow(
        [OrchestrationTrigger] TaskOrchestrationContext context)
    {
        var input = context.GetInput<string>() ?? throw new ArgumentNullException(nameof(context), "Input cannot be null");

        // Step 1: Get the main agent's response
        DurableAIAgent mainAgent = context.GetAgent("MyDurableAgent");
        AgentResponse<TextResponse> mainResponse = await mainAgent.RunAsync<TextResponse>(input);
        string agentResponse = mainResponse.Result.Text;

        // Step 2: Fan out - get the translation agents and run them concurrently
        DurableAIAgent frenchAgent = context.GetAgent("FrenchTranslator");
        DurableAIAgent spanishAgent = context.GetAgent("SpanishTranslator");

        Task<AgentResponse<TextResponse>> frenchTask = frenchAgent.RunAsync<TextResponse>(agentResponse);
        Task<AgentResponse<TextResponse>> spanishTask = spanishAgent.RunAsync<TextResponse>(agentResponse);

        // Step 3: Wait for both translation tasks to complete (fan-in)
        await Task.WhenAll(frenchTask, spanishTask);

        // Get the translation results
        TextResponse frenchResponse = (await frenchTask).Result;
        TextResponse spanishResponse = (await spanishTask).Result;

        // Step 4: Combine results into a dictionary
        var result = new Dictionary<string, string>
        {
            ["original"] = agentResponse,
            ["french"] = frenchResponse.Text,
            ["spanish"] = spanishResponse.Text
        };

        return result;
    }
}

Voeg de orkestratiefunctie toe aan uw function_app.py bestand.

import azure.durable_functions as df

@app.orchestration_trigger(context_name="context")
def agent_orchestration_workflow(context: df.DurableOrchestrationContext):
    """
    Orchestration function that coordinates multiple agents.
    Returns a dictionary with the original response and translations.
    """
    input_text = context.get_input()

    # Step 1: Get the main agent's response
    main_agent = app.get_agent(context, "MyDurableAgent")
    main_response = yield main_agent.run(input_text)
    agent_response = main_response.text

    # Step 2: Fan out - get the translation agents and run them concurrently
    french_agent = app.get_agent(context, "FrenchTranslator")
    spanish_agent = app.get_agent(context, "SpanishTranslator")

    parallel_tasks = [
        french_agent.run(agent_response),
        spanish_agent.run(agent_response)
    ]

    # Step 3: Wait for both translation tasks to complete (fan-in)
    translations = yield context.task_all(parallel_tasks) # type: ignore

    # Step 4: Combine results into a dictionary
    result = {
        "original": agent_response,
        "french": translations[0].text,
        "spanish": translations[1].text
    }

    return result

De orkestratie testen

Zorg ervoor dat uw lokale ontwikkelingsafhankelijkheden uit de eerste handleiding nog steeds actief zijn:

  • Azurite in één terminalvenster
  • Durable Task Scheduler Emulator in een ander terminalvenster

Zorg ervoor dat uw lokale ontwikkelingsafhankelijkheden actief zijn:

  1. Start uw Azure Functions-app in een nieuw terminalvenster:

    func start
    
  2. De Durable Functions-extensie maakt automatisch ingebouwde HTTP-eindpunten voor het beheren van indelingen. Start de orkestratie met behulp van de ingebouwde API.

    curl -X POST http://localhost:7071/runtime/webhooks/durabletask/orchestrators/agent_orchestration_workflow \
      -H "Content-Type: application/json" \
      -d '"\"What are three popular programming languages?\""'
    

  1. Het antwoord bevat URLs voor het beheren van de orchestratie-instantie.

    {
      "id": "abc123def456",
      "statusQueryGetUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/abc123def456",
      "sendEventPostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/abc123def456/raiseEvent/{eventName}",
      "terminatePostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/abc123def456/terminate",
      "purgeHistoryDeleteUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/abc123def456"
    }
    
  2. Voer een query uit op de orkestratiestatus met behulp van de statusQueryGetUri (vervang abc123def456 door uw werkelijke exemplaar-id):

    curl http://localhost:7071/runtime/webhooks/durabletask/instances/abc123def456
    

  1. Pols het status-eindpunt totdat runtimeStatusCompleted is. Als je klaar bent, zie je de orchestratie-uitvoer met het antwoord van de hoofdagent en de bijbehorende vertalingen:

    {
      "name": "agent_orchestration_workflow",
      "instanceId": "abc123def456",
      "runtimeStatus": "Completed",
      "output": {
        "original": "Three popular programming languages are Python, JavaScript, and Java. Python is known for its simplicity...",
        "french": "Trois langages de programmation populaires sont Python, JavaScript et Java. Python est connu pour sa simplicité...",
        "spanish": "Tres lenguajes de programación populares son Python, JavaScript y Java. Python es conocido por su simplicidad..."
      }
    }
    

De indeling in het dashboard bewaken

Het dashboard Durable Task Scheduler biedt inzicht in uw indeling:

  1. Open http://localhost:8082 in je browser.

  2. Selecteer de standaardtaak-hub.

  3. Selecteer het tabblad Orkestraties.

  4. Zoek uw orkestratie-exemplaar in de lijst.

  5. Selecteer de instantie om te zien:

    • De orkestratietijdlijn
    • Uitvoering van de hoofdagent gevolgd door gelijktijdig opererende vertaalagenten
    • Elke agentuitvoering (MyDurableAgent, vervolgens Frans en Spaans vertalers)
    • Gevisualiseerde fan-out- en fan-inpatronen
    • Timing en duur voor elke stap

De indeling implementeren in Azure

Implementeer de bijgewerkte toepassing met behulp van Azure Developer CLI:

azd deploy

Hiermee implementeert u de bijgewerkte code met de nieuwe indelingsfunctie en aanvullende agents in de Azure Functions-app die in de eerste zelfstudie is gemaakt.

De geïmplementeerde indeling testen

Test na de implementatie de indeling die wordt uitgevoerd in Azure.

  1. Haal de systeemsleutel voor de duurzame extensie op:

    SYSTEM_KEY=$(az functionapp keys list --name $(azd env get-value AZURE_FUNCTION_NAME) --resource-group $(azd env get-value AZURE_RESOURCE_GROUP) --query "systemKeys.durabletask_extension" -o tsv)
    

  1. Start de orkestratie met behulp van de ingebouwde API.

    curl -X POST "https://$(azd env get-value AZURE_FUNCTION_NAME).azurewebsites.net/runtime/webhooks/durabletask/orchestrators/agent_orchestration_workflow?code=$SYSTEM_KEY" \
      -H "Content-Type: application/json" \
      -d '"\"What are three popular programming languages?\""'
    

  1. Gebruik het statusQueryGetUri antwoord om te peilen naar voltooiing en de resultaten met vertalingen weer te geven.

Volgende stappen 

Aanvullende bronnen: