Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Trwałe rozszerzenie zadania dla programu Microsoft Agent Framework umożliwia tworzenie stanowych agentów sztucznej inteligencji i orkiestracji deterministycznych wielu agentów w środowisku bezserwerowym na platformie Azure.
Azure Functions to bezserwerowa usługa obliczeniowa, która umożliwia uruchamianie kodu na żądanie bez zarządzania infrastrukturą. Rozszerzenie trwałego zadania opiera się na tej podstawie, aby zapewnić trwałe zarządzanie stanem, co oznacza, że historia konwersacji i stan wykonywania agenta są niezawodnie utrwalane i przetrwać awarie, ponowne uruchomienia i długotrwałe operacje.
Przegląd
Agenci trwałe łączą możliwości platformy Agent Framework z usługą Azure Durable Functions, aby tworzyć agentów, którzy:
- Utrwalanie stanu automatycznie między wywołaniami funkcji
- Wznawianie po awariach bez utraty kontekstu konwersacji
- Automatyczne skalowanie na podstawie zapotrzebowania
- Organizowanie przepływów pracy z wieloma agentami przy użyciu niezawodnych gwarancji wykonania
Kiedy należy używać agentów trwałych
Wybierz agentów trwałych, gdy potrzebujesz:
- Pełna kontrola kodu: wdrażanie własnego środowiska obliczeniowego i zarządzanie nim przy zachowaniu korzyści bezserwerowych
- Złożone aranżacje: Koordynuj wielu agentów przy użyciu deterministycznych, niezawodnych przepływów pracy, które mogą być uruchamiane przez dni lub tygodnie
- Orkiestracja sterowana zdarzeniami: integracja z wyzwalaczami usługi Azure Functions (HTTP, czasomierzami, kolejkami itp.) i powiązaniami dla przepływów pracy agenta sterowanego zdarzeniami
- Stan konwersacji automatycznej: historia konwersacji agenta jest automatycznie zarządzana i utrwalana bez konieczności jawnej obsługi stanu w kodzie
Takie podejście do hostingu bezserwerowego różni się od hostingu agenta opartego na usłudze zarządzanej (na przykład usługi agenta usługi Azure AI Foundry), który zapewnia w pełni zarządzaną infrastrukturę bez konieczności wdrażania aplikacji usługi Azure Functions ani zarządzania nimi. Agenty trwałe są idealne, gdy wymagana jest elastyczność wdrażania opartego na kodzie w połączeniu z niezawodnością trwałego zarządzania stanem.
W przypadku hostowania w ramach planu hostingu Flex Consumption usługi Azure Functions agenci mogą skalować do tysięcy wystąpień lub do zera, gdy nie są używane, co pozwala płacić tylko za potrzebne zasoby obliczeniowe.
Wprowadzenie
W projekcie usługi Azure Functions platformy .NET dodaj wymagane pakiety NuGet.
dotnet add package Azure.AI.OpenAI --prerelease
dotnet add package Azure.Identity
dotnet add package Microsoft.Agents.AI.OpenAI --prerelease
dotnet add package Microsoft.Agents.AI.Hosting.AzureFunctions --prerelease
Uwaga / Notatka
Oprócz tych pakietów upewnij się, że projekt używa wersji 2.2.0 lub nowszej pakietu Microsoft.Azure.Functions.Worker .
W projekcie usługi Azure Functions w języku Python zainstaluj wymagane pakiety języka Python.
pip install azure-identity
pip install agent-framework-azurefunctions --pre
Hosting bezserwerowy
Rozszerzenie trwałych zadań umożliwia wdrażanie i hostowanie agentów korzystających z Microsoft Agent Framework w usłudze Azure Functions z użyciem wbudowanych punktów końcowych HTTP oraz wywołań opartych na orkiestracji. Usługa Azure Functions zapewnia oparte na zdarzeniach model cenowy z płatnością za użycie oraz automatyczne skalowanie i minimalne zarządzanie infrastrukturą.
Podczas konfigurowania trwałego agenta rozszerzenie trwałego zadania automatycznie tworzy punkty końcowe HTTP dla agenta i zarządza całą podstawową infrastrukturą do przechowywania stanu konwersacji, obsługi współbieżnych żądań i koordynowania przepływów pracy wielu agentów.
using System;
using Azure.AI.OpenAI;
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 AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredential())
.GetChatClient(deploymentName)
.AsAIAgent(
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();
import os
from agent_framework.azure import AzureOpenAIChatClient, AgentFunctionApp
from azure.identity import DefaultAzureCredential
endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")
deployment_name = os.getenv("AZURE_OPENAI_DEPLOYMENT_NAME", "gpt-4o-mini")
# Create an AI agent following the standard Microsoft Agent Framework pattern
agent = AzureOpenAIChatClient(
endpoint=endpoint,
deployment_name=deployment_name,
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])
Wątki agenta stanowego z historią konwersacji
Agenci utrzymują trwałe wątki, które przetrwają w wielu interakcjach. Każdy wątek jest identyfikowany przez unikatowy identyfikator wątku i przechowuje pełną historię konwersacji w trwałym magazynie zarządzanym przez Durable Task Scheduler.
Ten wzorzec umożliwia ciągłość konwersacji, w której stan agenta jest zachowywany przez awarie i ponowne uruchamianie procesu, dzięki czemu pełna historia konwersacji będzie utrzymywana w wątkach użytkownika. Trwały magazyn zapewnia, że nawet jeśli instancja Azure Functions zostanie uruchomiona ponownie lub przeskaluje się na inną instancję, rozmowa będzie płynnie kontynuowana od miejsca, w którym się zatrzymała.
W poniższym przykładzie pokazano wiele żądań HTTP do tego samego wątku, co pokazuje, jak kontekst konwersacji jest zachowywany:
# 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!
Stan agenta jest utrzymywany w trwałej pamięci, co umożliwia rozproszone wykonywanie w wielu instancjach. Każda instancja może wznowić wykonywanie agenta po przerwach lub awariach, zapewniając ciągłe działanie.
Deterministyczne aranżacje wielu agentów
Rozszerzenie trwałego zadania obsługuje tworzenie deterministycznych przepływów pracy, które koordynują wielu agentów, korzystając z orkiestracji usługi Azure Durable Functions.
Orkiestracje to oparte na kodzie przepływy pracy, które koordynują wiele operacji (takich jak wywołania agentów, zewnętrzne wywołania interfejsu API lub czasomierze) w niezawodny sposób. Deterministyczny oznacza, że kod orkiestracji jest wykonywany w taki sam sposób, gdy odtwarzany po awarii, co sprawia, że przepływy pracy są niezawodne i debugowane — podczas odtwarzania historii orkiestracji można zobaczyć dokładnie, co się stało w każdym kroku.
Orkiestracje są wykonywane niezawodnie, przetrzymując awarie między wywołaniami agentów, i zapewniają przewidywalne oraz powtarzalne procesy. To sprawia, że są idealne w przypadku złożonych scenariuszy obejmujących wiele agentów, w których potrzebna jest gwarantowana kolejność wykonywania i odporność na uszkodzenia.
Sekwencyjne aranżacje
W sekwencyjnym schemacie wielu agentów wyspecjalizowani agenci wykonują działania w określonej kolejności, gdzie wyniki każdego agenta mogą mieć wpływ na wykonanie następnego agenta. Ten wzorzec obsługuje logikę warunkową i rozgałęzianie na podstawie odpowiedzi agenta.
W przypadku korzystania z agentów w orkiestracjach należy użyć context.GetAgent() API, aby uzyskać wystąpienie DurableAIAgent, które jest specjalną podklasą typu standardowego AIAgent, opakowującą jednego z zarejestrowanych agentów. Opakowanie DurableAIAgent zapewnia, że wywołania agentów są właściwie śledzone i kontrolowane przez trwały framework orkiestracji.
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);
}
W przypadku używania agentów w orkiestracjach należy użyć app.get_agent() metody, aby uzyskać trwałe wystąpienie agenta, które jest specjalną otoką wokół jednego z zarejestrowanych agentów. Otoczka trwałego agenta gwarantuje, że wywołania agentów są prawidłowo śledzone i sprawdzane przez trwałe środowisko orkiestracyjne.
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
Orkiestracje koordynują pracę pomiędzy wieloma agentami, zarządzając błędami podczas wywołań agentów. Kontekst orkiestracji udostępnia metody pobierania i interakcji z hostowanymi agentami w ramach orkiestracji.
Aranżacje równoległe
W równoległym wzorcu wielu agentów, wykonuje się wielu agentów jednocześnie, a następnie po wykonaniu agreguje ich wyniki. Ten wzorzec jest przydatny do jednoczesnego zbierania różnych perspektyw lub przetwarzania niezależnych podzadań.
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', '')
Wykonywanie równoległe jest śledzone przy użyciu listy zadań. Automatyczna punktacja kontrolna zapewnia, że ukończone zadania agenta nie są powtarzane ani tracone, jeśli wystąpi awaria podczas agregacji.
Orkiestracje pętli "człowiek w pętli"
Orkiestracje agentów deterministycznych mogą być wstrzymane, oczekując na dane wejściowe, zatwierdzenie lub przegląd, bez zużywania zasobów obliczeniowych. Trwałe wykonywanie umożliwia orkiestracjom czekać dniami lub nawet tygodniami, oczekując na odpowiedzi od ludzi. W połączeniu z hostingiem bezserwerowym wszystkie zasoby obliczeniowe są wyłączane w okresie oczekiwania, eliminując koszty przetwarzania do momentu, gdy użytkownik nie poda swojego wkładu.
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
Deterministyczne orkiestracje agentów mogą czekać na zdarzenia zewnętrzne, trwale utrwalając swój stan podczas oczekiwania na informacje zwrotne od ludzi, przetrwanie niepowodzeń, ponowne uruchomienia i dłuższe okresy oczekiwania. Po nadejściu odpowiedzi człowieka orkiestracja zostanie automatycznie wznowiona z pełnym kontekstem konwersacji i stanem wykonywania bez zmian.
Dostarczanie danych wejściowych przez człowieka
Aby wysłać zatwierdzenie lub dane wejściowe do oczekującej aranżacji, zgłoś zdarzenie zewnętrzne do wystąpienia aranżacji przy użyciu zestawu SDK klienta rozszerzenia Durable Functions. Na przykład recenzent może zatwierdzić zawartość za pośrednictwem formularza internetowego, który wywołuje:
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)
Efektywność kosztowa
Przepływy pracy typu human-in-the-loop z trwałymi agentami są niezwykle ekonomiczne, gdy są hostowane w planie Flex Consumption usługi Azure Functions. W przypadku przepływu pracy czekającego 24 godziny na zatwierdzenie płacisz tylko za kilka sekund czasu wykonania (czas generowania zawartości, wysyłania powiadomień i przetwarzania odpowiedzi) — a nie za 24 godziny oczekiwania. W okresie oczekiwania nie są używane żadne zasoby obliczeniowe.
Możliwość obserwowania z trwałym harmonogramem zadań
Durable Task Scheduler (DTS) jest zalecanym trwałym zapleczem dla Twoich długotrwałych agentów, oferując najlepszą wydajność, w pełni zarządzaną infrastrukturę i wbudowaną funkcję monitorowania za pośrednictwem panelu UI. Chociaż usługa Azure Functions może używać innych zapleczy magazynu (takich jak Usługa Azure Storage), usługa DTS jest zoptymalizowana specjalnie pod kątem trwałych obciążeń i zapewnia lepszą wydajność i możliwości monitorowania.
Szczegółowe informacje o sesji agenta
- Historia konwersacji: wyświetlanie pełnej historii czatów dla każdej sesji agenta, w tym wszystkich wiadomości, wywołań narzędzi i kontekstu konwersacji w dowolnym momencie w czasie
- Chronometraż zadania: Monitorowanie czasu wykonywania określonych zadań i interakcji agenta
Szczegółowe informacje dotyczące orkiestracji
- Wizualizacja wielu agentów: zobacz przepływ wykonywania podczas wywoływania wielu wyspecjalizowanych agentów z wizualną reprezentacją równoległych wykonań i rozgałęziania warunkowego
- Historia wykonywania: uzyskiwanie dostępu do szczegółowych dzienników wykonywania
- Monitorowanie w czasie rzeczywistym: Śledź aktywne orkiestracje, zlecenia robocze w kolejce i stany agentów w całym wdrożeniu.
- Metryki wydajności: monitorowanie czasów odpowiedzi agenta, użycia tokenu i czasu trwania aranżacji
Możliwości debugowania
- Wyświetlanie danych wyjściowych agenta strukturalnego i wyników wywołania narzędzia
- Wywołania narzędzi śledzenia i ich wyniki
- Monitorowanie zewnętrznej obsługi zdarzeń dla scenariuszy z udziałem człowieka w procesie
Pulpit nawigacyjny umożliwia zrozumienie dokładnie tego, co robią agenci, szybkie diagnozowanie problemów i optymalizowanie wydajności na podstawie rzeczywistych danych wykonywania.
Samouczek: tworzenie i uruchamianie trwałego agenta
W tym samouczku pokazano, jak utworzyć i uruchomić trwałego agenta sztucznej inteligencji przy użyciu rozszerzenia trwałego zadania dla programu Microsoft Agent Framework. Utworzysz aplikację usługi Azure Functions, która hostuje agenta stanowego z wbudowanymi punktami końcowymi HTTP i dowiesz się, jak monitorować ją przy użyciu pulpitu nawigacyjnego narzędzia Durable Task Scheduler.
Wymagania wstępne
Przed rozpoczęciem upewnij się, że masz następujące wymagania wstępne:
- Pakiet SDK .NET 9.0 lub nowszy
- Narzędzia Azure Functions Core Tools w wersji 4.x
- Interfejs wiersza polecenia dewelopera Azure (azd)
- Interfejs wiersza polecenia platformy Azure zainstalowany i uwierzytelniony
- Zainstalowany i uruchomiony program Docker Desktop (na potrzeby programowania lokalnego za pomocą biblioteki Azurite i emulatora narzędzia Durable Task Scheduler)
- Subskrypcja platformy Azure z uprawnieniami do tworzenia zasobów
Uwaga / Notatka
Program Microsoft Agent Framework jest obsługiwany ze wszystkimi aktywnie obsługiwanymi wersjami platformy .NET. Na potrzeby tego przykładu zalecamy zestaw .NET 9 SDK lub nowszą wersję.
- Python w wersji 3.10 lub nowszej
- Narzędzia Azure Functions Core Tools w wersji 4.x
- Interfejs wiersza polecenia dewelopera Azure (azd)
- Interfejs wiersza polecenia platformy Azure zainstalowany i uwierzytelniony
- Zainstalowany i uruchomiony program Docker Desktop (na potrzeby programowania lokalnego za pomocą biblioteki Azurite i emulatora narzędzia Durable Task Scheduler)
- Subskrypcja platformy Azure z uprawnieniami do tworzenia zasobów
Pobierz projekt Quickstart
Użyj Azure Developer CLI, aby zainicjować nowy projekt z szablonu quickstart dla trwałych agentów.
Utwórz nowy katalog dla projektu i przejdź do niego:
mkdir MyDurableAgent cd MyDurableAgent
Zainicjuj projekt na podstawie szablonu:
azd init --template durable-agents-quickstart-dotnetPo wyświetleniu monitu o nazwę środowiska wprowadź nazwę, taką jak
my-durable-agent.
Spowoduje to pobranie projektu szybkiego startu ze wszystkimi niezbędnymi plikami, w tym konfiguracją usługi Azure Functions, kodem agenta i infrastrukturą jako szablonami kodu.
Utwórz nowy katalog dla projektu i przejdź do niego:
mkdir MyDurableAgent cd MyDurableAgent
Zainicjuj projekt na podstawie szablonu:
azd init --template durable-agents-quickstart-pythonPo wyświetleniu monitu o nazwę środowiska wprowadź nazwę, taką jak
my-durable-agent.Tworzenie i aktywowanie środowiska wirtualnego:
python3 -m venv .venv source .venv/bin/activate
Zainstaluj wymagane pakiety:
python -m pip install -r requirements.txt
Spowoduje to pobranie projektu szybkiego startu ze wszystkimi niezbędnymi plikami, w tym konfiguracją usługi Azure Functions, kodem agenta i infrastrukturą jako szablonami kodu. Przygotowuje również środowisko wirtualne z wymaganymi zależnościami.
Aprowizuj zasoby platformy Azure
Użyj interfejsu wiersza polecenia dla deweloperów platformy Azure, aby utworzyć wymagane zasoby platformy Azure dla swojego trwałego agenta.
Skonfiguruj infrastrukturę:
azd provisionTo polecenie tworzy:
- Usługa Azure OpenAI z wdrożeniem gpt-4o-mini
- Aplikacja usługi Azure Functions z planem hostingu Flex Consumption
- Konto usługi Azure Storage dla środowiska uruchomieniowego usługi Azure Functions i magazynu trwałego
- Trwałe wystąpienie harmonogramu zadań (plan zużycia) do zarządzania stanem agenta
- Niezbędne konfiguracje sieci i tożsamości
Po wyświetleniu monitu wybierz subskrypcję platformy Azure i wybierz lokalizację zasobów.
Proces przydzielania zasobów trwa kilka minut. Po zakończeniu usługa azd przechowuje informacje o utworzonym zasobie w środowisku.
Przeanalizować kod agenta
Teraz przyjrzyjmy się kodowi definiującemu trwałego agenta.
Otwórz plik , Program.cs aby wyświetlić konfigurację agenta:
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Hosting.AzureFunctions;
using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Hosting;
using OpenAI;
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 AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredential())
.GetChatClient(deploymentName)
.AsAIAgent(
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();
Ten kod:
- Pobiera konfigurację usługi Azure OpenAI ze zmiennych środowiskowych.
- Tworzy klienta usługi Azure OpenAI przy użyciu poświadczeń platformy Azure.
- Tworzy agenta sztucznej inteligencji z instrukcjami i nazwą.
- Konfiguruje aplikację usługi Azure Functions do hostowania agenta z trwałym zarządzaniem wątkami.
Otwórz plik , function_app.py aby wyświetlić konfigurację agenta:
import os
from agent_framework.azure import AzureOpenAIChatClient, AgentFunctionApp
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_NAME", "gpt-4o-mini")
# Create an AI agent following the standard Microsoft Agent Framework pattern
agent = AzureOpenAIChatClient(
endpoint=endpoint,
deployment_name=deployment_name,
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])
Ten kod:
- Pobiera konfigurację usługi Azure OpenAI ze zmiennych środowiskowych.
- Tworzy klienta usługi Azure OpenAI przy użyciu poświadczeń platformy Azure.
- Tworzy agenta sztucznej inteligencji z instrukcjami i nazwą.
- Konfiguruje aplikację usługi Azure Functions do hostowania agenta z trwałym zarządzaniem wątkami.
Agent jest teraz gotowy do hostowania w usłudze Azure Functions. Rozszerzenie trwałego zadania automatycznie tworzy punkty dostępu HTTP na potrzeby współdziałania z agentem i zarządza stanem konwersacji podczas wielu żądań.
Konfigurowanie ustawień lokalnych
local.settings.json Utwórz plik dla lokalnego rozwoju na podstawie przykładowego pliku zawartego w projekcie.
Skopiuj przykładowy plik ustawień:
cp local.settings.sample.json local.settings.json
Uzyskaj punkt końcowy usługi Azure OpenAI z zaaprowizowanych zasobów:
azd env get-value AZURE_OPENAI_ENDPOINTOtwórz
local.settings.jsoni zastąp<your-resource-name>wartośćAZURE_OPENAI_ENDPOINTpunktem końcowym z poprzedniego polecenia.
Twoje local.settings.json powinno wyglądać następująco:
{
"IsEncrypted": false,
"Values": {
// ... other settings ...
"AZURE_OPENAI_ENDPOINT": "https://your-openai-resource.openai.azure.com",
"AZURE_OPENAI_DEPLOYMENT": "gpt-4o-mini",
"TASKHUB_NAME": "default"
}
}
Uwaga / Notatka
Plik local.settings.json jest używany tylko do programowania lokalnego i nie jest wdrażany na platformie Azure. W przypadku wdrożeń produkcyjnych te ustawienia są automatycznie konfigurowane w aplikacji usługi Azure Functions przez szablony infrastruktury.
Uruchamianie lokalnych zależności programistycznych
Aby uruchomić agentów trwałych lokalnie, należy uruchomić dwie usługi:
- Azurite: emuluje usługi Azure Storage (używane przez usługę Azure Functions do zarządzania wyzwalaczami i stanem wewnętrznym).
- Emulator harmonogramu zadań trwałych (DTS): zarządza stanem trwałym (historia konwersacji, stan orkiestracji) oraz planowaniem agentów
Rozpocznij Azurite
Usługa Azurite emuluje usługi Azure Storage lokalnie. Usługa Azure Functions używa jej do zarządzania stanem wewnętrznym. Należy to uruchomić w nowym oknie terminalu i zachować jego działanie podczas opracowywania i testowania trwałego agenta.
Otwórz nowe okno terminalu i pobierz obraz Docker Azurite.
docker pull mcr.microsoft.com/azure-storage/azuriteUruchom Azurite w oknie terminalu:
docker run -p 10000:10000 -p 10001:10001 -p 10002:10002 mcr.microsoft.com/azure-storage/azuriteUsługa Azurite uruchamia się i nasłuchuje na domyślnych portach dla usług Blob (10000), Queue (10001) i Table (10002).
Pozostaw to okno terminalu otwarte podczas opracowywania i testowania trwałego agenta.
Tip
Aby uzyskać więcej informacji na temat platformy Azurite, w tym alternatywnych metod instalacji, zobacz Use Azurite emulator for local Azure Storage development (Używanie emulatora Azurite do lokalnego programowania w usłudze Azure Storage).
Uruchamianie emulatora harmonogramu zadań durable
Emulator DTS zapewnia trwałe zaplecze systemowe do zarządzania stanem agenta i orkiestracjami. Przechowuje historię konwersacji i zapewnia, że stan agenta jest zachowywany po ponownym uruchomieniu systemu. Wyzwala również trwałe aranżacje i agentów. Należy to uruchomić w osobnym nowym oknie terminalu i utrzymać go w działaniu podczas tworzenia i testowania wytrzymałego agenta.
Otwórz kolejne nowe okno terminalu i pobierz obraz Docker emulatora DTS.
docker pull mcr.microsoft.com/dts/dts-emulator:latestUruchom emulator DTS:
docker run -p 8080:8080 -p 8082:8082 mcr.microsoft.com/dts/dts-emulator:latestTo polecenie uruchamia emulator i uwidacznia:
- Port 8080: punkt końcowy gRPC dla harmonogramu zadań trwałych (używany przez aplikację Functions)
- Port 8082: pulpit nawigacyjny administracyjny
Pulpit nawigacyjny będzie dostępny pod adresem
http://localhost:8082.
Pozostaw to okno terminalu otwarte podczas opracowywania i testowania trwałego agenta.
Tip
Aby dowiedzieć się więcej na temat emulatora usługi DTS, w tym sposobu konfigurowania wielu centrów zadań i uzyskiwania dostępu do pulpitu nawigacyjnego, zobacz Develop with Durable Task Scheduler (Programowanie za pomocą harmonogramu zadań trwałych).
Uruchom aplikację funkcji
Teraz możesz uruchomić aplikację usługi Azure Functions z trwałym agentem.
W nowym oknie terminalu (zachowując zarówno Azurite, jak i emulator DTS uruchomiony w oddzielnych oknach), przejdź do katalogu projektu.
Uruchom środowisko uruchomieniowe usługi Azure Functions:
func startPowinny pojawić się wyniki wskazujące, że aplikacja funkcji działa, w tym punkty końcowe HTTP dla Twojego agenta.
Functions: http-MyDurableAgent: [POST] http://localhost:7071/api/agents/MyDurableAgent/run dafx-MyDurableAgent: entityTrigger
Te punkty końcowe automatycznie zarządzają stanem konwersacji — nie musisz samodzielnie tworzyć obiektów wątków ani zarządzać nimi.
Przetestuj agenta lokalnie
Teraz możesz interagować z trwałym agentem przy użyciu żądań HTTP. Agent zachowuje stan rozmowy w trakcie wielu żądań, umożliwiając rozmowy wieloetapowe.
Rozpoczynanie nowej rozmowy
Utwórz nowy wątek i wyślij pierwszą wiadomość:
curl -i -X POST http://localhost:7071/api/agents/MyDurableAgent/run \
-H "Content-Type: text/plain" \
-d "What are three popular programming languages?"
Przykładowa odpowiedź (zwróć uwagę, że x-ms-thread-id nagłówek zawiera identyfikator wątku):
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.
Zapisz identyfikator wątku z nagłówka x-ms-thread-id (np @dafx-mydurableagent@263fa373-fa01-4705-abf2-5a114c2bb87d. ) dla następnego żądania.
Kontynuuj konwersację
Wyślij komunikat kontynuacji do tego samego wątku, dołączając identyfikator wątku jako parametr zapytania:
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?"
Zastąp @dafx-mydurableagent@263fa373-fa01-4705-abf2-5a114c2bb87d rzeczywistym identyfikatorem wątku z nagłówka x-ms-thread-id poprzedniej odpowiedzi.
Przykładowa odpowiedź:
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.
Zwróć uwagę, że agent zapamiętuje kontekst z poprzedniego komunikatu (trzy języki programowania) bez konieczności ponownego określania ich. pl-PL: Ponieważ stan konwersacji jest trwale przechowywany przez Harmonogram Zadań Trwałych, ta historia się zachowuje, nawet jeśli ponownie uruchomisz aplikację funkcji lub konwersacja zostanie wznowiona przez inne wystąpienie.
Monitorowanie za pomocą pulpitu nawigacyjnego Durable Task Scheduler
Harmonogram zadań Durable Task Scheduler udostępnia wbudowany pulpit nawigacyjny do monitorowania i debugowania trwałych agentów. Pulpit zapewnia bezpośredni wgląd w operacje agentów, historię konwersacji i przepływ operacji.
Uzyskiwanie dostępu do pulpitu nawigacyjnego
Otwórz pulpit nawigacyjny lokalnego emulatora usługi DTS w
http://localhost:8082przeglądarce internetowej.Wybierz domyślne centrum zadań z listy, aby wyświetlić jego szczegóły.
Wybierz ikonę ustawień w prawym górnym rogu, aby otworzyć ustawienia, i upewnij się, że w obszarze Funkcje w wersji zapoznawczej wybrano opcję Włącz strony agenta.
Eksploruj rozmowy agenta
Na pulpicie nawigacyjnym przejdź do karty Agenci .
Z listy wybierz trwały wątek agenta (np.
mydurableagent - 263fa373-fa01-4705-abf2-5a114c2bb87d).Zobaczysz szczegółowy widok wątku agenta, w tym pełną historię konwersacji ze wszystkimi komunikatami i odpowiedziami.
Pulpit nawigacyjny zawiera widok osi czasu, który ułatwia zrozumienie przepływu konwersacji. Kluczowe informacje obejmują:
- Znaczniki czasu i czas trwania każdej interakcji
- Zawartość monitu i odpowiedzi
- Liczba użytych tokenów
Tip
Pulpit nawigacyjny usługi DTS zapewnia aktualizacje w czasie rzeczywistym, dzięki czemu możesz obserwować zachowanie agenta podczas interakcji z nim za pośrednictwem punktów końcowych HTTP.
Wdrażanie na platformie Azure
Po przetestowaniu agenta trwałego lokalnie wdróż go na platformie Azure.
Wdróż aplikację:
azd deployTo polecenie pakuje aplikację i wdraża ją w aplikacji usługi Azure Functions utworzonej podczas aprowizacji.
Poczekaj na zakończenie wdrożenia. Dane wyjściowe będą potwierdzać, kiedy agent jest uruchomiony na platformie Azure.
Testowanie wdrożonego agenta
Po wdrożeniu przetestuj agenta uruchomionego na platformie Azure.
Pobierz klucz funkcji
Usługa Azure Functions wymaga klucza interfejsu API dla funkcji wyzwalanych przez protokół HTTP w środowisku produkcyjnym:
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`
Rozpoczynanie nowej konwersacji na platformie Azure
Utwórz nowy wątek i wyślij pierwszy komunikat do wdrożonego agenta:
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?"
Zauważ zwrócony identyfikator wątku w nagłówku odpowiedzi x-ms-thread-id.
Kontynuuj konwersację na platformie Azure
Wyślij wiadomość uzupełniającą w tym samym wątku. Zastąp <thread-id> element identyfikatorem wątku z poprzedniej odpowiedzi:
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?"
Agent utrzymuje kontekst rozmów na platformie Azure tak samo jak lokalnie, co pokazuje trwałość stanu agenta.
Monitorowanie wdrożonego agenta
Wdrożony agent można monitorować przy użyciu pulpitu nawigacyjnego narzędzia Durable Task Scheduler na platformie Azure.
Pobierz nazwę wystąpienia narzędzia Durable Task Scheduler:
azd env get-value DTS_NAMEOtwórz witrynę Azure Portal i wyszukaj nazwę narzędzia Durable Task Scheduler z poprzedniego kroku.
W bloku przeglądu zasobu narzędzia Durable Task Scheduler wybierz z listy domyślne centrum zadań.
Wybierz pozycję Otwórz pulpit nawigacyjny w górnej części strony centrum zadań, aby otworzyć pulpit nawigacyjny monitorowania.
Wyświetl konwersacje agenta tak samo jak w przypadku emulatora lokalnego.
Pulpit nawigacyjny hostowany na platformie Azure udostępnia te same funkcje debugowania i monitorowania co lokalny emulator, co umożliwia inspekcję historii konwersacji, wywołań narzędzi śledzenia i analizowanie wydajności w środowisku produkcyjnym.
Samouczek: orkiestracja agentów trwałych
W tym samouczku pokazano, jak orkiestrować wielu trwałych agentów sztucznej inteligencji przy użyciu wzorca fan-out/fan-in. Rozszerzysz trwałego agenta z poprzedniego samouczka , aby utworzyć system z wieloma agentami, który przetwarza pytanie użytkownika, a następnie tłumaczy odpowiedź na wiele języków jednocześnie.
Zrozumienie wzorca orkiestracji
Orkiestracja, którą utworzysz, przebiega zgodnie z tym przepływem:
- Dane wejściowe użytkownika — pytanie lub wiadomość od użytkownika
-
Główny agent —
MyDurableAgentelement z pierwszego samouczka przetwarza pytanie - Fan-out — odpowiedź głównego agenta jest wysyłana współbieżnie do obu agentów tłumaczenia
- Agenci tłumaczenia — dwóch wyspecjalizowanych agentów tłumaczy odpowiedź (francuski i hiszpański)
- Fan-in — wyniki są agregowane w pojedynczą odpowiedź JSON z oryginalną odpowiedzią i tłumaczeniami
Ten wzorzec umożliwia współbieżne przetwarzanie, skracając całkowity czas odpowiedzi w porównaniu z tłumaczeniem sekwencyjnym.
Rejestrowanie agentów podczas uruchamiania
Aby prawidłowo używać agentów w trwałych orkiestracjach, zarejestruj je podczas uruchamiania aplikacji. Mogą być stosowane we wszystkich procesach orkiestracji.
Zaktualizuj element Program.cs , aby zarejestrować agentów tłumaczenia obok istniejącego MyDurableAgentelementu :
using System;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Hosting.AzureFunctions;
using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Extensions.Hosting;
using OpenAI;
using OpenAI.Chat;
// 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 Azure OpenAI client
AzureOpenAIClient client = new(new Uri(endpoint), new DefaultAzureCredential());
ChatClient chatClient = client.GetChatClient(deploymentName);
// Create the main agent from the first tutorial
AIAgent mainAgent = chatClient.AsAIAgent(
instructions: "You are a helpful assistant that can answer questions and provide information.",
name: "MyDurableAgent");
// Create translation agents
AIAgent frenchAgent = chatClient.AsAIAgent(
instructions: "You are a translator. Translate the following text to French. Return only the translation, no explanations.",
name: "FrenchTranslator");
AIAgent spanishAgent = chatClient.AsAIAgent(
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();
Zaktualizuj element function_app.py , aby zarejestrować agentów tłumaczenia obok istniejącego MyDurableAgentelementu :
import os
from azure.identity import DefaultAzureCredential
from agent_framework.azure import AzureOpenAIChatClient, AgentFunctionApp
# 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")
# Create the Azure OpenAI client
chat_client = AzureOpenAIChatClient(
endpoint=endpoint,
deployment_name=deployment_name,
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])
Utwórz funkcję orkiestracji
Funkcja orkiestracji koordynuje przepływ pracy między wieloma agentami. Pobiera zarejestrowanych agentów z trwałego kontekstu i organizuje ich wykonywanie, najpierw wywołując głównego agenta, a następnie równolegle kierując na agentów tłumaczenia.
Utwórz nowy plik o nazwie AgentOrchestration.cs w katalogu projektu:
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;
}
}
Dodaj funkcję orkiestracji do pliku function_app.py :
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
Testowanie aranżacji
Upewnij się, że lokalne zależności programowania z pierwszego samouczka nadal działają:
- Azurite w jednym oknie terminalu
- Trwały emulator harmonogramu zadań w innym oknie terminalu
Po uruchomieniu lokalnych zależności programistycznych:
Uruchom aplikację usługi Azure Functions w nowym oknie terminalu:
func startRozszerzenie Durable Functions automatycznie tworzy wbudowane punkty końcowe HTTP do zarządzania orkiestracjami. Rozpocznij aranżację przy użyciu wbudowanego interfejsu 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?\""'
Odpowiedź zawiera adresy URL do zarządzania instancją orkiestracji.
{ "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" }Wykonaj zapytanie o stan orkiestracji przy użyciu elementu
statusQueryGetUri(zastąpabc123def456rzeczywistym identyfikatorem instancji):curl http://localhost:7071/runtime/webhooks/durabletask/instances/abc123def456
Sonduj punkt końcowy stanu do momentu, gdy
runtimeStatusma wartośćCompleted. Po zakończeniu zobaczysz dane wyjściowe orkiestracji z odpowiedzią głównego agenta i jego tłumaczeniami:{ "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..." } }
Monitoruj orkiestrację na pulpicie nawigacyjnym
Panel kontrolny narzędzia Durable Task Scheduler zapewnia wgląd w orkiestrację:
Otwórz
http://localhost:8082w przeglądarce.Wybierz "domyślne" centrum zadań.
Wybierz kartę "Orkiestracje".
Znajdź swoją instancję orkiestracji na liście.
Wybierz instancję, aby wyświetlić:
- Oś czasu orkiestracji
- Wykonywanie agenta głównego, a następnie współbieżnych agentów tłumaczenia
- Każde wykonanie agenta (MyDurableAgent, następnie francuski i hiszpański tłumacz)
- Wizualizowane wzorce fan-out i fan-in
- Czas i czas trwania dla każdego kroku
Wdrażanie orkiestracji na platformie Azure
Wdróż zaktualizowaną aplikację przy użyciu interfejsu wiersza polecenia dla deweloperów platformy Azure:
azd deploy
Spowoduje to wdrożenie zaktualizowanego kodu za pomocą nowej funkcji orkiestracji i dodatkowych agentów w aplikacji usługi Azure Functions utworzonej w pierwszym samouczku.
Testowanie wdrożonej aranżacji
Po wdrożeniu przetestuj swoją orkiestrację działającą na platformie Azure.
Pobierz klucz systemowy dla rozszerzenia trwałego:
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)
Rozpocznij aranżację przy użyciu wbudowanego interfejsu 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?\""'
- Użyj
statusQueryGetUriz odpowiedzi, aby sprawdzić, czy zadanie zostało ukończone, i zapoznać się z wynikami z tłumaczeniami.
Dalsze kroki
Dodatkowe zasoby: