1. Wprowadzenie
Interfejs Private Service Connect to zasób, który umożliwia sieci VPC producenta inicjowanie połączeń z różnymi miejscami docelowymi w sieci VPC konsumenta. Sieci producenta i odbiorcy mogą znajdować się w różnych projektach i organizacjach.
Jeśli przyłącze sieci zaakceptuje połączenie z interfejsu Private Service Connect, Google Cloud przydzieli interfejsowi adres IP z podsieci konsumenta określonej przez przyłącze sieci. Sieci konsumenta i producenta są połączone i mogą komunikować się za pomocą wewnętrznych adresów IP.
Połączenie między przyłączem sieci a interfejsem Private Service Connect jest podobne do połączenia między punktem końcowym Private Service Connect a przyłączem usługi, ale ma 2 kluczowe różnice:
- Przyłącze sieci umożliwia sieci producenta inicjowanie połączeń z siecią konsumenta (ruch wychodzący usługi zarządzanej), a punkt końcowy umożliwia sieci konsumenta inicjowanie połączeń z siecią producenta (ruch przychodzący usługi zarządzanej).
- Połączenie interfejsu Private Service Connect jest przechodnie. Oznacza to, że sieć producenta może komunikować się z innymi sieciami połączonymi z siecią konsumenta.
Wskazówki dotyczące dostępności interfejsu PSC Vertex AI
- Interfejs PSC może kierować ruch do miejsc docelowych w sieci VPC lub lokalnych w bloku adresów RFC1918.
- Kierowanie na interfejs PSC na bloki adresów inne niż rfc-1918 wymaga wdrożenia w sieci VPC konsumenta jawnego serwera proxy z adresem rfc-1918. W ramach wdrożenia Vertex AI serwer proxy musi być zdefiniowany wraz z w pełni kwalifikowaną nazwą domeny docelowego punktu końcowego.
- Jeśli skonfigurujesz wdrożenie tylko za pomocą interfejsu PSC, zachowa ono domyślny dostęp do internetu. Ten ruch wychodzący jest kierowany bezpośrednio z zabezpieczonej sieci najemcy zarządzanej przez Google.
Wskazówki dotyczące interfejsu VPC-SC usługi Vertex AI PSC
- Gdy Twój projekt jest częścią granicy ustawień usługi VPC, domyślny dostęp do internetu w dzierżawach zarządzanych przez Google jest blokowany przez tę granicę, aby zapobiec wydobywaniu danych.
- Aby umożliwić wdrożeniu dostęp do publicznego internetu w tym scenariuszu, musisz wyraźnie skonfigurować bezpieczną ścieżkę ruchu wychodzącego, która kieruje ruch przez sieć VPC.
- Zalecany sposób to skonfigurowanie serwera proxy wewnątrz obwodu sieci VPC z adresem RFC1918 i utworzenie bramy Cloud NAT, aby umożliwić maszynie wirtualnej serwera proxy dostęp do internetu.
Więcej informacji znajdziesz w tych materiałach:
Wdrażanie agenta | Generatywna AI w Vertex AI | Google Cloud
Konfigurowanie interfejsu Private Service Connect dla zasobów Vertex AI | Google Cloud
Co utworzysz
W tym samouczku utworzysz kompleksowy silnik agenta wdrożony z interfejsem Private Service Connect (PSC), który umożliwi połączenie z publiczną witryną (https://api.frankfurter.app/) za pomocą maszyny wirtualnej serwera proxy wdrożonej w sieci VPC konsumenta z adresem RFC1918. Przykładowe wdrożenie ma zastosowanie w projekcie z włączoną usługą VPC-SC lub w przypadku administratorów, którzy wymagają wychodzącego ruchu internetowego przez sieć klienta zamiast przez sieć VPC najemcy.
Rysunek 1.
W konsumenckiej sieci VPC utworzysz pojedynczy zasób psc-network-attachment, który będzie korzystać z równorzędnego połączenia DNS, aby rozwiązać adres proxy-vm sieci konsumenckiej w projekcie najemcy hostującym Agent Engine. Umożliwi to następujące przypadki użycia:
wdrożyć Agent Engine i skonfigurować maszynę wirtualną proxy tak, aby działała jako serwer proxy jawny, co umożliwi jej dostęp do publicznego adresu URL https://api.frankfurter.app;
Czego się nauczysz
- Tworzenie przyłącza sieci
- Jak producent może użyć przyłącza sieci do utworzenia interfejsu PSC
- Jak nawiązać komunikację między producentem a konsumentem za pomocą połączenia równorzędnego DNS
- Jak wdrożyć i używać maszyny wirtualnej proxy do wychodzącego ruchu internetowego
Czego potrzebujesz
Projekt Google Cloud
Uprawnienia
- Administrator sieci Compute (roles/compute.networkAdmin)
- Administrator instancji Compute (roles/compute.instanceAdmin)
- Administrator zabezpieczeń Compute (roles/compute.securityAdmin)
- Administrator DNS (roles/dns.admin)
- Użytkownik tunelu zabezpieczonego przez IAP (roles/iap.tunnelResourceAccessor)
- Administrator rejestrowania (roles/logging.admin)
- Administrator notatek (roles/notebooks.admin)
- Administrator uprawnień projektu (roles/resourcemanager.projectIamAdmin)
- Administrator kont usługi (roles/iam.serviceAccountAdmin)
- Administrator korzystania z usług (roles/serviceusage.serviceUsageAdmin)
2. Zanim zaczniesz
Aktualizowanie projektu na potrzeby samouczka
W tym samouczku używamy zmiennych $variables, aby ułatwić implementację konfiguracji gcloud w Cloud Shell.
W Cloud Shell wykonaj te czynności:
gcloud config list project
gcloud config set project [YOUR-PROJECT-NAME]
projectid=YOUR-PROJECT-NAME
echo $projectid
Włączanie interfejsu API
W Cloud Shell wykonaj te czynności:
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"
Sprawdzanie, czy interfejsy API zostały włączone
gcloud services list --enabled
3. Konfiguracja dla konsumentów
Utwórz VPC klienta
Ta sieć VPC znajduje się w projekcie klienta. W tej sieci VPC zostaną utworzone te zasoby:
- Podsieć konsumencka
- Podsieć przyłącza sieci
- Cloud Router (wymagany w przypadku Cloud NAT)
- Cloud NAT
W Cloud Shell wykonaj te czynności:
gcloud compute networks create consumer-vpc --project=$projectid --subnet-mode=custom
Tworzenie podsieci konsumenckich
W Cloud Shell utwórz podsieć dla maszyny wirtualnej serwera proxy:
gcloud compute networks subnets create rfc1918-subnet1 --project=$projectid --range=10.10.10.0/28 --network=consumer-vpc --region=us-central1
Utwórz podsieć przyłącza sieci Private Service Connect
W Cloud Shell utwórz podsieć dla przyłącza sieci PSC:
gcloud compute networks subnets create intf-subnet --project=$projectid --range=192.168.10.0/28 --network=consumer-vpc --region=us-central1
Konfiguracja routera Cloud Router i NAT
W tym samouczku Cloud NAT służy do zapewnienia dostępu do internetu maszynie wirtualnej proxy, która nie ma publicznego adresu IP. Cloud NAT umożliwia maszynom wirtualnym, które mają tylko prywatne adresy IP, łączenie się z internetem, co pozwala im wykonywać zadania takie jak instalowanie pakietów oprogramowania.
W Cloud Shell utwórz router Cloud Router.
gcloud compute routers create cloud-router-for-nat --network consumer-vpc --region us-central1
W Cloud Shell utwórz bramę NAT z włączonym logowaniem. Będziemy używać logowania do weryfikowania dostępu do publicznego adresu IP w przypadku interfejsu Frankfurter API (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. Włączanie IAP
Aby umożliwić IAP połączenie z instancjami maszyn wirtualnych, utwórz regułę zapory sieciowej, która:
- Dotyczy wszystkich instancji maszyn wirtualnych, które mają być dostępne przez IAP.
- Zezwala na ruch przychodzący z zakresu adresów IP 35.235.240.0/20. Ten zakres zawiera wszystkie adresy IP, których IAP używa do przekierowywania TCP.
W Cloud Shell utwórz regułę zapory sieciowej IAP.
gcloud compute firewall-rules create ssh-iap-consumer \
--network consumer-vpc \
--allow tcp:22 \
--source-ranges=35.235.240.0/20
5. Tworzenie instancji maszyn wirtualnych konsumentów
W Cloud Shell utwórz instancję maszyny wirtualnej klienta, proxy-vm, która będzie służyć jako jawny serwer proxy dla Agent Engine. Do przekierowywania ruchu HTTP użyjemy aplikacji tinyproxy.
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. Przyłącze sieci Private Service Connect
Przyłącza sieci to zasoby regionalne, które reprezentują stronę konsumenta interfejsu Private Service Connect. Z przyłączem sieci możesz powiązać jedną podsieć, a producent przypisuje adresy IP do interfejsu Private Service Connect z tej podsieci. Podsieć musi znajdować się w tym samym regionie co przyłącze sieci. Przyłącze sieci musi znajdować się w tym samym regionie co usługa producenta.
Tworzenie przyłącza sieci
W Cloud Shell utwórz przyłącze sieci.
gcloud compute network-attachments create psc-network-attachment \
--region=us-central1 \
--connection-preference=ACCEPT_AUTOMATIC \
--subnets=intf-subnet
Wyświetlanie listy przyłączy sieci
W Cloud Shell wyświetl listę przyłączy sieci.
gcloud compute network-attachments list
Opisz przyłącza sieci
W Cloud Shell opisz przyłącze sieci.
gcloud compute network-attachments describe psc-network-attachment --region=us-central1
Zanotuj nazwę przyłącza sieci PSC, psc-network-attachment
, która będzie używana przez producenta podczas tworzenia interfejsu Private Service Connect.
Aby wyświetlić adres URL przyłączenia sieci PSC w konsoli Google Cloud, otwórz:
Usługi sieciowe → Private Service Connect → Przyłącze sieci → psc-network-attachment
7. Prywatna strefa DNS
Utwórz strefę Cloud DNS dla demo.com
i wypełnij ją rekordem A, który wskazuje adresy IP maszyny wirtualnej proxy. Później w Agent Engine zostanie wdrożona komunikacja równorzędna DNS, która umożliwi dostęp do rekordów DNS konsumenta.
W Cloud Shell wykonaj te czynności, aby utworzyć nazwę 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"
Pobierz i zapisz adresy IP instancji używanych w rekordach DNS A.
W Cloud Shell wykonaj opis instancji maszyn wirtualnych.
gcloud compute instances describe proxy-vm --zone=us-central1-a | grep networkIP:
W Cloud Shell utwórz zestaw rekordów dla maszyny wirtualnej proxy-vm.demo.com. Pamiętaj, aby zaktualizować adres IP na podstawie danych wyjściowych środowiska.
gcloud dns --project=$projectid record-sets create proxy-vm.demo.com. --zone="private-dns-codelab" --type="A" --ttl="300" --rrdatas="10.10.10.2"
Tworzenie reguły zapory sieciowej Cloud Firewall, która zezwala na dostęp z interfejsu PSC
W następnej sekcji utwórz regułę zapory sieciowej, która zezwala na ruch pochodzący z sieci PSC do maszyny wirtualnej proxy w sieci VPC klienta.
W Cloud Shell utwórz regułę zapory sieciowej dotyczącą ruchu przychodzącego.
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. Tworzenie notatnika Jupyter
W sekcji poniżej znajdziesz instrukcje tworzenia notatnika Jupyter. Ten notatnik będzie używany do wdrażania Agent Engine kierowanego na jawny serwer proxy na potrzeby wychodzącego ruchu internetowego.
Tworzenie konta usługi zarządzanego przez użytkownika
W następnej sekcji utworzysz konto usługi, które będzie powiązane z instancją Vertex AI Workbench używaną w tym samouczku.
W tym samouczku do konta usługi zostaną przypisane te role:
- Administrator miejsca na dane
- Użytkownik Vertex AI
- Administrator Artifact Registry
- Użytkownik konta usługi używanego przez funkcję uprawnień
W Cloud Shell utwórz konto usługi.
gcloud iam service-accounts create notebook-sa \
--display-name="notebook-sa"
W Cloud Shell zaktualizuj konto usługi, przypisując mu rolę Administrator miejsca na dane.
gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:notebook-sa@$projectid.iam.gserviceaccount.com" --role="roles/storage.admin"
W Cloud Shell zaktualizuj konto usługi, przypisując mu rolę Użytkownik Vertex AI.
gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:notebook-sa@$projectid.iam.gserviceaccount.com" --role="roles/aiplatform.user"
W Cloud Shell zaktualizuj konto usługi, przypisując mu rolę Administrator Artifact Registry.
gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:notebook-sa@$projectid.iam.gserviceaccount.com" --role="roles/artifactregistry.admin"
W Cloud Shell zezwól kontu usługi notatnika na używanie domyślnego konta usługi 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. Aktualizowanie serwera proxy
W następnej sekcji musisz połączyć się z serwerem proxy za pomocą protokołu SSH i zaktualizować plik konfiguracyjny tinyproxy.conf, a następnie zresetować serwer.
Z Cloud Shell
gcloud compute ssh --zone us-central1-a "proxy-vm" --tunnel-through-iap --project $projectid
Otwórz plik konfiguracyjny tinyproxy i zaktualizuj go w wybranym edytorze. Poniżej znajdziesz przykład użycia 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. Tworzenie instancji Vertex AI Workbench
W sekcji poniżej utwórz instancję Vertex AI Workbench, która zawiera utworzone wcześniej konto usługi notebook-sa.
W Cloud Shell utwórz instancję 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. Aktualizacja agenta usługi Vertex AI
Vertex AI działa w Twoim imieniu, wykonując operacje takie jak uzyskiwanie adresu IP z podsieci przyłącza sieci PSC używanej do tworzenia interfejsu PSC. W tym celu Vertex AI używa agenta usługi (wymienionego poniżej), który wymaga uprawnień administratora sieci:
service-$projectnumber@gcp-sa-aiplatform.iam.gserviceaccount.com
W Cloud Shell uzyskaj numer projektu.
gcloud projects describe $projectid | grep projectNumber
W Cloud Shell ustaw numer projektu.
projectnumber=YOUR-PROJECT-Number
W Cloud Shell utwórz konto usługi dla AI Platform. Pomiń ten krok, jeśli w projekcie masz już konto usługi.
gcloud beta services identity create --service=aiplatform.googleapis.com --project=$projectnumber
W Cloud Shell zaktualizuj konto agenta usługi, przypisując mu rolę compute.networkAdmin.
gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:service-$projectnumber@gcp-sa-aiplatform.iam.gserviceaccount.com" --role="roles/compute.networkAdmin"
W Cloud Shell zaktualizuj konto agenta usługi, nadając mu rolę dns.peer.
gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:service-$projectnumber@gcp-sa-aiplatform.iam.gserviceaccount.com" --role="roles/dns.peer"
Aktualizacja domyślnego konta usługi
Przyznaj domyślnemu kontu usługi dostęp do Vertex AI. Pamiętaj, że zanim zmiana dostępu zostanie zastosowana, może minąć trochę czasu.
W Cloud Shell zaktualizuj domyślne konto usługi, przypisując mu rolę aiplatform.user.
gcloud projects add-iam-policy-binding $projectid \
--member="serviceAccount:$projectnumber-compute@developer.gserviceaccount.com" \
--role="roles/aiplatform.user"
12. Proxy VM Tcpdump
Aby sprawdzić łączność IP z Agent Engine, możemy użyć narzędzia TCPDUMP. Dzięki temu będziemy mogli obserwować komunikację pochodzącą z podsieci PSC Network Attachment, 192.168.10.0/28, podczas wywoływania żądania GET z Agent Engine do publicznego adresu URL.
Połącz się z maszyną wirtualną serwera proxy przez SSH w Cloud Shell.
gcloud compute ssh --zone us-central1-a "proxy-vm" --tunnel-through-iap --project $projectid
Uruchom tcpdump w systemie operacyjnym maszyny wirtualnej proxy.
sudo tcpdump -i any net 192.168.10.0/28 -nn
13. Wdrażanie silnika agenta
Uwaga: do wykonania zadań w tej sekcji użyjemy konsoli GCP i notatnika JupyterLab.
W kolejnej sekcji utworzysz notatnik, który będzie wykonywać te zadania:
- Korzysta z interfejsu Frankfurter API (https://api.frankfurter.app/) do pobierania danych o kursach wymiany.
- Odwołuje się do serwera proxy (proxy_server) kierowanego na maszynę wirtualną proxy w sieci VPC konsumentów za pomocą w pełni kwalifikowanej nazwy domeny proxy-vm.demo.com.
- Zdefiniuj dnsPeeringConfigs "domain": "demo.com."
Uruchom zadanie trenowania w instancji Vertex AI Workbench.
- W konsoli Google Cloud otwórz Vertex AI → Workbench.
- Obok nazwy instancji Vertex AI Workbench (workbench-tutorial) kliknij Otwórz JupyterLab. Instancja Vertex AI Workbench otworzy się w JupyterLab.
- Wybierz Plik > Nowy > Notatnik.
- Wybierz Jądro > Python 3.
Zainstaluj niezbędne biblioteki Pythona: zainstaluj biblioteki wymagane przez Agent Engine, w tym pyyaml, google-cloud-aiplatform, cloudpickle, google-cloud-api-keys i langchain-google-vertexai.
W notatniku JupyterLab utwórz nową komórkę i uruchom to polecenie:
!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
Ponownie uruchom jądro Jupyter Notebook: upewnij się, że nowo zainstalowane biblioteki są prawidłowo załadowane.
W notatniku JupyterLab utwórz nową komórkę i uruchom to polecenie:
# Restart the notebook kernel after install, so you can run langchain successfully.
import IPython
app = IPython.Application.instance()
app.kernel.do_shutdown(True)
Ustaw zmienne projektu i zasobnika: zdefiniuj identyfikator projektu Google Cloud, numer projektu, nazwę usługi, katalog GCS, punkt końcowy, nazwę zasobnika i lokalizację.
Zanim uruchomisz komórkę, zaktualizuj te pola
- PROJECT_ID = "enter-your-projectid"
- PROJECT_NUMBER = "enter-your-projectnumber"
- BUCKET= "enter-a-unique-bucket-name"
Uwaga: w następnym kroku użyjemy zmiennej BUCKET do utworzenia zasobnika Cloud Storage.
W notatniku JupyterLab utwórz nową komórkę, zaktualizuj i uruchom poniższy kod.
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"}
Utwórz zasobnik GCS: utwórz zasobnik Cloud Storage do przechowywania kodu agenta.
W notatniku JupyterLab utwórz nową komórkę i uruchom to polecenie:
!gcloud storage buckets create gs://{BUCKET}
Określ nazwę przyłącza sieci: podaj nazwę przyłącza sieci Private Service Connect.
W notatniku JupyterLab utwórz nową komórkę i uruchom to polecenie:
NETWORK_ATTACHMENT_NAME = 'psc-network-attachment' #@param {type:"string"}
Zainicjuj biblioteki klienta w Pythonie: skonfiguruj niezbędne biblioteki klienta dla usług Google Cloud.
W notatniku JupyterLab utwórz nową komórkę i uruchom to polecenie:
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)
Skonfiguruj agenta i narzędzia: zdefiniuj klasę StreamingAgent i funkcję get_exchange_rate, aby pobierać kursy wymiany walut za pomocą interfejsu Frankfurter API przez jawny serwer proxy.
W notatniku JupyterLab utwórz nową komórkę i uruchom poniższą konfigurację. Zwróć uwagę na te elementy:
- Funkcja def get_exchange_rate będzie używać interfejsu Frankfurter API (https://api.frankfurter.app/) do pobierania danych o kursach wymiany.
- proxy_server = "http://proxy-vm.demo.com:8888" FQDN jest powiązana z maszyną wirtualną serwera proxy wdrożoną w sieci VPC konsumenta. W kolejnym kroku użyjemy komunikacji równorzędnej DNS, aby rozpoznać w pełni kwalifikowaną nazwę domeny.
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()
Prześlij pliki agenta do Cloud Storage: prześlij serializowanego agenta i jego wymagania do wyznaczonego zasobnika GCS.
W notatniku JupyterLab utwórz nową komórkę i uruchom to polecenie:
# 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}
Wdróż Agent Engine: wdróż Agent Engine, konfigurując go za pomocą interfejsu PSC i komunikacji równorzędnej DNS, aby rozwiązać w sieci VPC konsumenta w pełni kwalifikowaną nazwę domeny maszyny wirtualnej proxy.
W notatniku JupyterLab utwórz i uruchom komórkę poniżej. Zwróć uwagę na te elementy:
- DNS Peering do sieci VPC konsumenta jest konfigurowany za pomocą dnsPeeringConfigs (dnsPeeringConfigs) dla nazwy domeny 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)
Monitoruj stan wdrożenia: sprawdź stan operacji wdrożenia Agent Engine.
W notatniku JupyterLab utwórz nową komórkę i uruchom to polecenie:
operation_id = json.loads(response.content)["name"].split("/")[7]
pprint.pprint(operation_id)
W notatniku JupyterLab utwórz nową komórkę i uruchom to polecenie:
Uwaga: wykonanie tej operacji może potrwać około 5 minut. Uruchom ponownie komórkę, aby sprawdzić postęp. Nie przechodź do następnej sekcji, dopóki nie zobaczysz danych wyjściowych podobnych do tych na zrzucie ekranu poniżej.
# 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))
Przykład udanego uruchomienia:
Wysyłanie zapytań do wdrożonego agenta: wyślij zapytanie do wdrożonego silnika agenta, aby przetestować jego działanie.
W notatniku JupyterLab utwórz nową komórkę i uruchom to polecenie:
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)
Przesyłanie strumieniowe wyników zapytania: przesyłaj strumieniowo dane wyjściowe z zapytania do silnika agenta.
W notatniku JupyterLab utwórz nową komórkę i uruchom poniższy kod, który wywoła wywołanie interfejsu API do publicznego adresu URL przy użyciu jawnego serwera proxy w sieci VPC konsumentów.
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))
Przykład udanego uruchomienia:
14. Weryfikacja za pomocą narzędzia tcpdump
Wyświetl dane wyjściowe tcpdump, które szczegółowo opisują komunikację między adresem IP przyłączenia sieci PSC używanym przez Agent Engine a maszyną wirtualną Prox-VM po wysłaniu żądania.
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. Weryfikacja interfejsu PSC
Adresy IP połączenia sieciowego używane przez Agent Engine możesz też sprawdzić, wykonując te czynności:
Usługi sieciowe → Private Service Connect → Przyłącze sieci → psc-network-attachment
Wybierz projekt najemcy (nazwa projektu kończy się na -tp).
Wyróżnione pole oznacza adres IP używany przez Agent Engine z załącznika sieci PSC.
16. Weryfikacja Cloud Logging
Zakończ sesję TCPDump na maszynie wirtualnej proxy i wykonaj polecenie PING na adres api.frankfurter.app, aby uzyskać powiązany publiczny adres IP.
ping -c4 api.frankfurter.app
Przykład identyfikuje adres 104.26.1.198 jako publiczny adres IP domeny 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
Przyjrzyjmy się logowaniu NAT, aby sprawdzić, czy zaobserwowano ruch dla adresu 104.26.1.198.
Przejdź do:
Monitorowanie → Eksplorator logów
Użyj tego filtra:
resource.type="nat_gateway"
Wybierz przedział czasu, a następnie kliknij Uruchom zapytanie.
Rozwiń wpis dziennika, który identyfikuje (docelowy) publiczny adres IP (104.26.1.198) api.frankfurter.app oraz źródłowy adres IP i nazwę maszyny wirtualnej proxy, która weryfikuje użycie jawnego serwera proxy do wychodzącego ruchu internetowego.
17. Czyszczenie danych
W notatniku JupyterLab utwórz nową komórkę i uruchom poniższy kod, który spowoduje usunięcie wdrożenia silnika agenta.
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)
W Cloud Shell usuń komponenty samouczka.
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. Gratulacje
Gratulacje. Udało Ci się skonfigurować i zweryfikować silnik agenta wdrożony za pomocą interfejsu Private Service Connect z ruchem wychodzącym z internetu realizowanym przez jawny serwer proxy.
Infrastruktura konsumenta została utworzona, a do niej dodano przyłącze sieci, które umożliwiło producentowi utworzenie maszyny wirtualnej z wieloma interfejsami sieciowymi, aby połączyć komunikację konsumenta i producenta. Wiesz już, jak utworzyć jawny serwer proxy i połączenie równorzędne DNS, które umożliwiają łączność z internetem.
Cosmopup uważa, że samouczki są świetne!!
Co dalej?
Więcej informacji i filmy
Dokumentacja
- Omówienie dostępu do sieci Vertex AI | Google Cloud
- Informacje o dostępie do usług Vertex AI za pomocą interfejsów Private Service Connect | Google Cloud
- Korzystanie z interfejsu Private Service Connect z Vertex AI Agent Engine
- Konfigurowanie interfejsu Private Service Connect dla zasobów Vertex AI | Google Cloud