Асинхронный вызов приложения агентного ИИ с использованием событий

1. Введение

Обзор

В этой лабораторной работе показано, как безопасно реализовать вызов агента ADK, развёрнутого в Cloud Run, по событию, с помощью сервисов Eventarc и Pub/Sub. Чаще всего агент вызывается пользователем или другим агентом напрямую. Однако при интеграции агента в существующие рабочие процессы, основанные на событиях, прямой вызов требует внесения изменений в существующее программное обеспечение. Запуск вызова агента по событию позволяет интегрировать агента в существующие рабочие процессы без внесения изменений в них.

Что ты будешь делать?

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

Иллюстрация Zoo-Keeper

Вы развернёте приложение ZooKeeper как сервис в Cloud Run — полностью управляемой вычислительной платформе без сервера, которая запускает контейнеры без сохранения состояния в инфраструктуре Google. Затем вы настроите триггер Eventarc, который будет вызывать конечную точку сервиса для асинхронной обработки сообщений, опубликованных в теме Pub/Sub. Вы убедитесь, что развёртывание соответствует лучшим практикам, включая использование назначенных учётных записей сервиса IAM, предоставление доступа с минимальными привилегиями и минимизацию потенциальной поверхности атаки путём предоставления конечной точки приложения ZooKeeper только Eventarc. Вы сделаете это с помощью Cloud Shell и Cloud Console. Вы будете использовать библиотеки ADK и Cloud SDK для Python. Для проверки поведения используйте интерфейс командной строки gcloud.

Чему вы научитесь

  • Разверните свой агент ADK в Google Cloud Run.
  • Интегрируйте триггер Eventarc с агентом ADK, работающим в Google Cloud Run.
  • Защитите свое развертывание и интеграцию с Eventarc, используя принцип наименьших привилегий доступа с помощью Google Cloud IAM.
  • Публикуйте и извлекайте сообщения из Pub/Sub.
  • Минимизируйте публичность вашего приложения, развернутого в Google Cloud Run.

Что вам понадобится

Обратите внимание, что ваша учетная запись должна иметь IAM-доступ к проекту, который позволит вам предоставлять ресурсы и настраивать IAM-доступ к этим ресурсам.

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

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

2. Настройка среды

Для обеспечения полнофункциональной среды разработки в лаборатории вы будете использовать Google Cloud Shell со всеми необходимыми предустановленными инструментами. Следуйте инструкциям по настройке среды.

Если у вас нет учетной записи Google, создайте ее .

Инструкции по настройке

  1. Используйте свою учетную запись Google для входа в Google Cloud Console .
  2. 👉 Откройте панель выбора проектов в верхней панели навигации (там может быть написано «Выбрать проект» или показано имя существующего проекта) или нажмите сочетание клавиш Ctrl + O и выберите существующий проект или создайте новый. Создание нового проекта займёт несколько секунд. Дождитесь завершения и выберите его в панели выбора проектов.
  1. 👉 Нажмите значок Cloud Shell в верхней части консоли Google Cloud (отмечен красным прямоугольником): Кнопка Cloud Shell
    При появлении соответствующего запроса нажмите кнопку **Авторизовать** во всплывающем диалоговом окне, чтобы разрешить Cloud Shell использовать учетные данные вашей учетной записи.
    Диалог авторизации
  2. 👉💻 Убедитесь, что интерфейс командной строки gcloud настроен на использование выбранного (или созданного) вами проекта. Выполните следующую команду, чтобы проверить настроенный идентификатор проекта:
    gcloud config get-value project
    
    Ожидается, что вы увидите вывод, подобный следующему:
    Your active configuration is: [cloudshell-19597]
    [PROJECT_ID]
    
    где [PROJECT_ID] будет идентификатором проекта, который вы выбрали или создали.👉💻 Если вы видите другое значение, выполните следующую команду, чтобы настроить идентификатор вашего проекта в качестве идентификатора проекта по умолчанию для команд CLI gcloud:
    gcloud config set project [YOUR_PROJECT_ID]
    
    Например, если идентификатор вашего проекта — lab-project-id-example-123, то команда должна быть такой:
    gcloud config set project lab-project-id-example-123
    
    🤔💻 Если вы не можете вспомнить идентификатор своего проекта, используйте следующую команду, чтобы вывести список всех идентификаторов проектов, к которым у вас есть доступ, начиная с самого последнего:
    gcloud projects list \
        --format='value(projectId)' \
        --sort-by='~createTime'
    
  1. 👉💻 Настройте место для предоставления ресурсов, а также идентификатор и номер вашего проекта в переменных среды:
    export LOCATION="us-central1"
    export PROJECT_ID=$(gcloud config get-value project)
    export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")
    
  2. 👉💻 Включите API Google, необходимые для этой лабораторной работы.
    gcloud services enable \
        aiplatform.googleapis.com \
        eventarc.googleapis.com \
        run.googleapis.com \
        artifactregistry.googleapis.com \
        cloudbuild.googleapis.com \
        pubsub.googleapis.com
    
    Будьте терпеливы, выполнение команды может занять несколько минут. При успешном выполнении команды вы увидите сообщение, похожее на это:
    Operation "operations/ab12345c-6e7f-8ghi-jkl9-m0e1d23456f7" finished successfully.
    

3. Разверните демонстрационное приложение ZooKeeper.

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

Настройка ресурсов Pub/Sub

Вам нужно будет создать две темы Pub/Sub. Одна будет использоваться сторонним сервисом для отправки событий в ваше приложение с ИИ-агентом. Другая — приложением для публикации результатов обработки событий.

  1. 👉💻 Создайте тему Pub/Sub, используемую для запуска приложения агентного ИИ:
    gcloud pubsub topics create invoke_agent
    export INVOKE_TOPIC_ID=$(gcloud pubsub topics describe invoke_agent --format="value(name)")
    
  2. 👉💻 Создайте тему Pub/Sub, в которой приложение может публиковать свои ответы:
    gcloud pubsub topics create agent_responses
    export RESPONSE_TOPIC_ID=$(gcloud pubsub topics describe agent_responses --format="value(name)")
    gcloud pubsub subscriptions create agent_responses \
        --topic=agent_responses
    
    Эти команды также создают подписку на созданную тему Pub/Sub. Подписка будет использоваться при запуске демоверсии для просмотра результатов.

Настройка учетных записей служб и политик IAM на уровне проекта

Вам необходимо создать две учётные записи служб, чтобы ограничить область доступа службы Cloud Run и триггера Eventarc до минимума, следуя принципу наименьших привилегий. Службе Cloud Run требуются разрешения на запись журналов и трассировок, вызов Gemini LLM в Google Vertex AI и публикацию результатов в теме Pub/Sub. Для минимального доступа триггера Eventarc требуются разрешения на вызов службы Cloud Run ZooKeeper и доступ к Pub/Sub для чтения опубликованных событий. Эти инструкции помогут вам предоставить учётной записи службы триггера необходимые разрешения для олицетворения системной службы Pub/Sub. После создания ресурса триггера Eventarc выполните команду, которая предоставит роль roles/run.invoker , чтобы учётная запись службы триггера могла вызывать службу Cloud Run.

  1. 👉💻 Создайте учетную запись сервиса для сервиса Cloud Run:
    gcloud iam service-accounts create zookeeper-cloudrun-sa
    export ZOOKEEPER_SA="zookeeper-cloudrun-sa@${PROJECT_ID}.iam.gserviceaccount.com"
    
  2. 👉💻 Предоставьте учетной записи службы разрешения на запись журналов и трассировок, а также на использование моделей Gemini в Vertex AI:
    gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
         --member="serviceAccount:${ZOOKEEPER_SA}" \
         --role="roles/logging.logWriter" \
         --condition=None
    gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
        --member="serviceAccount:${ZOOKEEPER_SA}" \
        --role="roles/cloudtrace.agent" \
        --condition=None
    gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
        --member="serviceAccount:${ZOOKEEPER_SA}" \
        --role="roles/aiplatform.user" \
        --condition=None
    
  3. 👉💻 Предоставьте учетной записи службы разрешения на публикацию сообщений в теме «agent_responses»:
    gcloud pubsub topics add-iam-policy-binding agent_responses \
        --member="serviceAccount:${ZOOKEEPER_SA}" \
        --role="roles/pubsub.publisher"
    
  4. 👉💻 Создайте учетную запись службы для триггера Eventarc:
    gcloud iam service-accounts create zookeeper-trigger-sa
    export TRIGGER_SA="zookeeper-trigger-sa@${PROJECT_ID}.iam.gserviceaccount.com"
    
  5. 👉💻 Предоставьте учетной записи службы системы Pub/Sub разрешения на выполнение аутентифицированных push-запросов:
    gcloud iam service-accounts add-iam-policy-binding "${TRIGGER_SA}" \
           --member="serviceAccount:service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com" \
        --role="roles/iam.serviceAccountTokenCreator"
    
    Эта команда необязательна , если проект создан после 8 апреля 2021 года.

Развертывание приложения ZooKeeper в Cloud Run

Вам нужно загрузить код демонстрационного приложения с GitHub и развернуть его в Cloud Run.

  1. 👉💻 Загрузите приложение агентского ИИ:
    mkdir zoo-keeper-lab && cd zoo-keeper-lab
    git init
    git remote add origin https://github.com/GoogleCloudPlatform/devrel-demos
    git config set core.sparseCheckout true
    echo "ai-ml/agent-labs/adk_invoke_with_pubsub/" >> .git/info/sparse-checkout
    git pull origin main --depth 1
    cd ai-ml/agent-labs/adk_invoke_with_pubsub/
    
    Эти команды используют разреженную проверку Git папки с демонстрационным приложением для сокращения времени загрузки.
  2. 👉💻 Разверните приложение агентского ИИ в Cloud Run:
    gcloud run deploy zookeeper-agent \
        --region="${LOCATION}" \
        --source="." \
        --no-allow-unauthenticated \
        --quiet \
        --service-account="${ZOOKEEPER_SA}" \
        --set-env-vars="REPLY_TOPIC_ID=${RESPONSE_TOPIC_ID}"
    

Настроить триггер Eventarc

После подготовки всех ресурсов (тем Pub/Sub, учётных записей служб IAM и службы Cloud Run) необходимо настроить ресурс триггера Eventarc. Необходимо создать ресурс триггера Eventarc и предоставить учётной записи службы триггера разрешения на вызов службы Cloud Run.

  1. 👉💻 Создайте триггер Eventarc:
    gcloud eventarc triggers create invoke-agent \
        --location="${LOCATION}" \
        --destination-run-service="zookeeper-agent" \
        --destination-run-path="/zookeeper" \
        --destination-run-region="${LOCATION}" \
        --event-filters="type=google.cloud.pubsub.topic.v1.messagePublished" \
        --transport-topic="${INVOKE_TOPIC_ID}" \
        --service-account="${TRIGGER_SA}"
    
  2. 👉💻 Предоставьте разрешения учетной записи службы триггера на вызов службы Cloud Run:
    gcloud run services add-iam-policy-binding zookeeper-agent \
        --region="${LOCATION}" \
        --member="serviceAccount:${TRIGGER_SA}" \
        --role="roles/run.invoker"
    

4. Проверьте, как работает решение.

Теперь проверьте, что вы только что развернули. На следующей диаграмме показаны все ресурсы и их взаимодействие. Вы будете использовать интерфейс командной строки gcloud для публикации сообщения в теме «invoke_agent». Это смоделирует событие, которое сторонний сервис регистрирует в сервисе обмена сообщениями для вызова приложения агентского ИИ.

Диаграмма решения

Развёртывание защищено с помощью доступа с минимальными привилегиями. Служба Cloud Run принудительно применяет аутентификацию (см. аргумент --no-allow-unauthenticated в шаге 9 предыдущего раздела). Вызывать службу могут только пользователи с правами roles/run.invoker или аналогичными. Эта роль предоставляется только учётной записи службы триггера Eventarc. Аналогичным образом, доступ к теме «invoke_agent» минимизирован, чтобы предотвратить несанкционированную публикацию событий. По-прежнему возможно вызывать агент ZooKeeper напрямую, минуя публикацию в теме Pub/Sub. Подробнее о том, как скрыть конечную точку приложения от публичного доступа, см. в разделе 6.

Запустите рабочий процесс

Вы сымитируете внешнее событие, опубликовав вопрос на естественном языке в ZooKeeper.

👉💻 Используйте следующую команду, чтобы опубликовать сообщение в теме Pub/Sub:

gcloud pubsub topics publish invoke_agent \
    --message='{"user_id": "important_app", "prompt": "How many animals are in the zoo?"}'

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

Вы можете убедиться, что агент получил событие, обработал запрос и отправил ответ в теме «agent_responses». Чтобы прочитать ответ, воспользуйтесь подпиской «agent_responses» (в этой лабораторной работе используется один и тот же идентификатор как для темы, так и для подписки на ответы).

👉💻 Используйте следующую команду, чтобы прочитать ответ агента из подписки Pub/Sub:

gcloud pubsub subscriptions pull agent_responses --auto-ack

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

Как это работает

Чтобы ознакомиться с исходным кодом приложения агентского ИИ, откройте Cloud Shell Editor и просмотрите файлы в папке ~/zoo-keeper-lab . Вы также можете посмотреть исходный код на GitHub .

  • Main.py реализует базовое веб-приложение FastAPI с одним обработчиком, который обрабатывает события Eventarc.
  • Процессор processor.py анализирует сообщение о событии, чтобы получить идентификатор пользователя и запрос. Затем он создаёт новый сеанс в ADK Runner и вызывает агент Zookeeper для обработки запроса. Ответ агента публикуется в теме Pub/Sub «agent_responses».
  • В подпапке zookeeper_agent хранится исходный код агента ADK. Для взаимодействия с агентом через adk CLI можно выполнить команду adk run zookeeper_agent из корневой папки приложения.

Как устранить неполадки

Если какая-либо из предыдущих команд не выполнена, внимательно прочитайте сообщение об ошибке. Если развёртывание в Cloud Run не удалось, первым делом следует определить, на каком этапе процесса произошёл сбой.

  • Если выходные данные команды «gcloud run deploy...» сообщают о сбое сборки, просмотрите URL-адрес журнала сборки в выходных данных и откройте его в отдельном окне.
  • Если в выводе указано что-то вроде «service failed to start» (не удалось запустить службу) или что-то подобное, это означает, что служба развёртывается, но затем выполнение не проходит проверку работоспособности. В этом случае откройте Logs Explorer или ознакомьтесь со следующим абзацем, посвящённым команде gcloud CLI. Прочитайте журналы, чтобы найти причину сбоя.

Что делать, если вы отправили сообщение в Pub/Sub, но агент не отвечает или ответ выглядит странно?

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

gcloud logging read \
    'resource.type = "cloud_run_revision" AND \
     resource.labels.service_name = "zookeeper-agent" AND \
     resource.labels.location = "us-central1"'

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

5. Усильте безопасность развертывания

Развёрнутый вами сервис Cloud Run предоставляет публичную конечную точку, к которой может обратиться любой пользователь интернета. Хотя конечная точка защищена от несанкционированного вызова и строго проверяет структуру запроса, она всё равно оставляет вектор атаки, допускающий атаки типа «отказ в обслуживании» и «отказ в доступе к кошельку». Поскольку в текущей архитектуре единственный путь вызова сервиса — через триггер Eventarc, сервису не требуется предоставлять доступ к своей конечной точке из интернета.

👉💻 Закройте этот вектор атаки, ограничив вызовы службы только из ограниченного набора источников, включая триггеры Eventarc:

gcloud run services update zookeeper-agent --region=${LOCATION} --ingress=internal

Теперь, если вы попытаетесь вызвать URL-адрес сервиса с локального компьютера, вы получите ошибку «404 Страница не найдена».

👉💻 Используйте curl для отправки запроса на конечную точку сервиса:

URL=$(gcloud run services describe zookeeper-agent --region=${LOCATION} --format='value(status.url)')
curl -X POST -d '{}' "${URL}/zookeeper"

Вы увидите вывод, подобный следующему:

<html><head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>404 Page not found</title>
</head>
<body text=#000000 bgcolor=#ffffff>
<h1>Error: Page not found</h1>
<h2>The requested URL was not found on this server.</h2>
<h2></h2>
</body></html>

После этого изменения больше невозможно напрямую вызывать ZooKeeper, вызывая конечную точку службы Cloud Run, если только вызов не выполняется из VPC в том же проекте, из общей сети VPC, на которую ваша версия настроена для отправки трафика, или с хоста, который является частью периметра VPC Service Controls .

6. Резюме

Поздравляем! Вы успешно настроили среду для асинхронного вызова вашего агентского ИИ-приложения, запускаемого входящими событиями.

Уборка

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

Есть два способа сделать это:

Метод 1 : Закрытие проекта

Завершение (удаление) проекта освобождает все ресурсы и данные проекта, а также отключает платёжный аккаунт. Использование этого метода предотвращает дальнейшее взимание платы за любые ресурсы или данные, используемые в этой лабораторной работе. Для завершения проекта используйте следующую команду:

gcloud projects delete $(gcloud config get-value project) --quiet

Метод 2 : Удаление ресурсов в проекте

Удаление сервиса Cloud Run защищает от дальнейших списаний за использование бессерверной платформы. Обратите внимание, что этот метод не удаляет полностью все данные, созданные во время выполнения кодовой лабораторной работы, такие как журналы Cloud Build и приложения, образы контейнеров и т. д. Выполните следующую команду, чтобы удалить сервис:

gcloud run services delete zookeeper-agent --region=${LOCATION}

Определение триггера Eventarc и темы Pub/Sub не влекут за собой расходов на управление (более подробную информацию см. в разделах «Ценообразование Eventarc» и «Ценообразование Pub/Sub» ).

Подробнее о закрытии проекта .

Что дальше?