1. Przegląd
Środowisko wykonawcze agentów (wcześniej Agent Engine) to zarządzane środowcze wykonawcze przeznaczone do wdrażania, uruchamiania i skutecznego skalowania agentów AI. Domyślnie platforma automatycznie łączy kod źródłowy i zależności podczas procesu wdrażania.
W przypadku zadań w przedsiębiorstwie często wymagane jest jednak pełne przejęcie kontroli nad środowiskiem wykonawczym. Aby to umożliwić, środowisko wykonawcze agentów udostępnia funkcję Bring Your Own Container(BYOC), która pozwala wdrażać wstępnie utworzone niestandardowe obrazy kontenerów.
To ćwiczenie opisuje kompleksowy proces konteneryzacji agenta utworzonego za pomocą pakietu Google Agent Development Kit (ADK), konfigurowania niezbędnych uprawnień Google Cloud i wdrażania go w środowisku wykonawczym agentów 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 Agent Runtime.
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ę 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 pakiet 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 katalogów
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 konfiguracyjny
Uruchom to polecenie w Cloud Shell, aby zapisać parametry konfiguracji bezpośrednio w pliku weather_agent/config.json. 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
Uruchom ten skrypt, aby zapisać konfigurację agenta i logikę narzędzia pozorowanego w pliku weather_agent/agent.py:
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
Uruchom ten skrypt, aby zapisać konfigurację punktu wejścia serwera FastAPI w pliku main.py:
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, Request
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"]
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: Request) -> responses.JSONResponse:
request_json = await request.json()
class_method = request_json.get("class_method")
input_val = request_json.get("input")
method = getattr(adk_app, class_method)
output = await _invoke_callable_or_raise(method, input_val 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: Request) -> responses.StreamingResponse:
request_json = await request.json()
class_method = request_json.get("class_method")
input_val = request_json.get("input")
method = getattr(adk_app, class_method)
output = await _invoke_callable_or_raise(method, input_val 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 pliku 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 plik 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
Gdy uprawnienia są już skonfigurowane, możesz wdrożyć niestandardowy kontener.
Krok 1. Wdróż agenta BYOC
Utwórz plik Pythona deploy_byoc.py w katalogu głównym projektu, aby wdrożyć kontener hostowany w rejestrze w Agent Runtime:
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
Uruchom skrypt wdrożenia, aby wdrożyć agenta w Agent Runtime:
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
Uruchom ten skrypt, aby zapisać mapowanie dostawców w pliku providers.tf:
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 pliku 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 główne parametry definicji zasobów w pliku 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
region = 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 pliku 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)
Wdrażaj dynamicznie bez edytowania symboli zastępczych, przekazując zmienne środowiskowe bezpośrednio do pliku 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. Programowo przechwyć ją do pliku agent_resource_name.txt i wróć do folderu głównego:
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
Zapisz skrypt weryfikacji w pliku query_agent.py, używając dynamicznego sprawdzania konfiguracji, aby pobrać współrzędne lokalizacji:
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/reasoningEngines/v1/{agent_resource_name}/api/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 > Wdrożenia.

- 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 usuwający 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
Uruchom skrypt, aby usunąć agenta:
python3 delete_agent.py
Aby wyczyścić pozostałe zasoby, wróć do katalogu głównego i uruchom te polecenia w Cloud Shell:
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.
Dowiedziałeś(-aś) się, jak:
- używać ADK do definiowania agenta i opakowywania go za pomocą FastAPI;
- tworzyć plik Dockerfile i 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.