1. Wprowadzenie
To ćwiczenie pokazuje, jak skonfigurować prywatne, kontrolowane połączenie wychodzące dla Gemini Enterprise za pomocą Bramy agentów w trybie agent-to-anywhere (ruch wychodzący). Skonfigurujesz aplikację Gemini Enterprise, aby bezpiecznie wywoływać niestandardowy serwer protokołu kontekstu modelu (MCP) hostowany w Cloud Run, kierując ruch przez Agent Gateway przy użyciu interfejsów Private Service Connect (PSC) w celu połączenia się z punktem końcowym PSC dla interfejsów API Google w sieci VPC.
W środowiskach korporacyjnych przyznanie autonomicznym agentom bezpośredniego dostępu do sieci wiąże się z ryzykiem wydobycia danych i wykonywania niezweryfikowanych narzędzi. Brama agentów to scentralizowany punkt egzekwowania zasad zerowego zaufania na poziomie platformy, który dynamicznie sprawdza przesyłane strumieniowo ładunki narzędzi MCP HTTP. Żądania wychodzące są uwierzytelniane za pomocą kryptograficznie weryfikowalnej Agent Identity i autoryzowane przez Identity-Aware Proxy (IAP) przy użyciu ujednoliconych zasad dostępu (UAP) IAM z regułami języka CEL (Common Expression Language). Umożliwia to szczegółową kontrolę dostępu do konkretnych narzędzi i metod MCP bez udostępniania zadań backendu w internecie publicznym.
Co utworzysz
- Brama agentów działająca w trybie ruchu wychodzącego (od agenta do dowolnego miejsca) z weryfikacją punktu końcowego Agent Registry
- Usługa Cloud Run hostująca prywatny serwer MCP HTTP z możliwością przesyłania strumieniowego (
--ingress=internal) zarejestrowany w Agent Registry ze specyfikacjami narzędzi - Rozszerzenie autoryzacji Identity-Aware Proxy (IAP) dla bramy agentów
- Ujednolicone zasady dostępu (UAP) IAM z warunkami CEL na potrzeby autoryzacji narzędzia MCP
- Aplikacja Gemini Enterprise powiązana z bramą agentów i połączona z niestandardowym magazynem danych serwera MCP zaimportowanym z Agent Registry
- Zasoby sieci VPC, strefa Cloud DNS i punkt końcowy PSC dla interfejsów API Google
- Przyłącze sieci PSC na potrzeby prywatnego ruchu wychodzącego z bramy agenta
- Reguły zasad Cloud Next Generation Firewall (NGFW) do zabezpieczania ruchu VPC
Rys. 1. Architektura ćwiczeń z programowania
Czego się dowiesz
- Jak wdrożyć prywatny serwer MCP HTTP z możliwością przesyłania strumieniowego ze źródła w Cloud Run i zarejestrować jego punkt końcowy oraz schemat narzędzia w Agent Registry
- Jak skonfigurować bramę agentów za pomocą zgodnych wpisów w rejestrze i przekierowywać wywołania narzędzi aplikacji Gemini Enterprise przez bramę
- Jak skonfigurować prywatny ruch wychodzący z sieci VPC za pomocą przyłączy sieci PSC i interfejsów
- Delegowanie autoryzacji bramy agentów na Identity-Aware Proxy (IAP)
- Jak tworzyć i wiązać ujednolicone zasady dostępu (UAP) w IAM za pomocą atrybutów CEL
destination.agent_registry.*idestination.is_registered, aby ograniczyć wykonywanie narzędzia MCP - Jak weryfikować egzekwowanie zasad i ruch wychodzący z sieci za pomocą Cloud Logging
Wymagania
- Projekt Google Cloud z włączonymi płatnościami
- aktywną licencję Gemini Enterprise lub 30-dniowy okres próbny;
- Uprawnienia IAM do udostępniania usług sieciowych, Gemini Enterprise i zasobów Agent Platform
- Powłoka zgodna z POSIX (
bashlubzsh) z zainstalowanymi narzędziami Google Cloud CLI (gcloud),curlijq.
To koniec wprowadzenia. Przejdźmy teraz do sekcji Pojęcia.
2. Pojęcia
Sekwencja wdrażania
To ćwiczenie najpierw wdraża infrastrukturę, aby ścieżki sieci prywatnej i elementy sterujące zarządzaniem działały przed zarejestrowaniem i połączeniem narzędzi MCP z Gemini Enterprise:
- Infrastruktura sieciowa: udostępnij podsieci VPC, punkt końcowy PSC, przyłącze sieci PSC, reguły zasad Cloud NGFW i prywatne strefy Cloud DNS.
- Brama agentów: wdróż bramę agentów w trybie ruchu wychodzącego z integracją z Agent Registry (
registries) i prywatnym ruchem wychodzącym z sieci VPC (networkAttachment). - Zasady autoryzacji: skonfiguruj rozszerzenie autoryzacji IAP, zasadę autoryzacji bramy i zasadę ujednoliconego dostępu IAM za pomocą warunków CEL
destination.is_registeredidestination.agent_registry.*. - Wdróż i zarejestruj serwer MCP: wdróż serwer MCP do obliczeń matematycznych ze źródła w Cloud Run (
--ingress=internal) i zarejestruj specyfikacje usługi i narzędzia (addisubtract) w Agent Registry. - Aplikacja Gemini Enterprise: utwórz aplikację Gemini Enterprise (
Engine), skonfiguruj ustawienia tożsamości i widoczności oraz powiąż wychodzący ruch z bramą agentów (agentGatewaySetting). - Importowanie niestandardowego łącznika danych MCP: utwórz i aktywuj
REGISTRY_MCPłącznik danych (:setUpDataConnector), aby połączyć magazyn danych zarejestrowanego serwera MCP z aplikacją Gemini Enterprise. - Weryfikacja: testuj dozwolone i niedozwolone wykonania narzędzi na czacie oraz sprawdzaj egzekwowanie zasad w logach usługi bramy agentów, DNS, zapory sieciowej i Cloud Run.
Ruch wychodzący Gemini Enterprise
Gemini Enterprise kieruje żądania narzędzi niestandardowego serwera MCP do bramy agentów, gdy skonfigurowane są zarówno agentGatewaySetting na Engine, jak i use_agent_gateway_egress: true na DataConnector.
Rys. 2. Architektura ruchu wychodzącego Gemini Enterprise
Aplikacja Gemini Enterprise porządkuje routing narzędzi w 4 głównych obszarach:
- Widżet (
default_search_widget_config):- Obsługuje interfejs klienta internetowego. Widżet otrzymuje prompty od użytkownika i rozpoczyna sesje czatu z silnikiem bazowym.
- Podstawowy asystent (
assistants/default_assistant/agents/default/core_assistant):- Główny konwersacyjny agent rozumowania w silniku. Podczas oceny zapytania użytkownika Asystent główny określa, czy wymagane jest obliczenie arytmetyczne, sprawdza dostępne narzędzia i przekazuje wykonanie zadania do wygenerowanego podagenta bramy agenta.
- Magazyn danych i Łącznik danych:
DataStore: jest udostępniany w ramach dedykowanegoCollectionpodczas działania:setUpDataConnector. Łączy (dataStoreIds) zaimportowane schematy narzędzi Agent Registry (add,subtract), typy argumentów i instrukcje agenta zEngineGemini Enterprise.DataConnector: zarządza połączeniem działaniaREGISTRY_MCP(createBapConnection: true) ze zdalnym Serwerem MCP (instance_uri), rozwiązuje zasób Serwera MCP z Agent Registry (registry_mcp_server_name) i umożliwia ruch wychodzący z Bramy agentów (use_agent_gateway_egress: true).
- Agent Identity, Agent Registry i Brama agentów:
- Gdy łącznik danych wysyła wywołanie narzędzia wychodzącego, kieruje ruch do bramy określonej w
agentGatewaySetting. Centrum Asystenta tworzy token tożsamości SPIFFE potwierdzający jego tożsamość:principal://agents.global.org-.../agents/default/core_assistant. - Brama agentów jest zintegrowana z Agent Registry za pomocą pola
registries, aby dynamicznie rozpoznawać docelowe punkty końcowe i zarejestrowane schematy narzędzi. Wypełnia atrybutydestination.is_registeredidestination.agent_registry.*i przekazuje je do IAP w wersji 2 w celu oceny na podstawie reguł CEL ujednoliconych zasad dostępu (UAP) IAM przed zezwoleniem na przesyłanie danych do sieci VPC.
- Gdy łącznik danych wysyła wywołanie narzędzia wychodzącego, kieruje ruch do bramy określonej w
Połączenie z siecią VPC bramy
Brama agenta umożliwia prywatne połączenie z siecią VPC za pomocą 2 pól YAML:
networkConfig.egress.networkAttachment: kieruje ruch prywatnych adresów IP, aby był kierowany przez przyłącze sieci PSC do sieci VPC.dnsPeeringConfig.domains: łączy rozpoznawanie nazw DNS ze strefą DNS Cloud DNS sieci VPC, dzięki czemu docelowe nazwy hostów (*.run.app) są rozpoznawane jako prywatny adres IP punktu końcowego PSC zdefiniowany w sieci VPC.
Ograniczenia i wymagania
- Tylko StreamableHTTP: starszy transport zdarzeń wysyłanych przez serwer (SSE) nie jest obsługiwany. Serwery MCP muszą korzystać z StreamableHTTP.
- Wymagany publiczny CA TLS: punkty końcowe MCP muszą używać certyfikatów TLS podpisanych przez publicznie zaufany urząd certyfikacji, nawet jeśli dostęp do nich jest prywatny przez PSC.
- Zastąpienie zasad organizacji: przed zarejestrowaniem magazynu danych musisz wyraźnie zastąpić zasady organizacji dotyczące niestandardowych magazynów danych MCP.
To koniec części poświęconej koncepcjom. Przejdźmy teraz do sekcji Konfiguracja.
3. Konfiguracja
Wymagane role uprawnień
Aby ukończyć to ćwiczenie, musisz mieć te role:
Domena | Wymagane role uprawnień |
Projekt i IAM |
|
Sieć i brama |
|
Gemini Enterprise i rejestr |
|
Workloads & Build |
|
Dostrzegalność |
|
Możesz też użyć szerokiego poziomu podstawowego, np. roles/owner, w połączeniu z roles/orgpolicy.policyAdmin (ponieważ sam poziom podstawowy roles/owner nie może modyfikować zasad organizacji).
Dostęp do projektu
To ćwiczenie korzysta z jednego projektu Google Cloud. Etapy konfiguracji obejmują użycie interfejsu wiersza poleceń gcloud i poleceń powłoki Linux.
Zacznij od uzyskania dostępu do wiersza poleceń projektu w chmurze Google Cloud:
- Cloud Shell na stronie
shell.cloud.google.comlub - Terminal lokalny z zainstalowanym interfejsem wiersza poleceń
gcloud
Ustawianie identyfikatora projektu
gcloud config set project SET_YOUR_PROJECT_ID_HERE
Uwierzytelnianie sesji
# login to gcloud cli
gcloud auth login
# login for gcloud api
gcloud auth application-default login
Ustawianie zmiennych środowiskowych powłoki
# set custom var for slug (eg, "foo") and region preference
export SLUG="foo"
export REGION="us-central1"
echo ${SLUG}
echo ${REGION}
# create project vars (automatic)
export PROJ_ID=$(gcloud config list --format="value(core.project)")
export PROJ_NO=$(gcloud projects describe ${PROJ_ID} --format="value(projectNumber)")
export ORG_ID=$(gcloud projects get-ancestors ${PROJ_ID} --format="value(id)" | tail -n 1)
export USER_IDENTITY=$(gcloud config get-value account)
echo ${PROJ_ID}
echo ${PROJ_NO}
echo ${ORG_ID}
echo ${USER_IDENTITY}
# create resource vars for agent platform (automatic)
export AGW_NAME="agw-${SLUG}-${REGION}-ata"
export AGW_URI="projects/${PROJ_ID}/locations/${REGION}/agentGateways/${AGW_NAME}"
export UAP_POLICY_NAME="uap-policy-${SLUG}"
export UAP_BINDING_NAME="uap-binding-${SLUG}"
export MCP_NAME="math-wizard"
export MCP_URL="https://${MCP_NAME}-${PROJ_NO}.${REGION}.run.app/mcp"
echo ${AGW_NAME}
echo ${AGW_URI}
echo ${UAP_POLICY_NAME}
echo ${UAP_BINDING_NAME}
echo ${MCP_NAME}
echo ${MCP_URL}
# create resource vars for gemini enterprise (automatic)
export GE_APP_DISPLAY_NAME="Codelab app"
export GE_APP_ORG_NAME="${SLUG}, Inc."
export GE_LOCATION="global"
export GE_APP_NAME="app-${SLUG}-${GE_LOCATION}"
export GE_APP_INIT="${GE_APP_NAME}_$(date +%s)"
echo ${GE_APP_DISPLAY_NAME}
echo ${GE_APP_ORG_NAME}
echo ${GE_LOCATION}
echo ${GE_APP_NAME}
echo ${GE_APP_INIT}
Ustawianie domen zaufania tożsamości agenta
Instrukcja if-then-else sprawdza, czy projekt należy do organizacji, aby ustawić prawidłową domenę zaufania dla tożsamości agenta głównego.
# set var for trust domain
if [[ -n "${ORG_ID}" ]]; then
export TRUST_DOMAIN="agents.global.org-${ORG_ID}.system.id.goog"
else
export TRUST_DOMAIN="agents.global.proj-${PROJ_NO}.system.id.goog"
fi
echo "trust domain: ${TRUST_DOMAIN}"
Ustawianie projektu rozliczeniowego i projektu limitu
# set cli quota project
gcloud config set billing/quota_project ${PROJ_ID}
# set api quota project
gcloud auth application-default set-quota-project ${PROJ_ID}
Tworzenie lokalnego katalogu plików konfiguracyjnych
# create config folder
mkdir -p cfg
Zaktualizuj gcloud cli (zalecane)
Jeśli korzystasz z samodzielnie zarządzanej instalacji pakietu Google Cloud SDK (czyli poza Cloud Shell), zaktualizuj komponenty do najnowszej wersji.
# update gcloud cli
gcloud components update
Włączanie usług API
# enable google apis (part 1)
gcloud services enable \
agentregistry.googleapis.com \
agentidentity.googleapis.com \
aiplatform.googleapis.com \
apphub.googleapis.com \
apptopology.googleapis.com \
cloudapiregistry.googleapis.com \
cloudtrace.googleapis.com \
compute.googleapis.com \
dataform.googleapis.com \
iam.googleapis.com \
iap.googleapis.com \
logging.googleapis.com \
modelarmor.googleapis.com \
monitoring.googleapis.com \
networksecurity.googleapis.com \
networkservices.googleapis.com \
notebooks.googleapis.com \
observability.googleapis.com
# enable google apis (part 2)
gcloud services enable \
artifactregistry.googleapis.com \
cloudbuild.googleapis.com \
discoveryengine.googleapis.com \
dns.googleapis.com \
orgpolicy.googleapis.com \
run.googleapis.com \
saasservicemgmt.googleapis.com \
securitycenter.googleapis.com \
storage.googleapis.com \
telemetry.googleapis.com \
texttospeech.googleapis.com
Zasady organizacji
Domyślne zarządzane ograniczenia zasad organizacji Google Cloud ograniczają funkcje używane w tym laboratorium:
discoveryengine.managed.disableCustomMcpServerConnector:- Ogranicza tworzenie łączników danych, które jako źródło danych wykorzystują niestandardowy serwer MCP (
custom_mcp) (domyślnie wymuszane).
- Ogranicza tworzenie łączników danych, które jako źródło danych wykorzystują niestandardowy serwer MCP (
iam.managed.disableAccessPolicyBinding:- Ogranicza powiązania zasad dostępu IAM w wersji 3 do zasobów (wymuszane domyślnie).
discoveryengine.managed.allowedEgressFqdns:- Ogranicza wychodzące domeny wyjścia (
instance_uriw pełni kwalifikowane nazwy domen) dla łączników danych, gdy aktywne są Ustawienia usługi VPC (VPC-SC) lub projekt jest wymieniony w parametrzeenforcedProjectsorganizacji.
- Ogranicza wychodzące domeny wyjścia (
discoveryengine.managed.allowedDataSources:- Ogranicza dozwolone typy łączników danych (
dataSource), gdy aktywna jest usługa VPC-SC lub projekt jest wymieniony w parametrzeenforcedProjectsorganizacji.
- Ogranicza dozwolone typy łączników danych (
Zastąp wszelkie odziedziczone ograniczenia zasad organizacji na poziomie projektu, ustawiając wyraźnie wartość enforce: false.
Wyłączanie niestandardowego ograniczenia MCP
# disable data connector constraint (allow custom mcp servers)
gcloud org-policies set-policy /dev/stdin << EOF
name: projects/${PROJ_NO}/policies/discoveryengine.managed.disableCustomMcpServerConnector
spec:
rules:
- enforce: false
EOF
# verify org policy constraint on project
gcloud org-policies describe discoveryengine.managed.disableCustomMcpServerConnector \
--project=${PROJ_ID} --effective
Wyłączanie ograniczenia zasady dostępu
# disable iam v3 constraint (allow v3 access policies)
gcloud org-policies set-policy /dev/stdin << EOF
name: projects/${PROJ_NO}/policies/iam.managed.disableAccessPolicyBinding
spec:
rules:
- enforce: false
EOF
# verify org policy constraint on project
gcloud org-policies describe iam.managed.disableAccessPolicyBinding \
--project=${PROJ_ID} --effective
Sprawdzanie i wyłączanie ograniczeń warunkowego oprogramowania sprzęgającego dane
Domyślnie warunki discoveryengine.managed.allowedEgressFqdns i discoveryengine.managed.allowedDataSources blokują tworzenie oprogramowania sprzęgającego tylko wtedy, gdy Twój projekt znajduje się w granicach Ustawień usługi VPC lub gdy administrator organizacji dodał Twój projekt do enforcedProjects.
Najpierw sprawdź obowiązujące zasady w projekcie:
# check effective egress fqdn constraint on project
gcloud org-policies describe discoveryengine.managed.allowedEgressFqdns \
--project=${PROJ_ID} --effective
# check effective data source constraint on project
gcloud org-policies describe discoveryengine.managed.allowedDataSources \
--project=${PROJ_ID} --effective
~~IF~~ te ograniczenia są egzekwowane, aby mieć pewność, że nie blokują konfiguracji oprogramowania sprzęgającego custom_mcp w organizacji z usługą VPC SC lub ograniczeniami zasad, ustaw w obu zasadach dla projektu wartość enforce: false:
# disable egress fqdn constraint on project
gcloud org-policies set-policy /dev/stdin << EOF
name: projects/${PROJ_NO}/policies/discoveryengine.managed.allowedEgressFqdns
spec:
rules:
- enforce: false
EOF
# disable allowed data sources constraint on project
gcloud org-policies set-policy /dev/stdin << EOF
name: projects/${PROJ_NO}/policies/discoveryengine.managed.allowedDataSources
spec:
rules:
- enforce: false
EOF
# verify both constraints are disabled on project
gcloud org-policies describe discoveryengine.managed.allowedEgressFqdns \
--project=${PROJ_ID} --effective
gcloud org-policies describe discoveryengine.managed.allowedDataSources \
--project=${PROJ_ID} --effective
Uprawnienia
Przyznaj wymagane role uprawnień kontu użytkownika i domyślnemu kontu usługi Compute Engine używanemu przez Cloud Build:
- Konto użytkownika (
${USER_IDENTITY}):- Wymaga uprawnień do wdrażania i wywoływania usług Cloud Run (
roles/run.admin,roles/run.invoker,roles/iam.serviceAccountUser), tworzenia obrazów kontenerów (roles/cloudbuild.builds.editor), zarządzania Gemini Enterprise (roles/discoveryengine.admin) i tworzenia ujednoliconych zasad dostępu (roles/iam.accessPolicyAdmin).
- Wymaga uprawnień do wdrażania i wywoływania usług Cloud Run (
- Domyślne konto usługi Compute Engine
${PROJ_NO}-compute@developer.gserviceaccount.com:- Używane przez Cloud Build do przechowywania kodu źródłowego w Cloud Storage (
roles/storage.admin), przesyłania obrazów do Artifact Registry (roles/artifactregistry.writer) i zapisywania dzienników kompilacji (roles/logging.logWriter).
- Używane przez Cloud Build do przechowywania kodu źródłowego w Cloud Storage (
Aby przypisać powiązania ról, uruchom te polecenia:
# grant roles to user account
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="user:${USER_IDENTITY}" \
--role="roles/run.admin"
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="user:${USER_IDENTITY}" \
--role="roles/iam.serviceAccountUser"
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="user:${USER_IDENTITY}" \
--role="roles/run.invoker"
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="user:${USER_IDENTITY}" \
--role="roles/discoveryengine.admin"
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="user:${USER_IDENTITY}" \
--role="roles/iam.accessPolicyAdmin"
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="user:${USER_IDENTITY}" \
--role="roles/cloudbuild.builds.editor"
# grant roles to default compute (cloud build) service account
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="serviceAccount:${PROJ_NO}-compute@developer.gserviceaccount.com" \
--role="roles/storage.admin"
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="serviceAccount:${PROJ_NO}-compute@developer.gserviceaccount.com" \
--role="roles/artifactregistry.writer"
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="serviceAccount:${PROJ_NO}-compute@developer.gserviceaccount.com" \
--role="roles/logging.logWriter"
Sprawdzanie uprawnień
Sprawdź, czy na koncie użytkownika jest 6 powiązań ról (6).
# show iam policy on project for user account
gcloud projects get-iam-policy ${PROJ_ID} \
--flatten="bindings[].members" \
--filter="bindings.members:${USER_IDENTITY}" \
--format="table(bindings.role:label=ROLE, bindings.members:label=PRINCIPAL_IDENTITY)"
Sprawdź, czy na domyślnym koncie usługi Compute są 3 powiązania ról (3).
# show iam policy on project for default compute service account
gcloud projects get-iam-policy ${PROJ_ID} \
--flatten="bindings[].members" \
--filter="bindings.members:${PROJ_NO}-compute@developer.gserviceaccount.com" \
--format="table(bindings.role:label=ROLE, bindings.members:label=PRINCIPAL_IDENTITY)"
Weryfikowanie powiązań agenta usługi (środki ostrożności)
W nowym projekcie Google Cloud automatycznie udostępnia agenta usługi Brama agentów i przyznaje mu uprawnienia roles/agentgateway.serviceAgent, gdy po raz pierwszy włączona jest usługa networkservices.googleapis.com. Jeśli ponownie używasz istniejącego projektu, w którym wcześniejsze czyszczenie mogło spowodować usunięcie domyślnych powiązań agenta usługi, wykonaj te polecenia, aby mieć pewność, że tożsamość i powiązanie ról są nienaruszone:
# ensure network services service account has been created
gcloud beta services identity create \
--service=networkservices.googleapis.com \
--project="${PROJ_ID}"
# ensure network services service account has service agent roles applied
gcloud projects add-iam-policy-binding "${PROJ_ID}" \
--member="serviceAccount:service-${PROJ_NO}@gcp-sa-agentgateway.iam.gserviceaccount.com" \
--role="roles/agentgateway.serviceAgent"
To kończy część dotyczącą konfiguracji. Przejdź do sekcji Sieć.
4. Sieć
W tej sekcji wdrożysz sieć VPC w trybie niestandardowym z dedykowaną podsiecią /28 (192.168.10.0/28) obsługującą przyłącze sieciowe usługi PSC na potrzeby ruchu wychodzącego z sieci bramy agenta do sieci VPC.
Punkt końcowy PSC dla interfejsów API Google jest wdrażany przy użyciu jednego /32globalnego wewnętrznego adresu IPv4 (172.16.20.20), aby obsługiwać prywatny dostęp wewnętrzny do interfejsów API i usług Google. W tym ćwiczeniu Agent Gateway kieruje ruch do Cloud Run przy użyciu punktu końcowego PSC, rozwiązując domenę run.app. za pomocą komunikacji równorzędnej Cloud DNS.
Tworzenie sieci
Utwórz globalną sieć VPC.
# create vpc network
gcloud compute networks create vnet-${SLUG} --subnet-mode=custom
Utwórz podsieci dla przyłącza sieci PSC bramy agenta:
# create subnet for agent gateway psc na
gcloud compute networks subnets create subnet-${REGION}-agw \
--network=vnet-${SLUG} \
--range=192.168.10.0/28 \
--region=${REGION} \
--enable-private-ip-google-access
Utwórz reguły zapory sieciowej
Utwórz zasadę zapory sieciowej, która zezwala na cały ruch wychodzący z włączonym logowaniem. Będzie on używany do monitorowania ruchu wychodzącego z bramy agenta do sieci VPC. Cloud NGFW obsługuje poziomy Essentials i Standard w zakresie zabezpieczeń sieci i monitorowania ruchu.
# create fw policy
gcloud compute network-firewall-policies create fw-policy-${SLUG} --global
# create fw policy rule
gcloud compute network-firewall-policies rules create 1001 \
--description="allow all out and log" \
--firewall-policy=fw-policy-${SLUG} \
--global-firewall-policy \
--action=allow \
--direction=EGRESS \
--layer4-configs=all \
--dest-ip-ranges=0.0.0.0/0 \
--enable-logging
# bind fw policy to network
gcloud compute network-firewall-policies associations create \
--name=fw-policy-bind-${SLUG} \
--firewall-policy=fw-policy-${SLUG} \
--network=vnet-${SLUG} \
--global-firewall-policy
Tworzenie przyłącza sieci PSC
Utwórz przyłącze sieci Private Service Connect (PSC) skonfigurowane tak, aby automatycznie akceptować połączenia z Bramy agentów. Przyłącze sieciowe tworzy po stronie sieci VPC konsumenta połączenie, które bezpiecznie łączy się z bramą agenta po stronie producenta na potrzeby wychodzącego ruchu wychodzącego. Więcej informacji o wymaganiach dotyczących podsieci i specyfikacjach zakresów adresów IP znajdziesz w artykule Konfigurowanie połączenia z siecią VPC.
# create psc network attachment
gcloud compute network-attachments create psc-na-${REGION}-agw \
--region=${REGION} \
--subnets=subnet-${REGION}-agw \
--connection-preference=ACCEPT_AUTOMATIC
Weryfikowanie przyłącza sieci PSC
# show psc network attachment details
gcloud compute network-attachments describe psc-na-${REGION}-agw --region=${REGION}
Pobierz identyfikator URI zasobu przyłącza sieci PSC i zapisz go w zmiennej środowiskowej PSC_NA_URI. Ten URI będzie używany w konfiguracji bramy agenta (networkConfig.egress.networkAttachment) do udostępniania interfejsu PSC na potrzeby ruchu wychodzącego z sieci VPC:
# fetch psc network attachment uri
export PSC_NA_URI=$(gcloud compute network-attachments describe psc-na-${REGION}-agw \
--region=${REGION} \
--format="value(selfLink.scope(v1))")
echo ${PSC_NA_URI}
Tworzenie punktu końcowego PSC
Punkt końcowy Private Service Connect (PSC) dla interfejsów API Google jest używany przez Bramę agentów do nawiązywania prywatnego połączenia z serwerem MCP Cloud Run przez wewnętrzną ścieżkę sieciową bez udostępniania ruchu w internecie publicznym. Wywołania narzędzi wychodzące z Bramy agentów do sieci VPC będą rozpoznawać docelowy adres URL usługi Cloud Run (*.run.app) jako ten prywatny adres IP punktu końcowego.
Zarezerwuj globalny wewnętrzny adres IPv4 dla punktu końcowego PSC. Wybrany adres IP musi być adresem /32, który nie pokrywa się z żadną istniejącą podsiecią w sieci VPC:
# set env var for psc ep ip address
export PSC_EP_IP="172.16.20.20"
echo ${PSC_EP_IP}
# reserve internal global ipv4 address
gcloud compute addresses create ip-psc2gapis \
--global \
--purpose=PRIVATE_SERVICE_CONNECT \
--addresses=${PSC_EP_IP} \
--network=vnet-${SLUG}
Utwórz punkt końcowy PSC dla interfejsów API Google za pomocą pakietu all-apis, który obejmuje Cloud Run (run.app).
# create psc endpoint for google apis
gcloud compute forwarding-rules create psc2gapis \
--global \
--network=vnet-${SLUG} \
--address=ip-psc2gapis \
--target-google-apis-bundle=all-apis
Weryfikowanie punktu końcowego PSC
# show psc endpoint details
gcloud compute forwarding-rules describe psc2gapis --global
Tworzenie strefy i rekordów DNS
Cloud DNS umożliwia bramie agenta prywatną komunikację z serwerem MCP hostowanym w Cloud Run. Gdy Brama agentów ocenia wychodzące żądania narzędzi kierowane do Cloud Run, używa połączeń równorzędnych DNS (dnsPeeringConfig.domains) do rozpoznawania zapytań DNS dotyczących *.run.app przy użyciu prywatnej strefy DNS powiązanej z siecią VPC. Prywatny rekord DNS zwraca zapytanie z wewnętrznym adresem IP punktu końcowego PSC (172.16.20.20), co umożliwia kierowanie żądań narzędzia MCP przez ścieżkę sieci prywatnej.
Utwórz prywatną zarządzaną strefę Cloud DNS dla domeny run.app.:
# create private dns zone
gcloud dns managed-zones create priv-zone-run \
--description="private zone for run.app" \
--dns-name="run.app." \
--visibility=private \
--networks=vnet-${SLUG}
Utwórz rekord DNS z symbolem wieloznacznym A dla *.run.app. wskazujący adres IP punktu końcowego PSC:
# create dns record
gcloud dns record-sets create "*.run.app." \
--zone=priv-zone-run \
--type=A \
--ttl=300 \
--rrdatas=${PSC_EP_IP}
Utwórz zasadę Cloud DNS, aby włączyć logowanie zapytań DNS. Logowanie DNS rejestruje żądania rozpoznawania domen pochodzące z bramy agentów w sieci VPC, co zapewnia możliwość audytu i weryfikacji, czy żądania narzędzia *.run.app są prawidłowo rozpoznawane w wewnętrznym punkcie końcowym PSC:
# create dns policy (logging)
gcloud dns policies create dns-policy-${SLUG} \
--description="dns logging for vnet-${SLUG}" \
--networks=vnet-${SLUG} \
--enable-logging
To wszystko, jeśli chodzi o sieć. Przejdźmy teraz do sekcji Brama agenta.
5. Brama agentów
Brama agenta określa registries dla instancji rejestru agentów wraz z polami networkConfig, które konfigurują przyłącze sieci PSC i ustawienia połączenia równorzędnego DNS na potrzeby prywatnego połączenia VPC:
registries: łączy bramę z maksymalnie 2 instancjami Agent Registry: jedną regionalną (../locations/${REGION}) i jedną globalną (../locations/global). Integruje to Bramę agentów z Agent Registry, aby rozwiązywać zarówno wdrożenia regionalne (np. serwery MCP Cloud Run w${REGION}), jak i zasoby globalne (np. agenty Gemini Enterprise i globalne punkty końcowe) na potrzeby szczegółowego egzekwowania zasad IAP w wersji 2. Podczas rozwiązywania adresów URL miejsc docelowych wpisy regionalne mają pierwszeństwo przed wpisami globalnymi.networkAttachment: wskazuje przyłącze sieci PSC (psc-na-${REGION}-agw), które łączy bramę agenta z Twoją siecią VPC na potrzeby prywatnego ruchu wychodzącego.dnsPeeringConfig.domains: konfigurujerun.app.tak, aby zapytania DNS pochodzące z bramy agenta dla usług Cloud Run korzystały z połączenia równorzędnego DNS w celu rozpoznawania nazw hostów na adres IP punktu końcowego PSC prywatnych interfejsów API Google (172.16.20.20) skonfigurowanego w prywatnej strefie Cloud DNS.
Wdrażanie bramy agentów
Utwórz i zaimportuj plik konfiguracji bramy agentów.
# create agent gateway config file
cat > cfg/${AGW_NAME}-networkConfig.yaml << EOF
name: ${AGW_NAME}
protocols:
- MCP
googleManaged:
governedAccessPath: AGENT_TO_ANYWHERE
registries:
- "//agentregistry.googleapis.com/projects/${PROJ_ID}/locations/${REGION}"
networkConfig:
egress:
networkAttachment: ${PSC_NA_URI}
dnsPeeringConfig:
domains:
- run.app.
targetProject: ${PROJ_ID}
targetNetwork: projects/${PROJ_ID}/global/networks/vnet-${SLUG}
EOF
# import agent gateway config file (create gateway)
gcloud network-services agent-gateways import ${AGW_NAME} \
--source="cfg/${AGW_NAME}-networkConfig.yaml" \
--location=${REGION}
Sprawdzanie wdrożenia bramy agentów
Potwierdź Agent Registry i konfigurację sieci:
# show agent gateway registries and network config
gcloud network-services agent-gateways describe ${AGW_NAME} \
--location=${REGION} \
--format="yaml(registries,networkConfig)"
Oczekiwane dane wyjściowe:
networkConfig:
dnsPeeringConfig:
domains:
- run.app.
targetNetwork: projects/${PROJ_ID}/global/networks/vnet-${SLUG}
targetProject: ${PROJ_ID}
egress:
networkAttachment: projects/${PROJ_ID}/regions/${REGION}/networkAttachments/psc-na-${REGION}-agw
registries:
- //agentregistry.googleapis.com/projects/${PROJ_ID}/locations/${REGION}
Sprawdź, czy w danych wyjściowych wyświetlają się wymagane szczegóły konfiguracji:
registries: zawiera listę regionalnych (${REGION}) identyfikatorów URI Agent Registry powiązanych z bramą.egress.networkAttachment: określa identyfikator URI przyłącza sieci PSC dla ruchu wychodzącego z sieci VPC.dnsPeeringConfig.domains: zawierarun.app.wskazującytargetNetworkna potrzeby rozpoznawania domeny prywatnej.
Sprawdź przyłącze sieci PSC, aby potwierdzić połączenie z bramą:
# show psc network attachment details
gcloud compute network-attachments describe psc-na-${REGION}-agw \
--region=${REGION} \
--format="yaml(connectionEndpoints)"
Sprawdź, czy istnieje zaakceptowany punkt końcowy połączenia:
connectionEndpoints:
- ipAddress: 192.168.10.2
projectIdOrNum: '<AGW_TENANT_PROJ_NO>'
status: ACCEPTED
subnetwork: https://www.googleapis.com/compute/v1/projects/${PROJ_ID}/regions/${REGION}/subnetworks/subnet-${REGION}-agw
Przekazywanie autoryzacji
Brama agentów zabezpiecza i kontroluje ruch wychodzący narzędzi za pomocą zasad autoryzacji (networksecurity.authzPolicies) zintegrowanych z ujednoliconymi zasadami dostępu (UAP) Identity-Aware Proxy (IAP).
Brama agentów obsługuje podstawowe reguły wbudowane ALLOW i DENY, ale środowiska firmowe wymagają scentralizowanego zarządzania opartego na tożsamości. W przypadku ujednoliconych zasad dostępu IAM (lub zasad dostępu) regułami dostępu wychodzącego zarządzasz za pomocą standardowych zasad dostępu IAM w wersji 3.
Ilustracja 3. Architektura autoryzacji
Proces autoryzacji łączy 3 komponenty:
- Zasady autoryzacji bramy (
authzPolicy):- Zasób regionalny kierowany na bramę agenta.
- Skonfigurowano za pomocą
policyProfile: REQUEST_AUTHZiaction: CUSTOM, aby kierować wszystkie wychodzące sprawdzania autoryzacji do rozszerzenia autoryzacji IAP.
- Rozszerzenie usługi IAP (
authzExtension):- Zasób regionalny, który deleguje autoryzację żądań do Identity-Aware Proxy (
iap.googleapis.com). - Ocenia zasady w trybie
ENFORCE, używając wersji zasadV2.
- Zasób regionalny, który deleguje autoryzację żądań do Identity-Aware Proxy (
- Ujednolicone zasady dostępu i powiązania IAM (
accessPolicyipolicyBinding):- Zasoby globalnych uprawnień w wersji 3 zawierające szczegółowe reguły dostępu.
- Uwierzytelnia tożsamość podmiotu SPIFFE wywołującego agenta, weryfikuje uniwersalne uprawnienie
iap.googleapis.com/resources.egressViaIAPi ocenia warunki języka CEL (Common Expression Language) na podstawie atrybutów miejsca docelowego.
Wdrażanie rozszerzenia autoryzacji
Utwórz konfigurację rozszerzenia autoryzacji service-extensions, która przekazuje decyzje o autoryzacji do usługi IAP:
# create authz extension config file
cat > cfg/${AGW_NAME}-svc-ext-authz-iap.yaml << EOF
name: ${AGW_NAME}-svc-ext-authz-iap
service: iap.googleapis.com
failOpen: false
timeout: 1s
metadata:
iapPolicyVersion: "V2"
EOF
# import iap authz extension (create authz extension)
gcloud service-extensions authz-extensions import ${AGW_NAME}-svc-ext-authz-iap \
--source=cfg/${AGW_NAME}-svc-ext-authz-iap.yaml \
--location=${REGION}
Weryfikacja przedłużenia autoryzacji
Sprawdź, czy rozszerzenie autoryzacji jest aktywne:
# list authz extensions
gcloud service-extensions authz-extensions list \
--location=${REGION} \
--format="table(
name.basename():label=NAME,
createTime.date(tz=LOCAL):label=CREATED,
updateTime.date(tz=LOCAL):label=MODIFIED,
service:label=SERVICE,
metadata:label=METADATA,
timeout:label=TIMEOUT
)"
Wdrażanie zasady autoryzacji
Utwórz konfigurację zasady autoryzacji network-security, która jest kierowana na bramę agentów i przekazuje weryfikację żądań do rozszerzenia autoryzacji dla IAP:
# create authz policy config file
cat > cfg/${AGW_NAME}-authz-policy-iap.yaml << EOF
name: ${AGW_NAME}-authz-policy-iap
target:
resources:
- "projects/${PROJ_ID}/locations/${REGION}/agentGateways/${AGW_NAME}"
policyProfile: REQUEST_AUTHZ
action: CUSTOM
customProvider:
authzExtension:
resources:
- "projects/${PROJ_ID}/locations/${REGION}/authzExtensions/${AGW_NAME}-svc-ext-authz-iap"
EOF
# import authz policy config file (create authz policy)
gcloud network-security authz-policies import ${AGW_NAME}-authz-policy-iap \
--source=cfg/${AGW_NAME}-authz-policy-iap.yaml \
--location=${REGION}
Sprawdzanie zasad autoryzacji
Sprawdź, czy zasady autoryzacji są aktywne:
# list authz policies
gcloud network-security authz-policies list \
--location=${REGION} \
--format="table(
name.basename():label=NAME,
action:label=ACTION,
customProvider.list().sub('\W.*', ''):label=CUSTOM_PROVIDER_TYPE,
policyProfile:label=POLICY_PROFILE,
customProvider.authzExtension.resources[0].basename():label=CUSTOM_PROVIDER_RESOURCE
)"
Tworzenie zasad dostępu uprawnień
Brama agentów deleguje teraz sprawdzanie autoryzacji do IAP i rozwiązuje metadane miejsca docelowego z Agent Registry. Następnie zdefiniuj regułę ujednoliconych zasad dostępu IAM, która będzie regulować wykonywanie narzędzi wychodzących.
Usługa IAP ocenia wyrażenia atrybutów CEL na podstawie tych atrybutów docelowych Agent Registry:
- Stan rejestracji (
destination.is_registered):- Wartość logiczna (
true/false) wskazująca, czy miejsce docelowe jest skatalogowane w Agent Registry.
- Wartość logiczna (
- Nazwa serwera MCP (
destination.agent_registry.mcp_server.name):- Kanoniczna nazwa zasobu serwera MCP zarejestrowana w Agent Registry.
- Metoda MCP (
destination.agent_registry.mcp_server.method):- Wywoływana metoda MCP (np.
tools/call,tools/list,initialize).
- Wywoływana metoda MCP (np.
- Nazwa narzędzia
destination.agent_registry.mcp_server.tool.name:- Nazwa wywołanego narzędzia (np.
subtractlubadd), która umożliwia precyzyjną autoryzację na poziomie narzędzia na zarejestrowanych serwerach MCP.
- Nazwa wywołanego narzędzia (np.
Definiowanie reguły zasady dostępu uprawnień
Manifest reguły zasady uprawnień określa:
- Podmioty: tożsamość podmiotu SPIFFE reprezentująca agenta głównego asystenta Gemini Enterprise.
- Uprawnienia: uniwersalne uprawnienie
iap.googleapis.com/resources.egressViaIAPwymagane w przypadku całego ruchu wychodzącego objętego ochroną IAP. - Warunki: wyrażenie CEL (
destination.is_registered == true), które zapewnia, że agent może wywoływać tylko punkty końcowe skatalogowane w Agent Registry.
Utwórz plik manifestu reguły zasady:
# create access policy rule file
cat > cfg/${UAP_POLICY_NAME}-rules.json << EOF
[
{
"description": "allow ge assistant to any registered service",
"effect": "ALLOW",
"principals": [
"principal://${TRUST_DOMAIN}/resources/discoveryengine/projects/${PROJ_NO}/locations/global/engines/${GE_APP_INIT}/assistants/default_assistant/agents/default/core_assistant"
],
"operation": {
"permissions": [
"iap.googleapis.com/resources.egressViaIAP"
]
},
"conditions": {
"iap.googleapis.com": {
"expression": \
"destination.is_registered == true"
}
}
}
]
EOF
Wdrażanie zasady dostępu uprawnień
Utwórz globalną zasadę dostępu uprawnień, korzystając z reguł zdefiniowanych w pliku manifestu:
# create iam access policy
gcloud iam access-policies create ${UAP_POLICY_NAME} \
--details-rules=cfg/${UAP_POLICY_NAME}-rules.json \
--project=${PROJ_ID} \
--location=global
Sprawdzanie zasady dostępu uprawnień
Sprawdź, czy zasada dostępu IAM została utworzona, i zbadaj szczegóły reguły:
# show iam access policy details
gcloud iam access-policies describe ${UAP_POLICY_NAME} \
--project=${PROJ_ID} \
--location=global
Oczekiwane dane wyjściowe:
details:
rules:
- conditions:
iap.googleapis.com:
expression: destination.is_registered == true
description: allow ge assistant to any registered service
effect: ALLOW
operation:
permissions:
- iap.googleapis.com/resources.egressViaIAP
principals:
- principal://agents.global.org-${ORG_ID}.system.id.goog/resources/discoveryengine/projects/${PROJ_NO}/locations/global/engines/${GE_APP_INIT}/assistants/default_assistant/agents/default/core_assistant
name: projects/${PROJ_ID}/locations/global/accessPolicies/${UAP_POLICY_NAME}
Powiązywanie zasady dostępu uprawnień z projektem
Aby aktywować egzekwowanie we wszystkich bramach agentów w projekcie, utwórz powiązanie zasad, które dołącza zasady dostępu IAM do zasobu projektu:
# bind iam access policy to project resource
gcloud iam policy-bindings create ${UAP_BINDING_NAME} \
--policy="projects/${PROJ_ID}/locations/global/accessPolicies/${UAP_POLICY_NAME}" \
--target-resource="//cloudresourcemanager.googleapis.com/projects/${PROJ_ID}" \
--project=${PROJ_ID} \
--location=global
Sprawdzanie powiązania zasady dostępu uprawnień
Sprawdź, czy aktywne punkty wiązania zasad są powiązane z odpowiednimi zasadami i celem:
# show policy binding details
gcloud iam policy-bindings describe ${UAP_BINDING_NAME} \
--project=${PROJ_ID} \
--location=global
Oczekiwane dane wyjściowe:
name: projects/${PROJ_ID}/locations/global/policyBindings/${UAP_BINDING_NAME}
policy: projects/${PROJ_ID}/locations/global/accessPolicies/${UAP_POLICY_NAME}
policyKind: ACCESS
target:
resource: //cloudresourcemanager.googleapis.com/projects/${PROJ_ID}
To wszystko, jeśli chodzi o bramę agenta. Przejdźmy teraz do sekcji poświęconej serwerowi MCP.
6. Serwer MCP
W tej sekcji utworzysz niestandardowy serwer FastMCP udostępniający narzędzia add i subtract, a następnie wdrożysz go w Cloud Run bezpośrednio z kodu źródłowego. Podczas wdrażania źródła (--source) Cloud Build spakuje obraz kontenera za pomocą dołączonych plików Dockerfile i uv (które instalują zależności zdefiniowane w pyproject.toml i uruchamiają server.py).
Po wdrożeniu usługi Cloud Run zarejestruj serwer MCP w Agent Registry wraz ze specyfikacją narzędzia (toolspec.json), aby Gemini Enterprise mogła wykrywać i wywoływać jego narzędzia.
Tworzenie aplikacji serwera MCP
Utwórz math-wizard katalog projektu dla kodu aplikacji:
# create directory for code
mkdir -p math-wizard
Napisz plik manifestu projektu w Pythonie:
# create python project manifest file
cat > math-wizard/pyproject.toml << 'EOF'
[project]
name = "math-wizard"
version = "0.1.0"
description = "math wizard mcp server"
requires-python = ">=3.12"
dependencies = [
"fastmcp==2.13.1",
]
EOF
Kod zawiera dodatkowe funkcje instrumentacji, które rejestrują przychodzące nagłówki HTTP (mcp-session-id, x-forwarded-for, user-agent i x-cloud-trace-context) na potrzeby weryfikacji Cloud Logging i Cloud Trace.
Utwórz plik kodu aplikacji:
# create mcp server application code
cat > math-wizard/server.py << 'EOF'
import asyncio
import json
import logging
import os
from fastmcp import FastMCP
from fastmcp.server.dependencies import get_http_headers
from mcp.types import ToolAnnotations
logger = logging.getLogger(__name__)
logging.basicConfig(format="[%(levelname)s]: %(message)s", level=logging.INFO)
mcp = FastMCP("math wizard mcp server")
def log_network_context(tool_name: str, a: int, b: int) -> None:
headers = get_http_headers()
print(json.dumps({
"severity": "INFO",
"message": f">>> 🛠️ Tool: '{tool_name}' called with numbers '{a}' and '{b}'",
"tool": tool_name,
"mcp_session_id": headers.get("mcp-session-id"),
"x_forwarded_for": headers.get("x-forwarded-for"),
"user_agent": headers.get("user-agent"),
"trace_header": headers.get("x-cloud-trace-context"),
}), flush=True)
@mcp.tool(
annotations=ToolAnnotations(
readOnlyHint=True,
)
)
def add(a: int, b: int) -> int:
"""Use this to add two numbers together.
Args:
a: The first number.
b: The second number.
Returns:
The sum of the two numbers.
"""
logger.info(f">>> 🛠️ Tool: 'add' called with numbers '{a}' and '{b}'")
log_network_context("add", a, b)
return a + b
@mcp.tool(
annotations=ToolAnnotations(
readOnlyHint=True,
)
)
def subtract(a: int, b: int) -> int:
"""Use this to subtract two numbers.
Args:
a: The first number.
b: The second number.
Returns:
The difference of the two numbers.
"""
logger.info(f">>> 🛠️ Tool: 'subtract' called with numbers '{a}' and '{b}'")
log_network_context("subtract", a, b)
return a - b
if __name__ == "__main__":
logger.info(f"🚀 MCP server started on port {os.getenv('PORT', 8080)}")
asyncio.run(
mcp.run_async(
transport="streamable-http",
host="0.0.0.0",
port=int(os.getenv("PORT", 8080)),
)
)
EOF
Napisz plik Dockerfile, aby zdefiniować instrukcje kompilacji obrazu kontenera i polecenia uruchamiania:
# create dockerfile
cat > math-wizard/Dockerfile << 'EOF'
# use official python 3.12 image
FROM python:3.12-slim
# install uv
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
# install the project into /app
COPY . /app
WORKDIR /app
# allow statements and log messages to immediately appear in the logs
ENV PYTHONUNBUFFERED=1
# install dependencies
RUN uv sync
EXPOSE 8080
# run the mcp server
CMD ["uv", "run", "server.py"]
EOF
Wdrażanie usługi w Cloud Run
Wdróż serwer MCP ze źródła za pomocą Cloud Build (która używa domyślnego konta usługi Compute w projekcie ${PROJ_NO}-compute@developer.gserviceaccount.com):
# deploy cloud run service
gcloud run deploy ${MCP_NAME} \
--source math-wizard \
--region=${REGION} \
--no-invoker-iam-check \
--ingress=internal \
--quiet
Sprawdzanie wdrożenia Cloud Run
Sprawdź szczegóły usługi Cloud Run, aby zweryfikować jej aktywną konfigurację:
# show cloud run service details
gcloud run services describe ${MCP_NAME} --region=${REGION}
Oczekiwane dane wyjściowe:
<snip>
✔ Service math-wizard in region ${REGION}
URL: https://math-wizard-${PROJ_NO}.${REGION}.run.app
Ingress: internal
Traffic:
100% LATEST (currently math-wizard-00001-<id>)
</snip>
Rejestrowanie serwera MCP w Agent Registry
Aby Gemini Enterprise mogło wykryć dokładne narzędzia dostępne na serwerze MCP, podczas rejestracji w Agent Registry należy podać plik specyfikacji narzędzi (toolspec.json).
Tworzenie specyfikacji narzędzia MCP
# create tool spec file
cat > cfg/toolspec.json << 'EOF'
{
"tools": [
{
"name": "add",
"description": "Use this to add two numbers together.",
"inputSchema": {
"type": "object",
"properties": {
"a": { "type": "integer", "description": "The first number." },
"b": { "type": "integer", "description": "The second number." }
},
"required": ["a", "b"]
},
"isReadOnly": true,
"isDestructive": false,
"isIdempotent": true,
"isOpenWorld": false
},
{
"name": "subtract",
"description": "Use this to subtract two numbers.",
"inputSchema": {
"type": "object",
"properties": {
"a": { "type": "integer", "description": "The first number." },
"b": { "type": "integer", "description": "The second number." }
},
"required": ["a", "b"]
},
"isReadOnly": true,
"isDestructive": false,
"isIdempotent": true,
"isOpenWorld": false
}
]
}
EOF
Rejestrowanie serwera MCP w Agent Registry
# register mcp server in agent registry
gcloud agent-registry services create ${MCP_NAME} \
--project=${PROJ_ID} \
--location=${REGION} \
--display-name="${MCP_NAME}-${PROJ_NO}.${REGION}.run.app" \
--description="MANDATORY MATH & ARITHMETIC AGENT: You MUST ALWAYS invoke \
this tool for ANY mathematical calculation, addition (+), subtraction (-), \
sum, difference, or arithmetic question (including simple questions like \
'what is 67 + 345?'). NEVER compute arithmetic yourself and NEVER transfer \
math queries to file_and_coding_agent / code interpreter. Always delegate \
every math question to this tool." \
--mcp-server-spec-type=tool-spec \
--mcp-server-spec-content=cfg/toolspec.json \
--interfaces=protocolBinding=JSONRPC,url="${MCP_URL}"
Weryfikowanie serwera MCP w rejestrze agentów
Sprawdź, czy wdrożona usługa Cloud Run jest wymieniona jako zarejestrowany serwer MCP w regionie wraz z adresem URL punktu końcowego i dostępnymi narzędziami:
# list registered mcp servers in agent registry
gcloud agent-registry mcp-servers list \
--location=${REGION} \
--project=${PROJ_ID} \
--format="table(
name.basename():label=REGISTRY_ID,
displayName:label=DISPLAY_NAME,
interfaces[0].url:label=ENDPOINT_URL,
tools[].name.list():label=TOOLS
)"
Oczekiwane dane wyjściowe:
REGISTRY_ID DISPLAY_NAME ENDPOINT_URL TOOLS
agentregistry-00000000-0000-0000-0012-3456789abcde math-wizard-${PROJ_NO}.${REGION}.run.app https://math-wizard-${PROJ_NO}.${REGION}.run.app/mcp add,subtract
Wyświetl specyfikację konfiguracji usługi, aby sprawdzić, czy rejestruje ona dokładne definicje narzędzi, schematy wejściowe i adnotacje dotyczące działania każdego narzędzia:
# describe mcp server tool specs
gcloud agent-registry services describe ${MCP_NAME} \
--location=${REGION} \
--project=${PROJ_ID} \
--format="yaml(mcpServerSpec.content.tools)"
To wszystko, jeśli chodzi o serwer MCP. Przejdźmy teraz do sekcji Gemini Enterprise.
7. Gemini Enterprise
W tej sekcji utworzysz i skonfigurujesz aplikację Gemini Enterprise oraz połączony z nią zasób niestandardowego magazynu danych serwera MCP.
Model zasobów Discovery Engine
Aplikacja Gemini Enterprise (reprezentowana jako zasób Engine w interfejsie Discovery Engine API) to centralna warstwa orkiestracji i interfejs konwersacyjny dla użytkowników. Zarządza sesjami czatu użytkowników, opiera modele generatywne na danych przedsiębiorstwa i koordynuje dynamiczne wykonywanie narzędzi.
Aplikacje Gemini Enterprise wchodzą w interakcje z danymi i systemami za pomocą magazynów danych:
- Magazyny danych wiedzy: pozyskiwanie i indeksowanie treści statycznych (np. Cloud Storage, Dysk Google, BigQuery) na potrzeby generowania wspomaganego wyszukiwaniem (RAG).
- Łączniki danych (dostawcy działań): łączą się z dynamicznymi interfejsami API innych firm lub interfejsami niestandardowymi. Niestandardowy magazyn danych serwera MCP udostępnia narzędzia zdefiniowane przez protokół Model Context Protocol (MCP), co umożliwia modelowi dynamiczne wywoływanie funkcji zewnętrznych podczas rozmowy.
Routing ruchu wychodzącego przez bramę agenta
Domyślnie Gemini Enterprise kieruje ruch związany z wykonywaniem łączników i narzędzi przez sieci publiczne. W przypadku prywatnych zadań VPC i zarządzania opartego na zasadzie zerowego zaufania silnik można skonfigurować tak, aby kierował ruch wychodzący przez bramę agenta:
- Podczas tworzenia niestandardowego magazynu danych serwera MCP w dalszej części tego laboratorium włączysz w ustawieniach magazynu danych opcję Kieruj ruch wychodzący przez bramę agenta.
- Powoduje to powiązanie wychodzących wywołań narzędzi silnika z regionalną bramą agenta, dzięki czemu wszystkie żądania MCP zawierają
Agent Identityaplikacji, podlegają autoryzacji w czasie działania przy użyciu ujednoliconych zasad dostępu IAP i IAM oraz przechodzą przez przyłącze sieci PSC do Twojego prywatnego środowiska VPC.
Tworzenie aplikacji Gemini Enterprise
Poniższa metoda korzysta z interfejsu discoveryengine.googleapis.com API do tworzenia zasobów i konfiguracji aplikacji Gemini Enterprise. Instrukcje dotyczące konfiguracji za pomocą interfejsu konsoli Google Cloud znajdziesz w sekcji Tworzenie aplikacji.
# create engine (ge app)
curl -s -X POST "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines?engineId=${GE_APP_INIT}" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "X-Goog-User-Project: ${PROJ_ID}" -H "Content-Type: application/json" \
-d @- <<EOF
{
"displayName": "${GE_APP_DISPLAY_NAME}",
"dataStoreIds": [],
"solutionType": "SOLUTION_TYPE_SEARCH",
"industryVertical": "GENERIC",
"appType": "APP_TYPE_INTRANET",
"searchEngineConfig": {
"searchTier": "SEARCH_TIER_ENTERPRISE",
"searchAddOns": [
"SEARCH_ADD_ON_LLM"
]
},
"commonConfig": {
"companyName": "${GE_APP_ORG_NAME}"
}
}
EOF
Weryfikowanie utworzenia aplikacji
# fetch engine (ge app) id
export GE_APP_ID=$(curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" -H "X-Goog-User-Project: ${PROJ_ID}" \
| jq -r --arg name "${GE_APP_DISPLAY_NAME}" '.engines[] | select(.displayName==$name) | .name | split("/") | last')
echo "engine (ge app) id: ${GE_APP_ID}"
Wyświetl szczegóły silnika, aby zobaczyć utworzoną konfigurację:
# get engine (ge app) details
curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines/${GE_APP_ID}" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "X-Goog-User-Project: ${PROJ_ID}"
Zwróć uwagę na te właściwości w odpowiedzi JSON, które są wypełniane przez serwer:
name: kanoniczna ścieżka zasobu (projects/${PROJ_NO}/locations/global/collections/default_collection/engines/${GE_APP_ID}).sessionConfig.sessionManagementPolicy: domyślnie"VERTEX_AI_MANAGED", co powoduje, że stan czatu wieloetapowego i wywołań narzędzi jest zachowywany na Agent Platform (wcześniej znanej jako Vertex AI).observabilityConfig.observabilityEnabled: domyślnietruew przypadku danych podstawowych (szczegółowe rejestrowanie promptów i ładunków narzędzi zostanie włączone w późniejszym kroku).
Włączanie dostawcy tożsamości
Włącz Google Identity jako dostawcę tożsamości do uwierzytelniania użytkowników w aplikacji Gemini Enterprise.
Poniższa metoda korzysta z interfejsu discoveryengine.googleapis.com API do konfigurowania dostawcy tożsamości aplikacji Gemini Enterprise. Instrukcje dotyczące konfiguracji za pomocą interfejsu konsoli Google Cloud znajdziesz w sekcji Konfigurowanie dostawcy tożsamości.
# set identity provider
curl -s -X PATCH "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/aclConfig" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "X-Goog-User-Project: ${PROJ_ID}" -H "Content-Type: application/json" \
-d @- <<EOF
{
"idpConfig": {
"idpType": "GSUITE"
}
}
EOF
Weryfikowanie dostawcy tożsamości
# show identity provider
curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/aclConfig" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "X-Goog-User-Project: ${PROJ_ID}"
Dane wyjściowe "idpType": "GSUITE" odpowiadają dostawcy tożsamości Google.
Włączanie licencji próbnej Gemini Enterprise (opcjonalnie)
Jeśli używasz projektu, do którego przypisane są licencje Gemini Enterprise, możesz pominąć ten krok. Jeśli używasz nowego projektu bez licencji, przejdź dalej i wykonaj te czynności.
Utwórz zasób konfiguracji licencji, aby przyznać użytkownikom Gemini Enterprise licencje na 30 dni. Spowoduje to ustawienie nowej wersji próbnej jako domyślnej licencji, dzięki czemu każdy użytkownik logujący się na konto automatycznie otrzyma miejsce:
# configure free trial subscription
curl -s -X POST "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/licenseConfigs?licenseConfigId=free_trial_gemini" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "X-Goog-User-Project: ${PROJ_ID}" -H "Content-Type: application/json" \
-d @- <<EOF
{
"subscriptionTier": "SUBSCRIPTION_TIER_SEARCH_AND_ASSISTANT",
"freeTrial": true
}
EOF
Sprawdzanie, czy licencja została zastosowana
# show license config
curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/licenseConfigs/free_trial_gemini" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "X-Goog-User-Project: ${PROJ_ID}"
Sprawdź "subscriptionTerm": "SUBSCRIPTION_TERM_ONE_MONTH" i "freeTrial": true.
# verify auto-registration enabled on default user store
curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/userStores/default_user_store" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "X-Goog-User-Project: ${PROJ_ID}"
Sprawdź ../free_trial_gemini" i "enableLicenseAutoRegister": true.
Włączanie ustawień dostrzegalności
Włączenie obserwacji na poziomie aplikacji (silnika) Gemini Enterprise umożliwia wyświetlanie interakcji podstawowego asystenta z danymi o wartościach w Eksploratorze wartości oraz korelowanie kompleksowych śladów w Cloud Trace.
# set observability on engine (ge app)
curl -s -X PATCH "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines/${GE_APP_ID}?updateMask=observabilityConfig" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "X-Goog-User-Project: ${PROJ_ID}" -H "Content-Type: application/json" \
-d @- <<EOF
{
"observabilityConfig": {
"observabilityEnabled": true,
"sensitiveLoggingEnabled": true
}
}
EOF
Sprawdzanie ustawień dostrzegalności
# verify observability is enabled on engine (ge app)
curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines/${GE_APP_ID}" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "X-Goog-User-Project: ${PROJ_ID}" \
| jq '{observabilityConfig: .observabilityConfig}'
Sprawdź, czy jest "sensitiveLoggingEnabled": true.
Wiązanie z bramą agenta
Kierowanie ruchu wychodzącego z Gemini Enterprise przez Bramę agentów tworzy scentralizowaną granicę zarządzania i zabezpieczeń opartą na zasadzie zerowego zaufania dla wszystkich wywołań narzędzi agentów AI:
- Centralne egzekwowanie zasad: brama agentów działa jako wbudowany serwer proxy, który ocenia wychodzące żądania narzędzi pod kątem zasad autoryzacji i kontroli zarządzania, zanim ruch opuści środowisko agenta.
- Ruch wychodzący z sieci prywatnej: powiązanie Gemini Enterprise z Bramą agentów zapewnia, że wywołania narzędzi kierowane do prywatnych serwerów MCP w Cloud Run są bezpiecznie kierowane przez Private Service Connect (PSC), z pominięciem internetu publicznego.
- Ujednolicona możliwość kontroli: zapewnia scentralizowane rejestrowanie żądań, telemetrię i ścieżki audytu na wszystkich połączonych serwerach MCP i narzędziach zewnętrznych.
Konfigurując agentGatewaySetting w aplikacji Gemini Enterprise, możesz automatycznie kierować wychodzące wywołania narzędzi i agentów inicjowane przez zapytania użytkowników (np. wywołania niestandardowych serwerów MCP importowanych z Agent Registry i agentów A2A) przez bramę agentów.
Zastosuj poprawkę do silnika agentGatewaySetting, aby włączyć:
# bind engine (ge app) to agent gateway
curl -s -X PATCH "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines/${GE_APP_ID}?updateMask=agentGatewaySetting.defaultEgressAgentGateway.name" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "X-Goog-User-Project: ${PROJ_ID}" -H "Content-Type: application/json" \
-d @- <<EOF
{
"agentGatewaySetting": {
"defaultEgressAgentGateway": {
"name": "projects/${PROJ_ID}/locations/${REGION}/agentGateways/${AGW_NAME}"
}
}
}
EOF
Sprawdzanie powiązania bramy agenta
Pobierz konfigurację aplikacji, aby potwierdzić powiązanie agentGatewaySetting:
# verify engine (ge app) agent gateway configuration
curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines/${GE_APP_ID}" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "X-Goog-User-Project: ${PROJ_ID}" \
| jq '{name: .name, displayName: .displayName, agentGatewaySetting: .agentGatewaySetting}'
Oczekiwane dane wyjściowe:
{
"name": "projects/${PROJ_NO}/locations/${GE_LOCATION}/collections/default_collection/engines/${GE_APP_ID}",
"displayName": "${GE_APP_DISPLAY_NAME}",
"agentGatewaySetting": {
"defaultEgressAgentGateway": {
"name": "projects/${PROJ_ID}/locations/${REGION}/agentGateways/${AGW_NAME}"
}
}
}
Tworzenie magazynu danych niestandardowego serwera MCP
W tej sekcji połączysz serwer MCP z Gemini Enterprise, tworząc niestandardowy magazyn danych MCP.
W przypadku interfejsu Discovery Engine API jest to proces dwuetapowy:
- Utwórz (
:setUpDataConnector): tworzy dedykowany zasóbCollection(${MCP_NAME}-%timestamp-collection), dołączaDataConnector(custom_mcp) i udostępnia jego zasóbDataStore(..._mcp_data). - Aktywuj
PATCH .../dataConnector?updateMask=actionConfig: aktywuje środowisko wykonawcze działania konektora (actionState: "ACTIVE") przy użyciu specyfikacji narzędzia Agent Registry i wiążeDataStore(dataStoreIds) z Twoją usługą Gemini EnterpriseEngine.
# fetch mcp server agent registry resource name
export MCP_REGISTRY_URI=$(gcloud agent-registry mcp-servers list \
--location=${REGION} \
--project=${PROJ_ID} \
--filter="displayName:${MCP_NAME}" \
--format="value(name)")
echo "mcp registry name: ${MCP_REGISTRY_URI}"
echo "mcp url: ${MCP_URL}"
Tworzenie łącznika danych
# create custom mcp data connector from agent registry and link to engine
curl -s -X POST "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1alpha/projects/${PROJ_ID}/locations/${GE_LOCATION}:setUpDataConnector" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "X-Goog-User-Project: ${PROJ_ID}" \
-H "Content-Type: application/json" \
-d @- <<EOF
{
"collectionId": "${MCP_NAME}-$(date +%s)-collection",
"collectionDisplayName": "${MCP_NAME}-collection",
"dataConnector": {
"dataSource": "custom_mcp",
"dataSourceVersion": 1,
"params": {
"oauth_access_token": "unused"
},
"refreshInterval": "86400s",
"entities": [
{
"entityName": "mcp_data"
}
],
"connectorModes": [
"FEDERATED"
],
"actionConfig": {
"isActionConfigured": true,
"createBapConnection": true,
"actionParams": {
"auth_type": "NO_AUTH",
"instance_uri": "${MCP_URL}",
"mcp_server_source": "REGISTRY_MCP",
"registry_mcp_server_name": "${MCP_REGISTRY_URI}",
"mcp_agent_instructions": "MANDATORY MATH & ARITHMETIC AGENT: Always invoke this tool for any mathematical calculation, addition (+), subtraction (-), sum, or difference.",
"use_agent_gateway_egress": true,
"agent_gateway_engine": "projects/${PROJ_ID}/locations/global/collections/default_collection/engines/${GE_APP_ID}"
}
}
}
}
EOF
Weryfikowanie utworzenia łącznika danych
# fetch collection id
export GE_COLLECTION_ID=$(curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1alpha/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "X-Goog-User-Project: ${PROJ_ID}" \
| jq -r --arg dname "${MCP_NAME}-collection" '.collections[] | select(.displayName == $dname) | .name | split("/") | last' | head -n 1)
echo "ge collection id: ${GE_COLLECTION_ID}"
Sprawdź, czy pole "registry_mcp_server_name" jest wypełnione identyfikatorem UUID Agent Registry dla serwera MCP:
# show data connector details
curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1alpha/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/${GE_COLLECTION_ID}/dataConnector" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "X-Goog-User-Project: ${PROJ_ID}" \
| jq '{name, state, actionState, connectorModes, bapConfig, registry_mcp_server_name: .actionConfig.actionParams.registry_mcp_server_name}'
Wyświetl wpis rejestru serwera MCP w interfejsie konsoli Google Cloud:
echo "mcp server registry page url: https://console.cloud.google.com/agent-platform/agent-registry/mcp-servers/${REGION}/${MCP_REGISTRY_URI##*/}/overview?project=${PROJ_ID}"
Aktywowanie łącznika danych
# activate and bind data connector
curl -s -X PATCH "https://discoveryengine.googleapis.com/v1alpha/projects/${PROJ_ID}/locations/global/collections/${GE_COLLECTION_ID}/dataConnector?updateMask=actionConfig" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "X-Goog-User-Project: ${PROJ_ID}" \
-H "Content-Type: application/json" \
-d @- <<EOF
{
"name": "projects/${PROJ_ID}/locations/global/collections/${GE_COLLECTION_ID}/dataConnector",
"actionConfig": {
"isActionConfigured": true,
"createBapConnection": true,
"actionParams": {
"auth_type": "NO_AUTH",
"instance_uri": "${MCP_URL}",
"mcp_server_source": "REGISTRY_MCP",
"registry_mcp_server_name": "${MCP_REGISTRY_URI}",
"mcp_agent_instructions": "MANDATORY MATH & ARITHMETIC AGENT: Always invoke this tool for any mathematical calculation, addition (+), subtraction (-), sum, or difference.",
"use_agent_gateway_egress": true,
"agent_gateway_engine": "projects/${PROJ_ID}/locations/global/collections/default_collection/engines/${GE_APP_ID}"
}
}
}
EOF
Weryfikowanie połączeń z niestandardowym serwerem MCP
# show engine (ge app) details
curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines/${GE_APP_ID}" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "X-Goog-User-Project: ${PROJ_ID}" \
| jq '{name: .name, dataStoreIds: .dataStoreIds, agentGatewaySetting: .agentGatewaySetting}'
Sprawdź, czy połączony magazyn danych "dataStoreIds": "collection-math-wizard- jest widoczny.
# show collection details
curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1alpha/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "X-Goog-User-Project: ${PROJ_ID}" \
| jq --arg app "${GE_APP_ID}" '.collections[] | select(.dataConnector.actionConfig.actionParams.agent_gateway_engine // "" | endswith($app)) | .dataConnector | {name: .name, state: .state, actionState: .actionState, connectorModes: .connectorModes, actionParams: .actionConfig.actionParams}'
Sprawdź, czy w przypadku parametru "state": "ACTIVE" wszystkie pola są wypełnione.
Operacje na narzędziu
Gdy sprawdzisz magazyn danych math-wizard-collection na panelu Gemini Enterprise, zauważysz, że karta Działania nie jest używana, a przycisk ↻ Ponownie załaduj działania niestandardowe jest wyłączony. Jest to prawidłowy proces.
Wyświetl stronę szczegółów magazynu danych w interfejsie konsoli Google Cloud:
echo "data store details page url: https://console.cloud.google.com/gemini-enterprise/locations/${GE_LOCATION}/collections/${GE_COLLECTION_ID}/connector/details?project=${PROJ_ID}"
W zależności od tego, jak połączysz niestandardowy serwer MCP z Gemini Enterprise, wykrywanie narzędzi i zarządzanie nimi odbywa się na jeden z tych 2 sposobów:
- Bezpośredni niestandardowy MCP (
BYO_MCPprzepływ pracy): gdy skonfigurujesz niestandardowy serwer MCP bezpośrednio w Gemini Enterprise bez Agent Registry, katalog narzędzi (connectorModes: ["FEDERATED", "ACTIONS"]) będzie zarządzany przez sam magazyn danych. Musisz otworzyć kartę Działania i kliknąć ↻ Ponownie załaduj działania niestandardowe, aby pobrać schemattools/list, a następnie ręcznie włączyć lub wyłączyć poszczególne narzędzia (addisubtract) w interfejsie. - Import z Agent Registry (
REGISTRY_MCPprzepływ pracy używany w tym ćwiczeniu): gdy importujesz serwer MCP z Agent Registry, Agent Registry służy jako autorytatywne źródło informacji o punkcie końcowym MCP, metadanych interfejsu i katalogu narzędzi (connectorModes: ["FEDERATED"]). Gemini Enterprise automatycznie włącza zarejestrowane narzędzia MCP w czasie działania za pomocą Bramy agentów bez konieczności ręcznego ponownego wczytywania lub przełączania działań w interfejsie magazynu danych.
To kończy część dotyczącą aplikacji Gemini Enterprise. Przejdź do sekcji Sprawdzanie poprawności.
8. Weryfikuj
W tej sekcji wywołasz na żywo wywołania narzędzi MCP z aplikacji internetowej Gemini Enterprise i prześledzisz przepływ żądań w logach Agent Gateway, Cloud DNS, zapory sieci VPC i Cloud Run. Następnie zaostrzysz zasady dostępu ujednoliconego IAM, aby zezwalać na subtract i blokować add, weryfikując egzekwowanie zasady zerowego zaufania w bramie.
Dostęp użytkownika
Skonstruuj adres URL aplikacji internetowej Gemini Enterprise:
# fetch app user url
export GE_WIDGET_ID=$(curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines/${GE_APP_ID}/widgetConfigs/default_search_widget_config" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "X-Goog-User-Project: ${PROJ_ID}" \
-H "Content-Type: application/json" \
| jq -r '.configId')
export GE_APP_USER_URL="https://vertexaisearch.cloud.google.com/home/cid/${GE_WIDGET_ID}"
echo "app user url: ${GE_APP_USER_URL}"
Kliknij link, aby otworzyć interfejs czatu aplikacji internetowej Gemini Enterprise w przeglądarce, a następnie kliknij Rozpocznij.
Testowanie zapytań do agenta na czacie
W interfejsie czatu potwierdź, że math-wizard-collection łącznik danych jest włączony. W tym celu kliknij ikonę puzzli Oprogramowanie sprzęgające u dołu okna czatu. Powinien pojawić się przycisk przełączania, który jest włączony (pokolorowany).
Wypróbuj te zapytania testowe:
what is 2342345 - 98234798324?
what is 72347234 + 234234?
Sprawdź, czy asystent zwraca prawidłowe odpowiedzi i wyświetla interaktywną odznakę cytowania działania (np. Math Calculation (8s) 🤖 Agentgateway Agent) pod każdą odpowiedzią, potwierdzając wykonanie narzędzia.
Sprawdzanie logów w Cloud Logging
Sprawdź, czy Gemini Enterprise przekierował wywołania narzędzi przez Bramę agentów i prywatną sieć VPC, przeglądając logi w Cloud Logging.
1. Weryfikowanie autoryzacji Bramy agentów i IAP
Sprawdź, czy Brama agentów przechwyciła żądanie, rozpoznała miejsce docelowe w Agent Registry, przekazała autoryzację do IAP i zezwoliła na wywołanie narzędzia:
# show agent gateway logs
gcloud logging read 'resource.type="networkservices.googleapis.com/Gateway"' \
--project=${PROJ_ID} \
--limit=5 \
--format="table( \
timestamp.date(tz=LOCAL):label=TIMESTAMP, \
httpRequest.status:label=STATUS, \
httpRequest.serverIp:label=SERVER_IP, \
jsonPayload.agentGatewayInfo.mcpInfo.method:label=MCP_METHOD, \
jsonPayload.agentGatewayInfo.mcpInfo.parameter:label=TOOL, \
jsonPayload.authzPolicyInfo.result:label=AUTHZ, \
jsonPayload.agentGatewayInfo.agentRegistryResource.basename():label=REGISTRY_MCP
)"
Sprawdź, czy dane wyjściowe zawierają:
STATUS:200(udane wykonanie) i202(notifications/initializedhandshake).SERVER_IP: adres IP punktu końcowego PSC interfejsów API Google (172.16.20.20:443).MCP_METHODiTOOL: sekwencja protokołu MCP (notifications/initialized,tools/listitools/callzaddlubsubtract).AUTHZ:ALLOWED(autoryzacja zakupów w aplikacji zezwala na ruch wychodzący).REGISTRY_MCP: identyfikator zasobu Agent Registry (agentregistry-...).
2. Sprawdzanie tranzytu DNS i zapory sieciowej
Sprawdź, czy Cloud DNS rozpoznał nazwę hosta jako punkt końcowy PSC i czy zapora sieciowa zezwoliła na ruch z interfejsu bramy agenta:
# show dns logs
gcloud logging read 'resource.type="dns_query"' \
--project=${PROJ_ID} \
--limit=5 \
--format="table( \
timestamp.date(tz=LOCAL):label=TIMESTAMP, \
jsonPayload.queryName:label=QUERY_NAME, \
jsonPayload.queryType:label=TYPE, \
jsonPayload.responseCode:label=RCODE, \
jsonPayload.rdata:label=RDATA
)"
# show firewall logs
gcloud logging read 'logName:"compute.googleapis.com%2Ffirewall"' \
--project=${PROJ_ID} \
--limit=5 \
--format="table( \
timestamp.date(tz=LOCAL):label=TIMESTAMP, \
jsonPayload.connection.src_ip:label=SRC_IP, \
jsonPayload.connection.dest_ip:label=DEST_IP, \
jsonPayload.connection.dest_port:label=PORT, \
jsonPayload.rule_details.reference.basename():label=RULE, \
jsonPayload.disposition:label=DISPOSITION
)"
Sprawdź te wartości:
- DNS
QUERY_NAMEiRDATA: rozwiązujemath-wizard-...run.app.(rekordA,NOERROR) na172.16.20.20. - Zapora sieciowa
SRC_IPiDEST_IP:192.168.10.2(adres IP interfejsu PSC bramy agenta) do172.16.20.20:443. - Zapora sieciowa
RULEiDISPOSITION: dopasowanofirewallPolicy:fw-policy-...doALLOWED.
3. Sprawdzanie wykonania narzędzia Cloud Run
Sprawdź, czy kontener Cloud Run otrzymał i przetworzył wywołanie narzędzia:
# show cloud run logs
gcloud logging read 'resource.type="cloud_run_revision"
AND textPayload:"Tool:"' \
--project=${PROJ_ID} \
--limit=5 \
--format="value(timestamp.date(tz=LOCAL), textPayload)"
Sprawdź, czy textPayload wyświetla wpisy dotyczące wykonania narzędzia (np. >>> 🛠️ Tool: 'subtract' called with numbers '[x]' and '[y]').
Testowanie egzekwowania zasad jak najmniejszych uprawnień
W początkowej zasadzie dostępu do IAM dozwolona była dowolna metoda lub narzędzie, o ile miejsce docelowe było zarejestrowane (destination.is_registered == true). W tym kroku zaktualizuj zasadę, aby wymusić zasadę najmniejszych uprawnień, zezwalając tylko na narzędzie subtract i blokując add.
Aktualizowanie zasady dostępu uprawnień
Podczas ograniczania wykonywania narzędzia MCP używaj wzoru z 2 regułami:
- Reguła 1 (wykrywanie i uzgadnianie MCP): zezwala na metody cyklu życia MCP inne niż wywołania narzędzi (
destination.is_registered == trueidestination.agent_registry.mcp_server.method != 'tools/call'). Ponieważ Gemini Enterprise negocjuje konfigurację strumienia i wykrywanie (initialize,notifications/initialized,tools/list) przed wywołaniem narzędzia, adestination.agent_registry.mcp_server.tool.namejest wypełniane tylko podczastools/call, reguła 1 jest niezbędna do prawidłowego działania inicjowania sesji i wykrywania katalogu. - Reguła 2 (ograniczenie na poziomie narzędzia): ogranicza wykonywanie funkcji
tools/call, tak aby dozwolone było tylko narzędziesubtract(destination.is_registered == true,destination.agent_registry.mcp_server.method == 'tools/call'idestination.agent_registry.mcp_server.tool.name == 'subtract').
Zaktualizuj plik manifestu reguły zasad dostępu o obie reguły:
# create access policy rule file (update: allow subtract only)
cat > cfg/${UAP_POLICY_NAME}-rule-update.json << EOF
[
{
"description": "allow ge assistant to any registered endpoint to perform mcp discovery and handshake",
"effect": "ALLOW",
"principals": [
"principal://${TRUST_DOMAIN}/resources/discoveryengine/projects/${PROJ_NO}/locations/global/engines/${GE_APP_ID}/assistants/default_assistant/agents/default/core_assistant"
],
"operation": {
"permissions": [
"iap.googleapis.com/resources.egressViaIAP"
]
},
"conditions": {
"iap.googleapis.com": {
"expression": \
"destination.is_registered == true && \
destination.agent_registry.mcp_server.method != 'tools/call'"
}
}
},
{
"description": "allow ge assistant to any registered mcp server with tool call subtract",
"effect": "ALLOW",
"principals": [
"principal://${TRUST_DOMAIN}/resources/discoveryengine/projects/${PROJ_NO}/locations/global/engines/${GE_APP_ID}/assistants/default_assistant/agents/default/core_assistant"
],
"operation": {
"permissions": [
"iap.googleapis.com/resources.egressViaIAP"
]
},
"conditions": {
"iap.googleapis.com": {
"expression": \
"destination.is_registered == true && \
destination.agent_registry.mcp_server.method == 'tools/call' && \
destination.agent_registry.mcp_server.tool.name == 'subtract'"
}
}
}
]
EOF
Zastosuj zaktualizowane reguły w zasadach dostępu uprawnień:
# update iam access policy
gcloud iam access-policies update ${UAP_POLICY_NAME} \
--details-rules=cfg/${UAP_POLICY_NAME}-rule-update.json \
--project=${PROJ_ID} \
--location=global
Sprawdzanie zasady dostępu uprawnień
Sprawdź, czy nowa zasada dostępu IAM została zastosowana i czy tylko narzędzie do odejmowania jest dozwolone:
# show iam access policy details
gcloud iam access-policies describe ${UAP_POLICY_NAME} \
--project=${PROJ_ID} \
--location=global \
--flatten="details.rules[]" \
--format="table( \
details.rules.principals[0].scope(engines).sub('assistants/default_assistant/agents/default', '...'):label=PRINCIPAL, \
details.rules.effect:label=EFFECT, \
details.rules.conditions.'iap.googleapis.com'.expression.sub('\s*&&\s*', '\n&& ').sub('\s*\|\|\s*', '\n|| '):label=EXPRESSION
)"
Testowanie zabronionego wywołania narzędzia
Wróć do interfejsu czatu aplikacji internetowej Gemini Enterprise i wypróbuj inne zapytanie testowe:
what is 100 plus 20?
Asystent próbuje wywołać add, ale Brama agentów i IAP oceniają warunek zasady Uprawnień jako false i odrzucają żądanie ruchu wychodzącego z HTTP 403 Forbidden. W interfejsie czatu zobaczysz, że asystent wyświetla Calculate Sum i obraca się 🤖 Agentgateway Agent ... Working on it., gdy ponawia zablokowane wywołanie narzędzia. Jest to prawidłowy proces. Potwierdza, że bramy agentów i IAP aktywnie przechwytują i odrzucają niedozwolone wykonanie narzędzi na poziomie sieci.
Ponowne sprawdzanie logów w Cloud Logging
Wyświetl wpisy logu bramy agenta i zwróć uwagę na nowe wpisy 403 odpowiadające niedozwolonemu wywołaniu narzędzia add:
# show agent gateway logs
gcloud logging read 'resource.type="networkservices.googleapis.com/Gateway"' \
--project=${PROJ_ID} \
--limit=5 \
--format="table( \
timestamp.date(tz=LOCAL):label=TIMESTAMP, \
httpRequest.status:label=STATUS, \
httpRequest.serverIp:label=SERVER_IP, \
jsonPayload.agentGatewayInfo.mcpInfo.method:label=MCP_METHOD, \
jsonPayload.agentGatewayInfo.mcpInfo.parameter:label=TOOL, \
jsonPayload.authzPolicyInfo.result:label=AUTHZ, \
jsonPayload.agentGatewayInfo.agentRegistryResource.basename():label=REGISTRY_MCP
)"
Oczekiwane dane wyjściowe:
TIMESTAMP STATUS SERVER_IP MCP_METHOD TOOL AUTHZ REGISTRY_MCP
YYYY-MM-DDTHH:MM:SS 403 tools/call add DENIED agentregistry-00000000-0000-0000-0012-3456789abcde
YYYY-MM-DDTHH:MM:SS 403
YYYY-MM-DDTHH:MM:SS 202 172.16.20.20:443 notifications/initialized ALLOWED agentregistry-00000000-0000-0000-0012-3456789abcde
YYYY-MM-DDTHH:MM:SS 172.16.20.20:443 ALLOWED agentregistry-00000000-0000-0000-0012-3456789abcde
YYYY-MM-DDTHH:MM:SS 200 172.16.20.20:443 initialize ALLOWED agentregistry-00000000-0000-0000-0012-3456789abcde
Sprawdź, czy dodatkowe żądanie nigdy nie dotarło do backendu Cloud Run:
# show cloud run logs
gcloud logging read 'resource.type="cloud_run_revision"
AND textPayload:"Tool:"' \
--project=${PROJ_ID} \
--limit=5 \
--format="value(timestamp.date(tz=LOCAL), textPayload)"
Polecenie nie zwraca żadnych nowych wpisów, co potwierdza, że Brama agentów skutecznie zastosowała zasadę dostępu IAM.
To wszystko, jeśli chodzi o weryfikację. Przejdźmy teraz do sekcji Czyszczenie.
9. Czyszczenie
Aby usunąć zasoby i konfiguracje utworzone w tym laboratorium, wykonaj te czynności.
Usuwanie komponentów Gemini Enterprise
# delete gemini enterprise engine (app)
curl -s -X DELETE "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines/${GE_APP_ID}" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "X-Goog-User-Project: ${PROJ_ID}"
# delete custom mcp collection, data connector, and backing data store
curl -s -X DELETE "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1alpha/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/${GE_COLLECTION_ID}" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "X-Goog-User-Project: ${PROJ_ID}"
# reset identity provider configuration
curl -s -X PATCH "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/aclConfig" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "X-Goog-User-Project: ${PROJ_ID}" \
-H "Content-Type: application/json" \
-d '{"idpConfig":{"idpType":"IDP_TYPE_UNSPECIFIED"}}'
Usuwanie komponentów serwera MCP
# delete agent registry service
gcloud -q agent-registry services delete ${MCP_NAME} \
--location=${REGION} \
--project=${PROJ_ID}
# delete cloud run service, source-deploy artifact registry repo, and staging bucket
gcloud -q run services delete ${MCP_NAME} \
--region=${REGION} \
--project=${PROJ_ID}
gcloud -q artifacts repositories delete cloud-run-source-deploy \
--location=${REGION} \
--project=${PROJ_ID}
gcloud -q storage rm --recursive gs://run-sources-${PROJ_ID}-${REGION} \
--project=${PROJ_ID}
Usuwanie bramy agenta i zasad dostępu IAM
# delete gateway authorization policy, iap extension, and agent gateway
gcloud -q network-security authz-policies delete ${AGW_NAME}-authz-policy-iap \
--location=${REGION} \
--project=${PROJ_ID}
gcloud -q service-extensions authz-extensions delete ${AGW_NAME}-svc-ext-authz-iap \
--location=${REGION} \
--project=${PROJ_ID}
gcloud -q network-services agent-gateways delete ${AGW_NAME} \
--location=${REGION} \
--project=${PROJ_ID}
# delete iam policy binding and access policy
gcloud -q iam policy-bindings delete ${UAP_BINDING_NAME} \
--location=global \
--project=${PROJ_ID}
gcloud -q iam access-policies delete ${UAP_POLICY_NAME} \
--location=global \
--project=${PROJ_ID}
Usuwanie komponentów DNS i zapory sieciowej
# delete dns record set, managed zone, and policy
gcloud -q dns record-sets delete "*.run.app." \
--type=A \
--zone=priv-zone-run \
--project=${PROJ_ID}
gcloud -q dns managed-zones delete priv-zone-run \
--project=${PROJ_ID}
gcloud -q dns policies update dns-policy-${SLUG} \
--networks="" \
--project=${PROJ_ID}
gcloud -q dns policies delete dns-policy-${SLUG} \
--project=${PROJ_ID}
# delete firewall policy association, rule, and policy
gcloud -q compute network-firewall-policies associations delete \
--name=fw-policy-bind-${SLUG} \
--firewall-policy=fw-policy-${SLUG} \
--global-firewall-policy \
--project=${PROJ_ID}
gcloud -q compute network-firewall-policies rules delete 1001 \
--firewall-policy=fw-policy-${SLUG} \
--global-firewall-policy \
--project=${PROJ_ID}
gcloud -q compute network-firewall-policies delete fw-policy-${SLUG} \
--global \
--project=${PROJ_ID}
Usuwanie komponentów usługi PSC i sieci VPC
# delete psc forwarding rule and internal ip address
gcloud -q compute forwarding-rules delete psc2gapis \
--global \
--project=${PROJ_ID}
gcloud -q compute addresses delete ip-psc2gapis \
--global \
--project=${PROJ_ID}
# delete psc network attachment, subnet, and vpc network
gcloud -q compute network-attachments delete psc-na-${REGION}-agw \
--region=${REGION} \
--project=${PROJ_ID}
gcloud -q compute networks subnets delete subnet-${REGION}-agw \
--region=${REGION} \
--project=${PROJ_ID}
gcloud -q compute networks delete vnet-${SLUG} \
--project=${PROJ_ID}
Usuwanie zastąpień zasad organizacji i plików lokalnych
# delete project-level organization policy overrides
gcloud -q org-policies delete discoveryengine.managed.disableCustomMcpServerConnector --project=${PROJ_ID}
gcloud -q org-policies delete iam.managed.disableAccessPolicyBinding --project=${PROJ_ID}
# remove local project files
rm -rf cfg math-wizard
To koniec porządkowania. Przejdźmy teraz do podsumowania.
10. Podsumowanie
Gratulacje! Masz gotową architekturę kompleksową, która umożliwia aplikacji Gemini Enterprise bezpieczne wykrywanie i wywoływanie narzędzi na prywatnym niestandardowym serwerze MCP:
- Niestandardowy serwer MCP i Agent Registry: wdrożono prywatną usługę FastMCP w Cloud Run (
--ingress=internal) i zarejestrowano jej punkt końcowy oraz schemat narzędzia (addisubtract) w Agent Registry. - Integracja z Gemini Enterprise: udostępniono aplikację Gemini Enterprise, powiązano ruch wychodzący narzędzia z bramą agentów i dołączono zarejestrowany serwer MCP jako
REGISTRY_MCPłącznik danych. - Prywatny ruch wychodzący z sieci VPC i zarządzanie oparte na zasadzie zerowego zaufania: prywatne wykonywanie narzędzi za pomocą PSC (
172.16.20.20) i egzekwowanie zasady najmniejszych uprawnień na poziomie narzędzia za pomocą IAP i ujednoliconych zasad dostępu IAM (destination.agent_registry.*).

Cosmpup uważa, że Codelabs są świetne!
Co dalej?
- Zaawansowane funkcje i samouczki znajdziesz w dokumentacji Gemini Enterprise Agent Platform.
- Skonfiguruj bariery Model Armor w bramie agentów, aby zwiększyć bezpieczeństwo AI.
- Poznaj zasady zarządzania semantycznego, aby egzekwować reguły biznesowe i zapewniać zgodność z przepisami w przypadku zapytań w języku naturalnym.
Jeśli masz uwagi, pytania lub poprawki, możesz je przesłać za pomocą tego formularza opinii.
Dziękujemy!