1. Przegląd
Środowisko wykonawcze agentów (wcześniej Agent Engine) to zarządzane środowisko wykonawcze przeznaczone do skutecznego wdrażania, uruchamiania i skalowania agentów AI. Domyślnie platforma automatycznie łączy kod źródłowy i zależności podczas procesu wdrażania.
Jednak w przypadku zadań w przedsiębiorstwie często wymagane jest pełne przejęcie kontroli nad środowiskiem wykonawczym. Aby to umożliwić, Agent Runtime udostępnia funkcję Bring Your Own Container(BYOC), która pozwala wdrażać gotowe niestandardowe obrazy kontenerów.
To ćwiczenie zawiera opis kompleksowego procesu konteneryzacji agenta utworzonego za pomocą pakietu Agent Development Kit (ADK), konfigurowania niezbędnych uprawnień Google Cloud i wdrażania go w Agent Runtime za pomocą pakietu Python SDK lub Terraform.
W tym ćwiczeniu dowiesz się, jak:
- utworzyć agenta w Pythonie za pomocą pakietu Google Agent Development Kit (ADK);
- opakować agenta w aplikację FastAPI ;
- skonteneryzować aplikację za pomocą Dockera ;
- skonfigurować uprawnienia Google Cloud;
- wdrożyć i przetestować skonteneryzowanego agenta w środowisku wykonawczym agentów.
Proces tworzenia i wdrażania
Poniższy diagram przedstawia proces tworzenia i wdrażania, który wykonasz ręcznie w tym ćwiczeniu:

Wymagania
- Projekt Google Cloud z włączonym rozliczeniem.
- Dostęp do Cloud Shell (zalecane) lub lokalnego środowiska programistycznego z zainstalowanymi narzędziami
gcloudidocker. - Podstawowa znajomość Pythona i Dockera.
2. Konfiguracja środowiska
Zanim zaczniesz, musisz włączyć niezbędne interfejsy API i skonfigurować środowisko.
Krok 1. Otwórz Cloud Shell
W prawym górnym rogu konsoli Google Cloud kliknij przycisk Aktywuj Cloud Shell.

Krok 2. Skonfiguruj zmienne środowiskowe
W Cloud Shell ustaw identyfikator projektu i zdefiniuj kluczowe zmienne środowiskowe używane w tym ćwiczeniu. Zastąp "YOUR_PROJECT_ID" rzeczywistym identyfikatorem projektu Google Cloud:
gcloud config set project "YOUR_PROJECT_ID"
export PROJECT_ID=$(gcloud config get-value project)
export LOCATION="us-central1"
export MODEL="gemini-3.1-flash-lite"
export MODEL_REGION="global"
Te zmienne konfigurują ustawienia wdrożenia docelowego:
PROJECT_ID: unikalny identyfikator projektu Google Cloud, w którym będą się znajdować wszystkie zasoby platformy agentów Gemini Enterprise i Artifact Registry.LOCATION: region geograficzny (np.us-central1), w którym znajdują się Twoje repozytoria i zadania środowiska wykonawczego.MODEL: wersja modelu Gemini (np.gemini-3.1-flash-lite) wczytywana przez kontekst agenta.MODEL_REGION: region punktu końcowego modelu. Ustaw tutaj wartość"global", aby wywoływać model Gemini z globalnych punktów końcowych.
Krok 3. Włącz interfejsy API
Włącz wymagane Google Cloud APIs:
gcloud services enable \
aiplatform.googleapis.com \
cloudbuild.googleapis.com \
compute.googleapis.com \
artifactregistry.googleapis.com \
storage.googleapis.com
Krok 4. Zainstaluj SDK
Zainstaluj pakiet Vertex AI SDK z obsługą Agent Engine i ADK:
pip install --upgrade "google-cloud-aiplatform[agent_engines,adk]>=1.144"
3. Konfiguracja plików źródłowych
W tym kroku utworzysz strukturę i kod agenta.
Omówienie struktury katalogu
Po zakończeniu tego ćwiczenia pliki będą uporządkowane w następującej hierarchii obszaru roboczego:
weather-agent-byoc/
├── Dockerfile # Container definition
├── deploy_byoc.py # Python SDK deployment script
├── main.py # FastAPI server wrapper
├── query_agent.py # Verify / query script
├── requirements.txt # Python dependencies
│
├── weather_agent/ # Agent source module
│ ├── __init__.py # Package declaration
│ ├── agent.py # Agent & mock tools logic
│ └── config.json # Environment config variables
│
└── terraform/ # Terraform configuration files
├── main.tf
├── outputs.tf
├── providers.tf
├── terraform.tfvars
└── variables.tf
Krok 1. Utwórz katalogi
Zacznij w katalogu głównym i utwórz strukturę obszaru roboczego:
cd ~
mkdir -p weather-agent-byoc/weather_agent
cd weather-agent-byoc
Krok 2. Utwórz plik konfiguracji
Aby zapisać parametry konfiguracji bezpośrednio w weather_agent/config.json, uruchom w Cloud Shell to polecenie. To polecenie automatycznie zastępuje zmienne wartościami środowiska:
cat <<EOF > weather_agent/config.json
{
"PROJECT_ID": "${PROJECT_ID}",
"LOCATION": "${LOCATION}",
"MODEL": "${MODEL}",
"MODEL_REGION": "${MODEL_REGION}"
}
EOF
Krok 3. Zdefiniuj agenta
Aby zapisać konfigurację agenta i logikę narzędzia pozorowanego w weather_agent/agent.py, uruchom ten skrypt:
cat << 'EOF' > weather_agent/agent.py
import json
import random
from google.adk.agents import Agent
from google.adk.models.google_llm import Gemini
from functools import cached_property
from google.genai import Client
# Load config
llm_config = json.load(open("weather_agent/config.json"))
PROJECT_ID = llm_config["PROJECT_ID"]
MODEL = llm_config["MODEL"]
MODEL_REGION = llm_config["MODEL_REGION"]
# Override Gemini class for global endpoint compatibility
class GlobalGemini(Gemini):
@cached_property
def api_client(self) -> Client:
return Client(vertexai=True, location="global")
# Define Tool
def get_temperature(place: str) -> str:
'''Returns the current temperature of a given place.
Args:
place: The name of the city or location.
Returns:
str: A string describing the temperature.
'''
temp = random.randint(-10, 40)
return f"The current temperature in {place} is {temp}°C."
# Initialize LLM
llm_model = GlobalGemini(model=MODEL) if MODEL_REGION == "global" else Gemini(model=MODEL)
# Initialize Agent
root_agent = Agent(
model=llm_model,
name='weather_agent',
description='An agent that provides temperature information for locations.',
instruction='You are a helpful assistant that can provide the current temperature for any given place using the get_temperature tool.',
tools=[get_temperature],
)
EOF
Utwórz pusty plik __init__.py, aby przekształcić weather_agent w pakiet Pythona:
touch weather_agent/__init__.py
Krok 4. Utwórz otokę FastAPI
Aby zapisać konfigurację punktu wejścia serwera FastAPI w main.py, uruchom ten skrypt:
cat << 'EOF' > main.py
import inspect
import json
import logging
import os
from typing import Any, Dict, Optional
import uvicorn
import vertexai
from weather_agent.agent import root_agent
from fastapi import FastAPI, encoders, responses
from pydantic import BaseModel
from vertexai import agent_engines
app = FastAPI()
config_json = json.load(open("weather_agent/config.json"))
PROJECT_ID = config_json["PROJECT_ID"]
LOCATION = config_json["LOCATION"]
MODEL_REGION = config_json["MODEL_REGION"]
class QueryRequest(BaseModel):
input: Optional[Dict[str, Any]] = None
class_method: Optional[str] = None
vertexai.init(project=PROJECT_ID, location=MODEL_REGION)
adk_app = agent_engines.AdkApp(agent=root_agent)
def _encode_chunk_to_json(chunk):
try:
json_chunk = encoders.jsonable_encoder(chunk)
return json.dumps(json_chunk) + "\n"
except Exception:
logging.exception("Failed to encode chunk")
return None
async def json_generator(output):
async for chunk in output:
encoded_chunk = _encode_chunk_to_json(chunk)
if encoded_chunk is None:
break
yield encoded_chunk
async def _invoke_callable_or_raise(invocation_callable, invocation_payload):
if inspect.iscoroutinefunction(invocation_callable):
return await invocation_callable(**invocation_payload)
else:
return invocation_callable(**invocation_payload)
@app.post("/api/reasoning_engine")
async def query(request: QueryRequest) -> responses.JSONResponse:
method = getattr(adk_app, request.class_method)
output = await _invoke_callable_or_raise(method, request.input or {})
try:
json_serialized_content = encoders.jsonable_encoder({"output": output})
except ValueError as encoding_error:
logging.exception("Failed to encode response")
raise encoding_error
return responses.JSONResponse(content=json_serialized_content)
@app.post("/api/stream_reasoning_engine")
async def stream_query(request: QueryRequest) -> responses.StreamingResponse:
method = getattr(adk_app, request.class_method)
output = await _invoke_callable_or_raise(method, request.input or {})
return responses.StreamingResponse(
content=json_generator(output),
media_type="application/json",
)
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))
EOF
Krok 5. Zdefiniuj zależności
Zapisz wymagane zależności Pythona w requirements.txt:
cat << 'EOF' > requirements.txt
fastapi
uvicorn
vertexai
google-cloud-aiplatform[agent_engines,adk]>=1.144
pydantic
EOF
4. Konteneryzacja
Teraz określ, jak agent będzie pakowany w kontener.
Krok 1. Utwórz Dockerfile
Utwórz Dockerfile w katalogu głównym projektu, aby określić, jak ma być tworzona aplikacja FastAPI:
cat << 'EOF' > Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY weather_agent/ /app/weather_agent/
COPY main.py .
COPY requirements.txt .
RUN pip install -r requirements.txt
CMD ["sh", "-c", "uvicorn main:app --host 0.0.0.0 --port $PORT"]
EOF
5. Konfigurowanie Artifact Registry i Cloud Build
Potrzebujesz repozytorium do przechowywania obrazu kontenera i uprawnień do jego przekazywania.
Krok 1. Utwórz repozytorium
Zdefiniuj nazwę repozytorium i utwórz repozytorium Dockera w Artifact Registry za pomocą zmiennych środowiskowych zdefiniowanych podczas konfiguracji:
export REPOSITORY_NAME="agents-repo"
gcloud artifacts repositories create $REPOSITORY_NAME \
--project=$PROJECT_ID \
--repository-format=docker \
--location=$LOCATION \
--description="Docker repository for Agents"
Krok 2. Skonfiguruj uprawnienia konta usługi
Przyznaj domyślnemu kontu usługi Compute uprawnienia do przekazywania obrazów do Artifact Registry.
Najpierw znajdź numer projektu:
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")
Przyznaj role:
# Allow pushing to Artifact Registry
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com" \
--role="roles/artifactregistry.writer" \
--condition=None
# Allow Cloud Build to read storage objects
gcloud projects add-iam-policy-binding $PROJECT_NUMBER \
--member="serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com" \
--role="roles/storage.objectViewer" \
--condition=None
Krok 3. Przyznaj uprawnienia agentom usługi
Przyznaj agentom usługi AI Platform i Reasoning Engine dostęp do Artifact Registry w roli czytelnika:
gcloud projects add-iam-policy-binding $PROJECT_NUMBER \
--member="serviceAccount:service-$PROJECT_NUMBER@gcp-sa-aiplatform-re.iam.gserviceaccount.com" \
--role="roles/artifactregistry.reader" --condition=None
gcloud projects add-iam-policy-binding $PROJECT_NUMBER \
--member="serviceAccount:service-$PROJECT_NUMBER@gcp-sa-aiplatform.iam.gserviceaccount.com" \
--role="roles/artifactregistry.reader" --condition=None
Krok 4. Utwórz i prześlij obraz
Użyj Cloud Build, aby utworzyć i przesłać obraz kontenera:
gcloud builds submit \
--project=$PROJECT_ID \
--region=$LOCATION \
--tag $LOCATION-docker.pkg.dev/$PROJECT_ID/$REPOSITORY_NAME/weather-agent-image:latest \
.
6. Wdrażanie agenta za pomocą pakietu SDK
Teraz, gdy uprawnienia są skonfigurowane, możesz wdrożyć niestandardowy kontener.
Krok 1. Wdróż agenta BYOC
Aby wdrożyć kontener hostowany w rejestrze w Agent Runtime, utwórz plik Pythona deploy_byoc.py w katalogu głównym projektu:
cat << 'EOF' > deploy_byoc.py
import json
import os
import vertexai
from google.cloud import aiplatform
config = json.load(open("weather_agent/config.json"))
PROJECT_ID = config["PROJECT_ID"]
LOCATION = config["LOCATION"]
REPOSITORY_NAME = "agents-repo"
vertexai.init(project=PROJECT_ID, location=LOCATION)
client = vertexai.Client(project=PROJECT_ID, location=LOCATION)
image_uri = f"{LOCATION}-docker.pkg.dev/{PROJECT_ID}/{REPOSITORY_NAME}/weather-agent-image:latest"
print(f"Deploying custom container agent from {image_uri}...")
remote_agent = client.agent_engines.create(
config={
"display_name": "byoc_weather_agent",
"description": "BYOC weather agent from custom container",
"container_spec": {
"image_uri": image_uri
},
"class_methods": [
# For convenience to interact with the agent through the Python SDK
# https://docs.cloud.google.com/gemini-enterprise-agent-platform/scale/runtime/use-an-adk-agent#supported-operations
{"api_mode": "", "name": "get_session"},
{"api_mode": "", "name": "list_sessions"},
{"api_mode": "", "name": "create_session"},
{"api_mode": "", "name": "delete_session"},
{"api_mode": "async", "name": "async_get_session"},
{"api_mode": "async", "name": "async_list_sessions"},
{"api_mode": "async", "name": "async_create_session"},
{"api_mode": "async", "name": "async_delete_session"},
{"api_mode": "async", "name": "async_add_session_to_memory"},
{"api_mode": "async", "name": "async_search_memory"},
{"api_mode": "stream", "name": "stream_query"},
{"api_mode": "async_stream", "name": "async_stream_query"},
{"api_mode": "async_stream", "name": "streaming_agent_run_with_events"},
],
"agent_framework": "google-adk",
},
)
print(f"Agent successfully deployed!")
print(f"Resource Name: {remote_agent.api_resource.name}")
# Save resource name for testing
with open("agent_resource_name.txt", "w") as f:
f.write(remote_agent.api_resource.name)
EOF
Aby wdrożyć agenta w Agent Runtime, uruchom skrypt wdrożenia:
python3 deploy_byoc.py
7. Wdrażanie agenta za pomocą Terraform
Możesz też wdrożyć tego samego skonteneryzowanego agenta za pomocą Terraform. Jest to zalecane w środowiskach produkcyjnych, aby zarządzać infrastrukturą jako kodem.
Krok 1. Przejdź do katalogu Terraform
Utwórz katalog terraform w katalogu głównym projektu i przejdź do niego:
mkdir -p terraform
cd terraform
Krok 2. Utwórz konfigurację dostawców
Aby zapisać mapowanie dostawców w providers.tf, uruchom ten skrypt:
cat << 'EOF' > providers.tf
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">= 5.28.0"
}
}
}
provider "google" {
project = var.project_id
region = var.location
}
EOF
Krok 3. Utwórz definicję zmiennych
Zapisz blok opisu danych wejściowych w variables.tf:
cat << 'EOF' > variables.tf
variable "project_id" {
type = string
description = "The Google Cloud Project ID"
}
variable "location" {
type = string
description = "The region to deploy the reasoning engine"
default = "us-central1"
}
variable "repository_name" {
type = string
description = "The Artifact Registry repository name"
default = "agents-repo"
}
variable "image_tag" {
type = string
description = "The tag of the container image to deploy"
default = "latest"
}
EOF
Krok 4. Utwórz konfigurację główną
Zapisz parametry definicji zasobów głównych w main.tf:
cat << 'EOF' > main.tf
locals {
class_methods = [
{"api_mode" = "", "name" = "get_session"},
{"api_mode" = "", "name" = "list_sessions"},
{"api_mode" = "", "name" = "create_session"},
{"api_mode" = "", "name" = "delete_session"},
{"api_mode" = "async", "name" = "async_get_session"},
{"api_mode" = "async", "name" = "async_list_sessions"},
{"api_mode" = "async", "name" = "async_create_session"},
{"api_mode" = "async", "name" = "async_delete_session"},
{"api_mode" = "async", "name" = "async_add_session_to_memory"},
{"api_mode" = "async", "name" = "async_search_memory"},
{"api_mode" = "stream", "name" = "stream_query"},
{"api_mode" = "async_stream", "name" = "async_stream_query"},
{"api_mode" = "async_stream", "name" = "streaming_agent_run_with_events"}
]
}
# define the resource with the BYOC configuration, set agent_framework to "google-adk" to enable interactive features on the console.
resource "google_vertex_ai_reasoning_engine" "byoc_weather_agent" {
display_name = "byoc_weather_agent_tf"
description = "BYOC weather agent deployed via Terraform"
project = var.project_id
location = var.location
spec {
class_methods = jsonencode(local.class_methods)
agent_framework = "google-adk"
container_spec {
image_uri = "${var.location}-docker.pkg.dev/${var.project_id}/${var.repository_name}/weather-agent-image:${var.image_tag}"
}
}
}
EOF
Krok 5. Utwórz definicję danych wyjściowych
Zapisz blok danych wyjściowych w outputs.tf:
cat << 'EOF' > outputs.tf
output "reasoning_engine_id" {
value = google_vertex_ai_reasoning_engine.byoc_weather_agent.id
description = "The ID of the deployed reasoning engine"
}
output "reasoning_engine_resource_name" {
value = google_vertex_ai_reasoning_engine.byoc_weather_agent.id
description = "The resource name of the deployed reasoning engine"
}
EOF
Krok 6. Utwórz plik wartości zmiennych (tfvars)
Aby wdrożyć dynamicznie bez edytowania symboli zastępczych, przekaż zmienne środowiskowe bezpośrednio do terraform.tfvars:
cat <<EOF > terraform.tfvars
project_id = "${PROJECT_ID}"
location = "${LOCATION}"
repository_name = "agents-repo"
image_tag = "latest"
EOF
Krok 7. Zainicjuj i zastosuj
Zainicjuj Terraform i zastosuj konfigurację:
terraform init
terraform apply
Gdy pojawi się odpowiedni komunikat, potwierdź zastosowanie, wpisując yes.
Po zakończeniu Terraform wyświetli nazwę zasobu. Aby programowo przechwycić nazwę zasobu do agent_resource_name.txt i wrócić do folderu głównego, użyj tego polecenia:
terraform output -raw reasoning_engine_resource_name > ../agent_resource_name.txt
cd ..
8. Wysyłanie zapytań do agenta
Sprawdź, czy agent działa i odpowiada.
Krok 1. Utwórz skrypt zapytania
Aby pobrać współrzędne lokalizacji, zapisz skrypt weryfikacji w query_agent.py za pomocą dynamicznego sprawdzania konfiguracji:
cat << 'EOF' > query_agent.py
import json
import os
import requests
from google import auth as google_auth
from google.auth.transport import requests as google_requests
# Load config coordinates directly
config_json = json.load(open("weather_agent/config.json"))
LOCATION = config_json["LOCATION"]
PROJECT_ID = config_json["PROJECT_ID"]
# Load agent resource name
with open("agent_resource_name.txt", "r") as f:
agent_resource_name = f.read().strip()
def get_identity_token():
credentials, _ = google_auth.default()
auth_request = google_requests.Request()
credentials.refresh(auth_request)
return credentials.token
# Access the agent at the fastapi endpoint that was specified in main.py
url = f"https://{LOCATION}-aiplatform.googleapis.com/v1/{agent_resource_name}/api/stream_reasoning_engine"
payload = {
"class_method": "async_stream_query",
"input": {
"user_id": "codelab_test_user",
"message": "What is the temperature in Tokyo?",
},
}
print(f"Sending query to {url}...")
response = requests.post(
url,
headers={
"Content-Type": "application/json",
"Authorization": f"Bearer {get_identity_token()}",
},
data=json.dumps(payload),
stream=True,
)
for chunk in response.iter_content(chunk_size=8192):
if chunk:
print(chunk.decode('utf-8'))
EOF
Uruchom skrypt zapytania:
python3 query_agent.py
Powinny pojawić się dane wyjściowe przesyłane z agenta, w tym symulowana temperatura w Tokio.
Krok 2. Użyj konsoli
- Aby przefiltrować listę agentów, przejdź do wdrożonego agenta, klikając kolejno Agent Platform > Agenci > Deployment.

- Na panelu agenta kliknij Plac zabaw.

- Utwórz nową sesję i wpisz zapytanie, aby sprawdzić, czy agent odpowiada na żądania zgodnie z oczekiwaniami.

9. Czyszczenie
Aby uniknąć obciążenia konta opłatami, usuń utworzone przez siebie zasoby.
Jeśli wdrożono za pomocą Terraform, przejdź do katalogu terraform i wykonaj działanie usuwania:
cd ~/weather-agent-byoc/terraform
terraform destroy
cd ..
Jeśli wdrożono za pomocą pakietu SDK, utwórz skrypt usuwania wdrożonego agenta:
cat << 'EOF' > delete_agent.py
import json
import os
import vertexai
from google.cloud import aiplatform
config = json.load(open("weather_agent/config.json"))
PROJECT_ID = config["PROJECT_ID"]
LOCATION = config["LOCATION"]
vertexai.init(project=PROJECT_ID, location=LOCATION)
client = vertexai.Client(project=PROJECT_ID, location=LOCATION)
with open("agent_resource_name.txt", "r") as f:
agent_resource_name = f.read().strip()
# 1. Delete the Agent
# Note: We retrieve the list first to ensure we delete the ones created in this session
try:
page_size = 100
reasoning_engines = client.agent_engines.list()
for engine in reasoning_engines:
if agent_resource_name in engine.api_resource.name:
print(f"Deleting Reasoning Engine: {engine.api_resource.name}")
engine.delete(force=True)
except Exception as e:
print(f"Error deleting reasoning engines: {e}")
EOF
Aby usunąć agenta, uruchom skrypt:
python3 delete_agent.py
Aby usunąć pozostałe zasoby, wróć do katalogu głównego i uruchom w Cloud Shell te polecenia:
cd ~
# 1. Delete the Artifact Registry Repository
gcloud artifacts repositories delete $REPOSITORY_NAME --location=$LOCATION --quiet
# 2. Clean up files (Optional)
rm -rf ~/weather-agent-byoc
10. Podsumowanie
Gratulacje! Udało Ci się skonteneryzować i wdrożyć agenta AI w Agent Runtime za pomocą BYOC.
W tym ćwiczeniu dowiedziałeś się, jak:
- używać ADK do definiowania agenta i opakowywania go za pomocą FastAPI;
- tworzyć Dockerfile i tworzyć obrazy za pomocą Cloud Build;
- Zarządzaj uprawnieniami IAM dla Agent Runtime.
- wdrażać niestandardowy kontener za pomocą pakietu Python SDK i Terraform ;
- testować wdrożonego agenta i wysyłać do niego zapytania.