Sdílet prostřednictvím


Azure Functions (Durable)

Rozšíření trvalých úloh pro rozhraní Microsoft Agent Framework umožňuje vytvářet stavové agenty AI a deterministické orchestrace s více agenty v bezserverovém prostředí v Azure.

Azure Functions je bezserverová výpočetní služba, která umožňuje spouštět kód na vyžádání bez správy infrastruktury. Rozšíření trvalých úloh vychází z tohoto základu, které zajišťuje trvalou správu stavu, což znamená, že historie konverzací a stav spouštění vašeho agenta jsou spolehlivě trvalé a přežijí chyby, restartování a dlouhotrvající operace.

Přehled

Durable agents kombinují výkon rozhraní Agent Framework s Azure Durable Functions a vytvářejí agenty, které:

  • Automatické uchování stavu napříč vyvoláním funkcí
  • Obnovení po selhání bez ztráty kontextu konverzace
  • Automatické škálování na základě poptávky
  • Orchestrace pracovníchpostupůch

Kdy použít odolné agenty

Pokud potřebujete, vyberte odolné agenty:

  • Úplné řízení kódu: Nasazení a správa vlastního výpočetního prostředí při zachování výhod bez serveru
  • Složité orchestrace: Koordinace více agentů s deterministickými a spolehlivými pracovními postupy, které se můžou spouštět po dobu dnů nebo týdnů
  • Orchestrace řízená událostmi: Integrace s triggery Azure Functions (HTTP, časovače, fronty atd.) a vazbami pro pracovní postupy agenta řízeného událostmi
  • Automatický stav konverzace: Historie konverzací agenta se automaticky spravuje a zachovává bez nutnosti explicitního zpracování stavu v kódu.

Tento přístup bezserverového hostování se liší od hostování agentů založených na spravovaných službách (jako je služba agenta Azure AI Foundry), která poskytuje plně spravovanou infrastrukturu, aniž byste museli nasazovat nebo spravovat aplikace Azure Functions. Odolné agenty jsou ideální v případě, že potřebujete flexibilitu nasazení prvního kódu v kombinaci se spolehlivostí správy trvalých stavů.

Při hostování v plánu hostování Flex Consumption služby Azure Functions mohou být agenti škálováni na tisíce instancí nebo na nula instancí, pokud se nepoužívají, takže můžete platit jenom za výpočetní prostředky, které potřebujete.

Začínáme

V projektu .NET Azure Functions přidejte požadované balíčky 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

Poznámka:

Kromě těchto balíčků se ujistěte, že váš projekt používá verzi 2.2.0 nebo novější balíčku Microsoft.Azure.Functions.Worker .

V projektu Azure Functions v Pythonu nainstalujte požadované balíčky Pythonu.

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

Bezserverové hostování

S rozšířením trvalých úloh můžete nasadit a hostovat agenty rozhraní Microsoft Agent Framework ve službě Azure Functions s integrovanými koncovými body HTTP a voláním na základě orchestrace. Služba Azure Functions poskytuje ceny založené na událostech a průběžných platbách s automatickým škálováním a minimální správou infrastruktury.

Při konfiguraci odolného agenta rozšíření trvalých úloh automaticky vytvoří koncové body HTTP pro vašeho agenta a spravuje veškerou základní infrastrukturu pro ukládání stavu konverzace, zpracování souběžných požadavků a koordinaci pracovních postupů s více agenty.

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

Vlákna stavových agentů s historií konverzací

Agenti udržují trvalá vlákna, která přežijí napříč několika interakcemi. Každé vlákno je identifikováno jedinečným ID vlákna a ukládá kompletní historii konverzací v trvalém úložišti spravovaném plánovačem trvalých úloh.

Tento model umožňuje konverzační kontinuitu, kdy se stav agenta zachová prostřednictvím chybových ukončení procesu a restartování, což umožňuje udržovat úplnou historii konverzací napříč uživatelskými vlákny. Odolné úložiště zajišťuje, že i když se vaše instance Azure Functions restartuje nebo škáluje na jinou instanci, konverzace bez problémů pokračuje tam, kde skončila.

Následující příklad ukazuje více požadavků HTTP na stejné vlákno, které ukazuje, jak kontext konverzace přetrvává:

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

Stav agenta se udržuje v odolném úložišti a umožňuje distribuované spouštění napříč několika instancemi. Každá instance může obnovit spuštění agenta po přerušení nebo selháních a zajistit tak nepřetržitou operaci.

Deterministické orchestrace s více agenty

Rozšíření trvalých úloh podporuje vytváření deterministických pracovních postupů, které koordinuje více agentů pomocí orchestrací Azure Durable Functions .

Orchestrace jsou pracovní postupy založené na kódu, které spolehlivě koordinuje více operací (jako jsou volání agenta, externí volání rozhraní API nebo časovače). Deterministický znamená, že se kód orchestrace provádí stejným způsobem při přehrání po selhání, takže pracovní postupy jsou spolehlivé a laditelné – při přehrání historie orchestrace můžete přesně zjistit, co se stalo v jednotlivých krocích.

Orchestrace se provádějí spolehlivě, odolející selháním mezi voláními agenta a poskytují předvídatelnost a opakovatelnost procesů. Díky tomu jsou ideální pro složité scénáře s více agenty, ve kterých potřebujete garantované pořadí provádění a odolnost proti chybám.

Sekvenční orchestrace

Ve víceagentním sekvenčním vzoru se specializovaní agenti spouštějí v přesném pořadí, kde výstup každého agenta může ovlivnit provedení dalšího agenta. Tento model podporuje podmíněnou logiku a větvení na základě odpovědí agenta.

Při použití agentů v orchestracích je nutné pomocí context.GetAgent() rozhraní API získat instanci DurableAIAgent, což je speciální podtřída standardního typu AIAgent, která obaluje jednoho z vašich registrovaných agentů. Obálka DurableAIAgent zajišťuje správné sledování a checkpointování hovorů agenta rámcem trvalé orchestrace.

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

Při použití agentů v orchestracích musíte použít metodu app.get_agent() k získání trvalé instance agenta, což je speciální obálka kolem jednoho z registrovaných agentů. Odolná obálka agenta zajišťuje, že volání agenta jsou správně sledována a zaznamenávána kontrolními body odolným rámcem pro orchestrace.

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

Orchestrace koordinuje práci mezi více agenty a odolává selhání mezi voláními agentů. Kontext orchestrace poskytuje metody pro získání a interakci s hostovanými agenty v orchestracích.

Paralelní orchestrace

V paralelním vzoru s více agenty spustíte více agentů současně a pak agregujete jejich výsledky. Tento model je užitečný pro souběžné shromažďování různorodých perspektiv nebo zpracování nezávislých dílčích úkolů.

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

Paralelní provádění se sleduje pomocí seznamu úkolů. Automatické vytváření kontrolních bodů zajišťuje, že dokončená spuštění agenta se neopakují ani neztratí, pokud během agregace dojde k chybě.

Orchestrace human-in-the-loop

Deterministické orchestrace agentů se mohou dočasně zastavit kvůli zadání od člověka, schválení nebo kontrole, aniž by spotřebovávaly výpočetní kapacity. Trvalé provádění umožňuje orchestracím čekat celé dny nebo dokonce týdny na lidské reakce. V kombinaci s bezserverovým hostováním se všechny výpočetní zdroje během čekací doby vypnou, což eliminuje náklady na výpočet, dokud člověk neposkytne svůj vstup.

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

Deterministické orchestrace agentů mohou čekat na externí události a trvale uchovávat jejich stav při čekání na lidskou zpětnou vazbu, odolávat selháním, restartování a delším čekacím obdobím. Když dorazí lidská odpověď, orchestrace se automaticky obnoví, přičemž zůstává zachován úplný kontext konverzace i stav provádění beze změny.

Poskytování lidského vstupu

Pokud chcete odeslat schválení nebo vstup do čekající orchestrace, vytvořte externí událost do instance orchestrace pomocí klientské sady SDK Durable Functions. Recenzent může například schválit obsah prostřednictvím webového formuláře, který spustí:

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)

Nákladová efektivita

Pracovní postupy s člověkem ve smyčce s trvalými agenty jsou mimořádně nákladově efektivní, když jsou hostovány na plánu Flex Consumption služby Azure Functions. U pracovního postupu, který čeká na schválení 24 hodin, platíte jenom několik sekund spuštění (doba generování obsahu, odeslání oznámení a zpracování odpovědi) – ne 24 hodin čekání. Během čekací doby se nevyužívají žádné výpočetní prostředky.

Pozorovatelnost pomocí plánovače trvalých úloh

Plánovač úloh Durable Task Scheduler (DTS) je doporučený trvalý back-end pro vaše odolné agenty, který nabízí nejlepší výkon, plně spravovanou infrastrukturu a integrovanou pozorovatelnost prostřednictvím řídicího panelu uživatelského rozhraní. I když služba Azure Functions může používat další back-endy úložiště (jako je Azure Storage), DTS je optimalizovaná speciálně pro odolné úlohy a poskytuje vynikající možnosti výkonu a monitorování.

Přehledy relací agenta

  • Historie konverzací: Zobrazení úplné historie chatu pro každou relaci agenta, včetně všech zpráv, volání nástrojů a kontextu konverzace v jakémkoli okamžiku
  • Časování úloh: Monitorování doby trvání konkrétních úloh a interakcí agentů

Snímek obrazovky řídicího panelu Plánovače trvalých úloh zobrazující historii chatu agenta s vlákny konverzace a zprávami

Přehledy orchestrace

  • Vizualizace více agentů: Zobrazení průběhu provádění při volání více specializovaných agentů s vizuálním zobrazením paralelních spuštění a podmíněného větvení
  • Historie spuštění: Přístup k podrobným protokolům spuštění
  • Monitorování v reálném čase: Sledování aktivních orchestrací, pracovních položek zařazených do fronty a stavů agentů napříč nasazením
  • Metriky výkonu: Monitorování doby odezvy agenta, využití tokenů a doba orchestrace

Snímek obrazovky řídicího panelu Plánovače trvalých úloh zobrazující vizualizaci orchestrace s více interakcemi agentů a prováděním pracovního postupu

Možnosti ladění

  • Zobrazení výstupů strukturovaného agenta a výsledků volání nástrojů
  • Volání nástrojů trasování a jejich výsledky
  • Monitorování zpracování externích událostí pro scénáře s lidskou zpětnou vazbou

Řídicí panel umožňuje přesně pochopit, co dělají vaši agenti, rychle diagnostikovat problémy a optimalizovat výkon na základě skutečných dat spuštění.

Kurz: Vytvoření a spuštění odolného agenta

V tomto kurzu se dozvíte, jak vytvořit a spustit odolného agenta AI pomocí rozšíření trvalých úloh pro rozhraní Microsoft Agent Framework. Vytvoříte aplikaci Azure Functions, která je hostitelem stavového agenta s integrovanými koncovými body HTTP, a dozvíte se, jak ji monitorovat pomocí řídicího panelu Plánovače úloh Durable.

Požadavky

Než začnete, ujistěte se, že máte následující požadavky:

Poznámka:

Rozhraní Microsoft Agent Framework je podporováno ve všech aktivně podporovaných verzích rozhraní .NET. Pro účely této ukázky doporučujeme sadu .NET 9 SDK nebo novější verzi.

Stažení projektu rychlého startu

Pomocí Azure Developer CLI inicializujete nový projekt ze šablony rychlého startu durable agents.

  1. Vytvořte pro projekt nový adresář a přejděte na něj:

    mkdir MyDurableAgent
    cd MyDurableAgent
    

  1. Inicializace projektu ze šablony:

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

    Po zobrazení výzvy k zadání názvu prostředí zadejte název, například my-durable-agent.

Tím se stáhne projekt pro rychlý start se všemi potřebnými soubory, včetně konfigurace služby Azure Functions, kódu agenta a infrastruktury jako šablony kódu.

  1. Vytvořte pro projekt nový adresář a přejděte na něj:

    mkdir MyDurableAgent
    cd MyDurableAgent
    

  1. Inicializace projektu ze šablony:

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

    Po zobrazení výzvy k zadání názvu prostředí zadejte název, například my-durable-agent.

  2. Vytvoření a aktivace virtuálního prostředí:

    python3 -m venv .venv
    source .venv/bin/activate
    

  1. Nainstalujte požadované balíčky:

    python -m pip install -r requirements.txt
    

Tím se stáhne projekt pro rychlý start se všemi potřebnými soubory, včetně konfigurace služby Azure Functions, kódu agenta a infrastruktury jako šablony kódu. Připraví také virtuální prostředí s požadovanými závislostmi.

Zřízení prostředků Azure

Pomocí Azure Developer CLI vytvořte požadované prostředky Azure pro vašeho odolného agenta.

  1. Zřízení infrastruktury:

    azd provision
    

    Tento příkaz vytvoří:

    • Služba Azure OpenAI s nasazením gpt-4o-mini
    • Aplikace Azure Functions s plánem hostování Flex Consumption
    • Účet služby Azure Storage pro modul runtime Azure Functions a trvalé úložiště
    • Instance Plánovače trvalých úkolů (spotřební plán) pro správu stavu agenta
    • Nezbytné síťové a identitní konfigurace
  2. Po zobrazení výzvy vyberte své předplatné Azure a zvolte umístění prostředků.

Proces zřizování trvá několik minut. Po dokončení azd uloží ve vašem prostředí informace o vytvořených prostředcích.

Kontrola kódu agenta

Teď se podíváme na kód, který definuje vašeho odolného agenta.

Otevřete, Program.cs abyste viděli konfiguraci 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();

Tento kód:

  1. Načte konfiguraci Azure OpenAI z proměnných prostředí.
  2. Vytvoří klienta Azure OpenAI pomocí přihlašovacích údajů Azure.
  3. Vytvoří agenta AI s pokyny a názvem.
  4. Nakonfiguruje aplikaci Azure Functions pro hostování agenta s trvalou správou vláken.

Otevřete, function_app.py abyste viděli konfiguraci 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])

Tento kód:

  • Načte konfiguraci Azure OpenAI z proměnných prostředí.
  • Vytvoří klienta Azure OpenAI pomocí přihlašovacích údajů Azure.
  • Vytvoří agenta AI s pokyny a názvem.
  • Nakonfiguruje aplikaci Azure Functions pro hostování agenta s trvalou správou vláken.

Agent je teď připravený k hostovaní ve službě Azure Functions. Rozšíření trvalých úloh automaticky vytvoří koncové body HTTP pro interakci s vaším agentem a spravuje stav konverzací napříč několika požadavky.

Konfigurace místního nastavení

Vytvořte local.settings.json soubor pro místní vývoj na základě ukázkového souboru, který je součástí projektu.

  1. Zkopírujte ukázkový soubor nastavení:

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

  1. Získejte koncový bod Azure OpenAI ze zřízených prostředků:

    azd env get-value AZURE_OPENAI_ENDPOINT
    
  2. Otevřete local.settings.json a nahraďte <your-resource-name> hodnotu AZURE_OPENAI_ENDPOINT koncovým bodem z předchozího příkazu.

Vaše local.settings.json by mělo vypadat takto:

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

Poznámka:

Soubor local.settings.json se používá jenom pro místní vývoj a není nasazený do Azure. Pro produkční nasazení jsou tato nastavení automaticky nakonfigurovaná v aplikaci Azure Functions pomocí šablon infrastruktury.

Zahájit lokální vývojové závislosti

Pokud chcete spustit trvalé agenty místně, musíte spustit dvě služby:

  • Azurite: Emuluje služby Azure Storage (používané službou Azure Functions ke správě triggerů a interního stavu).
  • Emulátor plánovače trvalých úloh (DTS): Spravuje trvalý stav (historie konverzací, stav orchestrace) a plánování pro vaše agenty

Spustit Azurite

Azurite emuluje služby Azure Storage místně. Azure Functions ji používá ke správě interního stavu. Budete ho muset spustit v novém okně terminálu a nechat ho běžet při vývoji a testování odolného agenta.

  1. Otevřete nové okno terminálu a stáhněte image Azurite Dockeru:

    docker pull mcr.microsoft.com/azure-storage/azurite
    
  2. Spusťte Azurite v okně terminálu:

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

    Azurite se spustí a naslouchá na výchozích portech pro služby Blob (10000), Queue (10001) a Table (10002).

Během vývoje a testování odolného agenta nechte toto okno terminálu otevřené.

Návod

Další informace o Azurite, včetně alternativních metod instalace, naleznete v tématu Použití emulátoru Azurite pro místní vývoj služby Azure Storage.

Spuštění emulátoru Plánovače úloh Durable

Emulátor DTS poskytuje trvalý back-end pro správu stavu a orchestrací agenta. Ukládá historii konverzací a zajišťuje, aby se stav vašeho agenta zachoval při každém restartování. Aktivuje také trvanlivé orchestrace a agenty. Budete ho muset spustit v samostatném novém okně terminálu a nechat ho běžet při vývoji a testování odolného agenta.

  1. Otevřete další nové okno terminálu a stáhněte image Dockeru emulátoru DTS:

    docker pull mcr.microsoft.com/dts/dts-emulator:latest
    
  2. Spusťte emulátor DTS:

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

    Tento příkaz spustí emulátor a zpřístupní:

    • Port 8080: Koncový bod gRPC pro plánovač úloh Durable (používaný aplikací Functions)
    • Port 8082: Řídicí panel pro správu
  3. Řídicí panel bude k dispozici na adrese http://localhost:8082.

Během vývoje a testování odolného agenta nechte toto okno terminálu otevřené.

Návod

Další informace o emulátoru DTS, včetně postupu konfigurace více center úloh a přístupu k řídicímu panelu, najdete v tématu Vývoj s využitím Plánovače trvalých úloh.

Spuštění aplikace funkcí

Teď jste připraveni spustit aplikaci Azure Functions s trvalým agentem.

  1. V novém okně terminálu, zatímco Azurite a emulátor DTS běží v samostatných oknech, navigujte do adresáře projektu.

  2. Spusťte modul runtime Azure Functions:

    func start
    
  3. By měl být zobrazen výstup naznačující, že vaše funkční aplikace je spuštěna, včetně koncových bodů HTTP pro vašeho agenta:

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

Tyto koncové body spravují stav konverzace automaticky – nemusíte vytvářet ani spravovat objekty vlákna sami.

Otestujte agenta lokálně

Teď můžete s trvalým agentem pracovat pomocí požadavků HTTP. Agent udržuje stav konverzace napříč několika požadavky a umožňuje více konverzací.

Zahájení nové konverzace

Vytvořte nové vlákno a odešlete první zprávu:

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

Ukázková odpověď (všimněte si, že x-ms-thread-id záhlaví obsahuje ID vlákna):

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.

Uložte ID vlákna z hlavičky x-ms-thread-id (např @dafx-mydurableagent@263fa373-fa01-4705-abf2-5a114c2bb87d. ) pro další požadavek.

Pokračovat v konverzaci

Odeslání následné zprávy do stejného vlákna zahrnutím ID vlákna jako parametru dotazu:

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

Nahraďte @dafx-mydurableagent@263fa373-fa01-4705-abf2-5a114c2bb87d skutečným ID vlákna z hlavičky x-ms-thread-id předchozí odpovědi.

Ukázková odpověď:

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.

Všimněte si, že agent si pamatuje kontext z předchozí zprávy (tři programovací jazyky), aniž byste je museli znovu zadávat. Vzhledem k tomu, že stav konverzace je trvale uložený plánovačem trvalých úloh, tato historie přetrvává i v případě, že restartujete aplikaci funkcí nebo konverzaci obnovíte jinou instancí.

Monitorování pomocí řídicího panelu Plánovače úloh Durable

Durable Task Scheduler poskytuje integrovaný řídicí panel pro monitorování a ladění trvalých agentů. Řídicí panel nabízí hluboký přehled o operacích agenta, historii konverzací a toku provádění.

Přístup k řídicímu panelu

  1. Otevřete řídicí panel pro místní emulátor http://localhost:8082 DTS ve webovém prohlížeči.

  2. Výběrem výchozího centra úloh ze seznamu zobrazíte jeho podrobnosti.

  3. Klikněte na ikonu ozubeného kola v pravém horním rohu pro otevření nastavení a ujistěte se, že je možnost Povolit stránky agenta vybrána v části Ukázkové funkce.

Prozkoumání konverzací agentů

  1. Na řídicím panelu přejděte na kartu Agenti .

  2. Ze seznamu vyberte vlákno odolného agenta (např. mydurableagent - 263fa373-fa01-4705-abf2-5a114c2bb87d).

    Zobrazí se podrobné zobrazení vlákna agenta, včetně celé historie konverzací se všemi zprávami a odpověďmi.

    Snímek obrazovky řídicího panelu Plánovače trvalých úloh zobrazující historii konverzací vlákna agenta

Řídicí panel poskytuje zobrazení časové osy, které vám pomůže pochopit tok konverzace. Mezi klíčové informace patří:

  • Časová razítka a doba trvání pro každou interakci
  • Obsah výzvy a odpovědi
  • Počet použitých tokenů

Návod

Řídicí panel DTS poskytuje aktualizace v reálném čase, takže můžete sledovat chování agenta při interakci s ním prostřednictvím koncových bodů HTTP.

Nasazení do Azure

Teď, když jste místně otestovali odolného agenta, nasaďte ho do Azure.

  1. Nasazení aplikace:

    azd deploy
    

    Tento příkaz zabalí vaši aplikaci a nasadí ji do aplikace Azure Functions vytvořené během zřizování.

  2. Počkejte, až se nasazení dokončí. Výstup potvrdí, že je agent spuštěný v Azure.

Otestování nasazeného agenta

Po nasazení otestujte agenta spuštěný v Azure.

Získání klíče funkce

Azure Functions vyžaduje klíč rozhraní API pro funkce aktivované protokolem HTTP v produkčním prostředí:

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`

Zahájení nové konverzace v Azure

Vytvořte nové vlákno a odešlete první zprávu nasazeným agentům:

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

Poznamenejte si ID vlákna vrácené v x-ms-thread-id hlavičce odpovědi.

Pokračování v konverzaci v Azure

Odešlete následnou zprávu ve stejném vlákně. Nahraďte <thread-id> ID vlákna z předchozí odpovědi:

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 zachovává kontext konverzace v Azure stejně jako místně, což demonstruje trvanlivost stavu agenta.

Monitorování nasazeného agenta

Nasazeného agenta můžete monitorovat pomocí řídicího panelu Plánovače úloh Durable v Azure.

  1. Získejte název instance Plánovače úloh Durable:

    azd env get-value DTS_NAME
    
  2. Otevřete web Azure Portal a vyhledejte název plánovače trvalých úloh z předchozího kroku.

  3. V okně přehledu prostředku plánovače úloh Durable Task Scheduler vyberte ze seznamu výchozí centrum úloh.

  4. Výběrem možnosti Otevřít řídicí panel v horní části stránky centra úloh otevřete řídicí panel monitorování.

  5. Podívejte se na konverzace agenta stejně jako v místním emulátoru.

Řídicí panel hostovaný v Azure poskytuje stejné možnosti ladění a monitorování jako místní emulátor, což umožňuje kontrolovat historii konverzací, volání nástrojů trasování a analyzovat výkon v produkčním prostředí.

Kurz: Orchestrace trvalých agentů

V tomto kurzu se dozvíte, jak orchestrovat více trvalých agentů umělé inteligence pomocí vzoru fan-out/fan-in. Rozšířením odolného agenta z předchozího kurzu vytvoříte systém s více agenty, který zpracuje otázku uživatele, a pak současně přeloží odpověď do více jazyků.

Principy modelu orchestrace

Orchestrace, kterou vytvoříte, se řídí tímto tokem:

  1. Uživatelský vstup – otázka nebo zpráva od uživatele
  2. Hlavní agentMyDurableAgent z prvního tutoriálu zpracovává otázku
  3. Fan-out – odpověď hlavního agenta se odesílá souběžně oběma agentům překladu.
  4. Agenti překladu – dva specializovaní agenti překládají odpověď (francouzština a španělština)
  5. Fan-in – Výsledky se agregují do jedné odpovědi JSON s původní odpovědí a překlady.

Tento model umožňuje souběžné zpracování, což snižuje celkovou dobu odezvy v porovnání s sekvenčním překladem.

Registrace agentů při spuštění

Pokud chcete správně používat agenty v trvalých orchestracích, zaregistrujte je při spuštění aplikace. Dají se použít napříč prováděními orchestrace.

Aktualizujte váš Program.cs, aby registroval agenty překladu spolu s existujícími MyDurableAgent agenty:

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

Aktualizujte váš function_app.py, aby registroval agenty překladu spolu s existujícími MyDurableAgent agenty:

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

Vytvořte funkci orchestrace

Funkce orchestrace koordinuje pracovní postup napříč více agenty. Načte zaregistrované agenty z trvalého kontextu a orchestruje jejich spuštění, nejprve zavolá hlavního agenta, a poté roztříští úkoly na překladatelské agenty souběžně.

Vytvořte nový soubor s názvem AgentOrchestration.cs v adresáři 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;
    }
}

Přidejte do function_app.py souboru funkci orchestrace:

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

Otestování orchestrace

Ujistěte se, že vaše lokální závislosti na vývoji z prvního tutoriálu stále běží:

  • Azurite v jednom okně terminálu
  • Emulátor plánovače úloh Durable v jiném okně terminálu

Při běhu místních vývojových závislostí:

  1. Spusťte aplikaci Azure Functions v novém okně terminálu:

    func start
    
  2. Rozšíření Durable Functions automaticky vytvoří integrované koncové body HTTP pro správu orchestrací. Spusťte orchestraci pomocí integrovaného rozhraní API:

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

  1. Odpověď obsahuje adresy URL pro správu instance orchestrace:

    {
      "id": "abc123def456",
      "statusQueryGetUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/abc123def456",
      "sendEventPostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/abc123def456/raiseEvent/{eventName}",
      "terminatePostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/abc123def456/terminate",
      "purgeHistoryDeleteUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/abc123def456"
    }
    
  2. Zjistěte stav orchestrace pomocí hodnoty statusQueryGetUri (nahraďte abc123def456 vaším skutečným ID instance):

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

  1. Průběžně kontrolujte stav koncového bodu, dokud runtimeStatus není Completed. Po dokončení uvidíte výstup orchestrace s odpovědí hlavního agenta a jeho překlady:

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

Monitorování orchestrace na řídicím panelu

Řídicí panel plánovače trvalých úloh poskytuje přehled o orchestraci:

  1. Otevřete http://localhost:8082 v prohlížeči.

  2. Vyberte výchozí centrum úloh.

  3. Vyberte kartu Orchestrace.

  4. Vyhledejte instanci orchestrace v seznamu.

  5. Vyberte instanci, která se má zobrazit:

    • Časová osa orchestrace
    • Spuštění hlavního agenta následované souběžnými agenty pro překlad
    • Každé spuštění agenta (MyDurableAgent, francouzští a španělští překladatelé)
    • Fan-out a fan-in vzory vizualizovány
    • Časování a doba trvání jednotlivých kroků

Nasazení orchestrace do Azure

Nasazení aktualizované aplikace pomocí Azure Developer CLI:

azd deploy

Tím se nasadí aktualizovaný kód s novou funkcí orchestrace a dalšími agenty do aplikace Azure Functions vytvořené v prvním kurzu.

Otestování nasazené orchestrace

Po nasazení otestujte orchestraci spuštěnou v Azure.

  1. Získejte systémový klíč pro rozšíření Durable:

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

  1. Spusťte orchestraci pomocí integrovaného rozhraní API:

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

  1. Pomocí statusQueryGetUri z odpovědi můžete provádět dotazování na stav dokončení a zobrazit výsledky včetně překladů.

Další kroky

Další prostředky: