1. Introdução
A interface do Private Service Connect é um recurso que permite que uma rede de nuvem privada virtual (VPC, na sigla em inglês) do produtor inicie conexões com vários destinos em uma rede VPC do consumidor. As redes de produtor e consumidor podem estar em diferentes projetos e organizações.
Se um anexo de rede aceitar uma conexão de uma interface do Private Service Connect, o Google Cloud alocará à interface um endereço IP de uma sub-rede do consumidor especificada pelo anexo de rede. As redes de consumidores e produtores estão conectadas e podem se comunicar por endereços IP internos.
Uma conexão entre um anexo de rede e uma interface do Private Service Connect é semelhante à conexão entre um endpoint do Private Service Connect e um anexo de serviço, mas há duas diferenças principais:
- Um anexo de rede permite que uma rede produtora inicie conexões com uma rede consumidora (saída de serviço gerenciada), enquanto um endpoint permite que uma rede consumidora inicie conexões com uma rede produtora (entrada de serviço gerenciada).
- Uma conexão de interface do Private Service Connect é transitiva. Isso significa que uma rede do produtor pode se comunicar com outras que estão conectadas à rede do consumidor.
Considerações sobre a acessibilidade da interface do PSC da Vertex AI
- A interface do PSC pode rotear o tráfego para destinos baseados em VPC ou locais no bloco de endereços RFC1918.
- O direcionamento de interface do PSC a blocos de endereços não rfc-1918 exige um proxy explícito implantado na VPC do consumidor com um endereço rfc-1918. Na implantação da Vertex AI, o proxy precisa ser definido com um FQDN do endpoint de destino.
- Quando você configura a implantação apenas com uma interface do PSC, ela mantém o acesso padrão à Internet. Esse tráfego de saída sai diretamente da rede de locatário segura e gerenciada pelo Google.
Considerações sobre a VPC-SC da interface PSC da Vertex AI
- Quando seu projeto faz parte de um perímetro do VPC Service Controls, o acesso padrão à Internet dos tenants gerenciados pelo Google é bloqueado pelo perímetro para evitar a exfiltração de dados.
- Para permitir que a implantação acesse a Internet pública nesse cenário, configure explicitamente um caminho de saída seguro que roteie o tráfego pela sua VPC.
- A maneira recomendada de fazer isso é configurar um servidor proxy dentro do perímetro da VPC com um endereço RFC1918 e criar um gateway do Cloud NAT para permitir que a VM proxy acesse a Internet.
Para mais informações, consulte os seguintes recursos:
Implantar um agente | IA generativa na Vertex AI | Google Cloud
Configurar uma interface do Private Service Connect para recursos da Vertex AI | Google Cloud
O que você vai criar
Neste tutorial, você vai criar um Agent Engine abrangente implantado com uma interface do Private Service Connect (PSC) para permitir a conectividade com um site público (https://api.frankfurter.app/) por uma VM de proxy implantada na VPC do consumidor com um endereço RFC1918. A implantação de exemplo é aplicável em um projeto ativado para VPC-SC ou para administradores que exigem saída da Internet pela rede dos clientes em vez da VPC do locatário.
Figura 1.
Você vai criar um único psc-network-attachment na VPC do consumidor usando o peering de DNS para resolver a proxy-vm da rede do consumidor no projeto do locatário que hospeda o Agent Engine, resultando nos seguintes casos de uso:
Implante o Agent Engine e configure uma VM de proxy para atuar como um proxy explícito, permitindo que ela alcance um URL público https://api.frankfurter.app
O que você vai aprender
- Como criar um anexo de rede
- Como um produtor pode usar um anexo de rede para criar uma interface do PSC
- Como estabelecer comunicação do produtor para o consumidor usando o peering de DNS
- Como implantar e usar uma VM de proxy para saída da Internet
O que é necessário
Projeto do Google Cloud
Permissões do IAM
- Administrador de rede do Compute (roles/compute.networkAdmin)
- Administrador de instâncias do Compute (roles/compute.instanceAdmin)
- Administrador de segurança do Compute (roles/compute.securityAdmin)
- Administrador do DNS (roles/dns.admin)
- Usuário do túnel protegido pelo IAP (roles/iap.tunnelResourceAccessor)
- Administrador do Logging (roles/logging.admin)
- Administrador do Notebooks (roles/notebooks.admin)
- Administrador do IAM do projeto (roles/resourcemanager.projectIamAdmin)
- Administrador da conta de serviço (roles/iam.serviceAccountAdmin)
- Administrador do Service Usage (roles/serviceusage.serviceUsageAdmin)
2. Antes de começar
Atualizar o projeto para oferecer suporte ao tutorial
Este tutorial usa $variables para ajudar na implementação da configuração do gcloud no Cloud Shell.
No Cloud Shell, faça o seguinte:
gcloud config list project
gcloud config set project [YOUR-PROJECT-NAME]
projectid=YOUR-PROJECT-NAME
echo $projectid
Ativação da API
No Cloud Shell, faça o seguinte:
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"
Verificar se as APIs foram ativadas
gcloud services list --enabled
3. Configuração do consumidor
Criar a VPC do consumidor
Essa VPC reside em um projeto do cliente. Os seguintes recursos serão criados nesta VPC:
- Sub-rede do consumidor
- Sub-rede de anexo de rede
- Cloud Router (necessário para o Cloud NAT)
- Cloud NAT
No Cloud Shell, faça o seguinte:
gcloud compute networks create consumer-vpc --project=$projectid --subnet-mode=custom
Criar as sub-redes do consumidor
No Cloud Shell, crie a sub-rede para a VM do proxy:
gcloud compute networks subnets create rfc1918-subnet1 --project=$projectid --range=10.10.10.0/28 --network=consumer-vpc --region=us-central1
Criar a sub-rede de anexo de rede do Private Service Connect
No Cloud Shell, crie a sub-rede para a vinculação de rede do PSC:
gcloud compute networks subnets create intf-subnet --project=$projectid --range=192.168.10.0/28 --network=consumer-vpc --region=us-central1
Configuração do Cloud Router e do NAT
Neste tutorial, o Cloud NAT é usado para fornecer acesso à Internet à VM de proxy, que não tem um endereço IP público. O Cloud NAT permite que VMs com apenas endereços IP particulares se conectem à Internet, permitindo que elas executem tarefas como instalar pacotes de software.
No Cloud Shell, crie o Cloud Router.
gcloud compute routers create cloud-router-for-nat --network consumer-vpc --region us-central1
No Cloud Shell, crie o gateway NAT com a geração de registros ativada. Vamos usar o registro em registros para validar o acesso ao IP público da 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. Ativar o IAP
Para permitir que o IAP se conecte às suas instâncias de VM, crie uma regra de firewall que:
- Aplica-se a todas as instâncias de VM que você quer acessar usando o IAP.
- Permite o tráfego de entrada do intervalo de IP 35.235.240.0/20. Esse intervalo contém todos os endereços IP que o IAP usa para o encaminhamento de TCP.
No Cloud Shell, crie a regra de firewall do IAP.
gcloud compute firewall-rules create ssh-iap-consumer \
--network consumer-vpc \
--allow tcp:22 \
--source-ranges=35.235.240.0/20
5. Criar instâncias de VM do consumidor
No Cloud Shell, crie a instância de VM do consumidor, proxy-vm, que vai servir como proxy explícito para o Agent Engine. Vamos usar o tinyproxy como aplicativo para fazer proxy do tráfego HTTP.
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. Anexo de rede do Private Service Connect
Os anexos de rede são recursos regionais que representam o lado do consumidor de uma interface do Private Service Connect. Você associa uma única sub-rede a um anexo de rede, e o produtor atribui IPs à interface do Private Service Connect a partir dessa sub-rede. A sub-rede precisa estar na mesma região do anexo de rede. Um anexo de rede precisa estar na mesma região do serviço do produtor.
Criar o anexo de rede
No Cloud Shell, crie o anexo de rede.
gcloud compute network-attachments create psc-network-attachment \
--region=us-central1 \
--connection-preference=ACCEPT_AUTOMATIC \
--subnets=intf-subnet
Listar os anexos de rede
No Cloud Shell, liste o anexo de rede.
gcloud compute network-attachments list
Descrever os anexos de rede
No Cloud Shell, descreva o anexo de rede.
gcloud compute network-attachments describe psc-network-attachment --region=us-central1
Anote o nome do anexo de rede do PSC, psc-network-attachment
, que será usado pelo produtor ao criar a interface do Private Service Connect.
Para ver o URL de anexo de rede do PSC no console do Cloud, navegue até:
Serviços de rede → Private Service Connect → Anexo de rede → psc-network-attachment
7. Zona de DNS particular
Você vai criar uma zona do Cloud DNS para demo.com
e preenchê-la com um registro A que aponta para os endereços IP da proxy-vm. Depois, o peering de DNS será implantado no Agent Engine, o que permitirá o acesso aos registros de DNS do consumidor.
No Cloud Shell, execute o seguinte comando para criar um nome de 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"
Obtenha e armazene os endereços IP das instâncias usadas para registros A de DNS.
No Cloud Shell, execute uma descrição nas instâncias de VM.
gcloud compute instances describe proxy-vm --zone=us-central1-a | grep networkIP:
No Cloud Shell, crie o conjunto de registros para a VM, proxy-vm.demo.com, e atualize o endereço IP com base na saída do seu ambiente.
gcloud dns --project=$projectid record-sets create proxy-vm.demo.com. --zone="private-dns-codelab" --type="A" --ttl="300" --rrdatas="10.10.10.2"
Criar uma regra do Cloud Firewall para permitir o acesso da interface do PSC
Na seção a seguir, crie uma regra de firewall que permita o tráfego originado do acesso ao anexo de rede do PSC à proxy-vm na VPC do consumidor.
No Cloud Shell, crie a regra de firewall de entrada.
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. Crie um notebook do Jupyter
A seção a seguir orienta você na criação de um notebook do Jupyter. Este notebook será usado para implantar o Agent Engine direcionando um proxy explícito para saída da Internet.
Criar uma conta de serviço gerenciada pelo usuário
Na seção a seguir, você vai criar uma conta de serviço que será associada à instância do Vertex AI Workbench usada no tutorial.
No tutorial, a conta de serviço terá as seguintes funções aplicadas:
- Administrador do Storage
- Usuário da Vertex AI
- Administrador do Artifact Registry
- Usuário da conta de serviço do IAM
No Cloud Shell, crie a conta de serviço.
gcloud iam service-accounts create notebook-sa \
--display-name="notebook-sa"
No Cloud Shell, atualize a conta de serviço com o papel de administrador do Storage.
gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:notebook-sa@$projectid.iam.gserviceaccount.com" --role="roles/storage.admin"
No Cloud Shell, atualize a conta de serviço com o papel de usuário da Vertex AI.
gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:notebook-sa@$projectid.iam.gserviceaccount.com" --role="roles/aiplatform.user"
No Cloud Shell, atualize a conta de serviço com o papel Administrador do Artifact Registry.
gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:notebook-sa@$projectid.iam.gserviceaccount.com" --role="roles/artifactregistry.admin"
No Cloud Shell, permita que a conta de serviço do notebook use a conta de serviço padrão do Compute Engine.
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. Atualizar o proxy explícito
Na seção a seguir, você precisará fazer SSH no proxy explícito e atualizar o arquivo de configuração tinyproxy.conf, seguido de uma redefinição.
No Cloud Shell
gcloud compute ssh --zone us-central1-a "proxy-vm" --tunnel-through-iap --project $projectid
Abra o arquivo de configuração do tinyproxy e atualize usando um editor de sua escolha. Confira um exemplo usando o 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. criar uma instância do Vertex AI Workbench
Na seção a seguir, crie uma instância do Vertex AI Workbench que incorpore a conta de serviço criada anteriormente, notebook-sa.
No Cloud Shell, crie a instância private-client.
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. Atualização do agente de serviço da Vertex AI
A Vertex AI age em seu nome para realizar operações como a obtenção de um endereço IP da sub-rede de anexo de rede do PSC usada para criar a interface do PSC. Para isso, a Vertex AI usa um agente de serviço (listado abaixo) que exige a permissão de administrador de rede:
service-$projectnumber@gcp-sa-aiplatform.iam.gserviceaccount.com
No Cloud Shell, recupere o número do projeto.
gcloud projects describe $projectid | grep projectNumber
No Cloud Shell, defina o número do projeto.
projectnumber=YOUR-PROJECT-Number
No Cloud Shell, crie uma conta de serviço para o AI Platform. Pule esta etapa se você já tiver uma conta de serviço no projeto.
gcloud beta services identity create --service=aiplatform.googleapis.com --project=$projectnumber
No Cloud Shell, atualize a conta do agente de serviço com a função compute.networkAdmin.
gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:service-$projectnumber@gcp-sa-aiplatform.iam.gserviceaccount.com" --role="roles/compute.networkAdmin"
No Cloud Shell, atualize a conta do agente de serviço com a função dns.peer
gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:service-$projectnumber@gcp-sa-aiplatform.iam.gserviceaccount.com" --role="roles/dns.peer"
Atualização da conta de serviço padrão
Conceda à sua conta de serviço padrão acesso à Vertex AI. Pode levar algum tempo para a mudança no acesso ser propagada.
No Cloud Shell, atualize a conta de serviço padrão com a função aiplatform.user
gcloud projects add-iam-policy-binding $projectid \
--member="serviceAccount:$projectnumber-compute@developer.gserviceaccount.com" \
--role="roles/aiplatform.user"
12. Tcpdump da VM de proxy
Para validar a conectividade IP do Agent Engine, podemos usar o TCPDUMP. Isso nos permite observar a comunicação originada da sub-rede de anexação de rede do PSC, 192.168.10.0/28, ao invocar a solicitação GET do Agent Engine para o URL público.
No Cloud Shell, conecte-se via SSH à VM de proxy.
gcloud compute ssh --zone us-central1-a "proxy-vm" --tunnel-through-iap --project $projectid
No SO da VM de proxy, execute o tcpdump.
sudo tcpdump -i any net 192.168.10.0/28 -nn
13. Implantar o Agent Engine
Observação:vamos usar o console do GCP e o notebook do JupyterLab para concluir as tarefas desta seção.
Na seção a seguir, você vai criar um notebook que executa as seguintes tarefas:
- Usa a API Frankfurter (https://api.frankfurter.app/) para receber dados de taxa de câmbio.
- Faz referência a um proxy explícito (proxy_server) direcionado à VM de proxy na VPC dos consumidores usando o FQDN proxy-vm.demo.com
- Defina dnsPeeringConfigs "domain": "demo.com."
Execute o job de treinamento na instância do Vertex AI Workbench.
- No console do Google Cloud, acesse Vertex AI → Workbench.
- Ao lado do nome da instância do Vertex AI Workbench (workbench-tutorial), clique em "Abrir JupyterLab". A instância do Vertex AI Workbench será aberta no JupyterLab.
- Selecione Arquivo > Novo > Notebook.
- Selecione Kernel > Python 3
Instale as bibliotecas necessárias do Python: instale as bibliotecas necessárias para o Agent Engine, incluindo pyyaml, google-cloud-aiplatform, cloudpickle, google-cloud-api-keys e langchain-google-vertexai.
No notebook do JupyterLab, crie uma célula e execute o seguinte:
!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
Reinicie o kernel do Jupyter Notebook: garanta que as bibliotecas recém-instaladas sejam carregadas corretamente.
No notebook do JupyterLab, crie uma célula e execute o seguinte:
# Restart the notebook kernel after install, so you can run langchain successfully.
import IPython
app = IPython.Application.instance()
app.kernel.do_shutdown(True)
Defina as variáveis de projeto e bucket: defina o ID do projeto do Google Cloud, o número do projeto, o nome do serviço, o diretório do GCS, o endpoint, o nome do bucket e o local.
Atualize os campos a seguir antes de executar a célula
- PROJECT_ID = "enter-your-projectid"
- PROJECT_NUMBER = "enter-your-projectnumber"
- BUCKET= "enter-a-unique-bucket-name"
Observação: vamos usar a variável BUCKET para criar um bucket do Cloud Storage na próxima etapa.
No notebook do JupyterLab, crie uma nova célula, atualize e execute o seguinte.
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"}
Crie um bucket do GCS: crie um bucket do Cloud Storage para armazenar o código do agente.
No notebook do JupyterLab, crie uma célula e execute o seguinte:
!gcloud storage buckets create gs://{BUCKET}
Defina o nome do anexo de rede: especifique o nome do anexo de rede do Private Service Connect.
No notebook do JupyterLab, crie uma célula e execute o seguinte:
NETWORK_ATTACHMENT_NAME = 'psc-network-attachment' #@param {type:"string"}
Inicialize as bibliotecas de cliente do Python: configure as bibliotecas de cliente necessárias para os serviços do Google Cloud.
No notebook do JupyterLab, crie uma célula e execute o seguinte:
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)
Configure o agente e as ferramentas: defina a classe StreamingAgent e a função get_exchange_rate para buscar taxas de câmbio usando a API Frankfurter pelo proxy explícito.
No notebook do JupyterLab, crie uma nova célula e execute a configuração abaixo. Observe os seguintes destaques:
- A função "def get_exchange_rate" vai usar a API Frankfurter (https://api.frankfurter.app/) para receber os dados de taxa de câmbio.
- proxy_server = "http://proxy-vm.demo.com:8888" O FQDN está associado à VM de proxy implantada na VPC do consumidor. Estamos usando o peering de DNS para resolver o FQDN em uma etapa posterior.
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()
Faça upload dos arquivos do agente para o Cloud Storage: faça upload do agente serializado e dos requisitos dele para o bucket do GCS designado.
No notebook do JupyterLab, crie uma célula e execute o seguinte:
# 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}
Implante o Agent Engine: configure o Agent Engine com a interface do PSC e o peering de DNS para resolver o FQDN da VM proxy na VPC do consumidor.
No notebook do JupyterLab, crie e execute a célula abaixo. Observe os seguintes destaques:
- O peering de DNS para VPCs consumidoras é configurado usando dnsPeeringConfigs (dnsPeeringConfigs) para o nome de domínio 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)
Monitore o status da implantação: verifique o status da operação de implantação do Agent Engine.
No notebook do JupyterLab, crie uma célula e execute o seguinte:
operation_id = json.loads(response.content)["name"].split("/")[7]
pprint.pprint(operation_id)
No notebook do JupyterLab, crie uma célula e execute o seguinte:
Observação: essa operação pode levar cerca de cinco minutos para ser concluída. Execute a célula novamente para verificar o progresso. Não avance para a próxima seção até ver uma saída semelhante à captura de tela abaixo.
# 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))
Exemplo de uma execução bem-sucedida:
Consultar o agente implantado: envie uma consulta ao Agent Engine implantado para testar a funcionalidade dele.
No notebook do JupyterLab, crie uma célula e execute o seguinte:
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)
Transmitir resultados da consulta: transmita a saída da consulta do Agent Engine.
No notebook do JupyterLab, crie uma célula e execute o seguinte comando, que vai acionar a chamada de API para o URL público usando o proxy explícito na VPC dos consumidores.
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))
Exemplo de uma execução bem-sucedida:
14. Validação do tcpdump
Confira a saída do tcpdump que detalha a comunicação entre o endereço IP de anexo de rede do PSC usado pelo Agent Engine e a Prox-VM após a postagem da solicitação.
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. Validação da interface do PSC
Também é possível conferir os IPs de vinculação de rede usados pelo Agent Engine navegando até:
Serviços de rede → Private Service Connect → Anexo de rede → psc-network-attachment
Selecione o projeto do locatário (nome do projeto que termina em -tp).
O campo destacado indica o endereço IP usado pelo Agent Engine no anexo de rede do PSC.
16. Validação do Cloud Logging
Saia da sessão TCPDump da proxy-vm e execute um PING para Frankfurter api.frankfurter.app para receber o endereço IP público associado.
ping -c4 api.frankfurter.app
O exemplo identifica 104.26.1.198 como o IP público de 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
Vamos analisar o registro em NAT para verificar se o tráfego de 104.26.1.198 é observado.
Acesse:
Monitoramento → Explorador de registros
Use o seguinte filtro:
resource.type="nat_gateway"
Selecione o período e clique em "Executar consulta".
Expanda a entrada de registro que identifica o IP público (de destino) (104.26.1.198) de api.frankfurter.app e o endereço IP de origem e o nome da proxy-vm que valida o uso do proxy explícito para saída da Internet.
17. Limpar
No notebook do JupyterLab, crie uma célula e execute o seguinte comando, que vai acionar a exclusão da implantação do 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)
No Cloud Shell, exclua os componentes do tutorial.
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. Parabéns
Parabéns! Você configurou e validou o Agent Engine implantado com a interface do Private Service Connect e a saída da Internet realizada por um proxy explícito.
Você criou a infraestrutura do consumidor e adicionou um anexo de rede que permitiu ao produtor criar uma VM de várias NICs para fazer a ponte entre a comunicação do consumidor e do produtor. Você aprendeu a criar um proxy explícito e um peering de DNS que permitiram a conectividade com a Internet.
A Cosmopup acha que os tutoriais são incríveis!
Qual é a próxima etapa?
Leituras e vídeos complementares
Documentos de referência
- Visão geral do acesso à rede da Vertex AI | Google Cloud
- Como acessar os serviços da Vertex AI usando interfaces do Private Service Connect | Google Cloud
- Como usar a interface do Private Service Connect com o Vertex AI Agent Engine
- Configurar uma interface do Private Service Connect para recursos da Vertex AI | Google Cloud