Создание многоагентных систем искусственного интеллекта с помощью Microsoft Agent Framework

· 11 мин чтения

Введение

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

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

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

Что такое платформа агентов Microsoft?

Agent Framework — это ответ Microsoft на создание, оркестрацию и развертывание агентов искусственного интеллекта и многоагентных систем в .NET. Он находится рядом и глубоко интегрируется с семантическим ядром, которое с 2023 года является SDK Microsoft с открытым исходным кодом для оркестрации ИИ.

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

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

Ключевые возможности включают в себя:

  • Несколько типов агентов: ChatCompletionAgent, OpenAIAssistantAgent и AzureAIAgent для разных серверов.
  • Шаблоны оркестровки: последовательные, одновременные, перераспределяющие и групповые рабочие процессы чата.
  • Экосистема плагинов: расширяйте возможности агентов с помощью встроенных функций C#, спецификаций OpenAPI и инструментов протокола контекста модели (MCP).
  • Управление беседами: встроенные функции управления потоками, историей и стратегиями завершения.
  • Наблюдаемость: интеграция с OpenTelemetry для отслеживания взаимодействия агентов.

Ключевые понятия

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

Агенты

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

ChatCompletionAgentСамый простой тип агента. Он оборачивает конечную точку завершения чата (Azure OpenAI, OpenAI и т. д.) и поддерживает разговор. Между вызовами он не имеет состояния — вы предоставляете историю, и он отвечает. Это делает его легким и понятным.

[[[ТОК_3]]]

OpenAIAssistantAgent

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

[[[ТОК_4]]]

###ГрупповойЧат Агента

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

Шаблоны оркестровки

Платформа поддерживает четыре основных шаблона оркестровки, каждый из которых подходит для решения различных задач.

Последовательный

Агенты выполняются один за другим в определенном порядке. Выходные данные агента A передаются агенту B, чьи выходные данные передаются агенту C. Это идеально подходит для конвейеров: черновик → просмотр → редактирование → публикация.

[[[ТОК_6]]]

Параллельно

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

Передача

Агент решает передать управление другому агенту в зависимости от контекста разговора. Это имитирует работу команды обслуживания клиентов: агент первой линии обрабатывает базовые запросы и при необходимости передает их специалистам.

Групповой чат

В открытом разговоре участвуют несколько агентов, по очереди, в зависимости от стратегии выбора. Класс AgentGroupChat реализует этот шаблон с настраиваемой логикой очередности и завершения.

Создайте своего первого агента

Давайте перейдем к практике. Вот как шаг за шагом создать своего первого агента.

Предварительные условия

Вам понадобится:

  • .NET 9 SDK — Ресурс Azure OpenAI с развернутой моделью (например, gpt-4o).
  • Visual Studio или VS Code

Настройка проекта

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

[[[ТОК_9]]]

Создание простого агента

Сначала настройте ядро с вашей конфигурацией Azure OpenAI:

[[[ТОК_10]]]

Теперь создайте агента и вызовите его:

[[[ТОК_11]]]

Вот и все. У вас есть работающий агент. Но настоящая сила приходит, когда агенты работают вместе.

Многоагентная оркестровка с помощью AgentGroupChat

Давайте создадим что-то более интересное — групповой чат, в котором сотрудничают несколько агентов. Класс AgentGroupChat управляет ходом разговора, включая то, кто говорит следующим и когда остановиться.

Определение агентов

Мы создадим трех агентов: писателя, рецензента и редактора.

ChatCompletionAgent writer = new()
{
    Name = "Writer",
    Instructions = """
        You are a content writer. When given a topic, produce a well-structured
        draft. Focus on clarity and technical accuracy.
        When you receive feedback from the Reviewer, incorporate it into a
        revised draft.
        """,
    Kernel = kernel
};

ChatCompletionAgent reviewer = new()
{
    Name = "Reviewer",
    Instructions = """
        You are a content reviewer. Analyze drafts for technical accuracy,
        clarity, and completeness. Provide specific, actionable feedback.
        Do NOT rewrite the content  only provide feedback.
        When the content meets your standards, respond with: APPROVED
        """,
    Kernel = kernel
};

ChatCompletionAgent editor = new()
{
    Name = "Editor",
    Instructions = """
        You are an editor. Once content is approved by the Reviewer,
        polish it for grammar, tone, and formatting.
        Output only the final polished version.
        When you have produced the final version, respond with: COMPLETE
        """,
    Kernel = kernel
};

Настройка группового чата

Для AgentGroupChat необходимы две ключевые конфигурации: стратегия выбора (кто говорит следующим) и стратегия завершения (когда остановиться).

AgentGroupChat chat = new(writer, reviewer, editor)
{
    ExecutionSettings = new()
    {
        SelectionStrategy = new SequentialSelectionStrategy(),
        TerminationStrategy = new ApprovalTerminationStrategy()
        {
            Agents = [editor],
            MaximumIterations = 12
        }
    }
};

Пользовательская стратегия завершенияСтратегия завершения определяет, когда разговор заканчивается. Вот специальный вариант, который ищет ключевое слово «COMPLETE»:

class ApprovalTerminationStrategy : TerminationStrategy
{
    protected override Task<bool> ShouldAgentTerminateAsync(
        Agent agent,
        IReadOnlyList<ChatMessageContent> history,
        CancellationToken cancellationToken = default)
    {
        bool isComplete = history
            .Last()
            .Content?
            .Contains("COMPLETE", StringComparison.OrdinalIgnoreCase) ?? false;

        return Task.FromResult(isComplete);
    }
}

Ведение разговора

Начните разговор с пользовательского сообщения и позвольте агентам сотрудничать:

chat.AddChatMessage(
    new ChatMessageContent(AuthorRole.User,
        "Write a 300-word technical overview of gRPC vs REST for microservices.")
);

await foreach (ChatMessageContent message in chat.InvokeAsync())
{
    Console.WriteLine($"[{message.AuthorName}]: {message.Content}");
    Console.WriteLine("---");
}

Поток будет выглядеть примерно так:

  1. Автор создает черновик
  2. Рецензент оставляет отзыв.
  3. Автор вносит правки на основе отзывов.
  4. Рецензент говорит: «УТВЕРЖДЕНО».
  5. Редактор доводит до ума и говорит: «ЗАВЕРШЕНО».
  6. Разговор завершается.

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

Плагины и инструменты

Агенты становятся по-настоящему мощными, когда они могут взаимодействовать с внешними системами. Agent Framework поддерживает три основных механизма расширения.

Собственные функции (плагины ядра)

Вы можете предоставить агентам доступ к методам C# в качестве инструментов. Агент вызовет эти функции, когда определит, что они необходимы:

public class ContentToolsPlugin
{
    [KernelFunction("word_count")]
    [Description("Counts the number of words in the provided text.")]
    public int WordCount([Description("The text to count words in")] string text)
    {
        return text.Split(' ', StringSplitOptions.RemoveEmptyEntries).Length;
    }

    [KernelFunction("check_readability")]
    [Description("Calculates a readability score for the given text.")]
    public string CheckReadability([Description("The text to analyze")] string text)
    {
        var words = text.Split(' ', StringSplitOptions.RemoveEmptyEntries).Length;
        var sentences = text.Split(['.', '!', '?'], StringSplitOptions.RemoveEmptyEntries).Length;

        if (sentences == 0) return "Unable to calculate — no sentences found.";

        double avgWordsPerSentence = (double)words / sentences;

        return avgWordsPerSentence switch
        {
            < 15 => $"Easy to read (avg {avgWordsPerSentence:F1} words/sentence)",
            < 25 => $"Moderate difficulty (avg {avgWordsPerSentence:F1} words/sentence)",
            _ => $"Difficult to read (avg {avgWordsPerSentence:F1} words/sentence). Consider shorter sentences."
        };
    }
}

Зарегистрируйте плагин в ядре перед созданием агента:

kernel.Plugins.AddFromType<ContentToolsPlugin>();

ChatCompletionAgent analyst = new()
{
    Name = "ContentAnalyst",
    Instructions = "Analyze content using available tools. Report word count and readability.",
    Kernel = kernel,
    Arguments = new KernelArguments(
        new PromptExecutionSettings
        {
            FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
        })
};

Протокол контекста модели (MCP)

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

// Example: Adding an MCP server for file operations
kernel.Plugins.AddFromMcpServer("filesystem",
    new Uri("http://localhost:3000/mcp"));

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

Пример из реальной жизни: конвейер проверки контента

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

  1. Исследователь — собирает соответствующую техническую информацию.
  2. Писатель — создает черновик на основе исследований.
  3. Рецензент — проверяет точность и полноту.
  4. Издатель — форматирует и подготавливает окончательный результат.

Вот сокращенная реализация:

using Azure.Identity;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using Microsoft.SemanticKernel.ChatCompletion;

// Build the kernel
var builder = Kernel.CreateBuilder();
builder.AddAzureOpenAIChatCompletion(
    deploymentName: "gpt-4o",
    endpoint: "https://your-resource.openai.azure.com/",
    credentials: new DefaultAzureCredential()
);
Kernel kernel = builder.Build();

// Define specialized agents
ChatCompletionAgent researcher = new()
{
    Name = "Researcher",
    Instructions = """
        You are a technical researcher. Given a topic, identify the key
        concepts, recent developments, and important details that should
        be covered. Output a structured research brief.
        """,
    Kernel = kernel
};

ChatCompletionAgent writer = new()
{
    Name = "Writer",
    Instructions = """
        You are a technical writer. Using the research brief provided,
        write a comprehensive, well-structured article. Include code
        examples where relevant. Target audience: experienced developers.
        """,
    Kernel = kernel
};

ChatCompletionAgent reviewer = new()
{
    Name = "Reviewer",
    Instructions = """
        You are a senior technical reviewer. Check the article for:
        - Technical accuracy
        - Completeness relative to the research brief
        - Code correctness
        - Clarity and structure
        If everything looks good, respond with APPROVED.
        Otherwise, provide specific feedback for revision.
        """,
    Kernel = kernel
};

ChatCompletionAgent publisher = new()
{
    Name = "Publisher",
    Instructions = """
        You are a content publisher. Once the article is approved,
        format it with proper markdown, add a summary at the top,
        and ensure consistent formatting throughout.
        End your response with COMPLETE.
        """,
    Kernel = kernel
};

// Configure the group chat
AgentGroupChat chat = new(researcher, writer, reviewer, publisher)
{
    ExecutionSettings = new()
    {
        SelectionStrategy = new SequentialSelectionStrategy(),
        TerminationStrategy = new ApprovalTerminationStrategy()
        {
            Agents = [publisher],
            MaximumIterations = 15
        }
    }
};

// Start the pipeline
chat.AddChatMessage(new ChatMessageContent(
    AuthorRole.User,
    "Create a technical article about implementing health checks in ASP.NET Core microservices."
));

await foreach (ChatMessageContent message in chat.InvokeAsync())
{
    Console.ForegroundColor = message.AuthorName switch
    {
        "Researcher" => ConsoleColor.Cyan,
        "Writer" => ConsoleColor.Green,
        "Reviewer" => ConsoleColor.Yellow,
        "Publisher" => ConsoleColor.Magenta,
        _ => ConsoleColor.White
    };

    Console.WriteLine($"\n{'='new string('=', 60)}");
    Console.WriteLine($"[{message.AuthorName}]");
    Console.WriteLine(new string('=', 60));
    Console.WriteLine(message.Content);
}

Console.ResetColor();

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

Лучшие практики

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

Обработка ошибок

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

TerminationStrategy = new ApprovalTerminationStrategy()
{
    MaximumIterations = 12 // Safety net
}

Оберните вызовы агента в блоки try-catch. Ограничения скорости API, проблемы с сетью и ошибки моделей — все это реалии производственных систем:

try
{
    await foreach (var message in chat.InvokeAsync(cancellationToken))
    {
        // Process messages
    }
}
catch (HttpOperationException ex) when (ex.StatusCode == System.Net.HttpStatusCode.TooManyRequests)
{
    // Implement retry with exponential backoff
    await Task.Delay(TimeSpan.FromSeconds(30), cancellationToken);
}

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

Настройте базовую телеметрию, добавив пакеты телеметрии семантического ядра и настроив предпочитаемый экспортер (Application Insights, Jaeger и т. д.):

builder.Services.AddOpenTelemetry()
    .WithTracing(tracing =>
    {
        tracing.AddSource("Microsoft.SemanticKernel*");
        tracing.AddOtlpExporter();
    });

Управление затратами

Мультиагентные системы увеличивают ваши затраты на API: каждый поворот агента — это вызов API, а групповые чаты могут генерировать множество поворотов. Некоторые стратегии, позволяющие держать расходы под контролем:

  • Используйте более дешевые модели для более простых агентов: не каждому агенту требуется GPT-4o. Рецензент может прекрасно работать с моделью меньшего размера, в то время как мощный нападающий нужен только автору.
  • Ограничить историю: используйте ReducedHistoryCount в настройках выполнения, чтобы ограничить объем контекста разговора, который получает каждый агент.
  • Установите строгие ограничения на итерацию: предотвращайте неконтролируемые разговоры с разумными значениями MaximumIterations.
  • Кэшировать, когда это возможно: если агент неоднократно выполняет один и тот же поиск, кэшируйте результаты в плагине.

Дизайн агента

  • Соблюдайте четкость инструкций: у каждого агента должна быть единая и четкая ответственность. Широкие инструкции приводят к посредственной производительности во всех задачах. – Четко указывайте формат вывода. Сообщите агентам, как именно структурировать свои ответы. Это делает последующий синтаксический анализ надежным. – Используйте ключевые слова завершения. Определите четкие сигналы (например, «УТВЕРЖДЕНО» или «ЗАВЕРШЕНО»), которые агенты будут использовать, чтобы указать, что они закончили. Это делает стратегии завершения простыми и предсказуемыми.

Заключение

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

Microsoft Agent Framework делает это практичным для разработчиков .NET. Абстракции чистые — агенты, групповые чаты, стратегии выбора и прекращения — и они складываются естественным образом. В сочетании с экосистемой подключаемых модулей Semantic Kernel и хостингом моделей Azure у вас есть полный стек для создания многоагентных систем производственного уровня.

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

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

Приятного кодирования!