Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
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
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
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:
- .NET 9.0 SDK oder höher
- Azure Functions Core Tools v4.x
- Azure Developer CLI (azd)
- Azure CLI installiert und authentifiziert
- Docker Desktop installiert und ausgeführt (für die lokale Entwicklung mit Azurite und dem Emulator "Durable Task Scheduler")
- Ein Azure-Abonnement mit Berechtigungen zum Erstellen von Ressourcen
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.
- Python 3.10 oder höher
- Azure Functions Core Tools v4.x
- Azure Developer CLI (azd)
- Azure CLI installiert und authentifiziert
- Docker Desktop installiert und ausgeführt (für die lokale Entwicklung mit Azurite und dem Emulator "Durable Task Scheduler")
- Ein Azure-Abonnement mit Berechtigungen zum Erstellen von Ressourcen
Herunterladen des Schnellstartprojekts
Verwenden Sie Azure Developer CLI, um ein neues Projekt aus der Schnellstartvorlage für dauerhafte Agenten zu initialisieren.
Erstellen Sie ein neues Verzeichnis für Ihr Projekt, und navigieren Sie zu diesem Verzeichnis:
mkdir MyDurableAgent cd MyDurableAgent
Initialisieren Sie das Projekt aus der Vorlage:
azd init --template durable-agents-quickstart-dotnetWenn 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.
Erstellen Sie ein neues Verzeichnis für Ihr Projekt, und navigieren Sie zu diesem Verzeichnis:
mkdir MyDurableAgent cd MyDurableAgent
Initialisieren Sie das Projekt aus der Vorlage:
azd init --template durable-agents-quickstart-pythonWenn Sie zur Eingabe eines Umgebungsnamens aufgefordert werden, geben Sie einen Namen wie
my-durable-agent.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.
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.
Bereitstellen der Infrastruktur:
azd provisionMit 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
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:
- 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.
Ö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.
Kopieren Sie die Beispieleinstellungsdatei:
cp local.settings.sample.json local.settings.json
Rufen Sie Ihren Azure OpenAI-Endpunkt aus den bereitgestellten Ressourcen ab:
azd env get-value AZURE_OPENAI_ENDPOINTÖffnen Sie
local.settings.jsonund 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.
Öffnen Sie ein neues Terminalfenster, und ziehen Sie das Azurite Docker-Image:
docker pull mcr.microsoft.com/azure-storage/azuriteStarten Sie Azurite in einem Terminalfenster:
docker run -p 10000:10000 -p 10001:10001 -p 10002:10002 mcr.microsoft.com/azure-storage/azuriteAzurite 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.
Öffnen Sie ein weiteres neues Terminalfenster, und ziehen Sie das Docker-Image des DTS-Emulators:
docker pull mcr.microsoft.com/dts/dts-emulator:latestFühren Sie den DTS-Emulator aus:
docker run -p 8080:8080 -p 8082:8082 mcr.microsoft.com/dts/dts-emulator:latestDieser 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
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.
Navigieren Sie in einem neuen Terminalfenster (wobei sowohl Azurite als auch der DTS-Emulator in separaten Fenstern ausgeführt wird), zu Ihrem Projektverzeichnis.
Starten Sie die Azure Functions-Laufzeit:
func startEs 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
Öffnen Sie das Dashboard für Ihren lokalen DTS-Emulator in
http://localhost:8082Ihrem Webbrowser.Wählen Sie den Standardmäßigen Aufgabenhub aus der Liste aus, um die Details anzuzeigen.
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
Navigieren Sie im Dashboard zur Registerkarte "Agents ".
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.
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.
Bereitstellen der Anwendung:
azd deployDieser Befehl verpackt Ihre Anwendung und stellt sie in der Azure Functions-App bereit, die während der Bereitstellung erstellt wurde.
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.
Rufen Sie den Namen Ihrer Permanent Task Scheduler-Instanz ab:
azd env get-value DTS_NAMEÖffnen Sie das Azure-Portal , und suchen Sie im vorherigen Schritt nach dem Namen des dauerhaften Vorgangsplaners.
Wählen Sie im Übersichtsblatt der Ressource "Durable Task Scheduler" den Standardmäßigen Aufgabenhub aus der Liste aus.
Wählen Sie oben auf der Aufgabenhubseite " Dashboard öffnen" aus, um das Überwachungsdashboard zu öffnen.
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:
- Benutzereingabe – Eine Frage oder Nachricht des Benutzers
-
Hauptagent - Der
MyDurableAgentaus dem ersten Tutorial verarbeitet die Frage - Fan-out – Die Antwort des Hauptagenten wird parallel an beide Übersetzungsagenten gesendet.
- Übersetzungsmitarbeiter - Zwei spezialisierte Agenten übersetzen die Antwort (Französisch und Spanisch)
- 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:
Starten Sie Ihre Azure Functions-App in einem neuen Terminalfenster:
func startDie 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?\""'
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" }Abfragen des Orchestrierungsstatus mithilfe des
statusQueryGetUri(Ersetzenabc123def456durch Ihre tatsächliche Instanz-ID):curl http://localhost:7071/runtime/webhooks/durabletask/instances/abc123def456
Abfragen des Statusendpunkts, bis
runtimeStatusCompletedist. 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:
Öffnen Sie
http://localhost:8082in Ihrem Browser.Wählen Sie den Aufgabenhub "Standard" aus.
Wählen Sie die Registerkarte "Orchestrationen" aus.
Finden Sie Ihre Orchestrierungsinstanz in der Liste.
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.
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)
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?\""'
- Verwenden Sie die
statusQueryGetUriAntwort aus der Antwort, um die Fertigstellung abzufragen und die Ergebnisse mit Übersetzungen anzuzeigen.
Nächste Schritte
Zusätzliche Ressourcen: