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.
Hinweis
In diesem Handbuch werden C#- und Python Durable Extension Hosting behandelt. Informationen zum Go-Hosting finden Sie unter A2A-Hosting und das Agent Framework Go-Repository.
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
- Fortsetzen der streamten Übermittlung , wenn sie mit einem Streambroker konfiguriert ist, z. B. Redis; dauerhafte Fertigstellung separat bestätigen
- 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.
- Echtzeitantworten: Bereitstellen der inkrementellen Tokenausgabe mit brokerbasierter erneuter Verbindung, während das dauerhafte Ergebnis separat überprüft wird
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
Verwenden Sie die Installationsbefehle für Ihr Hostingmodell unten. Lassen Sie die Vorabversionsoptionen für Vorschaupakete angezeigt. Vollständige Anwendungen finden Sie in der Quelle und in den Beispielen.
Die Quellverzweigungsdokumentation kann Funktionen beschreiben, die noch nicht in veröffentlichten Paketen verfügbar sind. Wenden Sie Konfigurations- und Migrationsschritte nur für Features an, die in Ihrer installierten Version enthalten sind.
Important
Bevor Sie eine vorhandene Bereitstellung aktualisieren, überprüfen Sie die Bereitstellungs- und Schemamigration. Verweisen Sie nicht auf einen aktualisierten Worker auf alte Workflowhistorien, ohne die Kompatibilität der Wiedergabe zu überprüfen.
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 Microsoft.Agents.AI.Foundry --prerelease
dotnet add package Microsoft.Agents.AI.Hosting.AzureFunctions --prerelease
Hinweis
Verwenden Sie die Funktions-Worker-, DurableTask-Workererweiterungs- und AzureManaged-Workererweiterungsversionen, die von den Abhängigkeiten der Agenterweiterung deklariert wurden. Entfernen Sie direkte Paketverweise, die diese Abhängigkeiten herabstufen. Siehe die .NET Abhängigkeitsverweise. Parallele Schema-v2-Upgrades erfordern auch eine Arbeitsaufgabenfilterung; siehe Bereitstellungs- und Schemamigration.
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.Foundry --prerelease
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. Python Hosts erfordern eine explizite Bereitstellungsstrategie.
Verwenden Sie für Azure Functions Hosting Python 3.13 oder höher, und installieren Sie das Azure Functions Integrationspaket. Die folgenden Befehle installieren auch den in diesem Handbuch verwendeten Azure OpenAI-Client.
pip install agent-framework-azurefunctions agent-framework-openai azure-identity --pre
Verwenden Sie Python 3.10 oder höher, und installieren Sie das Integrationspaket "Durable Task", um Ihr eigenes Computehosting mitzubringen.
pip install agent-framework-durabletask agent-framework-openai azure-identity --pre
Legen Sie für einen neuen isolierten Aufgabenhub mit aktualisierten Workern und Clients fest DURABLE_AGENTS_DEPLOYMENT_MODE=isolated_v2 , bevor Sie einen der Hosts starten. Wählen Sie für einen vorhandenen Hub die Migrationsstrategie aus, anstatt diese Einstellung blind anzuwenden. Die Einstellung erkennt die Isolation an; es erkennt keine anderen Arbeiter oder macht alte Historien kompatibel.
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_azurefunctions 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_DEPLOYMENT", "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_durabletask 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.
Hinweis
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. Python unterstützt auch graphbasierte Workflows für einen eigenständigen Durable Task Worker.
Weitere Informationen finden Sie in den Beispielen Python Azure Functions für dauerhafte Agent, Orchestrierung, MCP-Server und Workflowbeispiele.
Eine selbst gehostete Graphausführung finden Sie im eigenständigen Python Workflowbeispiel.
Samples
| Sprache | Hostingmodell | Dauerhafte Agenten und Orchestrierungen | Graphbasierte Workflows |
|---|---|---|---|
| C# | Azure Functions | .NET Agentbeispiele | .NET Workflowbeispiele |
| C# | Selbstgehostet | Beispiele für .NET Konsolen-Agent | .NET Konsolenworkflowbeispiele |
| Python | Azure Functions | Beispiele für Python-Funktionen | Workflowbeispiele für Python Funktionen |
| Python | Selbstgehostet | Beispiele für Python Worker und Client | Python eigenständiger Workflow |
Diese Beispiele veranschaulichen die Unterstützung, nicht identische API-Verträge in allen Sprachen. Funktionen generieren HTTP-Endpunkte; Selbst gehostete Anwendungen implementieren und sichern ihre eigenen APIs.
Statusbehaftete Agent-Threads mit Unterhaltungsverlauf
Agents verwalten persistente Sitzungen, die über mehrere Interaktionen hinweg bestehen. Jede Sitzung verfügt über eine eindeutige Sitzungs-ID und speichert den Unterhaltungszustand im dauerhaften Speicher, der von der Infrastruktur für dauerhafte Aufgaben verwaltet wird, z. B. den Durable Task Scheduler.
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.
Konfigurieren Sie die Sitzungsbereinigung, die Verlaufsaufbewahrung und die Ergebnisaufbewahrung absichtlich. Diese Richtlinien haben unterschiedliche Auswirkungen; siehe Statuslebenszyklus und Kapazität.
Im folgenden Azure Functions Beispiel werden mehrere HTTP-Anforderungen für dieselbe Sitzung veranschaulicht. Beide Sprachintegrationen geben den kanonischen sessionId Abfrageparameter zurück x-ms-session-id und akzeptieren sie. Behandeln Sie die zurückgegebene ID als undurchsichtig: Das Beispiel zeigt eine .NET Schema-v2-Entitätsadresse, während Python Sitzungsformatierung von der Bereitstellungsstrategie abhängt. Verwenden Sie in selbst gehosteten Apps die Client-APIs für dauerhafte Aufgaben aus Ihrem eigenen Prozess oder Dienst.
# First interaction - start a new session
curl -i -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 session ID in x-ms-session-id header and joke as plain text
# HTTP/1.1 200 OK
# Content-Type: text/plain
# x-ms-session-id: @dafx-v2-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 - reuse the exact session ID returned by the first request
curl -X POST "https://your-function-app.azurewebsites.net/api/agents/Joker/run?sessionId=@dafx-v2-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.
Verwenden sessionId und waitForResponse in neuen Agent-HTTP-Clients.
thread_id ist ein veralteter Anforderungsalias, nicht der Antwortheader, der erfasst werden soll. Für Python JSON-Antworten lesen und correlationId.sessionId Siehe den Leitfaden zur HTTP-API-Migration für Aliase und Konfliktbehandlung.
Dauerhafte Fertigstellung bestätigen
Für generierte .NET Funktionen-Agent-Endpunkte interpretieren Sie den Abschluss wie folgt:
| HTTP-Status | Bedeutung |
|---|---|
202 Accepted |
Versand wird akzeptiert. Die Ausführung wird nicht bestätigt. |
200 OK |
Ein zugesichertes erfolgreiches Ergebnis ist verfügbar. |
500 Internal Server Error |
Es wird ein unterstützter Commit-Terminalfehler zurückgegeben. Unterscheiden Sie dies von gewöhnlichen Host- oder Transportfehlern. |
410 Gone |
Der Abschluss ist bekannt, aber das Ergebnis ist nicht verfügbar. Das beibehaltene Ergebnis kann oder failed; succeeded dies ist nicht notwendigerweise eine fehlgeschlagene Ausführung oder nur ein Ablauf des Ergebnisses. |
Lesen x-ms-durable-outcome , wenn ein Abschluss kein verfügbares Ergebnis hat. Behandeln 410 Sie das Ergebnis nicht als ausstehend, leitet Sie ein Ergebnis aus dem Unterhaltungsverlauf ab oder übermitteln Sie sie automatisch erneut mit einer neuen Identität. JSON-Aufrufer verwenden Zeichenfolge status und numerisch statusCode; das frühere status_code Feld ist ein temporärer Kompatibilitätsalias.
Python Funktionen unterscheiden auch den verfügbaren Erfolg, beibehaltene fehlgeschlagene Ergebnisse und nicht verfügbare abgeschlossene Ergebnisse. Die Fehlerumschläge und SDK-Optionen sind nicht mit .NET identisch. Siehe .NET Abschlussvertrag und Python HTTP-Vertrag.
Diese Status beschreiben Agentendpunkte. Die Durable Functions Orchestrierungsverwaltungs-API verfügt über einen eigenen Statusantwort- und Abrufvertrag.
Zuverlässiges Streaming
Die durable Extension unterstützt zuverlässiges Streaming für Anwendungen, die die Bereitstellung von Echtzeittoken zusammen mit der dauerhaften Agentausführung benötigen. Streaming kann mit der Kernerweiterung in beiden Hostingmodellen verwendet werden, verteilte Hosts benötigen jedoch einen zuverlässigen Streambroker, z. B. Redis, sodass Clients das Lesen beibehaltener Tokenstreams nach erneuten Verbindungs- oder Workeränderungen fortsetzen können, vorbehaltlich der Persistenz- und Aufbewahrungseinstellungen des Brokers.
Verwenden Sie zuverlässiges Streaming, wenn die Benutzererfahrung von inkrementellen Antworten abhängt, aber die Workload benötigt weiterhin dauerhafte Ausführungsemantik. Der Datenstromabschluss bestätigt nicht allein, dass das Ergebnis und der Zustand des Agenten dauerhaft beibehalten wurden; überprüfen Sie das autoritative dauerhafte Ergebnis separat. 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.
Die dauerhafte Prüfpunkterstellung macht keine Tools oder externe Schreibvorgänge für Transaktionen oder genau einmal. Machen Sie Aktivitäts- und Tool-Nebenwirkungen idempotent, und definieren Sie Wiederholungsgrenzen. Ein Fehler nach einem externen Schreibvorgang, aber vor einem dauerhaften Commit kann dazu führen, dass der Vorgang erneut ausgeführt wird.
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.
from durabletask.task import OrchestrationContext
from agent_framework_azurefunctions 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: OrchestrationContext, email: dict):
# 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,
options={"response_format": SpamDetectionResult},
)
spam_result = SpamDetectionResult.model_validate(spam_result_raw.value)
if spam_result.is_spam:
result = yield context.call_activity("handle_spam_email", input=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,
options={"response_format": EmailResponse},
)
email_response = EmailResponse.model_validate(email_response_raw.value)
result = yield context.call_activity("send_email", input=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;
}
from durabletask.task import OrchestrationContext, when_all
from agent_framework_azurefunctions import AgentFunctionApp
app = AgentFunctionApp(agents=[technical_agent, market_agent, competitor_agent, summary_agent])
@app.orchestration_trigger(context_name="context")
def research_orchestration(context: OrchestrationContext, topic: str):
# 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 when_all([technical_task, market_task, competitor_task])
# Aggregate results
all_research = "\n\n".join(r.text 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.text
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";
}
from durabletask.task import OrchestrationContext, when_any
from datetime import timedelta
from agent_framework_azurefunctions import AgentFunctionApp
app = AgentFunctionApp(agents=[content_agent])
@app.orchestration_trigger(context_name="context")
def content_approval_workflow(context: OrchestrationContext, topic: str):
# 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", input=draft_content.text)
# 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 when_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", input=draft_content.text)
return result
return "Content rejected"
# Timeout occurred - escalate for review
result = yield context.call_activity("escalate_for_review", input=draft_content.text)
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.
Bereitstellungs- und Schemamigration
Der Status des Schema-v2-Agents ändert sowohl persistente Status- als auch Verteileridentitäten. Planen Sie die Koexistenz des Arbeitsarbeiters getrennt von der Zustandskonvertierung.
Neue Sitzungen verwenden den Entitätsnamespace dafx-v2- . Verlassen Sie während eines zweistufigen Rollouts deaktiviert, ProcessLegacyEntities während v1-Mitarbeiter aktiv bleiben. Beenden Sie alle v1-Mitarbeiter, bevor ProcessLegacyEntities Sie berechtigt sind, ältere Entitäten zu verarbeiten und zu aktualisieren.
Eigenständige Mitarbeiter registrieren Arbeitsaufgabenfilter. Parallele Funktionenbereitstellungen erfordern außerdem kompatible Functions Worker-, DurableTask-Workererweiterungs- und AzureManaged-Workererweiterungspakete, die hostseitige Filterung auf jedem teilnehmenden Host sowie workItemFilteringEnabled in der Konfiguration des Planerspeicheranbieters unterstützen. Verwenden Sie ohne kompatible Filterung eine Offline-Übernahme anstelle gleichzeitiger v1- und v2-Hosts auf einem Hub. Folgen Sie der .NET Upgradeanleitung für die vollständige Konfiguration.
Wählen Sie eine explizite Strategie aus, bevor Sie einen Host erstellen:
-
two_phase: Verwenden Sie den permanenten Aufgabenplaner mit kompatibler Back-End-Arbeitselementfilterung. Neue versionsierte Namen isolieren den Versand, während berechtigte Legacyentitäten auf den alten Mitarbeitern verbleiben. Beenden Sie alte Mitarbeiter, bevor Sie die Verarbeitung von Historischen Namen und direkte Entitätsupgrades aktivieren. Warten Sie kompatible gefilterte Mitarbeiter während der Koexistenz; Namensfilter sind keine permanenten Reservierungen, wenn diese Flotte getrennt wird. -
isolated_v2: Verwenden Sie einen isolierten Aufgabenhub mit übereinstimmenden aktualisierten Mitarbeitern und Clients. Die Einstellung erkennt die Isolation an, untersucht aber nicht für andere Mitarbeiter. Verwenden Sie frische Workflowinstanzen.
Ein neuer Hub ist keine bedingungslose Anforderung für den Zwei-Phasen-Entitätsmigrationspfad. Siehe Python Entitätsmigration für hostspezifische Setups und Voraussetzungen.
Warning
Die Entitätsmigration repariert die Kompatibilität der Workflowwiedergabe nicht. Betroffene ältere Workflowhistorien, einschließlich älterer v2-Historien, werden von der aktualisierten Laufzeit nicht unterstützt. Wenn sie fertig sein müssen, halten Sie sie auf ihren ursprünglichen Mitarbeitern und hub. Neue Instanzen nach dem Upgrade starten; verlassen Sie sich nicht allein auf die Workflowversionsmarkierung, um die Kompatibilität zu beweisen. Siehe Python Laufzeitkompatibilität.
Statuslebenszyklus und Kapazität
Wählen Sie Richtlinien für jede Ebene unabhängig aus:
| Ebene | Was sie steuert |
|---|---|
| Sitzungs-TTL | Löscht die gesamte Entität, einschließlich Unterhaltungsstatus und Abschlussbestätigungen. |
| Aufbewahrung des dauerhaften Verlaufs | Entfernt berechtigte gespeicherte Transkriptinhalte; Der geschützte Zustand kann weiterhin die Kapazität überschreiten. |
| Modelleingabekomprimierung | Änderungen des Kontexts, der an das Modell gesendet wird; es schneidet nicht unbedingt dauerhafte Geschichte. |
| Ergebnisaufbewahrung | Steuert die Verfügbarkeit der Antwortnutzlast unabhängig vom beibehaltenen Abschlussergebnis. |
| Blob-Nutzlastlebenszyklus | Steuert sdk-offloaded payload blobs; Der Sitzungslöschvorgang oder die Orchestrierungsbereinigung bereinigt sie nicht. |
In .NET Schema-v2-Beleglagerzustand löscht die nicht konfigurierte 14-Tage-TTL die Entität nicht automatisch. Konfigurieren Sie eine globale oder agentspezifische TTL explizit, wenn Sie eine Bereinigung der Leerlaufsitzung wünschen. Übergeben timeToLive: null , um die konfigurierte globale Standardeinstellung zu AddAIAgent erben; sie überschreibt keine siebentägige globale Standardeinstellung mit "läuft nie ab.". Legen Sie fest DefaultTimeToLive = null , dass die globale TTL für Agents ohne positive Außerkraftsetzungen pro Agent deaktiviert wird.
.NET Standardwert ist DurableAgentHistoryRetentionMode.KeepAll; Auto ermöglicht die druckbasierte Transkriptaufbewahrung.
ResultRetentionPeriod Ist standardmäßig auf 60 Sekunden festgelegt und unterscheidet sich von der Sitzungs-TTL. Python verfügt über unterschiedliche Aufbewahrungs- und Budgetoptionen, einschließlich retention="keep_all" standardmäßig. Gehen Sie nicht von den gleichen Optionen oder Standardwerten auf hosts aus.
Python unterstützt das offloading optional vom SDK verwaltete BLOB-Nutzlast in beiden Hostingmodellen. Konfigurieren Sie sowohl Produzenten- als auch Consumerspeicher, Anmeldeinformationen und Blob-Lebenszyklus. Das Ausladen entfernt keine Kapazitätsbeschränkungen für ganze Entitäten oder ersetzt die Aufbewahrung; Blobs beibehalten, während auf den Zustand verwiesen wird oder der Verlauf der Wiedergabe benötigt wird. Weitere Informationen finden Sie unter .NET Status und Aufbewahrung, Python Aufbewahrungs- und Budgets sowie Python Funktionen blob offloading.
Informationen zu Planungsinfrastruktur, Kapazität und betriebsbereiten Anleitungen finden Sie unter "Durable Task integration for Agent Framework".
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.
Prerequisites
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
Hinweis
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.13 oder höher für Funktionenhosting. Das Python 3.10-Minimum des eigenständigen Pakets gilt nicht für dieses Lernprogramm.
- uv zum Erstellen der virtuellen Umgebung und zum Installieren von Abhängigkeiten
- 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
Legen Sie DURABLE_AGENTS_DEPLOYMENT_MODE=isolated_v2 erst nach der Bestätigung fest, dass der Lernprogrammhub isoliert ist, und alle Mitarbeiter und Clients verwenden die aktualisierte Laufzeit.
Verwenden Sie einen neuen Aufgabenhub für dieses Lernprogramm, getrennt von vorhandenen dauerhaften Anwendungen. Folgen Sie für eine vorhandene Anwendung stattdessen der Bereitstellungs- und Schemamigration .
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 --python 3.13 .venv source .venv/bin/activate
Hinweis
Sie können auch mit einem installierten Python 3.13-Dolmetscher verwendenpython -m venv .venv. Wenn dieser Befehl auf Windows hängt, verwenden Sie stattdessen den uv venv obigen Befehl. Überprüfen Sie den aktiven Interpreter vor python --version der Installation von Paketen.
Installieren Sie die erforderlichen Pakete:
Aktualisieren Sie die Vorlagen
requirements.txtin den Paketen "Funktionen" in " Erste Schritte", einschließlich desagent-framework-openaiClientpakets, vor der Installation. Lösen Sie widersprüchliche Abhängigkeits-Pins im Manifest, anstatt die Installation zu erzwingen.uv 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_azurefunctions 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_DEPLOYMENT", "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 ...
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"AZURE_OPENAI_ENDPOINT": "https://your-openai-resource.openai.azure.com",
"AZURE_OPENAI_DEPLOYMENT": "gpt-4o-mini",
"DURABLE_TASK_SCHEDULER_CONNECTION_STRING": "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None",
"TASKHUB_NAME": "default"
}
}
Hinweis
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.
Fügen Sie "DURABLE_AGENTS_DEPLOYMENT_MODE": "isolated_v2" für Python nur hinzuValues, nachdem bestätigt wurde, dass der Lernprogrammhub isoliert ist. Konfigurieren Sie bei der Bereitstellung die entsprechende Anwendungseinstellung; Lokale Einstellungen werden nicht automatisch hochgeladen.
Verwenden Sie für scheduler-gesichertes Hosting denselben Aufgabenhub in host.json (through %TASKHUB_NAME%), TASKHUB_NAME, DURABLE_TASK_SCHEDULER_CONNECTION_STRINGdem Emulator und dem Dashboard. In diesem Lernprogramm wird verwendet default, das der Emulator automatisch erstellt. Wenn dieser Hub bereits alte Historien enthält oder von anderen Mitarbeitern verwendet wird, wählen Sie einen eindeutigen, nicht verwendeten Hubnamen aus, legen Sie den Emulator DTS_TASK_HUB_NAMES auf diesen Namen fest, und aktualisieren Sie die Anwendungseinstellungen und die Dashboardauswahl konsistent. Das Definieren eines Schedulers Verbindungszeichenfolge wählt nicht den Planerspeicheranbieter aus.
host.jsonKonfigurieren Sie in , konfigurieren Sie den Planeranbieter unter extensions.durableTask, wobei die anderen Hosteinstellungen der Vorlage beibehalten werden:
{
"extensions": {
"durableTask": {
"hubName": "%TASKHUB_NAME%",
"storageProvider": {
"type": "AzureManaged",
"connectionStringName": "DURABLE_TASK_SCHEDULER_CONNECTION_STRING"
}
}
}
}
Verwenden Sie die Abhängigkeiten des Zeitplananbieters für Ihre Hostingsprache. Diese Konfiguration wählt das Back-End für eine neue isolierte Lernprogrammbereitstellung aus. es aktiviert nicht die für ein paralleles Upgrade erforderliche Filterung.
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
Bei diesen Schritten wird davon ausgegangen, dass der Funktionshost den Speicheranbieter "Durable Task Scheduler" verwendet. Die Python Functions-Beispiele der Version werden standardmäßig auf Azure Storage festgelegt. Wenn Sie mit diesen Beispielen beginnen, wählen Sie den Planeranbieter aus, und konfigurieren Sie es, bevor Sie das DTS-Dashboard verwenden. andernfalls hält Azurite den dauerhaften Zustand und das Planerdashboard bleibt leer. Weitere Informationen finden Sie unter "Setup des dauerhaften Vorgangsplaners".
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:latestMit diesem Befehl wird der
defaultAufgabenhub erstellt und der Emulator gestartet, der den Einstellungen dieses Lernprogramms entspricht. Der Befehl 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-v2-MyDurableAgent: entityTrigger
Dies veranschaulicht .NET Schema-v2-Registrierung; Python Triggernamen hängen von der Bereitstellungsstrategie ab. Diese Endpunkte verwalten den Unterhaltungszustand automatisch, sodass Sie keine Sitzungsobjekte selbst erstellen müssen.
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 eine neue Sitzung, 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 (der x-ms-session-id Header enthält die Sitzungs-ID; dieses Beispiel zeigt eine .NET Schema-v2-ID):
HTTP/1.1 200 OK
Content-Type: text/plain
x-ms-session-id: @dafx-v2-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 genaue Sitzungs-ID aus dem x-ms-session-id Header für die nächste Anforderung. Erstellen sie nicht, oder schreiben Sie sie neu. Python gibt auch diesen Header zurück, aber sein ID-Format kann unterschiedlich sein.
Fortsetzen der Unterhaltung
Senden Sie eine Nachverfolgungsnachricht an dieselbe Sitzung, indem Sie die zurückgegebene ID in den kanonischen sessionId Abfrageparameter einschließen:
Ersetzen Sie die Beispiel-ID durch den tatsächlichen Wert aus dem Header der vorherigen Antwort x-ms-session-id . URL-codiert den Wert bei Bedarf.
curl -X POST "http://localhost:7071/api/agents/MyDurableAgent/run?sessionId=@dafx-v2-mydurableagent@263fa373-fa01-4705-abf2-5a114c2bb87d" \
-H "Content-Type: text/plain" \
-d "Which one is best for beginners?"
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.
Auf das Dashboard zugreifen
Öffnen Sie das Dashboard für Ihren lokalen DTS-Emulator in
http://localhost:8082Ihrem Webbrowser.Wählen Sie den Standardnamen oder denselben eindeutigen Hubnamen aus, den Sie sowohl in Ihrer Anwendung als auch im Emulator konfiguriert haben, 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
Fügen Sie für die Standardautorisierung auf Funktionsebene der generierten Endpunkte einen Funktionsschlüssel in Anforderungen an Azure ein. Ein Funktionsschlüssel ist keine Anwendungsbenutzerautorisierung; siehe Produktionssicherheit und Problembehandlung.
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 eine neue Sitzung, 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?"
Speichern Sie die im Antwortheader zurückgegebene x-ms-session-id Sitzungs-ID.
Fortsetzen der Unterhaltung in Azure
Senden Einer Nachverfolgungsnachricht in derselben Sitzung. Verwenden Sie die genaue ID, die von der vorherigen Antwort zurückgegeben wird:
SESSION_ID="<session-id>"
curl -X POST "https://$(azd env get-value AZURE_FUNCTION_NAME).azurewebsites.net/api/agents/MyDurableAgent/run?code=$API_KEY" \
--url-query "sessionId=$SESSION_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 aufgabenhub aus, der für die bereitgestellte Anwendung konfiguriert ist.
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_azurefunctions 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_DEPLOYMENT", "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.
from durabletask.task import OrchestrationContext, when_all
@app.orchestration_trigger(context_name="context")
def agent_orchestration_workflow(context: OrchestrationContext, input_text: str):
"""
Orchestration function that coordinates multiple agents.
Returns a dictionary with the original response and translations.
"""
# 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 when_all(parallel_tasks)
# Step 4: Combine results into a dictionary
result = {
"original": agent_response,
"french": translations[0].text,
"spanish": translations[1].text
}
return result
Hinweis
In diesem Handbuch werden C#- und Python Durable Extension Hosting behandelt. Informationen zum Go-Hosting finden Sie unter A2A-Hosting und das Agent Framework Go-Repository.
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 aus, der für Ihre Anwendung konfiguriert ist.
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.
Produktionssicherheit und Problembehandlung
Behandeln Sie diese Zugriffsgrenzen separat:
- Anwendungsbenutzer: Authentifizieren Sie Anrufer, und autorisieren Sie den Zugriff auf jede Sitzung, jeden Workflow und die Reaktion auf die Genehmigung von Personen. Sitzungs-, Korrelations- und Anforderungs-IDs sind Bezeichner und keine Anmeldeinformationen.
- Funktionen-Endpunkte: Schlüssel auf Funktionsebene schützen generierte HTTP-Endpunkte, richten jedoch keine Anwendungsbenutzeridentität oder Sitzungsbesitz ein. Schützen und Drehen von Schlüsseln; machen Sie sie nicht im vom Browser bereitgestellten Anwendungscode verfügbar.
- Modellzugriff: Erteilen Sie der Workeridentität die erforderlichen Modellberechtigungen. Modellanmeldeinformationen gewähren keinen Zugriff auf den Zeitplan oder die Sitzung eines anderen Benutzers.
- Planerzugriff: Konfigurieren Sie Worker-, Client- und Dashboardberechtigungen für ihre vorgesehenen Rollen. Anleitungen zur Infrastruktur finden Sie unter "Durable Task integration".
| Symptom | Prüfen |
|---|---|
| Python Paketinstallation oder Funktionsstart schlägt fehl | Verwenden Sie Python 3.13 oder höher für Funktionen, installieren Sie die Funktionspakete in "Erste Schritte", und wählen Sie explizit eine Bereitstellungsstrategie aus. Das eigenständige Python Minimum unterscheidet sich. |
| Anforderungen erfolgreich, aber das DTS-Dashboard ist leer. | Vergewissern Sie sich, dass der Speicheranbieter AzureManagedfür Funktionen nicht AzureStorage, und dass der Zeitplanendpunkt und der Taskhub mit dem Dashboard übereinstimmen. |
| Eine Sitzung scheint den Kontext zu verlieren. | Verwenden Sie den exakt zurückgegebenen x-ms-session-id Wert mit sessionId; überprüfen Sie auf einen anderen Hub, bereitstellungsnamespace oder konfigurierte Sitzungsbereinigung. |
| Alte Workflows schlagen nach dem Upgrade fehl | Überprüfen Sie die Kompatibilität der Wiedergabe, bevor Sie verlaufsverlaufsausführungen fortsetzen. Die Entitätsmigration repariert keine inkompatiblen Workflowhistorien. |
| Ein Datenstrom wird beendet, aber der dauerhafte Abschluss fehlt. | Behandeln Sie die Datenstromausgabe als vorläufig, und überprüfen Sie das autoritative Ergebnis oder das beibehaltene Ergebnis. Eine Datenstromabschlussmarkierung ist keine dauerhafte Bestätigung des Commits. |
Ein abgeschlossener Vorgang gibt zurück. 410 |
Überprüfen Sie das beibehaltene Ergebnis und die Ergebnisverfügbarkeit. Gehen Sie nicht von einem Fehler aus, führen Sie die Abfrage so aus, als ob aussteht, oder senden Sie automatisch einen neuen Vorgang. |
| Schreibvorgänge im Entitätsstatus überschreiten die Kapazität. | Überprüfen Sie den Status der gesamten Entität, geschützte Datensätze, Aufbewahrungsrichtlinien und Nutzlastverweise. Die Modelleingabekomprimierung allein garantiert nicht, dass der gespeicherte Zustand passt. |
Nächste Schritte
Zusätzliche Ressourcen: