Создание совместных и мультиагентных систем с помощью подключенных агентов (классическая модель)

Примечание

Этот документ относится к порталу Microsoft Foundry (классическая модель).

Агенты (классические) в настоящее время устарели и будут удалены 31 марта 2027 года. Используйте новые агенты в общедоступной службе Microsoft Foundry Agents. Следуйте инструкциям по миграции , чтобы обновить рабочие нагрузки.

Примечание

Это средство доступно только в 2025-05-15-preview API. Мы настоятельно рекомендуем мигрировать на использование версии API 2025-11-15-previewрабочих процессов для оркестрации с несколькими агентами.

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

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

Функции

  • Упрощенная разработка рабочего процесса. Разбиите сложные задачи между специализированными агентами, чтобы снизить сложность и повысить ясность.
  • Не требуется настраиваемая оркестрация: основной агент использует естественный язык для маршрутизации задач, устраняя необходимость жесткой логики.
  • Простая расширяемость: добавление новых подключенных агентов (например, перевод или оценка рисков) без изменения основного агента.
  • Улучшенная надежность и возможность трассировки: назначьте конкретные обязанности каждому агенту для упрощения отладки и улучшения возможности аудита.
  • Варианты гибкой настройки: Настройка агентов с помощью интерфейса без необходимости программирования на портале Foundry или программным способом с помощью Python SDK.

Пример. Создание модульного агента проверки контракта с подключенными агентами

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

Обзор архитектуры

Главный агент — оркестратор договора

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

  • Используемые средства: отсутствуют напрямую

  • Обязанности: классификация намерений и делегирование

  • Пример описания агента:

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

Подключенный агент 1: суммаризатор предложений

Извлекает ключевые разделы (например, прекращение, возмещение или конфиденциальность) из контракта и суммирует их на простом языке.

  • Используемые инструменты:

    • Поиск файлов для восстановления загруженного контракта
    • Интерпретатор кода для сканирования документа для заголовков предложений и сводки содержимого
  • Обязанности: извлечение информации и сводка

  • Пример описания агента:

    Извлечение и обобщение положений "Прекращение", "Условия оплаты" и "Возмещение" из данного контракта.

Подключенный агент 2: валидатор соответствия

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

  • Используемые инструменты:

    • Поиск файлов для доступа к документам внутренней политики или шаблонам контрактов
    • Средство OpenAPI для вызова API внутренних правил соответствия
    • Azure Functions или Azure Logic Apps для выполнения простых логических проверок (например, наличие обязательного условия или проверка пороговых значений)
  • Обязанности: сопоставление политик и маркировка рисков

  • Пример инструкции запроса:

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

Ограничения

  • Подключенные агенты не могут вызывать локальные функции с помощью средства вызова функции. Вместо этого рекомендуется использовать средство OpenAPI или Функции Azure.
  • В настоящее время невозможно гарантировать, что цитаты будут переданы из подключенных агентов. Вы можете попробовать использовать создание подсказок в сочетании с различными моделями, чтобы повысить вероятность того, что основной агент системы будет выводить ссылки, но результаты подвержены изменчивости.
  • Подключенные агенты имеют максимальную глубину 2. Родительский агент может иметь несколько подагентов, но подагенты не могут иметь собственных подагентов. Превышение этой глубины приводит к ошибке Assistant Tool Call Depth Error.

Создание системы с несколькими агентами

  1. Перейдите на страницу "Агенты" на портале
  2. Выберите существующий агент из списка или создайте новый.
  3. Прокрутите вниз до раздела "Подключенные агенты " на панели настройки агента и нажмите кнопку "Добавить+".

Снимок экрана страницы агентов в Microsoft Foundry.

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

    • Выберите существующий агент из раскрывающегося списка. Это подключенный агент, которому главный агент будет делегировать задачи.
    • Введите уникальное имя подключенного агента (только буквы и подчеркивания). Это имя используется для вызова функции на уровне API. Сохраняйте его описательным и считываемым компьютером, чтобы максимально повысить точность воспроизведения (например, summarize_text, lookup_product_info).
    • Добавьте четкое описание того, когда и почему должен вызываться подключенный агент. Это помогает управлять принятием решений основного агента, когда следует передавать задачи подключенным агентам во время выполнения.
  2. Нажмите кнопку "Добавить+"

  3. Повторите шаги 3–5, чтобы добавить специализированные агенты к основному агенту.

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

  5. Используйте тестовые подсказки в песочнице агента, чтобы убедиться, что главный агент правильно направляет задачи в подключенные агенты при необходимости. Например, если вы создали главного агента с именем research_agent, у которого не настроены какие-либо средства, и подключили агента с именем stock_price_bot, попробуйте следующее:

    "Какова текущая цена акций Microsoft?"

    Этот research_agent должен делегировать этот запрос stock_price_bot на основе описания маршрутизации, которое вы определили.

Снимок экрана: экран подключенных агентов

Использование пакета SDK .NET

Примечание

Это показывает синхронное использование. Асинхронный пример можно найти в GitHub

Для того чтобы включить возможность для вашего агента использовать подключённого агента, вы используете ConnectedAgentToolDefinition вместе с идентификатором агента, именем и описанием.

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

    var projectEndpoint = configuration["ProjectEndpoint"];
    var modelDeploymentName = configuration["ModelDeploymentName"];
    
    PersistentAgentsClient client = new(projectEndpoint, new DefaultAzureCredential());
    
  2. Далее мы создадим основной агент mainAgent и подключенный агент stockAgent с помощью клиента агента. Этот подключенный агент будет использоваться для инициализации ConnectedAgentToolDefinition.

    PersistentAgent stockAgent = client.Administration.CreateAgent(
            model: modelDeploymentName,
            name: "stock_price_bot",
            instructions: "Your job is to get the stock price of a company. If you don't know the realtime stock price, return the last known stock price."
            // tools: [...] tools that would be used to get stock prices
        );
    ConnectedAgentToolDefinition connectedAgentDefinition = new(new ConnectedAgentDetails(stockAgent.Id, stockAgent.Name, "Gets the stock price of a company"));
    
    PersistentAgent mainAgent = client.Administration.CreateAgent(
            model: modelDeploymentName,
            name: "stock_price_bot",
            instructions: "Your job is to get the stock price of a company, using the available tools.",
            tools: [connectedAgentDefinition]
        );
    
    
    
  3. Теперь мы создадим поток, добавим сообщение, содержащее вопрос для агента, и запустим выполнение.

    PersistentAgentThread thread = client.Threads.CreateThread();
    
    // Create message to thread
    PersistentThreadMessage message = client.Messages.CreateMessage(
        thread.Id,
        MessageRole.User,
        "What is the stock price of Microsoft?");
    
    // Run the agent
    ThreadRun run = client.Runs.CreateRun(thread, agent);
    do
    {
        Thread.Sleep(TimeSpan.FromMilliseconds(500));
        run = client.Runs.GetRun(thread.Id, run.Id);
    }
    while (run.Status == RunStatus.Queued
        || run.Status == RunStatus.InProgress);
    
    // Confirm that the run completed successfully
    if (run.Status != RunStatus.Completed)
    {
        throw new Exception("Run did not complete successfully, error: " + run.LastError?.Message);
    }
    
  4. Напечатать сообщения агента в консоли в хронологическом порядке.

    Pageable<PersistentThreadMessage> messages = client.Messages.GetMessages(
        threadId: thread.Id,
        order: ListSortOrder.Ascending
    );
    
    foreach (PersistentThreadMessage threadMessage in messages)
    {
        Console.Write($"{threadMessage.CreatedAt:yyyy-MM-dd HH:mm:ss} - {threadMessage.Role,10}: ");
        foreach (MessageContent contentItem in threadMessage.ContentItems)
        {
            if (contentItem is MessageTextContent textItem)
            {
                string response = textItem.Text;
                if (textItem.Annotations != null)
                {
                    foreach (MessageTextAnnotation annotation in textItem.Annotations)
                    {
                        if (annotation is MessageTextUriCitationAnnotation urlAnnotation)
                        {
                            response = response.Replace(urlAnnotation.Text, $" [{urlAnnotation.UriCitation.Title}]({urlAnnotation.UriCitation.Uri})");
                        }
                    }
                }
                Console.Write($"Agent response: {response}");
            }
            else if (contentItem is MessageImageFileContent imageFileItem)
            {
                Console.Write($"<image from ID: {imageFileItem.FileId}");
            }
            Console.WriteLine();
        }
    }
    
  5. Очистка ресурсов путем удаления потока и агента.

    agentClient.DeleteThread(threadId: thread.Id);
    agentClient.DeleteAgent(agentId: agent.Id);
    agentClient.DeleteAgent(agentId: connectedAgent.Id);
    

Создание системы с несколькими агентами

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

  1. Инициализация клиентского объекта.

    import os
    from azure.ai.projects import AIProjectClient
    from azure.ai.agents.models import ConnectedAgentTool, MessageRole
    from azure.identity import DefaultAzureCredential
    
    
    project_client = AIProjectClient(
    endpoint=os.environ["PROJECT_ENDPOINT"],
    credential=DefaultAzureCredential(),
    )
    
  2. Создайте агент, который будет подключен к основному агенту.

    stock_price_agent = project_client.agents.create_agent(
        model=os.environ["MODEL_DEPLOYMENT_NAME"],
        name="stock_price_bot",
        instructions="Your job is to get the stock price of a company. If you don't know the realtime stock price, return the last known stock price.",
        #tools=... # tools to help the agent get stock prices
    )
    
  3. Инициализируйте инструмент подключенного агента с идентификатором агента, именем и описанием

    connected_agent = ConnectedAgentTool(
        id=stock_price_agent.id, name=stock_price_agent.name, description="Gets the stock price of a company"
    )
    
  4. Создайте агента «главный», который будет использовать подключённого агента.

    agent = project_client.agents.create_agent(
        model=os.environ["MODEL_DEPLOYMENT_NAME"],
        name="my-agent",
        instructions="You are a helpful agent, and use the available tools to get stock prices.",
        tools=connected_agent.definitions,
    )
    
    print(f"Created agent, ID: {agent.id}")
    
  5. Создайте поток и добавьте в него сообщение.

    thread = project_client.agents.threads.create()
    print(f"Created thread, ID: {thread.id}")
    
    # Create message to thread
    message = project_client.agents.messages.create(
        thread_id=thread.id,
        role=MessageRole.USER,
        content="What is the stock price of Microsoft?",
    )
    print(f"Created message, ID: {message.id}")
    
    
  6. Создайте запуск и дождитесь завершения.

    
    # Create and process Agent run in thread with tools
    run = project_client.agents.runs.create_and_process(thread_id=thread.id, agent_id=agent.id)
    print(f"Run finished with status: {run.status}")
    
    if run.status == "failed":
        print(f"Run failed: {run.last_error}")
    
    # Delete the Agent when done
    project_client.agents.delete_agent(agent.id)
    print("Deleted agent")
    
    # Delete the connected Agent when done
    project_client.agents.delete_agent(stock_price_agent.id)
    print("Deleted connected agent")
    
  7. Напечатать ответ агента. Главный агент компилирует ответы от подключенных агентов и предоставит ответ. Ответы подключенных агентов отображаются только для основного агента, а не для конечного пользователя.

    # Print the Agent's response message with optional citation
    response_message = project_client.agents.messages.get_last_message_by_role(
        thread_id=thread.id, 
        role=MessageRole.AGENT
    )
    if response_message:
        for text_message in response_message.text_messages:
            print(f"Agent response: {text_message.text.value}")
        for annotation in response_message.url_citation_annotations:
            print(f"URL Citation: [{annotation.url_citation.title}]({annotation.url_citation.url})")
    

Публикация подключенных агентов в Azure

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

Соображения, касающиеся подключенных агентов

  • Опубликуйте каждый агент по отдельности: сначала опубликуйте подключенные агенты, а затем главный агент. Каждый получает собственную стабильную конечную точку и удостоверение агента.
  • Маршрутизация продолжает работать: после публикации основной агент автоматически перенаправляет к опубликованным подключенным агентам, используя их идентификаторы агентов в ConnectedAgentToolDefinition. Изменения кода не требуются.
  • Управление удостоверениями: опубликованные подключенные агенты получают собственное удостоверение агента. Перенастройте разрешения для всех ресурсов Azure, к которым имеют доступ подключенные агенты, так как разрешения общей учётной записи разработчика не передаются.

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