1. Introduction
Une interface Private Service Connect est une ressource qui permet à un réseau cloud privé virtuel (VPC) de producteur d'initier des connexions avec différentes destinations dans un réseau VPC consommateur. Les réseaux de producteurs et les réseaux de clients peuvent appartenir à différents projets et organisations.
Si un rattachement de réseau accepte une connexion depuis une interface Private Service Connect, Google Cloud attribue à l'interface une adresse IP d'un sous-réseau client spécifié par le rattachement de réseau. Les réseaux utilisateur et producteur sont connectés et peuvent communiquer à l'aide d'adresses IP internes.
Une connexion entre un rattachement de réseau et une interface Private Service Connect est semblable à la connexion entre un point de terminaison Private Service Connect et un rattachement de service, avec toutefois deux différences majeures :
- Un rattachement de réseau permet à un réseau producteur d'établir des connexions avec un réseau consommateur (sortie de service géré), tandis qu'un point de terminaison permet à un réseau consommateur d'établir des connexions avec un réseau producteur (entrée de service géré).
- Une connexion d'interface Private Service Connect est transitive. Cela signifie qu'un réseau de producteur peut communiquer avec d'autres réseaux connectés au réseau du client.
Considérations concernant l'accessibilité de l'interface PSC Vertex AI
- L'interface PSC est capable de router le trafic vers des destinations VPC ou sur site dans le bloc d'adresses RFC1918.
- L'interface PSC ciblant des blocs d'adresses non-RFC 1918 nécessite un proxy explicite déployé dans le VPC du consommateur avec une adresse RFC 1918. Dans le déploiement Vertex AI, le proxy doit être défini avec un nom de domaine complet du point de terminaison cible.
- Lorsque vous configurez votre déploiement avec une interface PSC uniquement, il conserve son accès Internet par défaut. Ce trafic sortant quitte directement le réseau locataire sécurisé et géré par Google.
Considérations concernant l'interface VPC-SC de Vertex AI PSC
- Lorsque votre projet fait partie d'un périmètre VPC Service Controls, l'accès à Internet par défaut des locataires gérés par Google est bloqué par le périmètre pour empêcher l'exfiltration de données.
- Pour autoriser l'accès au déploiement à l'Internet public dans ce scénario, vous devez configurer explicitement un chemin de sortie sécurisé qui achemine le trafic via votre VPC.
- La méthode recommandée pour y parvenir consiste à configurer un serveur proxy à l'intérieur de votre périmètre VPC avec une adresse RFC1918 et à créer une passerelle Cloud NAT pour permettre à la VM proxy d'accéder à Internet.
Pour en savoir plus, consultez les ressources suivantes :
Déployer un agent | IA générative sur Vertex AI | Google Cloud
Configurer une interface Private Service Connect pour les ressources Vertex AI | Google Cloud
Ce que vous allez faire
Dans ce tutoriel, vous allez créer un moteur d'agent complet déployé avec une interface Private Service Connect (PSC) pour permettre la connectivité à un site public (https://api.frankfurter.app/) via une VM de proxy déployée dans le VPC du consommateur avec une adresse RFC1918. L'exemple de déploiement s'applique dans un projet VPC-SC activé ou pour les administrateurs qui ont besoin d'une sortie Internet via le réseau client au lieu du VPC locataire.
Figure 1
Vous allez créer un seul psc-network-attachment dans le VPC consommateur en utilisant l'appairage DNS pour résoudre la VM proxy du réseau consommateur dans le projet locataire hébergeant Agent Engine, ce qui permet les cas d'utilisation suivants :
Déployer Agent Engine et configurer une VM proxy pour qu'elle agisse en tant que proxy explicite, ce qui lui permet d'accéder à une URL publique https://api.frankfurter.app
Points abordés
- Créer un rattachement de réseau
- Comment un producteur peut utiliser un rattachement de réseau pour créer une interface PSC
- Établir une communication du producteur au consommateur à l'aide de l'appairage DNS
- Déployer et utiliser une VM proxy pour la sortie Internet
Prérequis
Projet Google Cloud
Autorisations IAM
- Administrateur de réseaux Compute (roles/compute.networkAdmin)
- Administrateur d'instances Compute (roles/compute.instanceAdmin)
- Administrateur de sécurité de Compute (roles/compute.securityAdmin)
- Administrateur DNS (roles/dns.admin)
- Utilisateur de tunnels sécurisés par IAP (roles/iap.tunnelResourceAccessor)
- Administrateur Logging (roles/logging.admin)
- Administrateur Notebooks (roles/notebooks.admin)
- Administrateur IAM du projet (roles/resourcemanager.projectIamAdmin)
- Administrateur de compte de service (roles/iam.serviceAccountAdmin)
- Administrateur Service Usage (roles/serviceusage.serviceUsageAdmin)
2. Avant de commencer
Mettre à jour le projet pour qu'il soit compatible avec le tutoriel
Ce tutoriel utilise des $variables pour faciliter l'implémentation de la configuration gcloud dans Cloud Shell.
Dans Cloud Shell, procédez comme suit :
gcloud config list project
gcloud config set project [YOUR-PROJECT-NAME]
projectid=YOUR-PROJECT-NAME
echo $projectid
Activation de l'API
Dans Cloud Shell, procédez comme suit :
gcloud services enable "compute.googleapis.com"
gcloud services enable "aiplatform.googleapis.com"
gcloud services enable "dns.googleapis.com"
gcloud services enable "notebooks.googleapis.com"
gcloud services enable "storage.googleapis.com"
gcloud services enable "iap.googleapis.com"
Vérifier que les API sont activées
gcloud services list --enabled
3. Configuration du client
Créer le VPC consommateur
Ce VPC réside dans un projet client. Les ressources suivantes seront créées dans ce VPC :
- Sous-réseau du client
- Sous-réseau de rattachement de réseau
- Cloud Router (requis pour Cloud NAT)
- Cloud NAT
Dans Cloud Shell, procédez comme suit :
gcloud compute networks create consumer-vpc --project=$projectid --subnet-mode=custom
Créer les sous-réseaux consommateurs
Dans Cloud Shell, créez le sous-réseau pour la VM proxy :
gcloud compute networks subnets create rfc1918-subnet1 --project=$projectid --range=10.10.10.0/28 --network=consumer-vpc --region=us-central1
Créer le sous-réseau de rattachement de réseau Private Service Connect
Dans Cloud Shell, créez le sous-réseau pour l'association de réseau PSC :
gcloud compute networks subnets create intf-subnet --project=$projectid --range=192.168.10.0/28 --network=consumer-vpc --region=us-central1
Configuration de Cloud Router et de NAT
Dans ce tutoriel, Cloud NAT est utilisé pour fournir un accès à Internet à la VM proxy, qui ne dispose pas d'adresse IP publique. Cloud NAT permet aux VM ne disposant que d'adresses IP privées de se connecter à Internet, ce qui leur permet d'effectuer des tâches telles que l'installation de packages logiciels.
Dans Cloud Shell, créez le routeur Cloud Router.
gcloud compute routers create cloud-router-for-nat --network consumer-vpc --region us-central1
Dans Cloud Shell, créez la passerelle NAT avec la journalisation activée. Nous utiliserons la journalisation pour valider l'accès à l'adresse IP publique de l'API Frankfurter (https://api.frankfurter.app/).
gcloud compute routers nats create cloud-nat-us-central1 --router=cloud-router-for-nat --auto-allocate-nat-external-ips --nat-all-subnet-ip-ranges --region us-central1 --enable-logging --log-filter=ALL
4. Activer IAP
Pour permettre à IAP de se connecter à vos instances de VM, créez une règle de pare-feu qui :
- S'applique à toutes les instances de VM auxquelles vous souhaitez être accessible à l'aide d'IAP.
- Autorise le trafic entrant à partir de la plage d'adresses IP 35.235.240.0/20. Cette plage contient toutes les adresses IP qu'IAP utilise pour le transfert TCP.
Dans Cloud Shell, créez la règle de pare-feu IAP.
gcloud compute firewall-rules create ssh-iap-consumer \
--network consumer-vpc \
--allow tcp:22 \
--source-ranges=35.235.240.0/20
5. Créer des instances de VM consommateur
Dans Cloud Shell, créez l'instance de VM consommateur, proxy-vm, qui servira de proxy explicite pour Agent Engine. Nous utiliserons tinyproxy comme application pour le trafic HTTP de proxy.
gcloud compute instances create proxy-vm \
--project=$projectid \
--machine-type=e2-micro \
--image-family debian-11 \
--no-address \
--can-ip-forward \
--image-project debian-cloud \
--zone us-central1-a \
--subnet=rfc1918-subnet1 \
--shielded-secure-boot \
--metadata startup-script="#! /bin/bash
sudo apt-get update
sudo apt-get install tcpdump
sudo apt-get install tinyproxy -y
sudo apt-get install apache2 -y
sudo service apache2 restart
echo 'proxy server !!' | tee /var/www/html/index.html
EOF"
6. Rattachement de réseau Private Service Connect
Les rattachements de réseau sont des ressources régionales qui représentent le côté utilisateur d'une interface Private Service Connect. Vous associez un seul sous-réseau à un rattachement de réseau, et le producteur attribue des adresses IP à l'interface Private Service Connect à partir de ce sous-réseau. Le sous-réseau doit se trouver dans la même région que le rattachement de réseau. Un rattachement réseau doit se trouver dans la même région que le service producteur.
Créer le rattachement de réseau
Dans Cloud Shell, créez le rattachement de réseau.
gcloud compute network-attachments create psc-network-attachment \
--region=us-central1 \
--connection-preference=ACCEPT_AUTOMATIC \
--subnets=intf-subnet
Lister les rattachements de réseau
Dans Cloud Shell, listez le rattachement réseau.
gcloud compute network-attachments list
Décrire les rattachements de réseau
Dans Cloud Shell, décrivez le rattachement de réseau.
gcloud compute network-attachments describe psc-network-attachment --region=us-central1
Notez le nom du rattachement de réseau PSC, psc-network-attachment
, qui sera utilisé par le producteur lors de la création de l'interface Private Service Connect.
Pour afficher l'URL d'association au réseau PSC dans la console Cloud, accédez à :
Services réseau → Private Service Connect → Rattachement de réseau → psc-network-attachment
7. Zone DNS privée
Vous allez créer une zone Cloud DNS pour demo.com
et la remplir avec un enregistrement A qui pointe vers les adresses IP de votre VM de proxy. L'appairage DNS sera ensuite déployé dans Agent Engine, ce qui permettra d'accéder aux enregistrements DNS du consommateur.
Dans Cloud Shell, exécutez la commande suivante pour créer un nom DNS demo.com.
gcloud dns --project=$projectid managed-zones create private-dns-codelab --description="" --dns-name="demo.com." --visibility="private" --networks="https://compute.googleapis.com/compute/v1/projects/$projectid/global/networks/consumer-vpc"
Obtenez et stockez les adresses IP des instances utilisées pour les enregistrements A DNS.
Dans Cloud Shell, exécutez une commande "describe" sur les instances de VM.
gcloud compute instances describe proxy-vm --zone=us-central1-a | grep networkIP:
Dans Cloud Shell, créez l'ensemble d'enregistrements pour la VM proxy-vm.demo.com. Veillez à mettre à jour l'adresse IP en fonction de la sortie de votre environnement.
gcloud dns --project=$projectid record-sets create proxy-vm.demo.com. --zone="private-dns-codelab" --type="A" --ttl="300" --rrdatas="10.10.10.2"
Créer une règle Cloud Firewall pour autoriser l'accès depuis l'interface PSC
Dans la section suivante, créez une règle de pare-feu qui autorise le trafic provenant de l'attachement de réseau PSC à accéder à la VM de proxy dans le VPC consommateur.
Dans Cloud Shell, créez la règle de pare-feu d'entrée.
gcloud compute firewall-rules create allow-access-to-compute \
--network=consumer-vpc \
--action=ALLOW \
--rules=ALL \
--direction=INGRESS \
--priority=1000 \
--source-ranges="192.168.10.0/28" \
--destination-ranges="10.10.10.0/28" \
--enable-logging
8. Créer un notebook Jupyter
La section suivante vous explique comment créer un notebook Jupyter. Ce notebook sera utilisé pour déployer Agent Engine en ciblant un proxy explicite pour la sortie Internet.
Créer un compte de service géré par l'utilisateur
Dans la section suivante, vous allez créer un compte de service qui sera associé à l'instance Vertex AI Workbench utilisée dans le tutoriel.
Dans le tutoriel, les rôles suivants seront appliqués au compte de service :
- Administrateur Storage
- Utilisateur Vertex AI
- Administrateur Artifact Registry
- Utilisateur du compte de service IAM
Dans Cloud Shell, créez le compte de service.
gcloud iam service-accounts create notebook-sa \
--display-name="notebook-sa"
Dans Cloud Shell, mettez à jour le compte de service avec le rôle "Administrateur Storage".
gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:notebook-sa@$projectid.iam.gserviceaccount.com" --role="roles/storage.admin"
Dans Cloud Shell, mettez à jour le compte de service avec le rôle Utilisateur Vertex AI.
gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:notebook-sa@$projectid.iam.gserviceaccount.com" --role="roles/aiplatform.user"
Dans Cloud Shell, mettez à jour le compte de service avec le rôle Administrateur Artifact Registry.
gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:notebook-sa@$projectid.iam.gserviceaccount.com" --role="roles/artifactregistry.admin"
Dans Cloud Shell, autorisez le compte de service du notebook à utiliser le compte de service Compute Engine par défaut.
gcloud iam service-accounts add-iam-policy-binding \
$(gcloud projects describe $(gcloud config get-value project) --format='value(projectNumber)')-compute@developer.gserviceaccount.com \
--member="serviceAccount:notebook-sa@$projectid.iam.gserviceaccount.com" \
--role="roles/iam.serviceAccountUser"
9. Mettre à jour le proxy explicite
Dans la section suivante, vous devrez vous connecter en SSH au proxy explicite, puis mettre à jour le fichier de configuration tinyproxy.conf et effectuer une réinitialisation.
Depuis Cloud Shell
gcloud compute ssh --zone us-central1-a "proxy-vm" --tunnel-through-iap --project $projectid
Ouvrez le fichier de configuration tinyproxy et mettez-le à jour à l'aide de l'éditeur de votre choix. Vous trouverez ci-dessous un exemple utilisant VIM.
sudo vim /etc/tinyproxy/tinyproxy.conf
# Locate the "Listen" configuration line to restrict listening to only its private IP address of the Proxy-VM, rather than all interfaces.
Listen 10.10.10.2
# Locate the "Allow" configuration line to allow requests ONLY from the PSC Network Attachment Subnet
Allow 192.168.10.0/24
Save the configs by the following steps:
1. Press the `ESC` key to enter Command Mode.
2. Type `:wq` to save (w) and quit (q).
3. Press `Enter`
Restart the tinyproxy service to apply the changes:
sudo systemctl restart tinyproxy
Validate the tinyproxy service is running:
sudo systemctl status tinyproxy
Perform an exit returning to cloud shell
exit
10. Créer une instance Vertex AI Workbench
Dans la section suivante, créez une instance Vertex AI Workbench qui intègre le compte de service notebook-sa créé précédemment.
Dans Cloud Shell, créez l'instance de client privé.
gcloud workbench instances create workbench-tutorial --vm-image-project=cloud-notebooks-managed --vm-image-family=workbench-instances --machine-type=n1-standard-4 --location=us-central1-a --subnet-region=us-central1 --subnet=rfc1918-subnet1 --disable-public-ip --shielded-secure-boot=true --shielded-integrity-monitoring=true --shielded-vtpm=true --service-account-email=notebook-sa@$projectid.iam.gserviceaccount.com
11. Mise à jour de l'agent de service Vertex AI
Vertex AI agit en votre nom pour effectuer des opérations telles que l'obtention d'une adresse IP à partir du sous-réseau de rattachement de réseau PSC utilisé pour créer l'interface PSC. Pour ce faire, Vertex AI utilise un agent de service (listé ci-dessous) qui nécessite l'autorisation Administrateur réseau :
service-$projectnumber@gcp-sa-aiplatform.iam.gserviceaccount.com
Dans Cloud Shell, obtenez le numéro de votre projet.
gcloud projects describe $projectid | grep projectNumber
Dans Cloud Shell, définissez le numéro de votre projet.
projectnumber=YOUR-PROJECT-Number
Dans Cloud Shell, créez un compte de service pour AI Platform. Ignorez cette étape si vous disposez déjà d'un compte de service dans votre projet.
gcloud beta services identity create --service=aiplatform.googleapis.com --project=$projectnumber
Dans Cloud Shell, mettez à jour le compte de l'agent de service avec le rôle compute.networkAdmin.
gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:service-$projectnumber@gcp-sa-aiplatform.iam.gserviceaccount.com" --role="roles/compute.networkAdmin"
Dans Cloud Shell, mettez à jour le compte de l'agent de service avec le rôle dns.peer.
gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:service-$projectnumber@gcp-sa-aiplatform.iam.gserviceaccount.com" --role="roles/dns.peer"
Mise à jour du compte de service par défaut
Accordez à votre compte de service par défaut l'accès à Vertex AI. Notez que la propagation de la modification d'accès peut prendre un certain temps.
Dans Cloud Shell, mettez à jour le compte de service par défaut avec le rôle aiplatform.user.
gcloud projects add-iam-policy-binding $projectid \
--member="serviceAccount:$projectnumber-compute@developer.gserviceaccount.com" \
--role="roles/aiplatform.user"
12. Tcpdump de la VM du proxy
Pour valider la connectivité IP depuis Agent Engine, nous pouvons utiliser TCPDUMP. Cela nous permettra d'observer la communication provenant du sous-réseau de rattachement au réseau PSC, 192.168.10.0/28, lors de l'appel de la requête GET depuis Agent Engine vers l'URL publique.
Depuis Cloud Shell, connectez-vous en SSH à la VM de proxy.
gcloud compute ssh --zone us-central1-a "proxy-vm" --tunnel-through-iap --project $projectid
Exécutez tcpdump à partir de l'OS de la VM proxy.
sudo tcpdump -i any net 192.168.10.0/28 -nn
13. Déployer Agent Engine
Remarque : Nous allons utiliser la console GCP et le notebook JupyterLab pour effectuer les tâches de cette section.
Dans la section suivante, vous allez créer un notebook qui effectue les tâches suivantes :
- Utilise l'API Frankfurter (https://api.frankfurter.app/) pour obtenir des données sur les taux de change.
- Fait référence à un proxy explicite (proxy_server) ciblant la VM de proxy dans le VPC des consommateurs à l'aide du nom de domaine complet proxy-vm.demo.com
- Définissez dnsPeeringConfigs "domain": "demo.com."
Exécutez le job d'entraînement dans l'instance Vertex AI Workbench.
- Dans la console Google Cloud, accédez à Vertex AI > Workbench.
- À côté du nom de votre instance Vertex AI Workbench (workbench-tutorial), cliquez sur "Ouvrir JupyterLab". Votre instance Vertex AI Workbench ouvre JupyterLab.
- Sélectionnez Fichier > Nouveau > Notebook.
- Sélectionnez Kernel > Python 3.
Installez les bibliothèques Python nécessaires : installez les bibliothèques requises pour Agent Engine, y compris pyyaml, google-cloud-aiplatform, cloudpickle, google-cloud-api-keys et langchain-google-vertexai.
Dans votre notebook JupyterLab, créez une cellule et exécutez la commande suivante.
!pip install pyyaml
!pip install google-cloud-aiplatform[agent_engines,langchain]==1.96.0
!pip install cloudpickle==3.1.1
!pip install google-cloud-api-keys
!pip install langchain-google-vertexai==2.0.24
Redémarrez le noyau Jupyter Notebook : assurez-vous que les bibliothèques nouvellement installées sont correctement chargées.
Dans votre notebook JupyterLab, créez une cellule et exécutez la commande suivante.
# Restart the notebook kernel after install, so you can run langchain successfully.
import IPython
app = IPython.Application.instance()
app.kernel.do_shutdown(True)
Définissez les variables de projet et de bucket : définissez l'ID de votre projet Google Cloud, le numéro de projet, le nom du service, le répertoire GCS, le point de terminaison, le nom du bucket et l'emplacement.
Mettez à jour les champs suivants avant d'exécuter la cellule.
- PROJECT_ID = "enter-your-projectid"
- PROJECT_NUMBER = "enter-your-projectnumber"
- BUCKET= "enter-a-unique-bucket-name"
Remarque : Nous utiliserons la variable BUCKET pour créer un bucket Cloud Storage à l'étape suivante.
Dans votre notebook JupyterLab, créez une cellule, puis mettez à jour et exécutez le code suivant.
PROJECT_ID = "enter-your-projectid" #@param {type:"string"}
PROJECT_NUMBER = "enter-your-projectnumber" #@param {type:"string"}
SERVICE_NAME = "aiplatform" #@param ["autopush-aiplatform", "staging-aiplatform", "aiplatform"]
# @markdown Specify where your agent code should be written in GCS:
GCS_DIR = "reasoning-engine-test" #@param {type:"string"}
ENDPOINT = "https://us-central1-aiplatform.googleapis.com" # @param ["https://us-central1-aiplatform.googleapis.com", "https://us-central1-autopush-aiplatform.sandbox.googleapis.com", "https://us-central1-staging-aiplatform.sandbox.googleapis.com"]
BUCKET= "enter-a-unique-bucket-name" #@param {type:"string"}
LOCATION="us-central1" #@param {type:"string"}
Créez un bucket GCS : créez un bucket Cloud Storage pour stocker le code de l'agent.
Dans votre notebook JupyterLab, créez une cellule et exécutez la commande suivante.
!gcloud storage buckets create gs://{BUCKET}
Définissez le nom du rattachement de réseau : spécifiez le nom de votre rattachement de réseau Private Service Connect.
Dans votre notebook JupyterLab, créez une cellule et exécutez la commande suivante.
NETWORK_ATTACHMENT_NAME = 'psc-network-attachment' #@param {type:"string"}
Initialisez les bibliothèques clientes Python : configurez les bibliothèques clientes nécessaires pour les services Google Cloud.
Dans votre notebook JupyterLab, créez une cellule et exécutez la commande suivante.
import json
import pprint
import cloudpickle
from google import auth as google_auth
from google.auth.transport import requests as google_requests
from google.cloud import storage
import yaml
def get_identity_token():
"""Gets ID token for calling Cloud Run."""
credentials, _ = google_auth.default()
auth_request = google_requests.Request()
credentials.refresh(auth_request)
return credentials.id_token
if not GCS_DIR or "your_ldap" in GCS_DIR:
raise ValueError("GCS_DIR must be set or you must set your ldap.")
if not PROJECT_ID:
raise ValueError("PROJECT_ID must be set.")
client = storage.Client(project=PROJECT_ID)
bucket = client.get_bucket(BUCKET)
Configurer l'agent et les outils : définissez la classe StreamingAgent et la fonction get_exchange_rate pour récupérer les taux de change à l'aide de l'API Frankfurter via le proxy explicite.
Dans votre notebook JupyterLab, créez une cellule et exécutez la configuration ci-dessous. Notez les points suivants :
- La fonction "get_exchange_rate" utilisera l'API Frankfurter (https://api.frankfurter.app/) pour obtenir les données sur les taux de change.
- proxy_server = "http://proxy-vm.demo.com:8888" Le nom de domaine complet est associé à la VM de proxy déployée dans le VPC consommateur. Nous utilisons le peering DNS pour résoudre le nom de domaine complet lors d'une étape ultérieure.
from langchain_google_vertexai import ChatVertexAI
from langchain.agents import AgentExecutor
from langchain.agents.format_scratchpad.tools import format_to_tool_messages
from langchain.agents.output_parsers.tools import ToolsAgentOutputParser
from langchain.tools.base import StructuredTool
from langchain_core import prompts
from re import S
from typing import Callable, Sequence
import google.auth
import vertexai
class StreamingAgent:
def __init__(
self,
model: str,
tools: Sequence[Callable],
project_id: str,
):
self.model_name = model
self.tools = tools
self.project_id = project_id
def set_up(self):
"""All unpickle-able logic should go here.
The .set_up() method should not be called for an object that is being
prepared for deployment.
"""
creds, _ = google.auth.default(quota_project_id=self.project_id)
vertexai.init(project=self.project_id, location="us-central1", credentials=creds)
prompt = {
"input": lambda x: x["input"],
"agent_scratchpad": (
lambda x: format_to_tool_messages(x["intermediate_steps"])
),
} | prompts.ChatPromptTemplate.from_messages([
("user", "{input}"),
prompts.MessagesPlaceholder(variable_name="agent_scratchpad"),
])
llm = ChatVertexAI(model_name=self.model_name)
if self.tools:
llm = llm.bind_tools(tools=self.tools)
self.agent_executor = AgentExecutor(
agent=prompt | llm | ToolsAgentOutputParser(),
tools=[StructuredTool.from_function(tool) for tool in self.tools],
)
def query(self, input: str):
"""Query the application.
Args:
input: The user prompt.
Returns:
The output of querying the application with the given input.
"""
return self.agent_executor.invoke(input={"input": input})
def stream_query(self, input: str):
"""Query the application and stream the output.
Args:
input: The user prompt.
Yields:
Chunks of the response as they become available.
"""
for chunk in self.agent_executor.stream(input={"input": input}):
yield chunk
def get_exchange_rate(
currency_from: str = "USD",
currency_to: str = "EUR",
currency_date: str = "latest",
):
"""Retrieves the exchange rate between two currencies on a specified date.
Uses the Frankfurter API (https://api.frankfurter.app/) to obtain
exchange rate data.
Args:
currency_from: The base currency (3-letter currency code).
Defaults to "USD" (US Dollar).
currency_to: The target currency (3-letter currency code).
Defaults to "EUR" (Euro).
currency_date: The date for which to retrieve the exchange rate.
Defaults to "latest" for the most recent exchange rate data.
Can be specified in YYYY-MM-DD format for historical rates.
Returns:
dict: A dictionary containing the exchange rate information.
Example: {"amount": 1.0, "base": "USD", "date": "2023-11-24",
"rates": {"EUR": 0.95534}}
"""
import requests
proxy_server = "http://proxy-vm.demo.com:8888" # This is the VM's FQDN to reach the proxy vm in the consumers network
proxies = {
"http": proxy_server,
"https": proxy_server,
}
response = requests.get(
f"https://api.frankfurter.app/{currency_date}",
params={"from": currency_from, "to": currency_to},
proxies=proxies,
)
return response.json()
Importez les fichiers de l'agent dans Cloud Storage : importez l'agent sérialisé et ses exigences dans le bucket GCS désigné.
Dans votre notebook JupyterLab, créez une cellule et exécutez la commande suivante :
# Upload files to Cloud Storage.
if not GCS_DIR:
raise ValueError("GCS_DIR must be set.")
FILE = "streaming_agent.pkl"
blob = bucket.blob(f"{GCS_DIR}/{FILE}")
with blob.open("wb") as f:
cloudpickle.dump(
StreamingAgent(
model="gemini-2.0-flash-001", # Required.
tools=[get_exchange_rate], # Optional.
project_id=PROJECT_ID
), f)
requirements = """
google-cloud-aiplatform[agent_engines,langchain]==1.96.0
cloudpickle==3.1.1
"""
blob = bucket.blob(f"{GCS_DIR}/requirements-streaming.txt")
blob.upload_from_string(requirements)
!gsutil ls gs://{BUCKET}/{GCS_DIR}
Déployez Agent Engine : déployez Agent Engine en le configurant avec l'interface PSC et l'appairage DNS pour résoudre le nom de domaine complet de la VM proxy dans le VPC consommateur.
Dans votre notebook JupyterLab, créez et exécutez la cellule ci-dessous. Notez les points suivants :
- L'appairage DNS aux VPC consommateurs est configuré à l'aide de dnsPeeringConfigs (dnsPeeringConfigs) pour le nom de domaine demo.com.
import requests
token = !gcloud auth application-default print-access-token
response = requests.post(
f"{ENDPOINT}/v1beta1/projects/{PROJECT_ID}/locations/{LOCATION}/reasoningEngines",
headers={
"Content-Type": "application/json; charset=utf-8",
"Authorization": f"Bearer {token[0]}"
},
data=json.dumps({
"displayName": "PSC-I Explicit Proxy",
"description": "test psc-i agent + proxy vm",
"spec": {
"packageSpec": {
"pickleObjectGcsUri": f"gs://{BUCKET}/{GCS_DIR}/streaming_agent.pkl",
"requirementsGcsUri": f"gs://{BUCKET}/{GCS_DIR}/requirements-streaming.txt",
"pythonVersion": "3.10"
},
"deploymentSpec": {
"pscInterfaceConfig": {
"networkAttachment": NETWORK_ATTACHMENT_NAME,
"dnsPeeringConfigs": [
{
"domain": "demo.com.",
"targetProject": PROJECT_ID,
"targetNetwork": "consumer-vpc", #Consumer VPC
},
],
}
}
},
})
)
pprint.pprint(json.loads(response.content))
reasoning_engine_id = json.loads(response.content)["name"].split("/")[5]
pprint.pprint(reasoning_engine_id)
Surveillez l'état du déploiement : vérifiez l'état de l'opération de déploiement du moteur d'agent.
Dans votre notebook JupyterLab, créez une cellule et exécutez la commande suivante.
operation_id = json.loads(response.content)["name"].split("/")[7]
pprint.pprint(operation_id)
Dans votre notebook JupyterLab, créez une cellule et exécutez la commande suivante.
Remarque : Cette opération peut prendre environ cinq minutes. Réexécutez la cellule pour vérifier la progression. Veuillez ne pas passer à la section suivante tant que vous n'avez pas obtenu un résultat semblable à celui de la capture d'écran ci-dessous.
# You can run this multiple times to check the status of the deployment operation, operation takes approx 5 min.
token = !gcloud auth application-default print-access-token
response = requests.get(
f"{ENDPOINT}/v1beta1/projects/{PROJECT_ID}/locations/{LOCATION}/operations/{operation_id} ",
headers={
"Content-Type": "application/json; charset=utf-8",
"Authorization": f"Bearer {token[0]}"
}
)
pprint.pprint(json.loads(response.content))
Exemple d'exécution réussie :
Interrogez l'agent déployé : envoyez une requête à l'agent déployé pour tester ses fonctionnalités.
Dans votre notebook JupyterLab, créez une cellule et exécutez la commande suivante.
response = requests.post(
f"{ENDPOINT}/v1beta1/projects/{PROJECT_ID}/locations/{LOCATION}/reasoningEngines/{reasoning_engine_id}:query",
headers={
"Content-Type": "application/json; charset=utf-8",
"Authorization": f"Bearer {token[0]}"
},
data=json.dumps({ "input": {"input": "What is the exchange rate from US dollars to Euro?"} })
)
print(response.text)
Diffuser les résultats de la requête : diffusez la sortie de la requête Agent Engine.
Dans votre notebook JupyterLab, créez une cellule et exécutez la commande suivante, qui déclenchera l'appel d'API à l'URL publique à l'aide du proxy explicite dans le VPC des consommateurs.
token = !gcloud auth application-default print-access-token
print(f"{ENDPOINT}/v1beta1/projects/{PROJECT_ID}/locations/us-central1/reasoningEngines/{reasoning_engine_id}:streamQuery")
response = requests.post(
f"{ENDPOINT}/v1beta1/projects/{PROJECT_ID}/locations/us-central1/reasoningEngines/{reasoning_engine_id}:streamQuery",
headers={
"Content-Type": "application/json; charset=utf-8",
"Authorization": f"Bearer {token[0]}"
},
data=json.dumps({ "input": {"input": "What is the exchange rate from US dollars to Euro?"} })
)
for chunk in response.iter_lines():
print(chunk.decode('utf-8'))
# pprint.pprint(json.loads(response.content))
Exemple d'exécution réussie :
14. Validation Tcpdump
Affichez la sortie tcpdump qui détaille la communication entre l'adresse IP de l'attachement réseau PSC utilisée par Agent Engine et la Prox-VM lors de la publication de la requête.
user@proxy-vm:~$ sudo tcpdump -i any net 192.168.10.0/28 -nn tcpdump: data link type LINUX_SLL2 tcpdump: verbose output suppressed, use -v[v]... for full protocol decode listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes 22:17:53.983212 ens4 In IP 192.168.10.2.22261 > 10.10.10.2.8888: Flags [S], seq 3841740961, win 28800, options [mss 1440,sackOK,TS val 4245243253 ecr 0,nop,wscale 7], length 0 22:17:53.983252 ens4 Out IP 10.10.10.2.8888 > 192.168.10.2.22261: Flags [S.], seq 2232973833, ack 3841740962, win 64768, options [mss 1420,sackOK,TS val 2251247643 ecr 4245243253,nop,wscale 7], length 0 22:17:53.985167 ens4 In IP 192.168.10.2.22261 > 10.10.10.2.8888: Flags [.], ack 1, win 225, options [nop,nop,TS val 4245243256 ecr 2251247643], length 0 22:17:53.986476 ens4 In IP 192.168.10.2.22261 > 10.10.10.2.8888: Flags [P.], seq 1:45, ack 1, win 16384, options [nop,nop,TS val 4245243256 ecr 2251247643], length 44 22:17:53.986485 ens4 Out IP 10.10.10.2.8888 > 192.168.10.2.22261: Flags [.], ack 45, win 506, options [nop,nop,TS val 2251247646 ecr 4245243256], length 0 22:17:54.043347 ens4 Out IP 10.10.10.2.8888 > 192.168.10.2.22261: Flags [P.], seq 1:71, ack 45, win 506, options [nop,nop,TS val 2251247703 ecr 4245243256], length 70
15. Validation de l'interface PSC
Vous pouvez également afficher les adresses IP de l'attachement réseau utilisées par Agent Engine en accédant à :
Services réseau → Private Service Connect → Rattachement de réseau → psc-network-attachment
Sélectionnez le projet locataire (nom de projet se terminant par "-tp").
Le champ en surbrillance indique l'adresse IP utilisée par Agent Engine à partir du rattachement de réseau PSC.
16. Validation de Cloud Logging
Quittez la session TCPDump de la VM proxy et effectuez un PING vers api.frankfurter.app pour obtenir l'adresse IP publique associée.
ping -c4 api.frankfurter.app
L'exemple identifie 104.26.1.198 comme adresse IP publique pour api.frankfurter.app.
user@proxy-vm:~$ ping -c4 api.frankfurter.app
PING api.frankfurter.app (104.26.1.198) 56(84) bytes of data.
64 bytes from 104.26.1.198 (104.26.1.198): icmp_seq=1 ttl=61 time=10.9 ms
64 bytes from 104.26.1.198 (104.26.1.198): icmp_seq=2 ttl=61 time=10.9 ms
64 bytes from 104.26.1.198 (104.26.1.198): icmp_seq=3 ttl=61 time=10.9 ms
64 bytes from 104.26.1.198 (104.26.1.198): icmp_seq=4 ttl=61 time=10.9 ms
Examinons la journalisation NAT pour voir si le trafic pour 104.26.1.198 est observé.
Accédez à l'un des éléments suivants :
Surveillance → Explorateur de journaux
Utilisez le filtre suivant :
resource.type="nat_gateway"
Sélectionnez la période, puis cliquez sur "Exécuter la requête".
Développez l'entrée de journal qui identifie l'adresse IP publique (de destination) (104.26.1.198) de api.frankfurter.app, ainsi que l'adresse IP source et le nom de la VM de proxy qui valide l'utilisation du proxy explicite pour la sortie Internet.
17. Effectuer un nettoyage
Dans votre notebook JupyterLab, créez une cellule et exécutez la commande suivante pour déclencher la suppression du déploiement Agent Engine.
token = !gcloud auth application-default print-access-token
response = requests.delete(
f"{ENDPOINT}/v1beta1/projects/{PROJECT_ID}/locations/us-central1/reasoningEngines/{reasoning_engine_id}",
headers={
"Content-Type": "application/json; charset=utf-8",
"Authorization": f"Bearer {token[0]}"
},
)
print(response.text)
Dans Cloud Shell, supprimez les composants du tutoriel.
gcloud dns record-sets delete proxy-vm.demo.com --zone=private-dns-codelab --type=A
gcloud dns managed-zones delete private-dns-codelab
gcloud compute instances delete proxy-vm --zone=us-central1-a --quiet
gcloud compute instances delete workbench-tutorial --zone=us-central1-a --quiet
gcloud compute routers delete cloud-router-for-nat --region=us-central1 --quiet
gcloud compute network-attachments delete psc-network-attachment --region=us-central1 --quiet
gcloud compute networks subnets delete intf-subnet rfc1918-subnet1 --region=us-central1 --quiet
gcloud compute networks delete consumer-vpc --quiet
18. Félicitations
Félicitations, vous avez configuré et validé Agent Engine déployé avec l'interface Private Service Connect, avec une sortie Internet effectuée via un proxy explicite.
Vous avez créé l'infrastructure consommateur et ajouté un rattachement de réseau qui a permis au producteur de créer une VM multi-NIC pour faire le pont entre les communications consommateur et producteur. Vous avez appris à créer un proxy explicite et un appairage DNS qui permettaient la connectivité Internet.
Cosmopup pense que les tutoriels sont géniaux !!
Et ensuite ?
Lectures et vidéos complémentaires
Documents de référence
- Présentation de l'accès au réseau Vertex AI | Google Cloud
- À propos de l'accès aux services Vertex AI via des interfaces Private Service Connect | Google Cloud
- Utiliser l'interface Private Service Connect avec Vertex AI Agent Engine
- Configurer une interface Private Service Connect pour les ressources Vertex AI | Google Cloud