Dauerhafte Erweiterung

Die dauerhafte Erweiterung für Microsoft Agent Framework bietet dauerhafte Ausführung für Agents, Multi-Agent-Orchestrierungen und Microsoft Agent Framework-Workflows. Sie können es verwenden, um Agentsitzungen, Prüfpunkt-Orchestrierung und Workflowfortschritt zu speichern, Fehler wiederherzustellen und die Arbeit auf verteilten Hosts zu skalieren, ohne Ihre Kern-Agent-Logik zu ändern.

Die Erweiterung unterstützt zwei Hostingmodelle in C# und Python:

  • Azure Functions für verwaltetes, serverloses Hosting mit dem Azure Functions Programmiermodell.
  • Bring-your-own-compute /self-hosted for running durable agents and workflows in your own worker process, service, container, kubernetes environment, or existing app infrastructure.

Overview

Dauerhafte Agents kombinieren das Agent Framework-Programmiermodell mit der Durable Task-Infrastruktur, z. B. dem Durable Task Scheduler, um Agents zu erstellen, die:

  • Status automatisch für Anforderungen und Arbeitsausführungen beibehalten
  • Fortsetzen nach Fehlern ohne Verlust des Unterhaltungskontexts oder wiederholter abgeschlossener Arbeit
  • Horizontal verteilte, zustandslose Arbeiter basierend auf Bedarf skalieren
  • Koordinieren von Multi-Agent-Workflows mit zuverlässigen Ausführungsgarantien
  • Workflows des Prüfpunkt-Agent-Frameworks , die mit dem graphbasierten Workflowmodell erstellt wurden
  • Anhalten für menschliche Eingaben oder externe Ereignisse ohne Verwenden von Compute- oder Modelltoken beim Warten
  • Datenstromantworten zuverlässig , wenn sie mit einem zuverlässigen Streambroker konfiguriert sind, z. B. Redis
  • Verwalten des Sitzungslebenszyklus mit Sitzungszeit-zu-Live-Bereinigung (TTL) und dashboardbasierter Überwachung

Wann sollte man dauerhafte Agenten verwenden?

Wählen Sie dauerhafte Agents aus, wenn Sie folgendes benötigen:

  • Status der beständigen Unterhaltung: Agentsitzungen überleben Prozessabstürzen, Neustarts und Skalierungsereignisse
  • Komplexe Orchestrierungen: Koordinieren mehrerer Agents mit deterministischen, zuverlässigen Workflows, die tage- oder wochenlang ausgeführt werden können
  • Ereignisgesteuerte Orchestrierung: Integration mit Triggern, Warteschlangen, Webhooks, Zeitgebern oder vorhandenen Anwendungsereignissen
  • Automatischer Unterhaltungszustand: Der Verlauf der Agentunterhaltung wird automatisch verwaltet und beibehalten, ohne dass eine explizite Verwaltung des Zustands in Ihrem Code erforderlich ist.
  • Durable Agent Framework-Workflows: Erstellen von graphbasierten Microsoft Agent Framework-Workflows dauerhaft, sodass jeder Schritt überprüft und fortgesetzt werden kann
  • Langlebige Sitzungen: Halten Sie nützliche Unterhaltungen zur Verfügung, während Sie die Sitzungszeit-zu-Live -Bereinigung (TTL) verwenden, um Leerlaufsitzungen automatisch zu entfernen.
  • Zuverlässige Echtzeitantworten: Streamtokenausgabe für Anwendungen, die Echtzeit-UX mit Übermittlungsgarantien benötigen

Dieser Hostingansatz unterscheidet sich von verwaltetem dienstbasiertem Agenthosting (z. B. Foundry Agent Service), das vollständig verwaltete Infrastruktur bereitstellt, ohne dass Sie Workerhosts bereitstellen oder verwalten müssen. Dauerhafte Agents sind ideal, wenn Sie die Flexibilität der Code-first-Bereitstellung in Kombination mit der dauerhaften Zustandsverwaltung benötigen.

Auswählen eines Hostingmodells

Hostingmodell Wählen Sie es aus, wenn Sie dies benötigen.
Azure-Funktionen Ein verwaltetes, serverloses Hostingmodell; integrierte Skalierung und Skalierungs-zu-Null-Skalierung; Azure Functions Trigger und Bindungen; HTTP-Endpunkte, die vom Funktionenprogrammiermodell generiert werden; der MCP-Servertrigger; und minimale Verwaltung der Hostinfrastruktur.
Bring-your-own-compute / self-hosted Mehr Kontrolle über den Hostprozess, die Bereitstellungsumgebung, den Laufzeitlebenszyklus, die Infrastruktur, das Netzwerk, die Authentifizierung oder die Integration in eine vorhandene App oder einen vorhandenen Dienst. Verwenden Sie dieses Modell für Container, Kubernetes, lange ausgeführte Mitarbeiter, Konsolen-Apps, benutzerdefinierte Dienste oder Nicht-Funktionen-Hostingumgebungen.

Wenn Sie im Hostingplan für Azure Functions Flex Consumption gehostet werden, können Agents auf Tausende von Instanzen oder auf Nullinstanzen skalieren, wenn sie nicht verwendet werden, sodass Sie nur für die berechnung bezahlen können, die Sie benötigen. In selbst gehosteten Szenarien steuert Ihr eigener Host die Prozesslebensdauer, Skalierung, Netzwerk und Bereitstellung.

Erste Schritte

Wählen Sie in einem .NET Projekt das Paket für Ihr Hostingmodell aus.

Fügen Sie für Azure Functions Hosting das Azure Functions Integrationspaket und die Arbeitspakete "Functions" hinzu.

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

Stellen Sie zusätzlich zu diesen Paketen sicher, dass Ihr Projekt Version 2.2.0 oder höher des Microsoft.Azure.Functions.Worker-Pakets verwendet.

Fügen Sie für bring-your-own-compute-Hosting das Grundlegende Integrationspaket für dauerhafte Aufgaben und die vom Host verwendeten Arbeits- und Clientpakete für dauerhafte Aufgabenplanung hinzu:

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

Wählen Sie in einem Python Projekt das Paket für Ihr Hostingmodell aus.

Installieren Sie für Azure Functions Hosting das Azure Functions Integrationspaket.

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

Installieren Sie das Integrationspaket "Durable Task", um Ihr eigenes Computehosting mitzubringen.

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

Azure Functions Hosting

Mit der durable Extension können Sie Microsoft Agent Framework-Agents in Azure Functions mit integrierten HTTP-Endpunkten und orchestrierungsbasiertem Aufruf bereitstellen und hosten. Azure Functions bietet ein ereignisgesteuertes, nutzungsabhängiges Preismodell mit automatischer Skalierung und minimalem Infrastrukturmanagement.

Wenn Sie einen dauerhaften Agent in Azure Functions konfigurieren, erstellt die Erweiterung automatisch HTTP-Endpunkte für Ihren Agent und verwaltet die zugrunde liegende Infrastruktur zum Speichern des Unterhaltungszustands, zum Behandeln gleichzeitiger Anforderungen und zur Koordination von Workflows mit mehreren Agents. Die Azure Functions Hostingintegration bietet auch funktionenspezifische Funktionen wie generierte REST-APIs zum Senden von Nachrichten, zum Überprüfen des Status und zum Verwalten von Sitzungen sowie Trigger wie den MCP-Servertrigger für Hosting-Agents als MCP-Server ohne Schreiben von Triggerklebern.

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 ist praktisch für die Entwicklung, erfordert aber sorgfältige Überlegungen in der Produktion. Berücksichtigen Sie in der Produktion die Verwendung bestimmter Anmeldeinformationen (z. B. ManagedIdentityCredential), um Latenzprobleme, unbeabsichtigte Abfragen von Anmeldeinformationen und potenzielle Sicherheitsrisiken durch Ausweichmechanismen zu vermeiden.

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 / self-hosted hosting

Verwenden Sie bring-your-own-compute hosting, wenn Sie die Durable Extension-Funktionen verwenden möchten, ohne das Azure Functions Programmiermodell zu verwenden. In diesem Modell startet Ihr Prozess einen Durable Task Worker, registriert dauerhafte Agents oder Workflows und stellt eine Verbindung mit einem Back-End für dauerhafte Aufgabenplanung her. Clientcode kann im selben Prozess oder in einem separaten Dienst ausgeführt werden.

Selbst gehostete Mitarbeiter verwenden die gleichen Kernfunktionen für dauerhafte Erweiterungen wie Azure Functions Hosting: Prüfpunkt und Wiederaufnahme, deterministische Agent-Orchestrierung, dauerhafte Agent Framework-Workflows, Human-in-the-Loop-Wartezeiten, zuverlässiges Streaming, Leerlaufsitzungsbereinigung, Dashboard-Sichtbarkeit und verteilte Ausführung über zustandslose Arbeitsinstanzen hinweg. Ihr Host ist für die Bereitstellung eigener APIs, Lebenszyklusverwaltung, Netzwerk, Authentifizierung und Bereitstellungsmodell verantwortlich.

Konfigurieren Sie Ihren Host mit dem Basisintegrationspaket für dauerhafte Aufgaben. Verwenden Sie ConfigureDurableAgents für dauerhafte Agents und ConfigureDurableWorkflows für graphbasierte Microsoft Agent Framework-Workflows.

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();

In den Konsolenbeispielen .NET Durable Agents und .NET Durable Workflows konsolenbeispiele finden Sie runnable selbst gehostete Beispiele.

Verwenden Sie das Integrationspaket für dauerhafte Aufgaben, um einen Arbeitsprozess auszuführen, der Agents registriert und auf Anforderungen lauscht. Clientcode kann über einen anderen Prozess eine Verbindung mit demselben Taskplaner-Hub für dauerhafte Vorgänge herstellen.

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()

Weitere Informationen finden Sie in den Beispielen Python Durable Task für Worker-Client-Beispiele, einschließlich Single-Agent-Hosting, Multi-Agent-Routing, zuverlässiges Streaming, Orchestrierungsverkettung, Parallelität, Bedingungen und menschlichen In-the-Loop-Mustern.

Dauerhafte Agent Framework-Workflows

Die Haltbarkeit ist nicht auf dauerhafte Orchestrierungen beschränkt. Microsoft Agent Framework-Workflows, die mit dem graphbasierten Workflowmodell erstellt wurden, können auch dauerhaft erstellt werden. Die Workflowausführung der dauerhaften Erweiterungsprüfpunkte, sodass abgeschlossene Ausführungs- und Agentschritte nach einem Prozessneustart oder Einem Fehler nicht wiederholt werden.

Verwenden Sie dauerhafte Orchestrierungen, wenn Sie die imperative Koordination mit codebasierten Verzweigungen, Zeitgebern, Aktivitäten und externen Ereignissen wünschen. Verwenden Sie dauerhafte Agent Framework-Workflows, wenn Sie ein deklaratives Diagramm von Executoren und Agents mit typiertem Routing, Fanout/Fan-In, bedingten Kanten, Workflowereignissen, gemeinsam genutztem Zustand, Unterworkflows oder menschlichen In-the-Loop-Anforderungsports verwenden möchten.

Note

Dauerhafte Agent Framework-Workflows unterscheiden sich vom Prüfpunktspeicher in Standardworkflows. Der Prüfpunktspeicher hilft beim Fortsetzen eines Workflows, der in der Agent Framework-Laufzeit ausgeführt wird. Die dauerhafte Erweiterung führt den Workflow in der Infrastruktur für dauerhafte Aufgaben aus, sodass der Workflowfortschritt über verteilte dauerhafte Mitarbeiter überprüft und wiederhergestellt wird. Informationen zum standardmäßigen Workflowprüfpunkt finden Sie unter "Prüfpunkte" und "Fortsetzen".

Registrieren Sie graphbasierte Workflows mit ConfigureDurableWorkflows für selbst gehostete Apps oder ConfigureDurableWorkflows im Funktions-App-Generator für Azure Functions Hosting.

Weitere Informationen finden Sie in den Konsolenbeispielen .NET Durable Azure Functions Workflows und .NET Durable Workflows.

Dauerhafte Workflowbeispiele sind für Azure Functions Hosting verfügbar, einschließlich freigegebener Status, kein freigegebener Zustand, parallele Workflowausführung und Workflows, die in der Schleife verwendet werden.

Weitere Informationen finden Sie in den Beispielen Python Azure Functions für dauerhafte Agent, Orchestrierung, MCP-Server und Workflowbeispiele.

Samples

Sprache Hostingmodell Samples
C# Azure-Funktionen .NET Durable Agents - Azure Functions, .NET Durable Workflows - Azure Functions
C# Bring-your-own-compute / self-hosted .NET Durable Agents – Konsolen-Apps, .NET Dauerhafte Workflows - Konsolen-Apps
Python Azure-Funktionen Python Azure Functions Beispiele
Python Bring-your-own-compute / self-hosted Python Beispiele für dauerhafte Aufgaben

Statusbehaftete Agent-Threads mit Unterhaltungsverlauf

Agents verwalten persistente Threads, die über mehrere Interaktionen hinweg überleben. Jeder Thread wird durch eine eindeutige Thread-ID identifiziert und speichert den vollständigen Unterhaltungsverlauf im dauerhaften Speicher, der von der Infrastruktur für dauerhafte Aufgaben verwaltet wird, z. B. dem Permanenten Aufgabenplaner.

Dieses Muster ermöglicht die Unterhaltungskontinuität, bei der der Agentstatus durch Prozessabstürzen und Neustarts beibehalten wird, sodass der vollständige Unterhaltungsverlauf über Benutzerthreads hinweg verwaltet werden kann. Der dauerhafte Speicher stellt sicher, dass die Unterhaltung auch dann nahtlos fortgesetzt wird, wenn ein Hostprozess neu gestartet oder die Arbeit an einer anderen Arbeitsinstanz fortgesetzt wird.

Verwenden Sie die Zeit-zu-Live-Bereinigung (Session Time-to-Live, TTL) für Arbeitslasten, die während der aktiven Verwendung dauerhafte Kontinuität erfordern, sollten aber automatisch Leerlaufunterhaltungen bereinigen. TTL-basierte Bereinigung verhindert, dass nicht verwendete Sitzungen und Aufgezeichnete Unterhaltungen unbegrenzt akkumuliert werden, während der aktive Sitzungszustand beibehalten wird.

Im folgenden Azure Functions Beispiel werden mehrere HTTP-Anforderungen für denselben Thread veranschaulicht, die zeigen, wie der Unterhaltungskontext beibehalten wird. Verwenden Sie in selbst gehosteten Apps die Client-APIs für dauerhafte Aufgaben aus Ihrem eigenen Prozess oder Dienst.

# 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!

Der Agentstatus wird im dauerhaften Speicher beibehalten und ermöglicht die verteilte Ausführung über mehrere Instanzen hinweg. Jede Instanz kann die Ausführung eines Agents nach Unterbrechungen oder Fehlern fortsetzen und den kontinuierlichen Betrieb sicherstellen.

Zuverlässiges Streaming

Die durable Extension unterstützt zuverlässiges Streaming für Anwendungen, die die Bereitstellung von Token in Echtzeit mit dauerhaften Übermittlungsgarantien benötigen. Streaming kann mit der Kernerweiterung in beiden Hostingmodellen verwendet werden, aber verteilte Hosts benötigen einen zuverlässigen Streambroker, z. B. Redis, sodass Tokenstreams konsistent über Prozessneustarts, erneute Verbindungen oder Workeränderungen bereitgestellt werden können.

Verwenden Sie zuverlässiges Streaming, wenn die Benutzererfahrung von inkrementellen Antworten abhängt, aber die Workload benötigt weiterhin dauerhafte Ausführungsemantik. Runnable examples, see the Python Durable Task samples, which include reliable streaming patterns.

Deterministische Multi-Agent-Orchestrierungen

Die durable Extension unterstützt das Erstellen deterministischer Workflows, die mehrere Agents mithilfe von Durable Task-Orchestrierungen koordinieren. In Azure Functions verwenden diese Durable Functions Orchestrierungen; bei Bring-your-own-Compute-Hosts werden sie über den von Ihnen konfigurierten Arbeitskraft für dauerhafte Aufgaben und den von Ihnen konfigurierten Client ausgeführt.

Orchestrierungen sind codebasierte Workflows, die mehrere Vorgänge (z. B. Agentaufrufe, externe API-Aufrufe oder Timer) zuverlässig koordinieren. Deterministisch bedeutet, dass der Orchestrierungscode bei der Wiedergabe nach einem Fehler auf die gleiche Weise ausgeführt wird, was Workflows zuverlässig und debuggierbar macht – wenn Sie den Verlauf einer Orchestrierung wiedergeben, können Sie genau sehen, was bei jedem Schritt passiert ist.

Orchestrierungen werden zuverlässig durchgeführt, überstehen Ausfälle zwischen Agentaufrufen und bieten vorhersehbare und wiederholbare Prozesse. Dies macht sie ideal für komplexe Multi-Agent-Szenarien, in denen Sie eine garantierte Ausführungsreihenfolge und Fehlertoleranz benötigen.

Sequenzielle Orchestrierungen

Im sequenziellen Multi-Agent-Muster werden spezialisierte Agents in einer bestimmten Reihenfolge ausgeführt, in der die Ausgabe jedes Agents die Ausführung des nächsten Agents beeinflussen kann. Dieses Muster unterstützt bedingte Logik und Verzweigung basierend auf Agentantworten.

Wenn Sie Agents in Orchestrierungen verwenden, müssen Sie die context.GetAgent() API verwenden, um eine Instanz abzurufen, bei der es sich um eine DurableAIAgent spezielle Unterklasse des Standardtyps AIAgent handelt, der einen Ihrer registrierten Agents umschließt. Der DurableAIAgent Wrapper stellt sicher, dass Agentaufrufe vom dauerhaften Orchestrierungsframework ordnungsgemäß nachverfolgt und überprüft werden.

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);
}

Wenn Sie Agenten in Orchestrierungen verwenden, müssen Sie die app.get_agent() Methode verwenden, um eine dauerhafte Agenteninstanz zu erhalten, die ein spezieller Wrapper um einen Ihrer registrierten Agenten ist. Der dauerhafte Agentwrapper stellt sicher, dass Agentaufrufe vom dauerhaften Orchestrierungsframework ordnungsgemäß nachverfolgt und überprüft werden.

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

Orchestrierungen koordinieren die Arbeit mehrerer Agenten und überstehen Fehler zwischen Agentenanrufen. Der Orchestrierungskontext stellt Methoden zum Abrufen und Interagieren mit gehosteten Agents innerhalb von Orchestrierungen bereit.

Parallele Orchestrierungen

Im parallelen Multi-Agent-Muster führen Sie mehrere Agents gleichzeitig aus und aggregieren dann deren Ergebnisse. Dieses Muster ist nützlich, um verschiedene Perspektiven zu sammeln oder unabhängige Teilvorgänge gleichzeitig zu verarbeiten.

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', '')

Die parallele Ausführung wird mithilfe einer Liste von Aufgaben nachverfolgt. Durch die automatische Prüfpunkterstellung wird sichergestellt, dass abgeschlossene Agenten-Ausführungen nicht wiederholt oder verloren gehen, wenn während der Aggregierung ein Fehler auftritt.

Human-in-the-Loop-Orchestrierungen

Deterministische Agent-Orchestrierungen können für menschliche Eingaben, Genehmigungen oder Überprüfungen anhalten, ohne Rechenressourcen zu verbrauchen. Dauerhafte Ausführung ermöglicht es Orchestrierungen, Tage oder sogar Wochen zu warten, während sie auf menschliche Reaktionen warten. In Kombination mit serverless Hosting werden alle Rechenressourcen während der Wartezeit heruntergefahren, wodurch die Rechenkosten vermieden werden, bis der Benutzer seine Eingabe bereitstellt.

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 Agent-Orchestrierungen können auf externe Ereignisse warten und ihren Zustand dauerhaft speichern, während sie auf menschliches Feedback warten, Fehler überstehen und Neustarts sowie erweiterte Wartezeiten überdauern. Wenn die menschliche Antwort eingeht, wird der Orchestrierungsvorgang automatisch fortgesetzt, wobei der vollständige Unterhaltungskontext und der Ausführungszustand intakt sind.

Bereitstellen von menschlichen Eingaben

Um genehmigungs- oder eingaben an eine Warte-Orchestrierung zu senden, lösen Sie ein externes Ereignis über das Durable Task-Client-SDK oder die Azure Functions Durable-Erweiterungsendpunkte an die Orchestrierungsinstanz aus. Beispielsweise kann ein Prüfer Inhalte über ein Webformular genehmigen, das Folgendes aufruft:

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)

Kosteneffizienz

Human-in-the-Loop-Workflows mit dauerhaften Agents sind extrem kostengünstig, wenn sie im Azure Functions Flex Consumption-Plan gehostet werden. Für einen Workflow, der 24 Stunden auf die Genehmigung wartet, zahlen Sie nur einige Sekunden Ausführungszeit (die Zeit zum Generieren von Inhalten, Senden von Benachrichtigungen und Verarbeiten der Antwort) – nicht die 24 Stunden wartezeit. Während des Wartezeitzeitraums werden keine Computeressourcen verbraucht.

Überwachbarkeit mit dem Durable Task Scheduler

Der Durable Task Scheduler (DTS) ist das empfohlene dauerhafte Back-End für Ihre dauerhaften Agents, das die beste Leistung, vollständig verwaltete Infrastruktur und integrierte Observierbarkeit über ein UI-Dashboard bietet. Azure Functions Apps können andere Speicher-Back-Ends (z. B. Azure Storage) verwenden, aber DTS ist speziell für dauerhafte Workloads optimiert und bietet überlegene Leistungs- und Überwachungsfunktionen. Selbst gehostete Mitarbeiter verwenden auch DTS für dauerhafte Planung, Zustand und Dashboard-Sichtbarkeit.

Einblicke in die Agentsitzung

  • Aufgezeichnete Unterhaltungen: Anzeigen des vollständigen Chatverlaufs für jede Agentsitzung, einschließlich aller Nachrichten, Toolanrufe und Unterhaltungskontexte zu einem beliebigen Zeitpunkt
  • Aufgabenzeitmessung: Überwachen, wie lange bestimmte Aufgaben und Agentinteraktionen zur Fertigstellung benötigen

Screenshot des Dashboards

Orchestrierungserkenntnisse

  • Visualisierung mit mehreren Agents: Anzeigen des Ausführungsflusses beim Aufrufen mehrerer spezialisierter Agents mit visueller Darstellung paralleler Ausführung und bedingter Verzweigung
  • Ausführungsverlauf: Zugreifen auf detaillierte Ausführungsprotokolle
  • Echtzeitüberwachung: Verfolgen aktiver Orchestrierungen, Warteschlangen-Arbeitsaufgaben und Agentenzustände über Ihre gesamte Bereitstellung hinweg
  • Leistungsmetriken: Überwachen von Agentantwortzeiten, Tokenverwendung und Orchestrierungsdauer

Screenshot des Dashboards

Debuggingfunktionen

  • Anzeigen strukturierter Agent-Ausgaben und Toolaufrufergebnisse
  • Aufrufe von Tracing-Tools und deren Ergebnisse
  • Überwachung der Verarbeitung externer Ereignisse in Szenarien mit menschlicher Einbindung

Mit dem Dashboard können Sie genau verstehen, was Ihre Agents tun, Probleme schnell diagnostizieren und die Leistung basierend auf realen Ausführungsdaten optimieren.

Lernprogramm: Erstellen und Ausführen eines dauerhaften Agents mit Azure Functions

In diesem Lernprogramm erfahren Sie, wie Sie einen dauerhaften KI-Agent mithilfe des Azure Functions Hostingmodells für die dauerhafte Erweiterung erstellen und ausführen. Sie erstellen eine Azure Functions-App, die einen zustandsbehafteten Agent mit integrierten HTTP-Endpunkten hostet, und erfahren, wie Sie sie mithilfe des Dashboards für dauerhafte Aufgabenplanung überwachen. Informationen zu selbst gehosteten Agents finden Sie in den Beispielen.

Voraussetzungen

Stellen Sie sicher, dass die folgenden Voraussetzungen erfüllt sind, bevor Sie beginnen:

Note

Microsoft Agent Framework wird mit allen aktiv unterstützten Versionen von .NET unterstützt. Für die Zwecke dieses Beispiels empfehlen wir das .NET 9 SDK oder eine höhere Version.

Herunterladen des Schnellstartprojekts

Verwenden Sie Azure Developer CLI, um ein neues Projekt aus der Schnellstartvorlage für dauerhafte Agenten zu initialisieren.

  1. Erstellen Sie ein neues Verzeichnis für Ihr Projekt, und navigieren Sie zu diesem Verzeichnis:

    mkdir MyDurableAgent
    cd MyDurableAgent
    

  1. Initialisieren Sie das Projekt aus der Vorlage:

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

    Wenn Sie zur Eingabe eines Umgebungsnamens aufgefordert werden, geben Sie einen Namen wie my-durable-agent.

Dadurch wird das Schnellstartprojekt mit allen erforderlichen Dateien heruntergeladen, einschließlich der Azure Functions-Konfiguration, des Agentcodes und der Infrastruktur als Codevorlagen.

  1. Erstellen Sie ein neues Verzeichnis für Ihr Projekt, und navigieren Sie zu diesem Verzeichnis:

    mkdir MyDurableAgent
    cd MyDurableAgent
    

  1. Initialisieren Sie das Projekt aus der Vorlage:

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

    Wenn Sie zur Eingabe eines Umgebungsnamens aufgefordert werden, geben Sie einen Namen wie my-durable-agent.

  2. Erstellen und Aktivieren einer virtuellen Umgebung:

    uv venv .venv
    source .venv/bin/activate
    

Note

python3 -m venv .venv funktioniert auch, kann jedoch aufgrund eines bekannten ensurepip Problems unbegrenzt an Windows mit Microsoft Store Python hängen. Verwenden Sie uv venv .venv dies, um dies zu vermeiden.

  1. Installieren Sie die erforderlichen Pakete:

    python -m pip install -r requirements.txt
    

Dadurch wird das Schnellstartprojekt mit allen erforderlichen Dateien heruntergeladen, einschließlich der Azure Functions-Konfiguration, des Agentcodes und der Infrastruktur als Codevorlagen. Außerdem wird eine virtuelle Umgebung mit den erforderlichen Abhängigkeiten vorbereitet.

Bereitstellen von Azure-Ressourcen

Verwenden Sie azure Developer CLI, um die erforderlichen Azure-Ressourcen für Ihren dauerhaften Agent zu erstellen.

  1. Bereitstellen der Infrastruktur:

    azd provision
    

    Mit diesem Befehl wird Folgendes erstellt:

    • Ein Azure OpenAI-Dienst mit einer gpt-4o-mini-Bereitstellung
    • Eine Azure Functions-App mit Flex-Verbrauch-Hostingplan
    • Ein Azure Storage-Konto für die Laufzeit und den dauerhaften Speicher von Azure Functions
    • Eine Dauerhafte Task Scheduler-Instanz (Verbrauchsplan) zur Verwaltung des Agent-Zustands
    • Erforderliche Netzwerk- und Identitätskonfigurationen
  2. Wenn Sie dazu aufgefordert werden, wählen Sie Ihr Azure-Abonnement aus, und wählen Sie einen Speicherort für die Ressourcen aus.

Der Bereitstellungsprozess dauert einige Minuten. Nach Abschluss speichert azd die erstellten Ressourceninformationen in Ihrer Umgebung.

Überprüfen des Agenten-Codes

Sehen wir uns nun den Code an, der Ihren dauerhaften Agenten definiert.

Öffnen Program.cs , um die Agentkonfiguration anzuzeigen:

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();

Dieser Code:

  1. Ruft Ihre Azure OpenAI-Konfiguration aus Umgebungsvariablen ab.
  2. Erstellt einen Azure OpenAI-Client mit Azure-Anmeldeinformationen.
  3. Erstellt einen KI-Agent mit Anweisungen und einem Namen.
  4. Konfiguriert die Azure Functions-App so, dass der Agent mit dauerhafter Threadverwaltung gehostet wird.

Öffnen function_app.py , um die Agentkonfiguration anzuzeigen:

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])

Dieser Code:

  • Ruft Ihre Azure OpenAI-Konfiguration aus Umgebungsvariablen ab.
  • Erstellt einen Azure OpenAI-Client mit Azure-Anmeldeinformationen.
  • Erstellt einen KI-Agent mit Anweisungen und einem Namen.
  • Konfiguriert die Azure Functions-App so, dass der Agent mit dauerhafter Threadverwaltung gehostet wird.

Der Agent kann jetzt in Azure-Funktionen gehostet werden. Die dauerhafte Aufgabenerweiterung erstellt automatisch HTTP-Endpunkte für die Interaktion mit Ihrem Agenten und verwaltet den Gesprächsstatus über mehrere Anforderungen hinweg.

Konfigurieren lokaler Einstellungen

Erstellen Sie eine local.settings.json Datei für die lokale Entwicklung basierend auf der Beispieldatei, die im Projekt enthalten ist.

  1. Kopieren Sie die Beispieleinstellungsdatei:

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

  1. Rufen Sie Ihren Azure OpenAI-Endpunkt aus den bereitgestellten Ressourcen ab:

    azd env get-value AZURE_OPENAI_ENDPOINT
    
  2. Öffnen Sie local.settings.json und ersetzen Sie den Wert in <your-resource-name> durch den Endpunkt aus dem vorherigen Befehl.

Ihr local.settings.json sollte wie folgt aussehen:

{
  "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

Die local.settings.json Datei wird nur für die lokale Entwicklung verwendet und wird nicht in Azure bereitgestellt. Bei Produktionsbereitstellungen werden diese Einstellungen automatisch in Ihrer Azure Functions-App anhand der Infrastrukturvorlagen konfiguriert.

Starte lokale Entwicklungsumgebungsverbindungen

Um dauerhafte Agents lokal auszuführen, müssen Sie zwei Dienste starten:

  • Azurite: Emuliert Azure Storage-Dienste (verwendet von Azure Functions zum Verwalten von Triggern und internem Zustand).
  • Durable Task Scheduler (DTS)-Emulator: Verwaltet dauerhaften Zustand (Unterhaltungsverlauf, Orchestrierungszustand) und Planung für Ihre Agents

Starten Sie Azurite

Azurite emuliert Azure Storage-Dienste lokal. Die Azure-Funktionen verwenden sie zum Verwalten des internen Zustands. Sie müssen dies in einem neuen Terminalfenster ausführen und es im Hintergrund weiterlaufen lassen, während Sie Ihren persistenten Agenten entwickeln und testen.

  1. Öffnen Sie ein neues Terminalfenster, und ziehen Sie das Azurite Docker-Image:

    docker pull mcr.microsoft.com/azure-storage/azurite
    
  2. Starten Sie Azurite in einem Terminalfenster:

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

    Azurite beginnt und überwacht die Standardports für Blob-Dienste (10000), Warteschlange (10001) und Tabelle (10002).

Lassen Sie dieses Terminalfenster geöffnet, während Sie Ihren dauerhaften Agent entwickeln und testen.

Tip

Weitere Informationen zu Azurite, einschließlich alternativer Installationsmethoden, finden Sie unter Verwenden des Azurite-Emulators für die lokale Azure Storage-Entwicklung.

Starten des Emulators "Durable Task Scheduler"

Der DTS-Emulator stellt das zuverlässige Back-End bereit, das für die Verwaltung des Agentenzustands und der Orchestrierungen zuständig ist. Er speichert den Gesprächsverlauf und stellt sicher, dass der Status Ihres Agenten über Neustarts hinweg beibehalten wird. Sie löst auch dauerhafte Orchestrierungen und Agenten aus. Sie müssen dies in einem separaten neuen Terminalfenster ausführen und laufen lassen, während Sie Ihren robusten Agenten entwickeln und testen.

  1. Öffnen Sie ein weiteres neues Terminalfenster, und ziehen Sie das Docker-Image des DTS-Emulators:

    docker pull mcr.microsoft.com/dts/dts-emulator:latest
    
  2. Führen Sie den DTS-Emulator aus:

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

    Dieser Befehl startet den Emulator und macht Folgendes verfügbar:

    • Port 8080: Der gRPC-Endpunkt für den Durable Task Scheduler (verwendet von Ihrer Functions-App)
    • Port 8082: Das Verwaltungsdashboard
  3. Das Dashboard ist verfügbar unter http://localhost:8082.

Lassen Sie dieses Terminalfenster geöffnet, während Sie Ihren dauerhaften Agent entwickeln und testen.

Tip

Weitere Informationen zum DTS-Emulator, einschließlich der Konfiguration mehrerer Aufgabenhubs und des Zugriffs auf das Dashboard, finden Sie unter Develop with Durable Task Scheduler.

Führen Sie die Funktions-App aus

Jetzt können Sie Ihre Azure Functions-App mit dem dauerhaften Agent ausführen.

  1. Navigieren Sie in einem neuen Terminalfenster (wobei sowohl Azurite als auch der DTS-Emulator in separaten Fenstern ausgeführt wird), zu Ihrem Projektverzeichnis.

  2. Starten Sie die Azure Functions-Laufzeit:

    func start
    
  3. Es sollte eine Ausgabe angezeigt werden, die angibt, dass Ihre Funktions-App ausgeführt wird, einschließlich der HTTP-Endpunkte für Ihren Agent:

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

Diese Endpunkte verwalten den Unterhaltungszustand automatisch – Sie müssen keine Threadobjekte selbst erstellen oder verwalten.

Testen Sie den Agenten lokal

Jetzt können Sie mit Ihrem dauerhaften Agent mithilfe von HTTP-Anforderungen interagieren. Der Agent verwaltet den Gesprächsstatus über mehrere Anforderungen hinweg und ermöglicht mehrere Gesprächsrunden.

Beginnen einer neuen Unterhaltung

Erstellen Sie einen neuen Thread, und senden Sie Ihre erste Nachricht:

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

Beispielantwort (Beachten Sie, dass der x-ms-thread-id Header die Thread-ID enthält):

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.

Speichern Sie die Thread-ID aus dem x-ms-thread-id Header (z. B. @dafx-mydurableagent@263fa373-fa01-4705-abf2-5a114c2bb87d) für die nächste Anforderung.

Fortsetzen der Unterhaltung

Senden Sie eine Nachverfolgungsnachricht an denselben Thread, indem Sie die Thread-ID als Abfrageparameter einschließen:

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?"

Ersetzen Sie @dafx-mydurableagent@263fa373-fa01-4705-abf2-5a114c2bb87d durch die tatsächliche Thread-ID aus dem x-ms-thread-id-Header der vorherigen Antwort.

Beispielantwort:

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.

Beachten Sie, dass der Agent den Kontext aus der vorherigen Nachricht (die drei Programmiersprachen) merkt, ohne sie erneut angeben zu müssen. Da der Gesprächszustand dauerhaft vom Durable Task Scheduler gespeichert wird, bleibt dieser Verlauf erhalten, selbst wenn Sie die Funktion-App neu starten oder die Unterhaltung von einer anderen Instanz fortgesetzt wird.

Überwachen mit dem Dashboard "Durable Task Scheduler"

Der Durable Task Scheduler bietet ein integriertes Dashboard zum Überwachen und Debuggen Ihrer dauerhaften Agenten. Das Dashboard bietet umfassende Einblicke in die Tätigkeiten der Agenten, den Konversationsverlauf und die Ablauffolge.

Zugreifen auf das Dashboard

  1. Öffnen Sie das Dashboard für Ihren lokalen DTS-Emulator in http://localhost:8082 Ihrem Webbrowser.

  2. Wählen Sie den Standardmäßigen Aufgabenhub aus der Liste aus, um die Details anzuzeigen.

  3. Wählen Sie das Zahnradsymbol in der oberen rechten Ecke aus, um die Einstellungen zu öffnen, und stellen Sie sicher, dass die Option „Seiten für Agenten aktivieren“ unter „Vorschaufeatures“ ausgewählt ist.

Agentengespräche erkunden

  1. Navigieren Sie im Dashboard zur Registerkarte "Agents ".

  2. Wählen Sie Ihren dauerhaften Agent-Thread (z. B. mydurableagent - 263fa373-fa01-4705-abf2-5a114c2bb87d) aus der Liste aus.

    Sie sehen eine detaillierte Ansicht des Agentthreads, einschließlich des vollständigen Unterhaltungsverlaufs mit allen Nachrichten und Antworten.

    Screenshot des Dashboards

Das Dashboard bietet eine Zeitachsenansicht, mit der Sie den Fluss der Unterhaltung verstehen können. Zu den wichtigsten Informationen gehören:

  • Zeitstempel und Dauer für jede Interaktion
  • Eingabe- und Antwortinhalte
  • Anzahl der verwendeten Token

Tip

Das DTS-Dashboard bietet Echtzeitupdates, sodass Sie das Verhalten Ihres Agents während der Interaktion mit dem Agent über die HTTP-Endpunkte beobachten können.

In Azure bereitstellen

Nachdem Sie Ihren dauerhaften Agent lokal getestet haben, stellen Sie ihn in Azure bereit.

  1. Bereitstellen der Anwendung:

    azd deploy
    

    Dieser Befehl verpackt Ihre Anwendung und stellt sie in der Azure Functions-App bereit, die während der Bereitstellung erstellt wurde.

  2. Warten Sie, bis die Bereitstellung abgeschlossen ist. Die Ausgabe bestätigt, ob Ihr Agent in Azure läuft.

Testen des bereitgestellten Agents

Testen Sie nach der Bereitstellung Ihren Agent, der in Azure ausgeführt wird.

Holen Sie die Funktionstaste

Azure Functions erfordert einen API-Schlüssel für HTTP-ausgelöste Funktionen in der Produktion:

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`

Starten einer neuen Unterhaltung in Azure

Erstellen Sie einen neuen Thread, und senden Sie Ihre erste Nachricht an den bereitgestellten 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?"

Beachten Sie die Thread-ID, die im x-ms-thread-id Antwortheader zurückgegeben wird.

Fortsetzen der Unterhaltung in Azure

Senden Sie eine Nachverfolgungsnachricht im selben Thread. Ersetzen Sie <thread-id> durch die Thread-ID aus der vorherigen Antwort:

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?"

Der Agent verwaltet den Unterhaltungskontext in Azure genauso wie lokal, was die Haltbarkeit des Agentstatus veranschaulicht.

Überwachen des bereitgestellten Agents

Sie können Ihren bereitgestellten Agent über das Dashboard "Durable Task Scheduler" in Azure überwachen.

  1. Rufen Sie den Namen Ihrer Permanent Task Scheduler-Instanz ab:

    azd env get-value DTS_NAME
    
  2. Öffnen Sie das Azure-Portal , und suchen Sie im vorherigen Schritt nach dem Namen des dauerhaften Vorgangsplaners.

  3. Wählen Sie im Übersichtsblatt der Ressource "Durable Task Scheduler" den Standardmäßigen Aufgabenhub aus der Liste aus.

  4. Wählen Sie oben auf der Aufgabenhubseite " Dashboard öffnen" aus, um das Überwachungsdashboard zu öffnen.

  5. Betrachten Sie die Unterhaltungen Ihres Agents genau wie mit dem lokalen Emulator.

Das von Azure gehostete Dashboard bietet die gleichen Debugging- und Überwachungsfunktionen wie der lokale Emulator, sodass Sie den Gesprächsverlauf betrachten, Aufrufe von Ablaufverfolgungstools einsehen und die Leistung in Ihrer Produktionsumgebung analysieren zu können.

Lernprogramm: Orchestrieren dauerhafter Agenten mit Azure Functions

In diesem Lernprogramm erfahren Sie, wie Sie mehrere dauerhafte KI-Agents mithilfe des Azure Functions Hostingmodells und des Fan-Out-/Fan-In-Musters koordinieren. Sie erweitern den dauerhaften Agent aus dem vorherigen Lernprogramm , um ein Multi-Agent-System zu erstellen, das die Frage eines Benutzers verarbeitet, und übersetzt dann die Antwort gleichzeitig in mehrere Sprachen. Beispiele für selbst gehostete Orchestrierung finden Sie in den Beispielen.

Grundlegendes zum Orchestrierungsmuster

Die Orchestrierung, die Sie erstellen, folgt diesem Fluss:

  1. Benutzereingabe – Eine Frage oder Nachricht des Benutzers
  2. Hauptagent - Der MyDurableAgent aus dem ersten Tutorial verarbeitet die Frage
  3. Fan-out – Die Antwort des Hauptagenten wird parallel an beide Übersetzungsagenten gesendet.
  4. Übersetzungsmitarbeiter - Zwei spezialisierte Agenten übersetzen die Antwort (Französisch und Spanisch)
  5. Fan-In - Ergebnisse werden in einer einzigen JSON-Antwort mit der ursprünglichen Antwort und Übersetzungen aggregiert.

Dieses Muster ermöglicht die gleichzeitige Verarbeitung, wodurch die Gesamtantwortzeit im Vergleich zur sequenziellen Übersetzung reduziert wird.

Agents beim Start registrieren

Um Agents ordnungsgemäß in dauerhaften Orchestrierungen zu verwenden, registrieren Sie sie beim Starten der Anwendung. Sie können für alle Orchestrierungsausführungen verwendet werden.

Aktualisieren Sie Ihre Program.cs, um die Übersetzungsagenten zusammen mit den vorhandenen MyDurableAgent zu registrieren.

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();

Aktualisieren Sie Ihre function_app.py, um die Übersetzungsagenten zusammen mit den vorhandenen MyDurableAgent zu registrieren.

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])

Erstellen einer Orchestrierungsfunktion

Eine Orchestrierungsfunktion koordiniert den Workflow über mehrere Agents hinweg. Sie ruft registrierte Agenten aus dem dauerhaften Kontext ab und koordiniert deren Ausführung, wobei sie zuerst den Hauptagenten aufruft und dann parallel Übersetzungsagenten aktiviert.

Erstellen Sie eine neue Datei mit dem Namen AgentOrchestration.cs in Ihrem Projektverzeichnis:

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;
    }
}

Fügen Sie die Orchestrierungsfunktion Ihrer function_app.py Datei hinzu.

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

Testen Sie die Orchestrierung

Stellen Sie sicher, dass Ihre lokalen Entwicklungsabhängigkeiten aus dem ersten Tutorial weiterhin ausgeführt werden:

  • Azurite in einem Terminalfenster
  • Emulator für dauerhafte Aufgabenplanung in einem anderen Terminalfenster

Während Ihre lokalen Entwicklungsabhängigkeiten laufen:

  1. Starten Sie Ihre Azure Functions-App in einem neuen Terminalfenster:

    func start
    
  2. Die Erweiterung "Durable Functions" erstellt automatisch integrierte HTTP-Endpunkte für die Verwaltung von Orchestrierungen. Starten Sie die Orchestrierung mithilfe der integrierten 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. Die Antwort enthält URLs zum Verwalten der Orchestrierungsinstanz:

    {
      "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. Abfragen des Orchestrierungsstatus mithilfe des statusQueryGetUri (Ersetzen abc123def456 durch Ihre tatsächliche Instanz-ID):

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

  1. Abfragen des Statusendpunkts, bis runtimeStatusCompleted ist. Nach Abschluss sehen Sie die Orchestrierungsausgabe mit der Antwort des Hauptagenten und deren Übersetzungen.

    {
      "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..."
      }
    }
    

Überwachen Sie die Orchestrierung im Dashboard

Das Dashboard "Durable Task Scheduler" bietet Einblicke in Ihre Orchestrierung:

  1. Öffnen Sie http://localhost:8082 in Ihrem Browser.

  2. Wählen Sie den Aufgabenhub "Standard" aus.

  3. Wählen Sie die Registerkarte "Orchestrationen" aus.

  4. Finden Sie Ihre Orchestrierungsinstanz in der Liste.

  5. Wählen Sie die Instanz aus, die angezeigt werden soll:

    • Die Zeitachse der Orchestrierung
    • Haupt-Agent-Ausführung gefolgt von gleichzeitigen Übersetzungs-Agents
    • Jede Agentenausführung (MyDurableAgent, dann Französisch- und Spanischübersetzer)
    • Fan-Out- und Fan-In-Muster visualisiert
    • Zeitplanung und Dauer für jeden Schritt

Bereitstellen der Orchestrierung in Azure

Bereitstellen der aktualisierten Anwendung mithilfe der Azure Developer CLI:

azd deploy

Dadurch wird Ihr aktualisierter Code mit der neuen Orchestrierungsfunktion und zusätzlichen Agenten für die Azure Functions-App bereitgestellt, die im ersten Tutorial erstellt wurde.

Testen der bereitgestellten Orchestrierung

Testen Sie nach der Bereitstellung Ihre Orchestrierung, die in Azure ausgeführt wird.

  1. Rufen Sie den Systemschlüssel für die dauerhafte Erweiterung ab:

    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. Starten Sie die Orchestrierung mithilfe der integrierten 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. Verwenden Sie die statusQueryGetUri Antwort aus der Antwort, um die Fertigstellung abzufragen und die Ergebnisse mit Übersetzungen anzuzeigen.

Nächste Schritte

Zusätzliche Ressourcen: