1. Présentation
Agent Runtime (anciennement Agent Engine) offre un environnement d'exécution géré conçu pour déployer, exécuter et faire évoluer efficacement des agents d'IA. Par défaut, la plate-forme regroupe automatiquement votre code source et vos dépendances lors du processus de déploiement.
Toutefois, les charges de travail d'entreprise nécessitent souvent une propriété complète de l'environnement d'exécution. Pour ce faire, Agent Runtime fournit la fonctionnalité Bring Your Own Container(BYOC), qui vous permet de déployer des images de conteneurs personnalisées prédéfinies.
Cet atelier de programmation décrit le processus de bout en bout pour conteneuriser un agent créé avec l'Agent Development Kit (ADK) Google, configurer les autorisations Google Cloud nécessaires et le déployer sur Agent Runtime à l'aide du SDK Python ou de Terraform.
Cet atelier de programmation vous guide à travers les étapes suivantes :
- Créer un agent Python à l'aide de Google Agent Development Kit (ADK).
- Encapsuler l'agent dans une application FastAPI.
- Conteneurisez l'application avec Docker.
- Configurer les autorisations Google Cloud.
- Déployer et tester l'agent conteneurisé sur Agent Runtime
Flux de compilation et de déploiement
Le schéma suivant illustre le workflow des étapes de compilation et de déploiement que vous effectuerez manuellement dans cet atelier de programmation :

Ce dont vous avez besoin
- Projet Google Cloud avec facturation activée
- Accès à Cloud Shell (recommandé) ou à un environnement de développement local avec
gcloudetdockerinstallés. - Connaissances de base de Python et Docker
2. Configuration de l'environnement
Avant de commencer, vous devez activer les API nécessaires et configurer votre environnement.
Étape 1 : Ouvrez Cloud Shell
Cliquez sur le bouton Activer Cloud Shell en haut à droite de la console Google Cloud.

Étape 2 : Configurez les variables d'environnement
Dans Cloud Shell, définissez l'ID de votre projet et définissez les principales variables d'environnement utilisées tout au long de cet atelier de programmation. Remplacez "YOUR_PROJECT_ID" par l'ID de votre projet 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"
Ces variables configurent les paramètres de déploiement cible :
PROJECT_ID: identifiant unique de votre projet Google Cloud dans lequel résideront toutes les ressources Gemini Enterprise Agent Platform et Artifact Registry.LOCATION: région géographique (par exemple,us-central1) hébergeant vos dépôts et vos charges de travail d'exécution.MODEL: version du modèle Gemini (par exemple,gemini-3.1-flash-lite) chargée par le contexte de l'agent.MODEL_REGION: région du point de terminaison du modèle. Définissez ici la valeur"global"pour appeler le modèle Gemini à partir des points de terminaison mondiaux.
Étape 3 : Activer les API
Activez les API Google Cloud requises :
gcloud services enable \
aiplatform.googleapis.com \
cloudbuild.googleapis.com \
compute.googleapis.com \
artifactregistry.googleapis.com \
storage.googleapis.com
Étape 4 : Installer le SDK
Installez le SDK Vertex AI avec la prise en charge d'Agent Engine et de l'ADK :
pip install --upgrade "google-cloud-aiplatform[agent_engines,adk]>=1.144"
3. Configurer les fichiers sources
Dans cette étape, vous allez créer la structure et le code de votre agent.
Présentation de la structure des répertoires
À la fin de cet atelier de programmation, vos fichiers seront organisés selon la hiérarchie d'espace de travail suivante :
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
Étape 1 : Créer des répertoires
Commencez dans votre répertoire d'accueil et créez la structure de l'espace de travail :
cd ~
mkdir -p weather-agent-byoc/weather_agent
cd weather-agent-byoc
Étape 2 : Créez le fichier de configuration
Exécutez la commande suivante dans Cloud Shell pour écrire les paramètres de configuration directement dans weather_agent/config.json. Cette commande remplace automatiquement les variables par les valeurs de votre environnement :
cat <<EOF > weather_agent/config.json
{
"PROJECT_ID": "${PROJECT_ID}",
"LOCATION": "${LOCATION}",
"MODEL": "${MODEL}",
"MODEL_REGION": "${MODEL_REGION}"
}
EOF
Étape 3 : Définir l'agent
Exécutez le script suivant pour écrire la configuration de l'agent et simuler la logique de l'outil dans 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
Créez un __init__.py vide pour faire de weather_agent un package Python :
touch weather_agent/__init__.py
Étape 4 : Créer un wrapper FastAPI
Exécutez le script suivant pour écrire la configuration du point d'entrée du serveur FastAPI dans 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
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
Étape 5 : Définir les dépendances
Écrivez les dépendances Python requises dans requirements.txt :
cat << 'EOF' > requirements.txt
fastapi
uvicorn
vertexai
google-cloud-aiplatform[agent_engines,adk]>=1.144
pydantic
EOF
4. Conteneurisation
Définissez maintenant comment votre agent sera empaqueté dans un conteneur.
Étape 1 : Créez un fichier Dockerfile
Créez le fichier Dockerfile à la racine du répertoire de votre projet pour spécifier la façon dont votre application FastAPI est créée :
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. Configurer Artifact Registry et Cloud Build
Vous avez besoin d'un dépôt pour stocker l'image de conteneur et des autorisations pour la transférer.
Étape 1 : Créer un dépôt
Définissez le nom du dépôt et créez un dépôt Docker dans Artifact Registry à l'aide des variables d'environnement définies lors de la configuration :
export REPOSITORY_NAME="agents-repo"
gcloud artifacts repositories create $REPOSITORY_NAME \
--project=$PROJECT_ID \
--repository-format=docker \
--location=$LOCATION \
--description="Docker repository for Agents"
Étape 2 : Configurer les autorisations du compte de service
Accordez au compte de service Compute par défaut l'autorisation de transférer des images vers Artifact Registry.
Tout d'abord, obtenez le numéro de votre projet :
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")
Attribuez les rôles :
# 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
Étape 3 : Accorder des autorisations aux agents de service
Accordez l'accès en lecture Artifact Registry aux agents de service AI Platform et Reasoning Engine :
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
Étape 4 : Créez et transférez l'image
Utilisez Cloud Build pour créer et transférer l'image de conteneur :
gcloud builds submit \
--project=$PROJECT_ID \
--region=$LOCATION \
--tag $LOCATION-docker.pkg.dev/$PROJECT_ID/$REPOSITORY_NAME/weather-agent-image:latest \
.
6. Déployer l'agent avec le SDK
Maintenant que les autorisations sont configurées, vous pouvez déployer votre conteneur personnalisé.
Étape 1 : Déployer l'agent BYOC
Créez le fichier Python deploy_byoc.py à la racine du répertoire de votre projet pour déployer le conteneur hébergé dans le registre sur 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
Exécutez le script de déploiement pour déployer l'agent sur Agent Runtime :
python3 deploy_byoc.py
7. Déployer l'agent avec Terraform
Vous pouvez également déployer le même agent conteneurisé à l'aide de Terraform. Cette méthode est recommandée pour les environnements de production afin de gérer l'infrastructure en tant que code.
Étape 1 : Accéder au répertoire Terraform
Créez un répertoire terraform à la racine de votre projet et accédez-y :
mkdir -p terraform
cd terraform
Étape 2 : Créez la configuration des fournisseurs
Exécutez le script suivant pour écrire le mappage des fournisseurs dans 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
Étape 3 : Créer une définition de variables
Écrivez le bloc de description des entrées dans 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
Étape 4 : Créez la configuration principale
Écrivez les principaux paramètres de définition des ressources dans 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
Étape 5 : Créer une définition des sorties
Écrivez le bloc de sorties dans 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
Étape 6 : Créer un fichier de valeurs de variables (tfvars)
Déployez de manière dynamique sans modifier les espaces réservés en transmettant les variables d'environnement directement à terraform.tfvars :
cat <<EOF > terraform.tfvars
project_id = "${PROJECT_ID}"
location = "${LOCATION}"
repository_name = "agents-repo"
image_tag = "latest"
EOF
Étape 7 : Initialiser et appliquer
Initialisez Terraform et appliquez la configuration :
terraform init
terraform apply
Confirmez l'application en saisissant yes lorsque vous y êtes invité.
Une fois l'opération terminée, Terraform affiche le nom de la ressource. Capturez-le de manière programmatique dans agent_resource_name.txt et revenez au dossier racine :
terraform output -raw reasoning_engine_resource_name > ../agent_resource_name.txt
cd ..
8. Interroger l'agent
Vérifiez que votre agent est en cours d'exécution et qu'il répond.
Étape 1 : Créer un script de requête
Écrivez le script de validation dans query_agent.py à l'aide d'une vérification de la configuration dynamique pour récupérer les coordonnées de l'emplacement :
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
Exécutez le script de requête :
python3 query_agent.py
Vous devriez voir le résultat renvoyé par l'agent, y compris la température simulée pour Tokyo.
Étape 2 : Utilisez la console
- Accédez à l'agent déployé en sélectionnant Plate-forme d'agent > Agents > Déploiements pour filtrer la liste des agents.

- Sélectionnez Playground (Terrain de jeu) dans le tableau de bord de l'agent.

- Créez une session et saisissez votre requête pour vérifier si l'agent répond aux demandes comme indiqué.

9. Nettoyage
Pour éviter que des frais ne vous soient facturés, nettoyez les ressources que vous avez créées.
Si vous avez effectué le déploiement à l'aide de Terraform, accédez au répertoire terraform et exécutez l'action de suppression :
cd ~/weather-agent-byoc/terraform
terraform destroy
cd ..
Si vous avez effectué le déploiement à l'aide du SDK, créez le script permettant de supprimer l'agent déployé :
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
Exécutez le script pour supprimer l'agent :
python3 delete_agent.py
Pour nettoyer le reste des ressources, revenez à votre répertoire d'accueil et exécutez les commandes suivantes dans 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. Conclusion
Félicitations ! Vous avez réussi à conteneuriser et à déployer un agent d'IA sur Agent Runtime à l'aide de BYOC.
Vous avez appris à :
- Utilisez ADK pour définir un agent et l'encapsuler à l'aide de FastAPI.
- Créez un fichier Dockerfile et générez des images à l'aide de Cloud Build.
- Gérez les autorisations IAM pour Agent Runtime.
- Déployez votre conteneur personnalisé à l'aide du SDK Python et de Terraform.
- Testez et interrogez votre agent déployé.