Поделиться через


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

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

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

Функции

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Извлечь и обобщить пункты "Завершение", "Условия оплаты", "Возмещение" из предоставленного контракта.

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

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

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

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

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

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

Ограничения

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

Создание многоагентной системы

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

Снимок экрана: страница агентов в Azure AI Foundry.

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

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

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

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

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

    "Что такое текущая цена акций Корпорации Майкрософт?"

    Этот 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.projects.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=connected_agent_name, description="Gets the stock price of a company"
    )
    
  4. Создайте агента "main", который будет использовать подключенного агента.

    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.create_thread()
    print(f"Created thread, ID: {thread.id}")
    
    # Create message to thread
    message = project_client.agents.create_message(
        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.create_and_process_run(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.list_messages(thread_id=thread.id).get_last_message_by_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})")