1. Введение
Обзор
В этом практическом занятии вы развернете агент ADK в Cloud Run в качестве бэкэнд-сервиса, а затем развернете интерфейс Gradio для агента ADK в качестве второго сервиса Cloud Run. В этом практическом занятии показано, как требовать аутентификацию для сервиса агента ADK и выполнять аутентифицированные вызовы к нему из сервиса интерфейса Gradio.
Что вы узнаете
- Как развернуть агент ADK в Cloud Run
- Как развернуть приложение Gradio в Cloud Run
- Как выполнять аутентифицированные вызовы между сервисами в Cloud Run
2. Включите API.
Сначала настройте свой проект в Google Cloud.
gcloud config set project <YOUR_PROJECT_ID>
Подтвердить свой проект Google Cloud можно, выполнив следующую команду:
gcloud config get-value project
Для выполнения этого практического задания необходимо включить следующие API:
gcloud services enable run.googleapis.com \
compute.googleapis.com \
run.googleapis.com \
cloudbuild.googleapis.com \
artifactregistry.googleapis.com \
aiplatform.googleapis.com
3. Настройка и требования
В этом разделе вы создадите несколько учетных записей служб и назначите им соответствующие роли IAM. Каждая облачная служба будет иметь свою собственную учетную запись службы.
Для начала установите переменные среды для этого практического занятия, которые будут использоваться на протяжении всего занятия.
export PROJECT_ID=<YOUR_PROJECT_ID>
export REGION=<YOUR_REGION>
export SERVICE_ACCOUNT_ADK="adk-agent-cr"
export SERVICE_ACCOUNT_ADDRESS_ADK=$SERVICE_ACCOUNT_ADK@$PROJECT_ID.iam.gserviceaccount.com
export SERVICE_ACCOUNT_GRADIO="adk-agent-gradio"
export SERVICE_ACCOUNT_ADDRESS_GRADIO=$SERVICE_ACCOUNT_GRADIO@$PROJECT_ID.iam.gserviceaccount.com
export AGENT_APP_NAME="multi_tool_agent"
Далее создайте учетную запись службы для агента ADK.
gcloud iam service-accounts create $SERVICE_ACCOUNT_ADK \
--display-name="Service account for adk agent on cloud run"
И предоставьте учетной записи службы ADK роль "Пользователь Vertex AI".
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_ADDRESS_ADK" \
--role="roles/aiplatform.user"
Теперь создайте учетную запись службы для интерфейса Gradio.
gcloud iam service-accounts create $SERVICE_ACCOUNT_GRADIO \
--display-name="Service account for gradio frontend cloud run"
А также предоставьте интерфейсу Gradio роль вызывающего объекта Cloud Run, что позволит ему вызывать агент ADK, размещенный в Cloud Run.
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_ADDRESS_GRADIO" \
--role="roles/run.invoker"
4. Создайте приложение ADK.
На следующем шаге вы создадите код для приложения быстрого запуска ADK.
Примечание: по завершении лабораторной работы структура ваших файлов должна выглядеть следующим образом:
- codelab-gradio-adk <-- you'll deploy the ADK agent from here
- gradio-frontend <-- you'll deploy the gradio app from here
- app.py
- requirements.txt
- multi_tool_agent
- __init__.py
- agent.py
- requirements.txt
Сначала создайте директорию для всего проекта.
mkdir codelab-gradio-adk
cd codelab-gradio-adk
Теперь создайте каталог для службы агента ADK.
mkdir multi_tool_agent && cd multi_tool_agent
Создайте файл __init__.py со следующим содержимым:
from . import agent
Создайте файл requirements.txt :
google-adk
Создайте файл с именем agent.py
import datetime
from zoneinfo import ZoneInfo
from google.adk.agents import Agent
def get_weather(city: str) -> dict:
"""Retrieves the current weather report for a specified city.
Args:
city (str): The name of the city for which to retrieve the weather report.
Returns:
dict: status and result or error msg.
"""
if city.lower() == "new york":
return {
"status": "success",
"report": (
"The weather in New York is sunny with a temperature of 25 degrees"
" Celsius (77 degrees Fahrenheit)."
),
}
else:
return {
"status": "error",
"error_message": f"Weather information for '{city}' is not available.",
}
def get_current_time(city: str) -> dict:
"""Returns the current time in a specified city.
Args:
city (str): The name of the city for which to retrieve the current time.
Returns:
dict: status and result or error msg.
"""
if city.lower() == "new york":
tz_identifier = "America/New_York"
else:
return {
"status": "error",
"error_message": (
f"Sorry, I don't have timezone information for {city}."
),
}
tz = ZoneInfo(tz_identifier)
now = datetime.datetime.now(tz)
report = (
f'The current time in {city} is {now.strftime("%Y-%m-%d %H:%M:%S %Z%z")}'
)
return {"status": "success", "report": report}
root_agent = Agent(
name="weather_time_agent",
model="gemini-2.5-flash",
description=(
"Agent to answer questions about the time and weather in a city."
),
instruction=(
"You are a helpful agent who can answer user questions about the time and weather in a city."
),
tools=[get_weather, get_current_time],
)
5. Разверните агент ADK.
В этом разделе вы развернете агент ADK в Cloud Run. Затем вы проверите успешность развертывания с помощью веб-интерфейса разработчика, предоставляемого ADK. Наконец, вам потребуются аутентифицированные вызовы к этой службе.
Перейдите в родительскую папку.
ПРИМЕЧАНИЕ: Код агента ADK должен включать папку multi_tool_agent в качестве своей корневой папки.
cd ..
Сначала создайте службу Cloud Run:
ПРИМЕЧАНИЕ: параметр --with_ui является необязательным для тестирования с использованием пользовательского интерфейса для разработчиков, как показано на следующем шаге:
ПРИМЕЧАНИЕ: команда -- позволяет передавать флаги командной строки в команду gcloud run deploy .
ПРИМЕЧАНИЕ: команда uvx --from выполняет команду из пакета `google-adk`. `uvx` создаст временное виртуальное окружение, установит в него `google-adk`, выполнит указанную команду, а затем удалит это окружение.
uvx --from google-adk \
adk deploy cloud_run \
--project=$PROJECT_ID \
--region=$REGION \
--service_name=adk-agent-cr \
--with_ui \
./multi_tool_agent \
-- \
--service-account=$SERVICE_ACCOUNT_ADDRESS_ADK \
--allow-unauthenticated
Далее сохраните URL-адрес в качестве переменной окружения, которую вы будете использовать во второй части этого практического задания.
AGENT_SERVICE_URL=$(gcloud run services describe adk-agent-cr --region $REGION --format 'value(status.url)')
Теперь попробуйте обратиться к агенту.
Откройте URL-адрес сервиса в своем веб-браузере и спросите: « tell me about the weather in new york ». Вы должны увидеть ответ, похожий на «В Нью-Йорке солнечно, температура 25 градусов Цельсия (77 градусов Фаренгейта)».
Наконец, обеспечьте безопасность агента.
Теперь давайте обеспечим безопасный доступ к агенту. В следующем разделе вы развернете службу Cloud Run, которая будет выполнять аутентифицированный вызов к этой серверной службе.
gcloud run services remove-iam-policy-binding adk-agent-cr \
--member="allUsers" \
--role="roles/run.invoker" \
--region=$REGION
6. Разверните интерфейс Gradio.
На этом этапе вы создадите интерфейс Gradio для вашего агента ADK.
Примечание: приложение Gradio может находиться в том же сервисе, что и агент ADK. В этом практическом занятии представлены 2 отдельных сервиса, демонстрирующих, как выполнять аутентифицированные вызовы между сервисами в Cloud Run.
Сначала создайте приложение рядом с папкой multi_tool_agent.
mkdir gradio-frontend && cd gradio-frontend
Далее создайте файл requirements.txt , содержащий следующее:
gradio
requests
google-auth
Теперь создайте файл app.py
import gradio as gr
import requests
import json
import uuid
import os
import google.auth.transport.requests
import google.oauth2.id_token
# https://weather-time-service2-392295011265.us-west4.run.app
BASE_URL = os.environ.get("AGENT_SERVICE_URL")
# multi_tool_agent
APP_NAME = os.environ.get("AGENT_APP_NAME")
# Generate a unique user ID for each session of the Gradio app
USER_ID = f"gradio-user-{uuid.uuid4()}"
# API Endpoints
CREATE_SESSION_URL = f"{BASE_URL}/apps/{APP_NAME}/users/{USER_ID}/sessions"
RUN_SSE_URL = f"{BASE_URL}/run_sse"
def get_id_token():
"""Get an ID token to authenticate with the other Cloud Run service."""
audience = BASE_URL
request = google.auth.transport.requests.Request()
id_token = google.oauth2.id_token.fetch_id_token(request, audience)
return id_token
def create_session() -> str | None:
"""Creates a new session and returns the session ID."""
try:
id_token = get_id_token()
headers = {"Authorization": f"Bearer {id_token}"}
response = requests.post(CREATE_SESSION_URL, headers=headers)
response.raise_for_status()
return response.json().get("id")
except Exception as e:
print(f"Error creating session: {e}")
return None
def query_agent(prompt: str):
"""Sends a prompt to the agent and returns the streamed response."""
session_id = create_session()
if not session_id:
return "Error: Could not create a session."
id_token = get_id_token()
headers = {
"Content-Type": "application/json",
"Accept": "text/event-stream",
"Authorization": f"Bearer {id_token}",
}
payload = {
"app_name": APP_NAME,
"user_id": USER_ID,
"session_id": session_id,
"new_message": {"role": "user", "parts": [{"text": prompt}]},
"streaming": True
}
full_response = ""
try:
with requests.post(RUN_SSE_URL, headers=headers, json=payload, stream=True) as response:
response.raise_for_status()
for chunk in response.iter_lines():
if chunk and chunk.decode('utf-8').startswith('data:'):
json_data = chunk.decode('utf-8')[len('data:'):].strip()
try:
data = json.loads(json_data)
text = data.get("content", {}).get("parts", [{}])[0].get("text", "")
if text:
full_response = text
except json.JSONDecodeError:
pass # Ignore chunks that are not valid JSON
return full_response
except requests.exceptions.RequestException as e:
return f"An error occurred: {e}"
iface = gr.Interface(
fn=query_agent,
inputs=gr.Textbox(lines=2, placeholder="e.g., What's the weather in new york?"),
outputs="text",
title="Weather and Time Agent",
description="Ask a question about the weather or time in a specific location.",
)
if __name__ == "__main__":
iface.launch()
7. Разверните и протестируйте ваше приложение Gradio.
На этом этапе вы развернете фронтенд-приложение Gradio в Cloud Run.
Убедитесь, что вы находитесь в каталоге приложения Gradio.
pwd
Вам следует посмотреть codelab-gradio-adk/gradio-frontend
Теперь разверните ваше приложение Gradio.
Примечание: хотя этот фронтенд-сервис Gradio является общедоступным веб-сайтом, бэкенд-сервис требует аутентификации. Чтобы проиллюстрировать, почему это может быть необходимо, вы можете добавить аутентификацию пользователей (например, Firebase Auth) к этому фронтенд-сервису и затем разрешить только авторизованным пользователям совершать вызовы к бэкенд-сервису.
gcloud run deploy my-adk-gradio-frontend \
--source . \
--region $REGION \
--allow-unauthenticated \
--set-env-vars AGENT_SERVICE_URL=$AGENT_SERVICE_URL,AGENT_APP_NAME=$AGENT_APP_NAME \
--service-account=$SERVICE_ACCOUNT_ADDRESS_GRADIO
После развертывания спросите: what's the weather in new york? , и вы должны получить ответ, похожий на The weather in New York is sunny with a temperature of 25 degrees Celsius (77 degrees Fahrenheit).
8. Поздравляем!
Поздравляем с завершением практического занятия!
Мы рекомендуем ознакомиться с документацией по размещению приложений и агентов искусственного интеллекта .
Что мы рассмотрели
- Как развернуть агент ADK в Cloud Run
- Как развернуть приложение Gradio в Cloud Run
- Как выполнять аутентифицированные вызовы между сервисами в Cloud Run
9. Уборка
Чтобы избежать непреднамеренных списаний средств, например, если службы Cloud Run будут случайно запущены больше раз, чем предусмотрено вашим ежемесячным лимитом на запуск Cloud Run в бесплатном тарифе , вы можете удалить службу Cloud Run, созданную на шаге 6.
Чтобы удалить службы Cloud Run, перейдите в консоль Cloud Run по адресу https://console.cloud.google.com/run и удалите службы my-adk-gradio-frontend и adk-agent-cr .
Чтобы удалить весь проект, перейдите в раздел «Управление ресурсами» , выберите проект, созданный на шаге 2, и нажмите «Удалить». Если вы удалите проект, вам потребуется изменить проекты в вашем Cloud SDK. Вы можете просмотреть список всех доступных проектов, выполнив gcloud projects list .