Устойчивое расширение

Устойчивое расширение для платформы агента Microsoft обеспечивает устойчивое выполнение агентов, оркестрации нескольких агентов и рабочих процессов Microsoft Agent Framework. Его можно использовать для сохранения сеансов агента, оркестрации контрольных точек и хода выполнения рабочего процесса, восстановления от сбоев и масштабирования работы между распределенными узлами без изменения логики основного агента.

Расширение поддерживает две модели размещения в C# и Python:

  • Функции Azure для управляемого бессерверного размещения с помощью модели программирования Функции Azure.
  • Приведите собственные вычислительные ресурсы или локальное размещение для выполнения устойчивых агентов и рабочих процессов в собственном рабочем процессе, службе, контейнере, среде Kubernetes или существующей инфраструктуре приложений.

Overview

Устойчивые агенты объединяют модель программирования Agent Framework с инфраструктурой устойчивых задач, например планировщик устойчивых задач, чтобы создать агенты, которые:

  • Автоматическое сохранение состояния между запросами и рабочими выполнениями
  • Возобновление после сбоев без потери контекста беседы или повторения завершенной работы
  • Масштабирование между распределенными, без отслеживания состояния рабочими ролей на основе спроса
  • Оркестрация рабочих процессов с несколькими агентами с надежными гарантиями выполнения
  • Рабочие процессы агента контрольных точек, созданные с помощью модели рабочих процессов на основе графа
  • Приостановка ввода или внешних событий без использования маркеров вычислений или моделей во время ожидания
  • Потоковые ответы надежно при настройке с помощью надежного брокера потоковой передачи, например Redis
  • Управление жизненным циклом сеанса с помощью очистки времени ожидания сеанса (TTL) и мониторинга на основе панели мониторинга

Когда следует использовать устойчивые агенты

Выберите устойчивые агенты при необходимости:

  • Состояние сохраняемой беседы: сеансы агента выживают сбои процесса, перезапуски и горизонтальное масштабирование событий
  • Сложные оркестрации: координация нескольких агентов с детерминированными, надежными рабочими процессами, которые могут выполняться в течение нескольких дней или недель.
  • Оркестрация на основе событий: интеграция с триггерами, очередями, веб-перехватчиками, таймерами или существующими событиями приложения
  • Автоматическое состояние беседы: журнал бесед агента автоматически управляется и сохраняется без явной обработки состояния в коде
  • Durable Agent Framework рабочих процессов. Создание рабочих процессов на основе графов Microsoft Agent Framework, чтобы каждый шаг можно было провести контрольные точки и возобновить работу.
  • Длительные сеансы. Сохранение полезных бесед при использовании очистки времени ожидания сеанса (TTL) для автоматического удаления сеансов бездействия
  • Надежные ответы в режиме реального времени: выходные данные маркера потоковой передачи для приложений, которым требуется UX в режиме реального времени с гарантиями доставки

Этот подход размещения отличается от размещения управляемого агента на основе служб (например, Службы агента Foundry), который предоставляет полностью управляемую инфраструктуру, не требуя развертывания или управления рабочими узлами. Устойчивые агенты идеально подходят, если требуется гибкость развертывания в коде в сочетании с устойчивым управлением состоянием.

Выбор модели размещения

Модель размещения Выберите его при необходимости
Функции Azure Управляемая, бессерверная модель размещения; встроенное горизонтальное масштабирование и масштабирование до нуля; триггеры и привязки Функции Azure; Конечные точки HTTP, созданные моделью программирования функций; триггер сервера MCP; и минимальное управление инфраструктурой узлов.
Перенос собственных вычислений или локально размещенных Дополнительные возможности контроля над процессом размещения, средой развертывания, жизненным циклом среды выполнения, инфраструктурой, сетью, проверкой подлинности или интеграцией с существующим приложением или службой. Используйте эту модель для контейнеров, Kubernetes, длительных рабочих ролей, консольных приложений, пользовательских служб или сред размещения, отличных от функций.

При размещении в плане размещения Функции Azure Flex Consumption агенты могут масштабироваться до тысяч экземпляров или уменьшаться до нуля, если они не используются, что позволяет платить только за необходимые вычислительные ресурсы. В локальных сценариях собственные элементы управления узлом управляют временем существования, масштабированием, сетью и развертыванием.

Начало работы

В проекте .NET выберите набор пакетов для модели размещения.

Для размещения Функции Azure добавьте пакет интеграции Функции Azure и рабочие пакеты Функций.

dotnet add package Azure.AI.Projects --prerelease
dotnet add package Azure.Identity
dotnet add package Microsoft.Agents.AI.Foundry --prerelease
dotnet add package Microsoft.Agents.AI.Hosting.AzureFunctions --prerelease

Note

В дополнение к этим пакетам убедитесь, что проект использует версию 2.2.0 или более позднюю версию пакета Microsoft.Azure.Functions.Worker .

Для размещения собственных вычислительных ресурсов добавьте базовый пакет интеграции устойчивых задач и пакеты планировщика устойчивых задач, используемые узлом:

dotnet add package Microsoft.Agents.AI.DurableTask --prerelease
dotnet add package Microsoft.DurableTask.Client.AzureManaged
dotnet add package Microsoft.DurableTask.Worker.AzureManaged
dotnet add package Microsoft.Extensions.Hosting

В проекте Python выберите пакет для модели размещения.

Для размещения Функции Azure установите пакет интеграции Функции Azure.

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

Для размещения собственных вычислений установите пакет интеграции устойчивых задач.

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

размещение Функции Azure

С помощью устойчивого расширения можно развертывать и размещать агенты агента агента Microsoft в Функции Azure со встроенными конечными точками HTTP и вызовом на основе оркестрации. Функции Azure предоставляют цену на основе событий, оплату за каждый вызов с автоматическим масштабированием и минимальным управлением инфраструктурой.

При настройке устойчивого агента в Функции Azure расширение автоматически создает конечные точки HTTP для агента и управляет базовой инфраструктурой для хранения состояния беседы, обработки одновременных запросов и координации рабочих процессов с несколькими агентами. Интеграция размещения Функции Azure также обеспечивает удобные функции, такие как созданные REST API для отправки сообщений, проверки состояния и управления сеансами, а также триггеры, такие как триггер сервера MCP для размещения агентов в качестве серверов MCP без записи клея триггера.

using System;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Hosting.AzureFunctions;
using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Extensions.Hosting;

var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT");
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT") ?? "gpt-4o-mini";

// Create an AI agent following the standard Microsoft Agent Framework pattern
AIAgent agent = new AIProjectClient(new Uri(endpoint), new DefaultAzureCredential())
    .AsAIAgent(
        model: deploymentName,
        instructions: "You are good at telling jokes.",
        name: "Joker");

// Configure the function app to host the agent with durable thread management
// This automatically creates HTTP endpoints and manages state persistence
using IHost app = FunctionsApplication
    .CreateBuilder(args)
    .ConfigureFunctionsWebApplication()
    .ConfigureDurableAgents(options =>
        options.AddAIAgent(agent)
    )
    .Build();
app.Run();

Предупреждение

DefaultAzureCredential удобно для разработки, но требует тщательного рассмотрения в рабочей среде. В рабочей среде рекомендуется использовать определенные учетные данные (например, ManagedIdentityCredential), чтобы избежать проблем с задержкой, непреднамеренной проверки данных аутентификации и потенциальных рисков безопасности из-за резервных механизмов.

import os
from agent_framework.azure import AgentFunctionApp
from agent_framework.openai import OpenAIChatCompletionClient
from azure.identity import DefaultAzureCredential

endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")
deployment_name = os.getenv("AZURE_OPENAI_CHAT_COMPLETION_MODEL", "gpt-4o-mini")
api_version = os.getenv("AZURE_OPENAI_API_VERSION")

# Create an AI agent following the standard Microsoft Agent Framework pattern
agent = OpenAIChatCompletionClient(
    azure_endpoint=endpoint,
    model=deployment_name,
    api_version=api_version,
    credential=DefaultAzureCredential()
).as_agent(
    instructions="You are good at telling jokes.",
    name="Joker"
)

# Configure the function app to host the agent with durable thread management
# This automatically creates HTTP endpoints and manages state persistence
app = AgentFunctionApp(agents=[agent])

Перенос собственного вычислительного или локального размещения

Используйте размещение собственных вычислений, если требуется возможность устойчивых расширений без использования модели программирования Функции Azure. В этой модели процесс запускает рабочую роль устойчивых задач, регистрирует устойчивые агенты или рабочие процессы и подключается к серверной части планировщика устойчивых задач. Клиентский код может выполняться в одном процессе или в отдельной службе.

Локальные работники используют те же основные возможности устойчивых расширений, что и Функции Azure размещения: контрольные точки и возобновление, детерминированное оркестрация агента, рабочие процессы устойчивых агентов, ожидания в цикле, надежная потоковая передача, очистка сеанса простоя, видимость панели мониторинга и распределенное выполнение между экземплярами рабочих ролей без отслеживания состояния. Узел отвечает за предоставление собственных API, управления жизненным циклом, сети, проверки подлинности и развертывания.

Настройте узел с базовым пакетом интеграции устойчивых задач. Используйте ConfigureDurableAgents для устойчивых агентов и ConfigureDurableWorkflows для рабочих процессов на основе графов Microsoft Agent Framework.

string connectionString = Environment.GetEnvironmentVariable("DURABLE_TASK_SCHEDULER_CONNECTION_STRING")
    ?? "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None";

IHost host = Host.CreateDefaultBuilder(args)
    .ConfigureServices(services =>
    {
        services.ConfigureDurableAgents(
            options => options.AddAIAgent(agent),
            workerBuilder: builder => builder.UseDurableTaskScheduler(connectionString),
            clientBuilder: builder => builder.UseDurableTaskScheduler(connectionString));
    })
    .Build();

await host.StartAsync();

Примеры консоли устойчивых агентов .NET и .NET примеры консоли устойчивых рабочих процессов для запускаемых примеров.

Используйте пакет интеграции устойчивых задач для запуска рабочего процесса, который регистрирует агенты и прослушивает запросы. Клиентский код может подключаться к одному концентратору задач планировщика устойчивых задач из другого процесса.

from agent_framework.azure import DurableAIAgentWorker
from durabletask.azuremanaged.worker import DurableTaskSchedulerWorker

worker = DurableTaskSchedulerWorker(
    host_address="http://localhost:8080",
    secure_channel=False,
    taskhub="default",
)

agent_worker = DurableAIAgentWorker(worker)
agent_worker.add_agent(agent)

worker.start()

См. примеры устойчивых задач Python, включая размещение с одним агентом, маршрутизацию с несколькими агентами, надежную потоковую передачу, цепочку оркестрации, параллелизм, условные условия и шаблоны цикла с одним агентом.

Рабочие процессы платформы устойчивых агентов

Устойчивость не ограничивается устойчивыми оркестрациями. Microsoft рабочих процессов Agent Framework, созданных с помощью модели рабочих процессов на основе графов, также можно сделать устойчивыми. Контрольные точки устойчивых расширений выполняют рабочий процесс, поэтому завершенные действия исполнителя и агента не повторяются после перезапуска или сбоя процесса.

Используйте устойчивые оркестрации, если требуется императивная координация с ветвлением на основе кода, таймерами, действиями и внешними событиями. Используйте устойчивые рабочие процессы Agent Framework, если требуется декларативный граф исполнителей и агентов с типизированной маршрутизацией, вентилятором и вентилятором, условными краями, событиями рабочего процесса, общим состоянием, вложенными рабочими процессами или портами запросов в цикле.

Note

Рабочие процессы устойчивых агентов отличаются от хранилища контрольных точек в стандартных рабочих процессах. Хранилище контрольных точек помогает возобновить выполнение рабочего процесса в среде выполнения Agent Framework. Устойчивый модуль запускает рабочий процесс в инфраструктуре устойчивых задач, чтобы ход выполнения рабочего процесса был контрольным и восстановлен между распределенными устойчивыми рабочими возможностями. Сведения о стандартной контрольной точке рабочего процесса см. в разделе "Контрольные точки" и "Возобновление".

Зарегистрируйте рабочие процессы на основе графов с помощью ConfigureDurableWorkflows для локальных приложений или ConfigureDurableWorkflows в построителе приложений "Функции" для размещения Функции Azure.

См. примеры Функции Azure< Функции Azure .NET> и .NET устойчивых рабочих процессов.

Примеры устойчивых рабочих процессов доступны для размещения Функции Azure, включая общее состояние, общее состояние, параллельное выполнение рабочих процессов и рабочие процессы в цикле.

Примеры Python Функции Azure для устойчивых агентов, оркестрации, сервера MCP и рабочих процессов.

Samples

Language Модель размещения Samples
C# Функции Azure .NET устойчивые агенты — Функции Azure, .NET устойчивые рабочие процессы — Функции Azure
C# Перенос собственных вычислений или локально размещенных .NET устойчивые агенты — консольные приложения, .NET устойчивые рабочие процессы — консольные приложения
Python Функции Azure примеры Python Функции Azure
Python Перенос собственных вычислений или локально размещенных Python примеры устойчивых задач

Потоки агента с отслеживанием состояния с журналом бесед

Агенты поддерживают постоянные потоки, которые продолжают существовать в течение нескольких взаимодействий. Каждый поток определяется уникальным идентификатором потока и сохраняет полный журнал бесед в устойчивом хранилище, управляемом инфраструктурой устойчивых задач, например планировщик устойчивых задач.

Этот шаблон позволяет обеспечить непрерывность бесед, в которой состояние агента сохраняется с помощью сбоев процесса и перезапусков, что позволяет поддерживать полный журнал бесед в потоках пользователей. Устойчивое хранилище гарантирует, что даже если процесс узла перезагружается или возобновляет работу в другом рабочем экземпляре, беседа легко продолжается с того места, где он остался.

Используйте очистку времени сеанса (TTL) для рабочих нагрузок, которые нуждаются в устойчивой непрерывности во время активного использования, но должны автоматически очищать бездействующие беседы. Очистка на основе TTL предотвращает накопление неиспользуемых сеансов и журнала бесед при сохранении активного состояния сеанса.

В следующем Функции Azure примере показано несколько HTTP-запросов к одному потоку, в котором показано, как сохраняется контекст беседы. В локальных приложениях используйте API клиента устойчивых задач из собственного процесса или службы.

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

Состояние агента сохраняется в надежном хранилище, что позволяет распределенное выполнение на нескольких процессах. Любой экземпляр может возобновить выполнение агента после прерываний или сбоев, обеспечивая непрерывную операцию.

Надежная потоковая передача

Устойчивое расширение поддерживает надежную потоковую передачу для приложений, которым требуется доставка маркеров в режиме реального времени с устойчивыми гарантиями доставки. Потоковая передача может использоваться с основным расширением в обеих моделях размещения, но распределенные узлы нуждаются в надежном брокере потоковой передачи, например Redis, поэтому потоки маркеров можно обеспечить согласованно во время перезапусков процессов, повторного подключения или рабочих изменений.

Используйте надежную потоковую передачу, если взаимодействие с пользователем зависит от добавочных ответов, но рабочая нагрузка по-прежнему нуждается в устойчивой семантике выполнения. Примеры запуска см. в примерах Python устойчивых задач, включая надежные шаблоны потоковой передачи.

Детерминированные оркестрации с несколькими агентами

Устойчивое расширение поддерживает создание детерминированных рабочих процессов, которые координирует несколько агентов с помощью оркестрации устойчивых задач. В Функции Azure используются Устойчивые функции оркестрации; в узлах собственных вычислений они выполняются через настраиваемую рабочую роль устойчивых задач и клиент.

Оркестрации — это рабочие процессы на основе кода, которые координируют несколько различных операций (например, вызовы агента, внешние вызовы API или таймеры) надежным способом. Детерминированный означает, что код оркестрации выполняется так же, как при повторном воспроизведении после сбоя, что делает рабочие процессы надежными и отлаживаемыми— при повторном воспроизведении журнала оркестрации можно увидеть точно то, что произошло на каждом шаге.

Оркестрации выполняются надежно, выживая сбои между вызовами агента, а также обеспечивают прогнозируемые и повторяющиеся процессы. Это делает их идеальными для сложных сценариев с несколькими агентами, где требуется гарантированное порядок выполнения и отказоустойчивость.

Последовательные оркестрации

В последовательном шаблоне нескольких агентов специализированные агенты выполняются в определенном порядке, где выходные данные каждого агента могут повлиять на выполнение следующего агента. Этот шаблон поддерживает условную логику и ветвление на основе ответов агента.

При работе с агентами в оркестрации необходимо использовать context.GetAgent() API для получения экземпляра DurableAIAgent, который является специальным подклассом стандартного типа AIAgent, инкапсулирующего одного из зарегистрированных агентов. Оболочка DurableAIAgent гарантирует правильность отслеживания вызовов агента и контрольных точек платформой устойчивой оркестрации.

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

При использовании агентов в оркестрации необходимо использовать app.get_agent() метод для получения устойчивого экземпляра агента, который является специальной оболочкой для одного из зарегистрированных агентов. Оболочка устойчивого агента гарантирует правильность отслеживания вызовов агента и контрольных точек в рамках устойчивой платформы оркестрации.

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

Оркестрации координируют работу между несколькими агентами, справляясь с ошибками между вызовами агентов. Контекст оркестрации предоставляет методы для извлечения и взаимодействия с размещёнными агентами в рамках оркестраций.

Параллельные оркестрации

В многоагентном параллельном шаблоне вы одновременно выполняете несколько агентов, а затем агрегируете их результаты. Этот шаблон полезен для одновременного сбора разнообразных перспектив или обработки независимых подзадач.

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

Параллельное выполнение отслеживается с помощью списка задач. Автоматические контрольные точки гарантируют, что завершенные выполнения агента не повторяются и не теряются при сбое во время агрегирования.

Оркестрации "человек в цикле"

Детерминированные оркестрации агентов могут приостановить ввод, утверждение или проверку без использования вычислительных ресурсов. Устойчивое выполнение позволяет оркестрации ждать в течение нескольких дней или даже недель во время ожидания человеческих ответов. При сочетании с бессерверным размещением все вычислительные ресурсы отключаются в период ожидания, устраняя затраты на вычисления, пока пользователь не предоставит свои входные данные.

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

Детерминированные оркестрации агентов могут ожидать внешних событий, надежно сохраняя свое состояние во время ожидания человеческой обратной связи, переживая сбои, перезапуски и длительные периоды ожидания. Когда ответ человека поступает, оркестрация автоматически возобновляется с полным контекстом беседы и состоянием выполнения без изменений.

Предоставление человеческих данных

Чтобы отправить утверждение или входные данные в оркестрацию ожидания, создайте внешнее событие в экземпляр оркестрации с помощью пакета SDK для клиента устойчивых задач или конечных точек Функции Azure устойчивых расширений. Например, рецензент может утвердить содержимое через веб-форму, которая вызывает:

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)

Рентабельность

Рабочие процессы с участием человека и долговечными агентами являются чрезвычайно экономичными при размещении на плане потребления функций Azure Flex. Для рабочего процесса, ожидающего 24 часа утверждения, вы оплачиваете только несколько секунд выполнения (время для создания содержимого, отправки уведомления и обработки ответа) — не за 24 часа ожидания. В период ожидания вычислительные ресурсы не используются.

Наблюдаемость с помощью планировщика устойчивых задач

Устойчивый планировщик задач (DTS) — это рекомендуемая устойчивая серверная часть для ваших агентов, обеспечивающая наилучшую производительность, полностью управляемую инфраструктуру и встроенную наблюдаемость через интерфейсную панель. Функции Azure приложения могут использовать другие серверные серверы хранилища (например, служба хранилища Azure), но DTS оптимизирован специально для устойчивых рабочих нагрузок и обеспечивает более высокую производительность и возможности мониторинга. Локальные рабочие роли также используют DTS для устойчивого планирования, состояния и видимости панели мониторинга.

Аналитика сеанса агента

  • Журнал бесед: просмотр полного журнала чата для каждого сеанса агента, включая все сообщения, вызовы инструментов и контекст беседы в любой момент времени
  • Время выполнения задачи: мониторинг времени выполнения конкретных задач и взаимодействий с агентом

Снимок экрана: панель мониторинга планировщика устойчивых задач с журналом чата агента с потоками бесед и сообщениями.

Аналитика оркестрации

  • Визуализация с несколькими агентами: см. поток выполнения при вызове нескольких специализированных агентов с визуальным представлением параллельных выполнений и условной ветвью
  • Журнал выполнения. Доступ к подробным журналам выполнения
  • Мониторинг в режиме реального времени: отслеживание активных оркестраций, поставленных в очередь рабочих элементов и состояний агентов в развертывании
  • Метрики производительности: отслеживайте время отклика агентов, использование токенов и продолжительность оркестрации.

Снимок экрана панели управления планировщика долговечных задач, отображающий визуализацию оркестрации с различными взаимодействиями агентов и выполнением рабочего процесса.

Возможности отладки

  • Просмотр структурированных выходных данных агента и результатов вызова средства
  • Вызовы средств трассировки и их результаты
  • Мониторинг обработки внешних событий для сценариев взаимодействия с человеком

Панель мониторинга позволяет точно понять, что делают агенты, быстро диагностировать проблемы и оптимизировать производительность на основе реальных данных выполнения.

Руководство. Создание и запуск устойчивого агента с помощью Функции Azure

В этом руководстве показано, как создать и запустить устойчивый агент ИИ с помощью модели размещения Функции Azure для расширения Устойчивый. Вы создадите приложение Функций Azure, в котором размещен агент с отслеживанием состояния со встроенными конечными точками HTTP, и узнайте, как отслеживать его с помощью панели мониторинга планировщика устойчивых задач. Примеры см. в примерах для локальных агентов.

Необходимые условия

Перед началом работы убедитесь, что у вас есть следующие предварительные требования:

Note

Microsoft Agent Framework поддерживается всеми активно поддерживаемыми версиями .NET. В целях этого примера рекомендуется использовать пакет SDK для .NET 9 или более позднюю версию.

Скачивание проекта быстрого запуска

Инициализация нового проекта из шаблона быстрого запуска устойчивых агентов с помощью Интерфейса командной строки разработчика Azure.

  1. Создайте новый каталог для проекта и перейдите к нему:

    mkdir MyDurableAgent
    cd MyDurableAgent
    

  1. Инициализировать проект из шаблона:

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

    При появлении запроса на имя среды введите имя, например my-durable-agent.

Скачайте проект быстрого запуска со всеми необходимыми файлами, включая конфигурацию Функций Azure, код агента и инфраструктуру в качестве шаблонов кода.

  1. Создайте новый каталог для проекта и перейдите к нему:

    mkdir MyDurableAgent
    cd MyDurableAgent
    

  1. Инициализировать проект из шаблона:

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

    При появлении запроса на имя среды введите имя, например my-durable-agent.

  2. Создайте и активируйте виртуальную среду:

    uv venv .venv
    source .venv/bin/activate
    

Note

python3 -m venv .venv также работает, но может зависать неограниченное время на Windows с Microsoft Store Python из-за известной проблемы ensurepip. Используйте uv venv .venv , чтобы избежать этого.

  1. Установите необходимые пакеты:

    python -m pip install -r requirements.txt
    

Скачайте проект быстрого запуска со всеми необходимыми файлами, включая конфигурацию Функций Azure, код агента и инфраструктуру в качестве шаблонов кода. Он также подготавливает виртуальную среду с необходимыми зависимостями.

Развертывание ресурсов Azure

Используйте CLI разработчика Azure для создания необходимых ресурсов Azure для Durable Agent.

  1. Подготовка инфраструктуры:

    azd provision
    

    Эта команда создает следующее:

    • Служба Azure OpenAI с развертыванием gpt-4o-mini
    • Приложение Функции Azure с тарифным планом Flex Consumption
    • Учетная запись хранения Azure для среды выполнения Функций Azure и устойчивого хранилища
    • Экземпляр планировщика устойчивых задач (план потребления) для управления состоянием агента
    • Необходимые сетевые и идентификационные конфигурации
  2. При появлении запроса выберите подписку Azure и укажите расположение для ресурсов.

Процесс подготовки занимает несколько минут. После завершения azd сохраняет сведения о созданном ресурсе в вашей среде.

Просмотреть код агента

Теперь давайте рассмотрим код, определяющий устойчивый агент.

Откройте Program.cs , чтобы просмотреть конфигурацию агента:

using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Hosting.AzureFunctions;
using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Extensions.Hosting;

var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") 
    ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT environment variable is not set");
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT") ?? "gpt-4o-mini";

// Create an AI agent following the standard Microsoft Agent Framework pattern
AIAgent agent = new AIProjectClient(new Uri(endpoint), new DefaultAzureCredential())
    .AsAIAgent(
        model: deploymentName,
        instructions: "You are a helpful assistant that can answer questions and provide information.",
        name: "MyDurableAgent");

using IHost app = FunctionsApplication
    .CreateBuilder(args)
    .ConfigureFunctionsWebApplication()
    .ConfigureDurableAgents(options => options.AddAIAgent(agent))
    .Build();
app.Run();

Этот код:

  1. Извлекает конфигурацию Azure OpenAI из переменных среды.
  2. Создает клиент Azure OpenAI с помощью учетных данных Azure.
  3. Создает агент ИИ с инструкциями и именем.
  4. Настраивает приложение Функции Azure для размещения агента с использованием надежного управления потоками.

Откройте function_app.py , чтобы просмотреть конфигурацию агента:

import os
from agent_framework.azure import AgentFunctionApp
from agent_framework.openai import OpenAIChatCompletionClient
from azure.identity import DefaultAzureCredential

endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")
if not endpoint:
    raise ValueError("AZURE_OPENAI_ENDPOINT is not set.")
deployment_name = os.getenv("AZURE_OPENAI_CHAT_COMPLETION_MODEL", "gpt-4o-mini")
api_version = os.getenv("AZURE_OPENAI_API_VERSION")

# Create an AI agent following the standard Microsoft Agent Framework pattern
agent = OpenAIChatCompletionClient(
    azure_endpoint=endpoint,
    model=deployment_name,
    api_version=api_version,
    credential=DefaultAzureCredential()
).as_agent(
    instructions="You are a helpful assistant that can answer questions and provide information.",
    name="MyDurableAgent"
)

# Configure the function app to host the agent with durable thread management
app = AgentFunctionApp(agents=[agent])

Этот код:

  • Извлекает конфигурацию Azure OpenAI из переменных среды.
  • Создает клиент Azure OpenAI с помощью учетных данных Azure.
  • Создает агент ИИ с инструкциями и именем.
  • Настраивает приложение Функции Azure для размещения агента с использованием надежного управления потоками.

Теперь агент готов к размещению в Функции Azure. Расширение долговечных задач автоматически создает конечные точки HTTP для взаимодействия с вашим агентом и управляет состоянием взаимодействия в рамках нескольких запросов.

Настройка локальных параметров

local.settings.json Создайте файл для локальной разработки на основе примера файла, включенного в проект.

  1. Скопируйте файл параметров примера:

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

  1. Получите конечную точку Azure OpenAI из подготовленных ресурсов:

    azd env get-value AZURE_OPENAI_ENDPOINT
    
  2. Откройте local.settings.json и замените <your-resource-name> значение конечной AZURE_OPENAI_ENDPOINT точкой из предыдущей команды.

Ваш local.settings.json должен выглядеть следующим образом:

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

Note

Файл local.settings.json используется только для локальной разработки и не развертывается в Azure. Для рабочих развертываний эти параметры автоматически настраиваются в приложении "Функции Azure" шаблонами инфраструктуры.

Запуск локальных зависимостей разработки

Для локального запуска безотказных агентов необходимо запустить две службы:

  • Azurite: эмулирует службы хранилища Azure (используется функциями Azure для управления триггерами и внутренним состоянием).
  • Эмулятор планировщика устойчивых задач (DTS): управление устойчивым состоянием (журнал беседы, состояние оркестрации) и планированием для агентов

Запуск Azurite

Azurite эмулирует службы хранилища Azure локально. Функции Azure используют его для управления внутренним состоянием. Вам нужно запустить это в новом окне терминала и поддерживать его работу в процессе разработки и тестирования устойчивого программного агента.

  1. Откройте новое окно терминала и извлеките образ Azurite Docker:

    docker pull mcr.microsoft.com/azure-storage/azurite
    
  2. Запустите Azurite в окне терминала:

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

    Azurite начнет прослушивание на портах по умолчанию для служб Blob (10000), очереди (10001) и таблицы (10002).

Оставьте это окно терминала открытым во время разработки и тестирования долговечного агента.

Tip

Дополнительные сведения об Azurite, включая альтернативные методы установки, см. в статье Об использовании эмулятора Azurite для разработки локальной службы хранилища Azure.

Запустите эмулятор Планировщика устойчивых задач

Эмулятор DTS предоставляет надёжную серверную часть для управления состоянием агента и оркестрациями. Он сохраняет журнал бесед и гарантирует, что состояние агента сохраняется во время перезапуска. Он также активирует долговечные оркестрации и агентов. Вам потребуется запустить это в отдельном новом окне терминала и оставить его работающим, пока вы будете разрабатывать и тестировать устойчивого агента.

  1. Откройте другое новое окно терминала и извлеките образ Docker эмулятора DTS:

    docker pull mcr.microsoft.com/dts/dts-emulator:latest
    
  2. Запустите эмулятор DTS:

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

    Эта команда запускает эмулятор и предоставляет:

    • Порт 8080: конечная точка gRPC для планировщика устойчивых задач (используется приложением "Функции")
    • Порт 8082: информационная панель администрирования
  3. Панель мониторинга будет доступна по адресу http://localhost:8082.

Оставьте это окно терминала открытым во время разработки и тестирования долговечного агента.

Tip

Дополнительные сведения о эмуляторе DTS, включая настройку нескольких центров задач и доступ к панели мониторинга, см. в статье "Разработка с помощью планировщика устойчивых задач".

Запустите функциональное приложение

Теперь вы готовы запустить приложение Функций Azure с устойчивым агентом.

  1. В новом окне терминала (оставляя Azurite и эмулятор DTS работающими в отдельных окнах), перейдите в каталог проекта.

  2. Запустите среду выполнения Функций Azure:

    func start
    
  3. Вы увидите выходные данные, указывающие, что приложение-функция запущено, включая конечные точки HTTP для агента:

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

Эти конечные точки автоматически управляют состоянием беседы. Вам не нужно самостоятельно создавать или управлять объектами потоков.

Тестируйте агента локально

Теперь вы можете взаимодействовать с устойчивым агентом с помощью HTTP-запросов. Агент поддерживает контекст беседы во многих запросах, что позволяет вести многоходовые разговоры.

Запуск новой беседы

Создайте новый поток и отправьте первое сообщение:

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

Пример ответа (обратите внимание, что x-ms-thread-id заголовок содержит идентификатор потока):

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.

Сохраните идентификатор потока из заголовка x-ms-thread-id (например, @dafx-mydurableagent@263fa373-fa01-4705-abf2-5a114c2bb87d) для следующего запроса.

Продолжить беседу

Отправьте следующее сообщение в тот же поток, включив идентификатор потока в качестве параметра запроса:

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

Замените @dafx-mydurableagent@263fa373-fa01-4705-abf2-5a114c2bb87d фактическим идентификатором потока из заголовка предыдущего x-ms-thread-id ответа.

Пример ответа:

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.

Обратите внимание, что агент запоминает контекст из предыдущего сообщения (три языка программирования) без необходимости их повторно указывать. Поскольку состояние беседы хранится в Диспетчере устойчивых задач, этот журнал может сохраняться, даже если вы перезапустите функциональное приложение или беседа будет возобновлена другим экземпляром.

Мониторинг с помощью панели планировщика долговременных задач

Планировщик устойчивых задач предоставляет встроенную панель мониторинга для мониторинга и отладки устойчивых агентов. Панель мониторинга обеспечивает детальное представление операций агента, истории бесед и потока выполнения.

Доступ к панели мониторинга

  1. Откройте панель мониторинга для локального эмулятора http://localhost:8082 DTS в веб-браузере.

  2. Выберите центр задач по умолчанию в списке, чтобы просмотреть его сведения.

  3. Щелкните значок шестеренки в правом верхнем углу, чтобы открыть параметры, и убедитесь, что выбран параметр "Включить страницы агента " в разделе "Предварительные версии компонентов ".

Изучение бесед агентов

  1. На панели мониторинга перейдите на вкладку "Агенты ".

  2. Выберите в списке поток устойчивых агентов (например, mydurableagent - 263fa373-fa01-4705-abf2-5a114c2bb87d).

    Вы увидите подробное представление потока агента, включая полный журнал бесед со всеми сообщениями и ответами.

    Снимок экрана панели управления Durable Task Scheduler, показывающий историю переписки потоков агента.

Панель мониторинга предоставляет представление временной шкалы для понимания потока беседы. К ключевым сведениям относятся:

  • Метки времени и длительность каждого взаимодействия
  • Содержимое запроса и ответа
  • Количество используемых токенов

Tip

Панель мониторинга DTS предоставляет обновления в режиме реального времени, поэтому вы можете наблюдать за поведением агента при взаимодействии с ним через конечные точки HTTP.

Развертывание в Azure

Теперь, когда вы протестировали устойчивый агент локально, разверните его в Azure.

  1. Разверните приложение:

    azd deploy
    

    Эта команда упаковывает приложение и развертывает его в приложении Функции Azure, созданном во время подготовки.

  2. Дождитесь завершения развертывания. Когда ваш агент будет запущен в Azure, выходные данные подтвердят это.

Тестирование развернутого агента

После развертывания проверьте агент, работающий в Azure.

Получение ключа функции

Для функций Azure требуется ключ API для функций, активированных HTTP, в рабочей среде:

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`

Запуск новой беседы в Azure

Создайте новую тему и отправьте свое первое сообщение развернутому агенту:

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

Обратите внимание на идентификатор потока, возвращенный в заголовке x-ms-thread-id ответа.

Продолжить беседу в Azure

Отправьте следующее сообщение в том же потоке. Замените <thread-id> на идентификатор потока из предыдущего ответа.

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

Агент поддерживает контекст беседы в Azure так же, как и локально, демонстрируя устойчивость состояния агента.

Мониторьте развернутого агента

Вы можете следить за развернутым агентом с помощью панели мониторинга планировщика долговременных задач в Azure.

  1. Получите имя экземпляра планировщика устойчивых задач:

    azd env get-value DTS_NAME
    
  2. Откройте портал Azure и найдите имя планировщика устойчивых задач на предыдущем шаге.

  3. В панели обзора ресурса планировщика устойчивых задач выберите хаб задач по умолчанию из списка.

  4. Выберите "Открыть панель мониторинга" в верхней части страницы центра задач, чтобы открыть панель мониторинга.

  5. Просматривайте беседы агента так же, как и в локальном эмуляторе.

Панель мониторинга, размещенная в Azure, предоставляет те же возможности отладки и мониторинга, что и локальный эмулятор, что позволяет проверять журнал бесед, вызовы средств трассировки и анализировать производительность в рабочей среде.

Руководство. Оркестрация устойчивых агентов с помощью Функции Azure

В этом руководстве показано, как оркестрировать несколько устойчивых агентов ИИ с помощью модели размещения Функции Azure и шаблона вентилятора или вентилятора. Вы расширите устойчивый агент из предыдущего руководства , чтобы создать систему с несколькими агентами, которая обрабатывает вопрос пользователя, а затем преобразует ответ на несколько языков одновременно. Примеры локальной оркестрации см. в примерах.

Общие сведения о шаблоне оркестрации

Оркестрация, которую вы создадите, следует этому потоку:

  1. Входные данные пользователя — вопрос или сообщение от пользователя
  2. Главный агентMyDurableAgent из первого туториала обрабатывает вопрос
  3. Фан-аут — ответ основного агента отправляется одновременно обоим агентам перевода
  4. Агенты перевода — два специализированных агента переводят ответ (французский и испанский)
  5. Fan-in — результаты собираются в единый ответ JSON, содержащий исходный ответ и переводы

Этот шаблон позволяет одновременно обрабатывать, уменьшая общее время отклика по сравнению с последовательным переводом.

Регистрация агентов при запуске

Чтобы корректно использовать агентов в стабильных оркестрациях, зарегистрируйте их при запуске приложения. Их можно использовать в различных случаях выполнения оркестрации.

Обновите ваш Program.cs, чтобы зарегистрировать агентов перевода вместе с существующим MyDurableAgent.

using System;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Hosting.AzureFunctions;
using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Extensions.Hosting;

// Get the Azure OpenAI configuration
string endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")
    ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
string deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT")
    ?? "gpt-4o-mini";

// Create the Microsoft Foundry client
AIProjectClient client = new(new Uri(endpoint), new DefaultAzureCredential());

// Create the main agent from the first tutorial
AIAgent mainAgent = client.AsAIAgent(
    model: deploymentName,
    instructions: "You are a helpful assistant that can answer questions and provide information.",
    name: "MyDurableAgent");

// Create translation agents
AIAgent frenchAgent = client.AsAIAgent(
    model: deploymentName,
    instructions: "You are a translator. Translate the following text to French. Return only the translation, no explanations.",
    name: "FrenchTranslator");

AIAgent spanishAgent = client.AsAIAgent(
    model: deploymentName,
    instructions: "You are a translator. Translate the following text to Spanish. Return only the translation, no explanations.",
    name: "SpanishTranslator");

// Build and configure the Functions host
using IHost app = FunctionsApplication
    .CreateBuilder(args)
    .ConfigureFunctionsWebApplication()
    .ConfigureDurableAgents(options =>
    {
        // Register all agents for use in orchestrations and HTTP endpoints
        options.AddAIAgent(mainAgent);
        options.AddAIAgent(frenchAgent);
        options.AddAIAgent(spanishAgent);
    })
    .Build();

app.Run();

Обновите ваш function_app.py, чтобы зарегистрировать агентов перевода вместе с существующим MyDurableAgent.

import os
from azure.identity import DefaultAzureCredential
from agent_framework.azure import AgentFunctionApp
from agent_framework.openai import OpenAIChatCompletionClient

# Get the Azure OpenAI configuration
endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")
if not endpoint:
    raise ValueError("AZURE_OPENAI_ENDPOINT is not set.")
deployment_name = os.getenv("AZURE_OPENAI_CHAT_COMPLETION_MODEL", "gpt-4o-mini")
api_version = os.getenv("AZURE_OPENAI_API_VERSION")

# Create the Azure OpenAI client
chat_client = OpenAIChatCompletionClient(
    azure_endpoint=endpoint,
    model=deployment_name,
    api_version=api_version,
    credential=DefaultAzureCredential()
)

# Create the main agent from the first tutorial
main_agent = chat_client.as_agent(
    instructions="You are a helpful assistant that can answer questions and provide information.",
    name="MyDurableAgent"
)

# Create translation agents
french_agent = chat_client.as_agent(
    instructions="You are a translator. Translate the following text to French. Return only the translation, no explanations.",
    name="FrenchTranslator"
)

spanish_agent = chat_client.as_agent(
    instructions="You are a translator. Translate the following text to Spanish. Return only the translation, no explanations.",
    name="SpanishTranslator"
)

# Create the function app and register all agents
app = AgentFunctionApp(agents=[main_agent, french_agent, spanish_agent])

Создание функции оркестрации

Функция оркестрации координирует рабочий процесс между несколькими агентами. Он извлекает зарегистрированных агентов из устойчивого контекста и организует их выполнение, сначала вызывая основного агента, а затем распределяя выполнение агентов обработки перевода одновременно.

Создайте файл с именем AgentOrchestration.cs в каталоге проекта:

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

Добавьте функцию оркестрации в 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

Тестирование оркестрации

Убедитесь, что локальные зависимости разработки из первого руководства по-прежнему выполняются:

  • Azurite в одном окне терминала
  • Эмулятор планировщика устойчивых задач в другом окне терминала

При запуске локальных зависимостей разработки:

  1. Запустите приложение Функций Azure в новом окне терминала:

    func start
    
  2. Расширение Устойчивые функции автоматически создает встроенные HTTP точки входа для управления оркестрациями. Запустите оркестрацию с помощью встроенного 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. Ответ содержит URL-адреса для управления оркестрационным экземпляром.

    {
      "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. Запросите состояние оркестрации с помощью команды statusQueryGetUri (замените abc123def456 на фактический идентификатор вашего экземпляра).

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

  1. Выполняйте опрос состояния конечной точки до тех пор, пока runtimeStatus не станет Completed. По завершении вы увидите результаты оркестрации с ответом главного агента и его переводами.

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

Отслеживайте оркестрацию на информационной панели

Панель мониторинга планировщика задач Durable Task Scheduler обеспечивает видимость вашей оркестрации:

  1. Откройте http://localhost:8082 в браузере.

  2. Выберите концентратор задач по умолчанию.

  3. Перейдите на вкладку "Оркестрации".

  4. Найдите экземпляр оркестрации в списке.

  5. Выберите экземпляр, чтобы увидеть:

    • Временная шкала оркестрации
    • Выполнение основного агента, за которым следует параллельные агенты перевода
    • Каждое выполнение агента (MyDurableAgent, затем запуск французского и испанского переводчиков)
    • Визуализация моделей расширения и объединения
    • Время и длительность каждого шага

Развертывание оркестрации в Azure

Разверните обновленное приложение с помощью Интерфейса командной строки разработчика Azure:

azd deploy

Это позволяет развернуть обновленный код с новой функцией оркестрации и дополнительными агентами в приложении Функции Azure, созданном в первом руководстве.

Протестируйте развернутую оркестрацию

После развертывания проверьте оркестрацию, запущенную в Azure.

  1. Получите системный ключ для устойчивого расширения:

    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. Запустите оркестрацию с помощью встроенного 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. Используйте statusQueryGetUri из ответа, чтобы опросить статус завершения и просмотреть результаты с переводами.

Дальнейшие действия

Дополнительные ресурсы: