Agent Engine PSC Explicit Proxy

1. Pengantar

Antarmuka Private Service Connect adalah resource yang memungkinkan jaringan Virtual Private Cloud (VPC) produsen memulai koneksi ke berbagai tujuan dalam jaringan VPC konsumen. Jaringan produsen dan konsumen dapat berada dalam project dan organisasi yang berbeda.

Jika lampiran jaringan menerima koneksi dari antarmuka Private Service Connect, Google Cloud akan mengalokasikan alamat IP ke antarmuka dari subnet konsumen yang ditentukan oleh lampiran jaringan. Jaringan konsumen dan produsen terhubung dan dapat berkomunikasi menggunakan alamat IP internal.

Koneksi antara lampiran jaringan dan antarmuka Private Service Connect mirip dengan koneksi antara endpoint Private Service Connect dan lampiran layanan, tetapi memiliki dua perbedaan utama:

  • Lampiran jaringan memungkinkan jaringan produsen memulai koneksi ke jaringan konsumen (traffic keluar layanan terkelola), sedangkan endpoint memungkinkan jaringan konsumen memulai koneksi ke jaringan produsen (traffic masuk layanan terkelola).
  • Koneksi antarmuka Private Service Connect bersifat transitif. Artinya, jaringan produsen dapat berkomunikasi dengan jaringan lain yang terhubung ke jaringan konsumen.

Pertimbangan aksesibilitas PSC-Interface Vertex AI

  • PSC-Interface dapat merutekan traffic ke tujuan berbasis VPC atau lokal dalam blok alamat RFC1918.
  • Penargetan PSC-Interface ke blok alamat non-rfc-1918 memerlukan proxy eksplisit yang di-deploy di VPC konsumen dengan alamat rfc-1918. Dalam deployment Vertex AI, proxy harus ditentukan bersama dengan FQDN endpoint target.
  • Saat Anda mengonfigurasi deployment hanya dengan Antarmuka PSC, deployment tersebut akan mempertahankan akses internet default-nya. Traffic keluar ini keluar langsung dari jaringan tenant yang aman dan dikelola Google.

Pertimbangan VPC-SC antarmuka PSC Vertex AI

  • Jika project Anda adalah bagian dari perimeter Kontrol Layanan VPC, akses internet default tenant yang dikelola Google akan diblokir oleh perimeter untuk mencegah pemindahan data yang tidak sah.
  • Untuk mengizinkan akses deployment ke internet publik dalam skenario ini, Anda harus mengonfigurasi jalur keluar yang aman secara eksplisit yang merutekan traffic melalui VPC Anda.
  • Cara yang direkomendasikan untuk melakukannya adalah dengan menyiapkan server proxy di dalam perimeter VPC Anda dengan alamat RFC1918 dan membuat gateway Cloud NAT untuk mengizinkan VM proxy mengakses internet.

Untuk informasi tambahan, lihat referensi berikut:

Men-deploy agen | AI Generatif di Vertex AI | Google Cloud

Menyiapkan antarmuka Private Service Connect untuk resource Vertex AI | Google Cloud

Yang akan Anda build

Dalam tutorial ini, Anda akan membangun Agent Engine komprehensif yang di-deploy dengan Antarmuka Private Service Connect (PSC) untuk memungkinkan konektivitas ke situs publik (https://api.frankfurter.app/) melalui VM Proxy yang di-deploy di VPC konsumen dengan alamat RFC1918. Contoh deployment ini berlaku dalam project yang mengaktifkan VPC-SC atau untuk administrator yang memerlukan egress internet melalui jaringan pelanggan, bukan VPC tenant.

Gambar 1

f42f2db921f6d5af.png

Anda akan membuat satu psc-network-attachment di VPC konsumen dengan memanfaatkan peering DNS untuk menyelesaikan proxy-vm jaringan konsumen di project tenant yang menghosting Agent Engine sehingga menghasilkan kasus penggunaan berikut:

Men-deploy Agent Engine dan mengonfigurasi VM proxy agar bertindak sebagai proxy eksplisit, sehingga dapat menjangkau URL publik https://api.frankfurter.app

Yang akan Anda pelajari

  • Cara membuat lampiran jaringan
  • Cara produsen dapat menggunakan lampiran jaringan untuk membuat antarmuka PSC
  • Cara membuat komunikasi dari produsen ke konsumen menggunakan Peering DNS
  • Cara men-deploy dan menggunakan VM proxy untuk traffic keluar internet

Yang Anda butuhkan

Project Google Cloud

Izin IAM

2. Sebelum memulai

Mengupdate project untuk mendukung tutorial

Tutorial ini menggunakan $variables untuk membantu penerapan konfigurasi gcloud di Cloud Shell.

Di dalam Cloud Shell, lakukan hal berikut:

gcloud config list project
gcloud config set project [YOUR-PROJECT-NAME]
projectid=YOUR-PROJECT-NAME
echo $projectid

Pengaktifan API

Di dalam Cloud Shell, lakukan hal berikut:

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"

Pastikan API berhasil diaktifkan

gcloud services list --enabled

3. Penyiapan Konsumen

Buat VPC Konsumen

VPC ini berada di project pelanggan. Resource berikut akan dibuat di VPC ini

  • Subnet Konsumen
  • Subnet Lampiran Jaringan
  • Cloud Router (Diperlukan untuk Cloud NAT)
  • Cloud NAT

Di dalam Cloud Shell, lakukan hal berikut:

gcloud compute networks create consumer-vpc --project=$projectid --subnet-mode=custom

Buat subnet konsumen

Di dalam Cloud Shell, buat subnet untuk VM Proxy:

gcloud compute networks subnets create rfc1918-subnet1 --project=$projectid --range=10.10.10.0/28 --network=consumer-vpc --region=us-central1

Buat subnet Lampiran Jaringan Private Service Connect

Di dalam Cloud Shell, buat subnet untuk PSC Network Attachment:

gcloud compute networks subnets create intf-subnet --project=$projectid --range=192.168.10.0/28 --network=consumer-vpc --region=us-central1

Konfigurasi Cloud Router dan NAT

Dalam tutorial ini, Cloud NAT digunakan untuk menyediakan akses internet bagi VM proxy, yang tidak memiliki alamat IP publik. Cloud NAT memungkinkan VM yang hanya memiliki alamat IP pribadi terhubung ke internet, sehingga dapat melakukan tugas seperti menginstal paket software.

Di dalam Cloud Shell, buat Cloud Router.

gcloud compute routers create cloud-router-for-nat --network consumer-vpc --region us-central1

Di dalam Cloud Shell, buat gateway NAT dengan logging yang diaktifkan. Kami akan menggunakan logging untuk memvalidasi akses ke IP publik untuk 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. Aktifkan IAP

Untuk mengizinkan IAP terhubung ke instance VM Anda, buat aturan firewall yang:

  • Berlaku untuk semua instance VM yang ingin Anda akses menggunakan IAP.
  • Mengizinkan traffic masuk dari rentang IP 35.235.240.0/20. Rentang ini berisi semua alamat IP yang digunakan IAP untuk penerusan TCP.

Di dalam Cloud Shell, buat aturan firewall IAP.

gcloud compute firewall-rules create ssh-iap-consumer \
    --network consumer-vpc \
    --allow tcp:22 \
    --source-ranges=35.235.240.0/20

5. Membuat instance VM konsumen

Di dalam Cloud Shell, buat instance VM konsumen, proxy-vm, yang akan berfungsi sebagai proxy eksplisit untuk Agent Engine. Kita akan menggunakan tinyproxy sebagai aplikasi untuk mem-proxy traffic 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. Lampiran jaringan Private Service Connect

Lampiran jaringan adalah resource regional yang mewakili sisi konsumen antarmuka Private Service Connect. Anda mengaitkan satu subnet dengan lampiran jaringan, dan produsen akan menetapkan IP ke antarmuka Private Service Connect dari subnet tersebut. Subnet harus berada di region yang sama dengan lampiran jaringan. Lampiran jaringan harus berada di region yang sama dengan layanan produsen.

Buat lampiran jaringan

Di dalam Cloud Shell, buat lampiran jaringan.

gcloud compute network-attachments create psc-network-attachment \
    --region=us-central1 \
    --connection-preference=ACCEPT_AUTOMATIC \
    --subnets=intf-subnet

Mencantumkan lampiran jaringan

Di dalam Cloud Shell, cantumkan lampiran jaringan.

gcloud compute network-attachments list

Mendeskripsikan lampiran jaringan

Di dalam Cloud Shell, deskripsikan lampiran jaringan.

gcloud compute network-attachments describe psc-network-attachment --region=us-central1

Catat nama Lampiran Jaringan PSC, psc-network-attachment, yang akan digunakan oleh produsen saat membuat Antarmuka Private Service Connect.

Untuk melihat URL Lampiran Jaringan PSC di Konsol Cloud, buka:

Network Services → Private Service Connect → Network Attachment → psc-network-attachment

8eec51cb197da218.png

7. Zona DNS Pribadi

Anda akan membuat Zona Cloud DNS untuk demo.com dan mengisinya dengan data A yang mengarah ke alamat IP proxy-vm Anda. Selanjutnya, peering DNS akan di-deploy di Agent Engine, yang akan memungkinkan akses ke data DNS konsumen.

Di dalam Cloud Shell, lakukan perintah berikut yang membuat nama 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"

Dapatkan dan simpan Alamat IP instance yang digunakan untuk data DNS A.

Di dalam Cloud Shell, lakukan deskripsi terhadap instance VM.

gcloud compute instances describe proxy-vm --zone=us-central1-a | grep  networkIP:

Di dalam Cloud Shell, buat set data untuk VM, proxy-vm.demo.com, pastikan untuk memperbarui Alamat IP berdasarkan output lingkungan Anda.

gcloud dns --project=$projectid record-sets create proxy-vm.demo.com. --zone="private-dns-codelab" --type="A" --ttl="300" --rrdatas="10.10.10.2"

Membuat aturan Cloud Firewall untuk mengizinkan akses dari Antarmuka PSC

Di bagian berikut, buat aturan firewall yang mengizinkan traffic yang berasal dari akses Lampiran Jaringan PSC ke proxy-vm di VPC Konsumen.

Di Cloud Shell, buat aturan firewall masuk.

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. Membuat Notebook Jupyter

Bagian berikut akan memandu Anda membuat Notebook Jupyter. Notebook ini akan digunakan untuk men-deploy Agent Engine yang menargetkan proxy eksplisit untuk Egress Internet.

Buat akun layanan yang dikelola pengguna

Di bagian berikut, Anda akan membuat akun layanan yang akan dikaitkan dengan instance Vertex AI Workbench yang digunakan dalam tutorial.

Dalam tutorial ini, akun layanan akan memiliki peran berikut yang diterapkan:

Di dalam Cloud Shell, buat akun layanan.

gcloud iam service-accounts create notebook-sa \
    --display-name="notebook-sa"

Di dalam Cloud Shell, perbarui akun layanan dengan peran Storage Admin.

gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:notebook-sa@$projectid.iam.gserviceaccount.com" --role="roles/storage.admin"

Di dalam Cloud Shell, perbarui akun layanan dengan peran Vertex AI User.

gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:notebook-sa@$projectid.iam.gserviceaccount.com" --role="roles/aiplatform.user"

Di dalam Cloud Shell, perbarui akun layanan dengan peran Artifact Registry Admin.

gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:notebook-sa@$projectid.iam.gserviceaccount.com" --role="roles/artifactregistry.admin"

Di dalam Cloud Shell, izinkan akun layanan notebook menggunakan akun layanan default 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. Memperbarui proxy eksplisit

Di bagian berikut, Anda harus melakukan SSH ke proxy eksplisit dan memperbarui file konfigurasi tinyproxy.conf, lalu melakukan reset.

Dari Cloud Shell

gcloud compute ssh --zone us-central1-a "proxy-vm" --tunnel-through-iap --project $projectid

Buka file konfigurasi tinyproxy, perbarui menggunakan editor pilihan Anda. Berikut adalah contoh menggunakan 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. Membuat Instance Vertex AI Workbench

Di bagian berikut, buat instance Vertex AI Workbench yang menggabungkan akun layanan yang dibuat sebelumnya, notebook-sa.

Di dalam Cloud Shell, buat instance 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. Pembaruan Agen Layanan Vertex AI

Vertex AI bertindak atas nama Anda untuk melakukan operasi seperti mendapatkan Alamat IP dari subnet PSC Network Attachment yang digunakan untuk membuat Antarmuka PSC. Untuk melakukannya, Vertex AI menggunakan agen layanan (yang tercantum di bawah) yang memerlukan izin Admin Jaringan:

service-$projectnumber@gcp-sa-aiplatform.iam.gserviceaccount.com

Di dalam Cloud Shell, dapatkan nomor project Anda.

gcloud projects describe $projectid | grep projectNumber

Di dalam Cloud Shell, tetapkan nomor project Anda.

projectnumber=YOUR-PROJECT-Number

Di dalam Cloud Shell, buat akun layanan untuk AI Platform. Lewati langkah ini jika Anda sudah memiliki akun layanan di project Anda.

gcloud beta services identity create --service=aiplatform.googleapis.com --project=$projectnumber

Di dalam Cloud Shell, perbarui akun agen layanan dengan peran compute.networkAdmin.

gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:service-$projectnumber@gcp-sa-aiplatform.iam.gserviceaccount.com" --role="roles/compute.networkAdmin"

Di dalam Cloud Shell, perbarui akun agen layanan dengan peran dns.peer

gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:service-$projectnumber@gcp-sa-aiplatform.iam.gserviceaccount.com" --role="roles/dns.peer"

Pembaruan Akun Layanan Default

Beri akun layanan default Anda akses ke Vertex AI. Perhatikan bahwa mungkin perlu beberapa saat agar perubahan akses diterapkan.

Di dalam Cloud Shell, perbarui akun layanan default dengan peran aiplatform.user

gcloud projects add-iam-policy-binding $projectid \
  --member="serviceAccount:$projectnumber-compute@developer.gserviceaccount.com" \
    --role="roles/aiplatform.user"

12. Tcpdump VM Proxy

Untuk memvalidasi konektivitas IP dari Agent Engine, kita dapat menggunakan TCPDUMP. Hal ini akan memungkinkan kami mengamati komunikasi yang berasal dari subnet PSC Network Attachment, 192.168.10.0/28 saat memanggil permintaan get dari Agent Engine ke URL publik.

Dari Cloud Shell, lakukan SSH ke VM proxy.

gcloud compute ssh --zone us-central1-a "proxy-vm" --tunnel-through-iap --project $projectid

Dari OS proxy-vm, jalankan tcpdump.

sudo tcpdump -i any net 192.168.10.0/28 -nn

13. Men-deploy Agent Engine

Catatan: Kita akan menggunakan konsol GCP dan notebook JupyterLab untuk menyelesaikan tugas di bagian ini

Di bagian berikut, Anda akan membuat notebook yang melakukan tugas berikut:

  • Menggunakan Frankfurter API (https://api.frankfurter.app/) untuk mendapatkan data nilai tukar
  • Mereferensikan proxy eksplisit (proxy_server) yang menargetkan proxy-vm di VPC konsumen menggunakan FQDN proxy-vm.demo.com
  • Tentukan dnsPeeringConfigs "domain": "demo.com."

Jalankan tugas pelatihan di instance Vertex AI Workbench.

  • Di konsol Google Cloud, buka Vertex AI → Workbench
  • Di samping nama instance Vertex AI Workbench (workbench-tutorial), klik Open JupyterLab. Instance Vertex AI Workbench Anda akan terbuka di JupyterLab.
  • Pilih File > New > Notebook
  • Pilih Kernel > Python 3

Instal library Python yang diperlukan: Instal library yang diperlukan untuk Agent Engine, termasuk pyyaml, google-cloud-aiplatform, cloudpickle, google-cloud-api-keys, dan langchain-google-vertexai.

Di notebook JupyterLab, buat sel baru dan jalankan kode berikut.

!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

Mulai ulang kernel Jupyter Notebook: Pastikan library yang baru diinstal dimuat dengan benar.

Di notebook JupyterLab, buat sel baru dan jalankan kode berikut.

# Restart the notebook kernel after install, so you can run langchain successfully.

import IPython

app = IPython.Application.instance()
app.kernel.do_shutdown(True)

Tetapkan variabel project dan bucket: Tentukan ID project Google Cloud, nomor project, nama layanan, direktori GCS, endpoint, nama bucket, dan lokasi Anda.

Perbarui kolom berikut sebelum Anda menjalankan sel

  • PROJECT_ID = "enter-your-projectid"
  • PROJECT_NUMBER = "enter-your-projectnumber"
  • BUCKET= "enter-a-unique-bucket-name"

Catatan: Kita akan menggunakan variabel BUCKET untuk membuat bucket Cloud Storage di langkah berikutnya.

Di notebook JupyterLab Anda, buat sel baru, perbarui, lalu jalankan yang berikut.

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"}

Buat bucket GCS: Buat bucket Cloud Storage untuk menyimpan kode agen.

Di notebook JupyterLab, buat sel baru dan jalankan kode berikut.

!gcloud storage buckets create gs://{BUCKET}

Tentukan nama lampiran jaringan: Tentukan nama lampiran jaringan Private Service Connect Anda.

Di notebook JupyterLab, buat sel baru dan jalankan kode berikut.

NETWORK_ATTACHMENT_NAME = 'psc-network-attachment' #@param {type:"string"}

Lakukan inisialisasi library klien Python: Siapkan library klien yang diperlukan untuk layanan Google Cloud.

Di notebook JupyterLab, buat sel baru dan jalankan kode berikut.

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)

Konfigurasi agen dan alat: Tentukan class StreamingAgent dan fungsi get_exchange_rate untuk mengambil nilai tukar mata uang menggunakan Frankfurter API melalui proxy eksplisit.

Di notebook JupyterLab Anda, buat sel baru dan jalankan konfigurasi di bawah, perhatikan poin-poin berikut:

  • Fungsi def get_exchange_rate akan menggunakan Frankfurter API (https://api.frankfurter.app/) untuk mendapatkan data nilai tukar.
  • proxy_server = "http://proxy-vm.demo.com:8888" FQDN dikaitkan dengan VM proxy yang di-deploy di VPC konsumen. Kita menggunakan peering DNS untuk me-resolve FQDN pada langkah selanjutnya.
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()

Upload file agen ke Cloud Storage: Upload agen yang diserialisasi dan persyaratannya ke bucket GCS yang ditentukan.

Di notebook JupyterLab, buat sel baru dan jalankan perintah berikut:

# 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}

Deploy Agent Engine: Deploy Agent Engine, konfigurasikan dengan antarmuka PSC dan peering DNS untuk menyelesaikan FQDN VM proxy di VPC konsumen.

Di notebook JupyterLab Anda, buat dan jalankan sel di bawah, perhatikan poin-poin penting berikut:

  • Peering DNS ke VPC konsumen dikonfigurasi menggunakan dnsPeeringConfigs (dnsPeeringConfigs) untuk demo nama domain 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)

Pantau status deployment: Periksa status operasi deployment Agent Engine.

Di notebook JupyterLab, buat sel baru dan jalankan kode berikut.

operation_id = json.loads(response.content)["name"].split("/")[7]
pprint.pprint(operation_id)

Di notebook JupyterLab, buat sel baru dan jalankan kode berikut.

Catatan: Operasi ini dapat memerlukan waktu sekitar 5 menit untuk selesai. Jalankan kembali sel untuk memeriksa progres. Jangan lanjutkan ke bagian berikutnya hingga Anda melihat output yang mirip dengan screenshot di bawah.

# 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))

Contoh eksekusi yang berhasil:

3f6dcd1074af7651.png

Kueri agen yang di-deploy: Kirim kueri ke Agent Engine yang di-deploy untuk menguji fungsinya.

Di notebook JupyterLab, buat sel baru dan jalankan kode berikut.

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)

Hasil kueri streaming: Streaming output dari kueri Agent Engine.

Di notebook JupyterLab, buat sel baru dan jalankan perintah berikut yang akan memicu panggilan API ke URL publik menggunakan proxy eksplisit di VPC konsumen.

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))

Contoh eksekusi yang berhasil:

1bd81d12426a348f.png

14. Validasi Tcpdump

Lihat output tcpdump yang menjelaskan komunikasi antara alamat IP Lampiran Jaringan PSC yang digunakan oleh Agent Engine dan Prox-VM saat permintaan diposting.

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. Validasi Antarmuka PSC

Anda juga dapat melihat IP Network Attachment yang digunakan oleh Agent Engine dengan membuka:

Network Services → Private Service Connect → Network Attachment → psc-network-attachment

Pilih project tenant (nama project yang berakhiran -tp)

8a4b5a6e5dfd63d7.png

Kolom yang ditandai menunjukkan alamat IP yang digunakan oleh Agent Engine dari PSC Network Attachment.

c618359f6eafc0c6.png

16. Validasi Cloud Logging

Keluar dari sesi TCPDump proxy-vm dan lakukan PING ke Frankfurter api.frankfurter.app untuk mendapatkan Alamat IP publik terkait.

ping -c4 api.frankfurter.app 

Contoh mengidentifikasi 104.26.1.198 sebagai IP publik untuk 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

Mari kita lihat NAT Logging untuk melihat apakah traffic untuk 104.26.1.198 diamati.

Buka bagian berikut:

Monitoring → Log Explorer

Gunakan filter berikut:

resource.type="nat_gateway"

31024dc29c39084.png

Pilih jangka waktu, lalu Jalankan Kueri

5976857e92d149d3.png

Perluas entri log yang mengidentifikasi IP publik (tujuan) (104.26.1.198) api.frankfurter.app dan Alamat IP sumber serta nama proxy-vm yang memvalidasi penggunaan proxy eksplisit untuk traffic keluar internet.

14e293a7fea68db4.png

17. Pembersihan

Di notebook JupyterLab, buat sel baru dan jalankan perintah berikut yang akan memicu penghapusan deployment 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)

Dari Cloud Shell, hapus komponen 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. Selamat

Selamat, Anda telah berhasil mengonfigurasi dan memvalidasi Agent Engine yang di-deploy dengan Antarmuka Private Service Connect dengan egress internet yang dilakukan melalui proxy eksplisit.

Anda membuat infrastruktur konsumen, dan menambahkan lampiran jaringan yang memungkinkan produsen membuat VM multi-NIC untuk menjembatani komunikasi konsumen dan produsen. Anda telah mempelajari cara membuat peering DNS dan proxy eksplisit yang memungkinkan konektivitas Internet.

Cosmopup menganggap tutorial itu luar biasa!!

c911c127bffdee57.jpeg

Apa selanjutnya?

Bacaan lebih lanjut & Video

Dokumen referensi