Baza danych jako narzędzie: RAG z agentem z ADK, MCP Toolbox i Cloud SQL

1. Wprowadzenie

Agenty AI są przydatne tylko w zakresie danych, do których mają dostęp. Większość danych w świecie rzeczywistym znajduje się w bazach danych, a łączenie agentów z bazami danych zwykle oznacza pisanie kodu zarządzania połączeniami, logiki zapytań i potoków osadzania w kodzie agenta. Każdy agent, który potrzebuje dostępu do bazy danych, powtarza tę pracę, a każda zmiana zapytania wymaga ponownego wdrożenia agenta.

W tym laboratorium znajdziesz inne podejście. Narzędzia do obsługi baz danych deklarujesz w pliku YAML – zapytania w standardowej wersji SQL, wyszukiwanie podobieństwa wektorowego, a nawet automatyczne generowanie osadzania. MCP Toolbox for Databases obsługuje wszystkie operacje na bazie danych jako serwer MCP. Kod agenta pozostaje minimalny: wczytaj narzędzia i pozwól Gemini zdecydować, które z nich wywołać.

Co utworzysz

Asystent Smart Job Board dla „TechJobs” – agent ADK oparty na Gemini, który pomaga deweloperom przeglądać oferty pracy w branży technicznej za pomocą standardowych filtrów (stanowisko, stos technologiczny) i odkrywać oferty pracy na podstawie opisów w języku naturalnym, np. „Chcę pracować zdalnie nad chatbotami AI”. Agent odczytuje dane z bazy danych Cloud SQL PostgreSQL i zapisuje w niej dane w całości za pomocą MCP Toolbox for Databases, który obsługuje cały dostęp do bazy danych, w tym automatyczne generowanie osadzania na potrzeby wyszukiwania wektorowego. Na koniec zarówno Toolbox, jak i agent będą działać w Cloud Run.

eb6de681c40990c1.jpeg

Czego się nauczysz

  • Jak protokół MCP (Model Context Protocol) standaryzuje dostęp do narzędzi dla agentów AI i jak MCP Toolbox for Databases stosuje to w przypadku operacji na bazach danych
  • Konfigurowanie MCP Toolbox for Databases jako oprogramowania pośredniczącego między agentem ADK a Cloud SQL PostgreSQL
  • Zdefiniuj narzędzia bazy danych deklaratywnie w tools.yaml – w agencie nie ma kodu bazy danych.
  • Tworzenie agenta ADK, który wczytuje narzędzia z uruchomionego serwera Toolbox za pomocą ToolboxToolset
  • Generowanie wektorów dystrybucyjnych za pomocą wbudowanej funkcji embedding() w Cloud SQL i włączanie wyszukiwania semantycznego za pomocą funkcji pgvector
  • Użyj funkcji valueFromParam do automatycznego wczytywania wektorów podczas operacji zapisu.
  • Wdrażanie serwera Toolbox i agenta ADK w Cloud Run

Wymagania wstępne

  • Konto Google Cloud z próbnym kontem rozliczeniowym
  • podstawowa znajomość Pythona i SQL,
  • Nie jest wymagane wcześniejsze doświadczenie z ADK, MCP Toolbox ani pgvector.

2. Konfigurowanie środowiska

Ten krok przygotowuje środowisko Cloud Shell, konfiguruje projekt Google Cloud i klonuje repozytorium referencyjne.

Otwórz Cloud Shell

Otwórz Cloud Shell w przeglądarce. Cloud Shell zapewnia wstępnie skonfigurowane środowisko ze wszystkimi narzędziami potrzebnymi do tego ćwiczenia. Gdy pojawi się prośba o autoryzację, kliknij Autoryzuj.

Następnie kliknij „Widok” –> „Terminal”, aby otworzyć terminal.Interfejs powinien wyglądać podobnie do tego:

86307fac5da2f077.png

Będzie to nasz główny interfejs: IDE u góry, terminal u dołu.

Konfigurowanie katalogu roboczego

Utwórz katalog roboczy. Cały kod, który napiszesz w tym ćwiczeniu, będzie się znajdować tutaj:

mkdir -p ~/build-agent-adk-toolbox-cloudsql
cloudshell workspace ~/build-agent-adk-toolbox-cloudsql && cd ~/build-agent-adk-toolbox-cloudsql

Konfigurowanie projektu Google Cloud

Utwórz plik .env ze zmiennymi lokalizacji:

# For Vertex AI / Gemini API calls
echo "GOOGLE_CLOUD_LOCATION=global" > .env
# For Cloud SQL, Cloud Run, Artifact Registry
echo "REGION=us-central1" >> .env

Pobierz skrypt konfiguracji projektu do katalogu roboczego:

curl -sL https://raw.githubusercontent.com/alphinside/cloud-trial-project-setup/main/setup_verify_trial_project.sh -o setup_verify_trial_project.sh

Uruchom skrypt. Weryfikuje ono Twoje próbne konto rozliczeniowe, tworzy nowy projekt (lub weryfikuje istniejący), zapisuje identyfikator projektu w pliku .env w bieżącym katalogu i ustawia aktywny projekt w gcloud.

bash setup_verify_trial_project.sh && source .env

Skrypt wykona te działania:

  1. Sprawdź, czy masz aktywne konto rozliczeniowe w wersji próbnej
  2. Sprawdź, czy w .env istnieje projekt (jeśli tak)
  3. Utwórz nowy projekt lub użyj istniejącego.
  4. Połącz próbne konto rozliczeniowe z projektem
  5. Zapisz identyfikator projektu w .env.
  6. Ustaw projekt jako aktywny projekt gcloud.

Sprawdź, czy projekt jest prawidłowo ustawiony, sprawdzając żółty tekst obok katalogu roboczego w wierszu poleceń terminala Cloud Shell. Powinien wyświetlać identyfikator projektu.

dcba35ce1389f313.png

Jeśli sesja Cloud Shell zostanie w dowolnym momencie zresetowana, wróć do katalogu roboczego i ponownie uruchom polecenie bash setup_verify_trial_project.sh && source .env, aby przywrócić konfigurację projektu. Sprawdź, czy w prompcie terminala ponownie pojawił się żółty tekst identyfikatora projektu.

gcloud services enable \
  aiplatform.googleapis.com \
  sqladmin.googleapis.com \
  compute.googleapis.com \
  run.googleapis.com \
  cloudbuild.googleapis.com \
  artifactregistry.googleapis.com
  • Vertex AI API (aiplatform.googleapis.com) – Twój agent korzysta z modeli Gemini, a Toolbox używa interfejsu Embedding API do wyszukiwania wektorowego.
  • Cloud SQL Admin API (sqladmin.googleapis.com) – możesz udostępniać instancję PostgreSQL i nią zarządzać.
  • Compute Engine API (compute.googleapis.com) – wymagany do tworzenia instancji Cloud SQL.
  • Cloud Run, Cloud Build, Artifact Registry – używane w kroku wdrażania w dalszej części tego laboratorium

3. Tworzenie instancji bazy danych

Ten krok powoduje utworzenie w tle instancji Cloud SQL – jest ona udostępniana podczas kontynuowania samouczka.

Rozpoczęcie tworzenia instancji

Dodaj hasło do bazy danych do pliku .env i załaduj go ponownie:

echo "DB_PASSWORD=techjobs-pwd-2025" >> .env
source .env

Rozpocznij tworzenie instancji Cloud SQL. Działa w tle, więc możesz kontynuować pracę:

gcloud sql instances create jobs-instance \
  --database-version=POSTGRES_17 \
  --tier=db-custom-1-3840 \
  --edition=ENTERPRISE \
  --region=$REGION \
  --root-password=$DB_PASSWORD \
  --enable-google-ml-integration \
  --database-flags cloudsql.enable_google_ml_integration=on \
  --quiet &
  • db-custom-1-3840 to najmniejszy poziom Cloud SQL z dedykowanymi rdzeniami (1 procesor wirtualny, 3,75 GB pamięci RAM) w wersji ENTERPRISE. Więcej informacji znajdziesz tutaj. Integracja z Vertex AI ML wymaga dedykowanego rdzenia. Nie jest obsługiwana w przypadku warstw z rdzeniem współdzielonym (db-f1-micro, db-g1-small).
  • --root-password ustawia hasło domyślnego użytkownika postgres.
  • --enable-google-ml-integration włącza wbudowaną integrację Cloud SQL z Vertex AI, która umożliwia wywoływanie modeli osadzania bezpośrednio z SQL za pomocą funkcji embedding().
  • & uruchamia polecenie w tle.

Będzie on działać w tle. Następnie pobierzmy plik binarny MCP Toolbox. Możesz to zrobić w tym samym terminalu.

Pobierz plik binarny Toolbox

W tym samouczku użyjemy zestawu narzędzi MCP. Na szczęście zawiera on gotowy plik binarny, który można wykorzystać w środowisku Linux. Pobierzmy go w tle, ponieważ zajmie to trochę czasu.

cd ~/build-agent-adk-toolbox-cloudsql
curl -O https://storage.googleapis.com/genai-toolbox/v0.27.0/linux/amd64/toolbox &

Pozwól, aby ten proces działał na bieżącej karcie (działa już w tle, ale dane wyjściowe będą nadal wyświetlane). Otwórzmy nową kartę terminala w Cloud Shell (kliknij ikonę +) dla większej wygody.

b01e3fbd89f17332.png

Ponownie przejdź do katalogu roboczego i aktywuj projekt za pomocą poprzedniego skryptu konfiguracji.

cd ~/build-agent-adk-toolbox-cloudsql
bash setup_verify_trial_project.sh && source .env

Ten krok konfiguruje projekt Pythona, instaluje zależności i tworzy szkielet katalogu agenta ADK.

4. Inicjowanie projektu agenta

Konfigurowanie projektu w Pythonie

uv to szybki menedżer pakietów i projektów Pythona napisany w Rust ( dokumentacja uv ). W tych ćwiczeniach z programowania używamy go ze względu na szybkość i prostotę.

Zainicjuj projekt w Pythonie i dodaj wymagane zależności:

uv init
uv add google-adk==1.25.0 toolbox-adk==0.6.0
  • google-adk – pakiet Google Agent Development Kit, w tym pakiet Gemini SDK.
  • toolbox-adk – integracja ADK z zestawem narzędzi MCP dla baz danych.

Tworzenie struktury katalogów agenta

ADK oczekuje określonego układu folderów: katalogu o nazwie agenta zawierającego pliki __init__.py, agent.py.env. Aby Ci w tym pomóc, ma wbudowane polecenie, które pozwala szybko utworzyć strukturę:

uv run adk create jobs_agent \
    --model gemini-2.5-flash \
    --project ${GOOGLE_CLOUD_PROJECT} \
    --region ${GOOGLE_CLOUD_LOCATION}

Twój katalog powinien teraz wyglądać tak:

build-agent-adk-toolbox-cloudsql/
├── jobs_agent/
│   ├── __init__.py
│   ├── agent.py
│   └── .env
├── pyproject.toml
├── .env              (project setup — already exists)
└── .venv/

5. Wypełnianie bazy danych z ofertami pracy

Ten krok zapisuje dane początkowe, czeka na zakończenie udostępniania instancji Cloud SQL i wczytuje do tabeli jobs 15 ofert pracy wraz z ich opisami.

Napisz początkowy kod SQL

W edytorze Cloud Shell utworzymy plik o nazwie seed.sql z treścią listy zadań. Spowoduje to utworzenie jobs tabeli z pgvector obsługą i wstawienie 15 ofert pracy w firmach technologicznych.

Najpierw utwórz plik seed.sql za pomocą tego polecenia:

cloudshell edit seed.sql

Następnie skopiuj te skrypty do pliku.

-- seed.sql
-- DISCLAIMER: These job listings are entirely fictional and created for tutorial
-- purposes only. Company names are used for illustrative context — the positions,
-- salaries, and descriptions do not reflect real openings.

CREATE EXTENSION IF NOT EXISTS google_ml_integration;
CREATE EXTENSION IF NOT EXISTS vector;

CREATE TABLE IF NOT EXISTS jobs (
    id SERIAL PRIMARY KEY,
    title VARCHAR NOT NULL,
    company VARCHAR NOT NULL,
    role VARCHAR NOT NULL,
    tech_stack VARCHAR NOT NULL,
    salary_range VARCHAR NOT NULL,
    location VARCHAR NOT NULL,
    openings INTEGER NOT NULL,
    description TEXT NOT NULL,
    description_embedding vector(3072)
);

INSERT INTO jobs (title, company, role, tech_stack, salary_range, location, openings, description) VALUES
('Senior Backend Engineer', 'Stripe', 'Backend', 'Go, PostgreSQL, gRPC, Kubernetes', '$180-250K/year', 'San Francisco, Hybrid', 3,
 'Design and build high-throughput microservices powering payment infrastructure for millions of businesses. Optimize Go services for sub-100ms latency at scale, work with PostgreSQL and Redis for data persistence, and deploy on Kubernetes clusters handling billions of API calls.'),

('Machine Learning Engineer', 'Spotify', 'Data/AI', 'Python, TensorFlow, BigQuery, Vertex AI', '$170-230K/year', 'Stockholm, Remote', 2,
 'Build and deploy ML models for music recommendation and personalization systems serving hundreds of millions of listeners. Design feature pipelines in BigQuery, train models using distributed computing, and serve predictions through real-time APIs processing thousands of requests per second.'),

('Frontend Engineer', 'Vercel', 'Frontend', 'React, TypeScript, Next.js', '$140-190K/year', 'Remote', 4,
 'Build developer-facing dashboard interfaces and deployment tools used by millions of developers worldwide. Create responsive, accessible React components for project management, analytics, and real-time deployment monitoring with a focus on developer experience.'),

('DevOps Engineer', 'Datadog', 'DevOps', 'Terraform, GCP, Docker, Kubernetes, ArgoCD', '$160-220K/year', 'New York, Hybrid', 2,
 'Manage cloud infrastructure powering an observability platform used by thousands of engineering teams. Automate deployment pipelines with ArgoCD, manage multi-cloud Kubernetes clusters, and implement infrastructure-as-code with Terraform across production environments.'),

('Mobile Engineer (Android)', 'Grab', 'Mobile', 'Kotlin, Jetpack Compose, GraphQL', '$120-170K/year', 'Singapore, Hybrid', 3,
 'Develop features for a super-app serving millions of users across Southeast Asia. Build modern Android UIs with Jetpack Compose, integrate GraphQL APIs, and optimize app performance for diverse device capabilities and network conditions.'),

('Data Engineer', 'Airbnb', 'Data', 'Python, Apache Spark, Airflow, BigQuery', '$160-210K/year', 'San Francisco, Hybrid', 2,
 'Build data pipelines that process booking, search, and pricing data for a global travel marketplace. Design ETL workflows with Apache Spark and Airflow, maintain data warehouses in BigQuery, and ensure data quality for analytics and machine learning teams.'),

('Full Stack Engineer', 'Revolut', 'Full Stack', 'TypeScript, Node.js, React, PostgreSQL', '$130-180K/year', 'London, Remote', 5,
 'Build the next generation of financial products making banking accessible to millions of users across 35 countries. Develop real-time trading interfaces with React and WebSockets, build Node.js APIs handling market data streams, and design PostgreSQL schemas for financial transactions.'),

('Site Reliability Engineer', 'Cloudflare', 'SRE', 'Go, Prometheus, Grafana, GCP, Terraform', '$170-230K/year', 'Austin, Hybrid', 2,
 'Ensure 99.99% uptime for a global network handling millions of requests per second. Define SLOs, build monitoring dashboards with Prometheus and Grafana, manage incident response, and automate infrastructure scaling across 300+ data centers worldwide.'),

('Cloud Architect', 'Google Cloud', 'Cloud', 'GCP, Terraform, Kubernetes, Python', '$200-280K/year', 'Seattle, Hybrid', 1,
 'Help enterprises modernize their infrastructure on Google Cloud. Design multi-region architectures, lead migration projects from on-premises to GKE, and build reference implementations using Terraform and Cloud Foundation Toolkit.'),

('Backend Engineer (Payments)', 'Square', 'Backend', 'Java, Spring Boot, PostgreSQL, Kafka', '$160-220K/year', 'San Francisco, Hybrid', 3,
 'Build payment processing systems handling millions of transactions for businesses of all sizes. Design event-driven architectures using Kafka, implement idempotent payment flows with Spring Boot, and ensure PCI-DSS compliance across all services.'),

('AI Engineer', 'Hugging Face', 'Data/AI', 'Python, LangChain, Vertex AI, FastAPI, PostgreSQL', '$150-210K/year', 'Paris, Remote', 2,
 'Build AI-powered tools for the largest open-source ML community. Develop RAG pipelines that index and search model documentation, create conversational agents using LangChain, and deploy AI services with FastAPI on cloud infrastructure.'),

('Platform Engineer', 'Coinbase', 'Platform', 'Rust, Kubernetes, AWS, Terraform', '$180-250K/year', 'Remote', 0,
 'Build the infrastructure platform for a leading cryptocurrency exchange. Develop high-performance matching engines in Rust, manage Kubernetes clusters for microservices, and design CI/CD pipelines that enable rapid feature deployment with zero downtime.'),

('QA Automation Engineer', 'Shopify', 'QA', 'Python, Selenium, Cypress, Jenkins', '$110-160K/year', 'Toronto, Hybrid', 3,
 'Design and maintain automated test suites for a commerce platform powering millions of merchants. Build end-to-end test frameworks with Cypress and Selenium, integrate tests into Jenkins CI pipelines, and establish quality gates that prevent regressions in checkout and payment flows.'),

('Security Engineer', 'CrowdStrike', 'Security', 'Python, SIEM, Kubernetes, Penetration Testing', '$170-240K/year', 'Austin, On-site', 1,
 'Protect enterprise customers from cyber threats on a leading endpoint security platform. Conduct penetration testing, design security monitoring with SIEM tools, implement zero-trust networking in Kubernetes environments, and lead incident response for security events.'),

('Product Engineer', 'GitLab', 'Full Stack', 'Go, React, PostgreSQL, Redis, GCP', '$140-200K/year', 'Remote', 4,
 'Own features end-to-end for an all-in-one DevSecOps platform used by millions of developers. Build Go microservices for CI/CD pipelines, create React frontends for code review and project management, and collaborate with product managers to iterate on user-facing features using data-driven development.');

Skrypt początkowy instaluje 2 rozszerzenia PostgreSQL:

  • google_ml_integration – udostępnia funkcję SQL embedding(), która wywołuje modele wektorów dystrybucyjnych Vertex AI bezpośrednio z SQL. Jest to rozszerzenie na poziomie bazy danych, które udostępnia funkcje ML w jobs_db. Flaga na poziomie instancji (--enable-google-ml-integration) ustawiona podczas tworzenia instancji umożliwia maszynie wirtualnej Cloud SQL dostęp do Vertex AI – rozszerzenie udostępnia funkcje SQL w tej konkretnej bazie danych.
  • vector (pgvector) – dodaje typ danych vector i operatory odległości do przechowywania i wysyłania zapytań dotyczących osadzania.

Kolumna description_embedding to vector(3072) – kolumna pgvector, która przechowuje wektory 3072-wymiarowe. Obecnie ma wartość NULL. W następnym kroku wygenerujesz i wypełnisz wektory za pomocą funkcji embedding().

Dokończ konfigurację bazy danych

Tworzenie instancji Cloud SQL rozpoczęte w poprzednim kroku może nadal trwać i nie być jeszcze zakończone. Sprawdź, czy instancja jest gotowa:

gcloud sql instances describe jobs-instance --format="value(state)"

Powinny pojawić się te dane wyjściowe:

RUNNABLE

34f5b48006b4cb3a.png

Następnie przyznaj kontu usługi instancji Cloud SQL uprawnienia do wywoływania Vertex AI. Jest to wymagane w przypadku wbudowanej funkcji embedding(), której użyjesz w następnym kroku:

SERVICE_ACCOUNT=$(gcloud sql instances describe jobs-instance --format="value(serviceAccountEmailAddress)")

gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
  --member="serviceAccount:$SERVICE_ACCOUNT" \
  --role="roles/aiplatform.user" \
  --quiet

Następnie utwórz dedykowaną bazę danych dla ofert pracy:

gcloud sql databases create jobs_db --instance=jobs-instance

Powinny się wyświetlić dane wyjściowe potwierdzające utworzenie bazy danych:

Creating Cloud SQL database...done.                                                                         
Created database [jobs_db].
instance: jobs-instance
name: jobs_db
project: workshop-xxxxxxx

Połącz się z bazą danych i ją zainicjuj

Uruchom serwer proxy uwierzytelniania Cloud SQL (cloud-sql-proxy jest wstępnie zainstalowany w Cloud Shell). Zapewnia to bezpieczne, uwierzytelnione połączenie z Cloud Shell z instancją Cloud SQL:

d72e56478b517b5c.jpeg

cloud-sql-proxy ${GOOGLE_CLOUD_PROJECT}:${REGION}:jobs-instance --port 5432 &

Jeśli serwer proxy się uruchomi, w terminalu powinny się pojawić te dane wyjściowe:

... Authorizing with Application Default Credentials
... [workshop-xxxxxx:your-location:jobs-instance] Listening on 127.0.0.1:5432
... The proxy has started successfully and is ready for new connections!

W bieżącym terminalu dziennik serwera proxy Cloud SQL jest teraz wyświetlany w sposób ciągły. Otwórzmy nową kartę terminala w Cloud Shell (kliknij ikonę +) dla większej wygody.

b01e3fbd89f17332.png

Ponownie przejdź do katalogu roboczego i aktywuj projekt za pomocą poprzedniego skryptu konfiguracji.

cd ~/build-agent-adk-toolbox-cloudsql
bash setup_verify_trial_project.sh && source .env

Następnie uruchom skrypt początkowy.

psql "host=127.0.0.1 port=5432 dbname=jobs_db user=postgres password=$DB_PASSWORD" -f seed.sql

Zobaczysz dane wyjściowe terminala podobne do tych:

CREATE EXTENSION
CREATE EXTENSION
CREATE TABLE
INSERT 0 15

Sprawdźmy dane

psql "host=127.0.0.1 port=5432 dbname=jobs_db user=postgres password=$DB_PASSWORD" \
  -c "SELECT title, company, role, openings FROM jobs ORDER BY role, title;"

Powinno się wyświetlić 15 ofert pracy na różnych stanowiskach:

             title              |    company     |   role    | openings
---------------------------------+----------------+-----------+----------
 Senior Backend Engineer         | Stripe         | Backend   |        3
 Backend Engineer (Payments)     | Square         | Backend   |        3
 Cloud Architect                 | Google Cloud   | Cloud     |        1
 ...
(15 rows)

Generowanie wektorów dystrybucyjnych dla opisów stanowisk

Kolumna description_embedding w tabeli jobs ma obecnie wartość NULL. Wbudowane rozszerzenie google_ml_integration Cloud SQL udostępnia funkcję embedding(), która wywołuje Vertex AI bezpośrednio z SQL – nie wymaga skryptu w Pythonie ani zewnętrznego pakietu SDK.

Rozpocznij generowanie osadzania w tle. Wywołuje to Vertex AI, aby wygenerować 3072-wymiarowy wektor za pomocą modelu gemini-embedding-001 dla każdego z 15 opisów stanowisk:

psql "host=127.0.0.1 port=5432 dbname=jobs_db user=postgres password=$DB_PASSWORD" \
  -c "UPDATE jobs SET description_embedding = embedding('gemini-embedding-001', description)::vector;" &

Skrypt wykonuje te działania:

  • embedding('gemini-embedding-001', description) – wywołuje model wektorów dystrybucyjnych Gemini w Vertex AI bezpośrednio z SQL, przekazując tekst description każdego zadania. Jest to rozszerzenie google_ml_integration zainstalowane w skrypcie początkowym.
  • ::vector – rzutuje zwróconą tablicę liczb zmiennoprzecinkowych na typ vector pgvector, aby można było ją przechowywać i wykonywać na niej zapytania za pomocą operatorów odległości.
  • Model UPDATE działa na wszystkich 15 wierszach, generując 1 osadzenie o 3072 wymiarach dla każdego opisu stanowiska.
  • Symbol & uruchamia polecenie w tle, dzięki czemu możesz kontynuować pracę, podczas gdy Vertex AI przetwarza wektory.

Podobnie jak w przypadku poprzednich procesów działających w tle, w bieżącym terminalu zostanie wyświetlony dziennik procesu. Otwórzmy nową kartę terminala w Cloud Shell (kliknij ikonę +) dla większej wygody.

b01e3fbd89f17332.png

Ponownie przejdź do katalogu roboczego i aktywuj projekt za pomocą poprzedniego skryptu konfiguracji.

cd ~/build-agent-adk-toolbox-cloudsql
bash setup_verify_trial_project.sh && source .env

Następnie możemy przejść do kolejnego procesu

6. Konfigurowanie MCP Toolbox for Databases

Ten krok wprowadza MCP Toolbox for Databases, konfiguruje go pod kątem połączenia z instancją Cloud SQL i definiuje 2 standardowe narzędzia do wykonywania zapytań SQL.

Czym jest MCP i dlaczego warto korzystać z Toolbox?

e7b9be2e1c98b4db.png

MCP (Model Context Protocol) to otwarty protokół, który standaryzuje sposób, w jaki agenci AI wykrywają narzędzia zewnętrzne i wchodzą z nimi w interakcje. Definiuje model klient-serwer: agent hostuje klienta MCP, a narzędzia są udostępniane przez serwery MCP. Każdy klient zgodny z MCP może używać dowolnego serwera zgodnego z MCP – agent nie potrzebuje niestandardowego kodu integracji dla każdego narzędzia.

d5baa77423f0f465.png

MCP Toolbox for Databases to serwer MCP typu open source stworzony specjalnie na potrzeby dostępu do baz danych. Bez niego musisz pisać funkcje Pythona, które otwierają połączenia z bazą danych, zarządzają pulami połączeń, tworzą zapytania parametryzowane, aby zapobiegać wstrzykiwaniu kodu SQL, obsługują błędy i osadzają cały ten kod w agencie. Każdy agent, który potrzebuje dostępu do bazy danych, powtarza tę pracę. Zmiana zapytania oznacza ponowne wdrożenie agenta.

W Toolboxie piszesz plik YAML. Każde narzędzie jest mapowane na sparametryzowaną instrukcję SQL. Zestaw narzędzi obsługuje pulę połączeń, zapytania parametryzowane, uwierzytelnianie i obserwację. Narzędzia są odłączone od agenta – możesz zaktualizować zapytanie, edytując tools.yaml i ponownie uruchamiając Toolbox, bez ingerowania w kod agenta. Te same narzędzia działają w przypadku ADK, LangGraph, LlamaIndex i dowolnej platformy zgodnej z MCP.

Zapisz konfigurację narzędzi

Teraz musimy utworzyć plik o nazwie tools.yaml w edytorze Cloud Shell, aby skonfigurować narzędzia.

cloudshell edit tools.yaml

Plik używa formatu YAML z wieloma dokumentami – każdy blok oddzielony znakiem --- jest samodzielnym zasobem. Każde źródło ma pole kind, które określa, czym jest (sources w przypadku połączeń z bazą danych, tools w przypadku działań wywoływanych przez agenta), oraz pole type, które określa backend (cloud-sql-postgres w przypadku źródła, postgres-sql w przypadku narzędzi opartych na SQL). Narzędzie odwołuje się do swojego źródła za pomocą znaku name. Dzięki temu Zestaw narzędzi wie, z której puli połączeń ma korzystać. Zmienne środowiskowe używają składni ${VAR_NAME} i są rozwiązywane podczas uruchamiania.

Teraz skopiuj te skrypty do pliku tools.yaml.

# tools.yaml

# --- Data Source ---
kind: sources
name: jobs-db
type: cloud-sql-postgres
project: ${GOOGLE_CLOUD_PROJECT}
region: ${REGION}
instance: jobs-instance
database: jobs_db
user: postgres
password: ${DB_PASSWORD}

---

Ten skrypt definiuje ten zasób:

  • Źródło (jobs-db) – informuje Toolbox, jak połączyć się z instancją Cloud SQL PostgreSQL. Typ cloud-sql-postgres wewnętrznie korzysta z oprogramowania sprzęgającego Cloud SQL, które automatycznie obsługuje uwierzytelnianie i bezpieczne połączenia. Obiekty zastępcze ${GOOGLE_CLOUD_PROJECT} , ${REGION}${DB_PASSWORD} są tłumaczone ze zmiennych środowiskowych podczas uruchamiania.

Następnie dodaj ten skrypt pod symbolem --- w pliku tools.yaml.

# --- Tool 1: Search jobs by role and/or tech stack ---
kind: tools
name: search-jobs
type: postgres-sql
source: jobs-db
description: >-
  Search for job listings by role category and/or tech stack.
  Use this tool when the developer wants to browse listings
  by role (e.g., Backend, Frontend, Data) or find jobs
  using a specific technology. Both parameters accept an
  empty string to match all values.
statement: |
  SELECT title, company, role, tech_stack, salary_range, location, openings
  FROM jobs
  WHERE ($1 = '' OR LOWER(role) = LOWER($1))
  AND ($2 = '' OR LOWER(tech_stack) LIKE '%' || LOWER($2) || '%')
  ORDER BY title
  LIMIT 10
parameters:
  - name: role
    type: string
    description: "The role category to filter by (e.g., 'Backend', 'Frontend', 'Data/AI', 'DevOps'). Use empty string for all roles."
  - name: tech_stack
    type: string
    description: "A technology to search for in the tech stack (partial match, e.g., 'Python', 'Kubernetes'). Use empty string for all tech stacks."

---

# --- Tool 2: Get full details for a specific job ---
kind: tools
name: get-job-details
type: postgres-sql
source: jobs-db
description: >-
  Get full details for a specific job listing including its description,
  salary range, location, and number of openings. Use this tool when the
  developer asks about a particular job by title or company.
statement: |
  SELECT title, company, role, tech_stack, salary_range, location, openings, description
  FROM jobs
  WHERE LOWER(title) LIKE '%' || LOWER($1) || '%'
  OR LOWER(company) LIKE '%' || LOWER($1) || '%'
parameters:
  - name: search_term
    type: string
    description: "The job title or company name to look up (partial match supported)."

---

Ten skrypt definiuje ten zasób:

  • Narzędzia 1 i 2 (search-jobs, get-job-details) – narzędzia do zapytań w standardowej wersji SQL. Każda z nich mapuje nazwę narzędzia (widoczną dla agenta) na sparametryzowaną instrukcję SQL (wykonywaną przez bazę danych). Parametry używają obiektów zastępczych $1$2. Toolbox wykonuje je jako przygotowane instrukcje, co zapobiega wstrzyknięciu kodu SQL.

Kontynuujmy. Dodaj ten skrypt pod symbolem --- w pliku tools.yaml.

# --- Embedding Model ---
kind: embeddingModels
name: gemini-embedding
type: gemini
model: gemini-embedding-001
dimension: 3072

---

Ten skrypt definiuje ten zasób:

  • Model wektorów dystrybucyjnych (gemini-embedding) – konfiguruje Toolbox do wywoływania modelu gemini-embedding-001 Gemini w celu generowania 3072-wymiarowych wektorów dystrybucyjnych tekstu. Toolbox używa do uwierzytelniania domyślnych danych logowania aplikacji (ADC) – w Cloud Shell ani Cloud Run nie jest potrzebny klucz interfejsu API. Zwróć uwagę, że dimension skonfigurowane tutaj musi być takie samo jak wcześniej skonfigurowane do wypełnienia bazy danych.

Kontynuujmy. Dodaj ten skrypt pod symbolem --- w pliku tools.yaml.

# --- Tool 3: Semantic search by description ---
kind: tools
name: search-jobs-by-description
type: postgres-sql
source: jobs-db
description: >-
  Find jobs that match a natural language description of what the developer
  is looking for. Use this tool when the developer describes their ideal job
  using interests, work style, career goals, or project type rather than a
  specific role or tech stack. Examples: "I want to work on AI chatbots,"
  "a remote job at a fintech startup," "something involving infrastructure
  and reliability."
statement: |
  SELECT title, company, role, tech_stack, salary_range, location, description
  FROM jobs
  WHERE description_embedding IS NOT NULL
  ORDER BY description_embedding <=> $1
  LIMIT 5
parameters:
  - name: search_query
    type: string
    description: "A natural language description of the kind of job the developer is looking for."
    embeddedBy: gemini-embedding

---

Ten skrypt definiuje ten zasób:

  • Narzędzie 3 (search-jobs-by-description) – narzędzie do wyszukiwania wektorowego. Parametr search_query ma wartość embeddedBy: gemini-embedding, która informuje Zestaw narzędzi, że ma przechwycić tekst w formie surowej, wysłać go do modelu osadzania i użyć wynikowego wektora w instrukcji SQL. Operator <=> to odległość kosinusowa pgvector – mniejsze wartości oznaczają bardziej podobne opisy.

Na koniec dodaj ostatnie narzędzie pod symbolem --- w pliku tools.yaml.

# --- Tool 4: Add a new job listing with automatic embedding ---
kind: tools
name: add-job
type: postgres-sql
source: jobs-db
description: >-
  Add a new job listing to the platform. Use this tool when a user asks
  to post a job that is not currently listed.
statement: |
  INSERT INTO jobs (title, company, role, tech_stack, salary_range, location, openings, description, description_embedding)
  VALUES ($1, $2, $3, $4, $5, $6, CAST($7 AS INTEGER), $8, $9)
  RETURNING title, company
parameters:
  - name: title
    type: string
    description: "The job title (e.g., 'Senior Backend Engineer')."
  - name: company
    type: string
    description: "The company name (e.g., 'Stripe', 'Spotify')."
  - name: role
    type: string
    description: "The role category (e.g., 'Backend', 'Frontend', 'Data/AI', 'DevOps')."
  - name: tech_stack
    type: string
    description: "Comma-separated list of technologies (e.g., 'Python, FastAPI, GCP')."
  - name: salary_range
    type: string
    description: "The salary range (e.g., '$150-200K/year')."
  - name: location
    type: string
    description: "Work location and arrangement (e.g., 'Remote')."
  - name: openings
    type: string
    description: "The number of open positions."
  - name: description
    type: string
    description: "A short description of the job (2-3 sentences)."
  - name: description_vector
    type: string
    description: "Auto-generated embedding vector for the job description."
    valueFromParam: description
    embeddedBy: gemini-embedding

Ten skrypt definiuje ten zasób:

  • Narzędzie 4 (add-job) – pokazuje wczytywanie wektorów. Parametr description_vector ma 2 pola specjalne:
  • valueFromParam: description – Toolbox kopiuje wartość z parametru description do tego parametru. LLM nigdy nie widzi tego parametru.
  • embeddedBy: gemini-embedding – Toolbox umieszcza skopiowany tekst w wektorze przed przekazaniem go do SQL.

W rezultacie jedno wywołanie narzędzia przechowuje zarówno tekst opisu w formie surowej, jak i jego osadzenie wektorowe, a agent nie ma żadnej wiedzy o osadzeniach.

Format YAML z wieloma dokumentami rozdziela poszczególne zasoby znakiem ---. Każdy dokument ma pola kind, nametype, które określają, czym jest. Podsumowując, skonfigurowaliśmy już wszystkie te elementy:

  • Określanie źródłowej bazy danych
  • Zdefiniuj narzędzia ( narzędzie 1 i 2), aby wykonywać zapytania w bazie danych za pomocą standardowego filtra.
  • Definiowanie modelu wektora dystrybucyjnego
  • Zdefiniuj narzędzie do wyszukiwania wektorowego ( narzędzie 3) w bazie danych.
  • Zdefiniuj narzędzie do pozyskiwania danych wektorowych ( narzędzie 4) do bazy danych.

Sprawdzanie wektorów

Zanim uruchomisz Toolbox, sprawdź, czy generowanie osadzania w tle zostało zakończone. Sprawdź, czy wszystkie zadania mają teraz osadzanie:

psql "host=127.0.0.1 port=5432 dbname=jobs_db user=postgres password=$DB_PASSWORD" \
  -c "SELECT title, (description_embedding IS NOT NULL) AS has_embedding FROM jobs ORDER BY title;"

W każdym wierszu w kolumnie has_embedding powinna być wyświetlana wartość t (prawda). Jeśli nie, możesz poczekać, aż zakończy się proces tworzenia wszystkich osadzeń wierszy.

           title            | has_embedding 
-----------------------------+---------------
 AI Engineer                 | t
 Backend Engineer (Payments) | t
 Cloud Architect             | t
 Data Engineer               | t
 DevOps Engineer             | t
 Frontend Engineer           | t
 Full Stack Engineer         | t

Uruchamianie serwera Zestawu narzędzi

W kroku konfiguracji pobraliśmy już plik wykonywalny toolbox. Sprawdź, czy ten plik binarny istnieje i czy został pobrany. Jeśli nie, pobierz go i poczekaj na zakończenie.

cd ~/build-agent-adk-toolbox-cloudsql
if [ ! -f toolbox ]; then
  curl -O https://storage.googleapis.com/genai-toolbox/v0.27.0/linux/amd64/toolbox
fi
chmod +x toolbox

Wyeksportuj wymagane zmienne środowiskowe i uruchom Toolbox. Zmienne GOOGLE_CLOUD_LOCATIONGOOGLE_GENAI_USE_VERTEXAI są wymagane, ponieważ konfiguracja obejmuje model osadzania. Zmienna GOOGLE_GENAI_USE_VERTEXAI informuje pakiet Gemini SDK, że ma kierować żądania przez Vertex AI (zamiast przez interfejs Gemini API dla konsumentów), a zmienna GOOGLE_CLOUD_LOCATION informuje go, którego regionalnego punktu końcowego ma używać.

export GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT
export GOOGLE_CLOUD_LOCATION=$GOOGLE_CLOUD_LOCATION
export GOOGLE_GENAI_USE_VERTEXAI=true
export DB_PASSWORD=$DB_PASSWORD
export REGION=$REGION
./toolbox --tools-file tools.yaml &

Powinny się wyświetlić dane wyjściowe potwierdzające, że serwer jest gotowy, jak pokazano poniżej:

... INFO "Initialized 0 authServices: " 
... INFO "Initialized 1 embeddingModels: gemini-embedding" 
... INFO "Initialized 4 tools: add-job, search-jobs, get-job-details, search-jobs-by-description" 
...
... INFO "Server ready to serve!"

Podobnie jak w przypadku poprzedniego kroku, spowoduje to uruchomienie kolejnego procesu i wygenerowanie danych wyjściowych. Otwórzmy nową kartę terminala w Cloud Shell (kliknij ikonę +) dla większej wygody.

b01e3fbd89f17332.png

Ponownie przejdź do katalogu roboczego i aktywuj projekt za pomocą poprzedniego skryptu konfiguracji.

cd ~/build-agent-adk-toolbox-cloudsql
bash setup_verify_trial_project.sh && source .env

Weryfikowanie narzędzi

Wyślij zapytanie do interfejsu Toolbox API, aby wyświetlić listę wszystkich zarejestrowanych narzędzi:

curl -s http://localhost:5000/api/toolset | python3 -m json.tool

Powinny być widoczne narzędzia wraz z opisami i parametrami. Jak pokazano poniżej

...
       
"search-jobs-by-description": {
            "description": "Find jobs that match a natural language description of what the developer is looking for. Use this tool when the developer describes their ideal job using interests, work style, career goals, or project type rather than a specific role or tech stack. Examples: \"I want to work on AI chatbots,\" \"a remote job at a fintech startup,\" \"something involving infrastructure and reliability.\"",
            "parameters": [
                {
                    "name": "search_query",
                    "type": "string",
                    "required": true,
                    "description": "A natural language description of the kind of job the developer is looking for.",
                    "authSources": []
                }
            ],
            "authRequired": []
        }
...

Przetestuj narzędzie search-jobs bezpośrednio:

curl -s -X POST http://localhost:5000/api/tool/search-jobs/invoke \
  -H "Content-Type: application/json" \
  -d '{"role": "Backend", "tech_stack": ""}' | jq '.result | fromjson'

Odpowiedź powinna zawierać 2 oferty pracy na stanowisko inżyniera backendu z danych początkowych.

[
  {
    "title": "Backend Engineer (Payments)",
    "company": "Square",
    "role": "Backend",
    "tech_stack": "Java, Spring Boot, PostgreSQL, Kafka",
    "salary_range": "$160-220K/year",
    "location": "San Francisco, Hybrid",
    "openings": 3
  },
  {
    "title": "Senior Backend Engineer",
    "company": "Stripe",
    "role": "Backend",
    "tech_stack": "Go, PostgreSQL, gRPC, Kubernetes",
    "salary_range": "$180-250K/year",
    "location": "San Francisco, Hybrid",
    "openings": 3
  }
]

7. Tworzenie agenta ADK

Ten krok łączy agenta ADK z działającym serwerem Toolbox i testuje wszystkie 4 narzędzia: zapytania standardowe, wyszukiwanie semantyczne i przetwarzanie wektorowe. Kod agenta jest minimalny: cała logika bazy danych znajduje się w tools.yaml.

Konfigurowanie środowiska agenta

Pakiet ADK odczytuje wartości GOOGLE_GENAI_USE_VERTEXAI, GOOGLE_CLOUD_PROJECTGOOGLE_CLOUD_LOCATION ze środowiska powłoki, które zostały już ustawione w poprzednim kroku. Jedyną zmienną specyficzną dla agenta jest TOOLBOX_URL – dodaj ją do pliku .env agenta:

echo -e "\nTOOLBOX_URL=http://127.0.0.1:5000" >> jobs_agent/.env

Aktualizowanie modułu agenta

Otwórz plik jobs_agent/agent.py w edytorze Cloud Shell.

cloudshell edit jobs_agent/agent.py

i zastąp zawartość tym kodem:

# jobs_agent/agent.py
import os

from google.adk.agents import LlmAgent
from toolbox_adk import ToolboxToolset

TOOLBOX_URL = os.environ.get("TOOLBOX_URL", "http://127.0.0.1:5000")

toolbox = ToolboxToolset(TOOLBOX_URL)

root_agent = LlmAgent(
    name="jobs_agent",
    model="gemini-2.5-flash",
    instruction="""You are a helpful assistant at "TechJobs," a tech job listing platform.

Your job:
- Help developers browse job listings by role or tech stack.
- Provide full details about specific positions, including salary range and number of openings.
- Recommend jobs based on natural language descriptions of what the developer is looking for.
- Add new job listings to the platform when asked.

When a developer asks about a specific job by title or company, use the get-job-details tool.
When a developer asks for a specific role category or tech stack, use the search-jobs tool.
When a developer describes what kind of job they want — by interest area, work style,
career goals, or project type — use the search-jobs-by-description tool for semantic search.
When in doubt between search-jobs and search-jobs-by-description, prefer
search-jobs-by-description — it searches job descriptions and finds more relevant matches.

If a position has no openings (openings is 0), let the developer know
and suggest similar alternatives from the search results.

Be conversational, knowledgeable, and concise.""",
    tools=[toolbox],
)

Zwróć uwagę, że nie ma tu kodu bazy danych – ToolboxToolset łączy się z serwerem Toolbox przy uruchamianiu i wczytuje wszystkie dostępne narzędzia. Agent wywołuje narzędzia po nazwie, a Toolbox tłumaczy te wywołania na zapytania SQL kierowane do Cloud SQL.

W przypadku lokalnego środowiska programistycznego zmienna środowiskowa TOOLBOX_URL ma domyślnie wartość http://127.0.0.1:5000. Gdy później wdrożysz usługę w Cloud Run, zastąpisz ten adres URL adresem URL Cloud Run usługi Toolbox – nie musisz wprowadzać żadnych zmian w kodzie.

Instrukcja odnosi się obecnie tylko do 2 standardowych narzędzi (search-jobsget-job-details). Rozszerzysz ją w następnym kroku, gdy dodasz narzędzia do wyszukiwania semantycznego i przetwarzania danych.

Testowanie agenta

Uruchom interfejs programisty ADK:

cd ~/build-agent-adk-toolbox-cloudsql
uv run adk web

Otwórz adres URL wyświetlany w terminalu (zwykle http://localhost:8000) za pomocą funkcji Podgląd w przeglądarce w Cloud Shell lub kliknij adres URL wyświetlany w terminalu, przytrzymując Ctrl. W menu agentów w lewym górnym rogu kliknij jobs_agent.

Testowanie standardowych zapytań

Aby sprawdzić narzędzia standardowego SQL, wypróbuj te prompty:

What backend engineering jobs do you have?
Any jobs using Kubernetes?
Tell me about the Cloud Architect position

93ac33e7f73aa0b9.png 240c53376042a916.png

Wypróbuj opisy w języku naturalnym, które nie są powiązane z określoną rolą ani zestawem technologii:

I want a remote job where I can work on AI and machine learning
Find me something in fintech with good work-life balance
I'm interested in infrastructure and reliability engineering

W zależności od typu zapytania agent spróbuje wybrać odpowiednie narzędzie: zapytania z filtrami strukturalnymi są przetwarzane przez search-jobs, a opisy w języku naturalnym przez search-jobs-by-description.

b0ea629f5c9b4c26.png

Testowanie przetwarzania wektorów

Poproś agenta o dodanie nowego zadania:

Add a new job: 'Robotics Software Engineer' at Boston Dynamics, role Robotics, tech stack: Python, C++, ROS, Computer Vision, salary $160-230K/year, location Waltham MA, Hybrid, 2 openings. Description: Design and implement autonomous navigation and manipulation algorithms for next-generation robots. Work on perception pipelines using computer vision and lidar, develop motion planning software in C++ and Python, and test systems on real hardware in warehouse and logistics environments.

c601a7a9bc0a705b.png

Teraz spróbuj wyszukać:

Find me jobs involving autonomous systems and working with physical hardware

Osadzenie zostało wygenerowane automatycznie podczas operacji INSERT – nie jest potrzebny żaden dodatkowy krok.

5a3d8e6f523dc18b.png

Masz już w pełni działającą aplikację opartą na agentach, która korzysta z ADK, zestawu narzędzi MCP i CloudSQL. Gratulacje! Przejdźmy do wdrażania tych aplikacji w Cloud Run.

Teraz zatrzymajmy interfejs programisty, kończąc proces przez dwukrotne naciśnięcie Ctrl+C.

8. Wdrożenie w Cloud Run

Agent i Toolbox działają lokalnie. W tym kroku obie usługi są wdrażane jako usługi Cloud Run, dzięki czemu są dostępne w internecie. Usługa Toolbox działa jako serwer MCP w Cloud Run, a usługa agenta łączy się z nią.

Przygotowywanie zestawu narzędzi do wdrożenia

Utwórz katalog wdrożenia usługi Toolbox:

cd ~/build-agent-adk-toolbox-cloudsql
mkdir -p deploy-toolbox
cp toolbox tools.yaml deploy-toolbox/

Utwórz plik Dockerfile dla zestawu narzędzi. Otwórz plik deploy-toolbox/Dockerfile w edytorze Cloud Shell:

cloudshell edit deploy-toolbox/Dockerfile

i skopiuj do niego ten skrypt:

# deploy-toolbox/Dockerfile
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY toolbox tools.yaml ./
RUN chmod +x toolbox
EXPOSE 8080
CMD ["./toolbox", "--tools-file", "tools.yaml", "--address", "0.0.0.0", "--port", "8080"]

Narzędzia i tools.yaml są spakowane w minimalnym obrazie Debiana. Cloud Run kieruje ruch do portu 8080.

Wdrażanie usługi Zestaw narzędzi

cd ~/build-agent-adk-toolbox-cloudsql
gcloud run deploy toolbox-service \
  --source deploy-toolbox/ \
  --region $REGION \
  --set-env-vars "DB_PASSWORD=$DB_PASSWORD,GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT,REGION=$REGION,GOOGLE_CLOUD_LOCATION=$GOOGLE_CLOUD_LOCATION,GOOGLE_GENAI_USE_VERTEXAI=true" \
  --allow-unauthenticated \
  --quiet

To polecenie przesyła źródło do Cloud Build, tworzy obraz kontenera, wypycha go do Artifact Registry i wdraża w Cloud Run. Zajmie to kilka minut. Otwórz nową kartę terminala w Cloud Shell (kliknij ikonę +), aby się bardziej skupić.

b01e3fbd89f17332.png

Ponownie przejdź do katalogu roboczego i aktywuj projekt za pomocą poprzedniego skryptu konfiguracji.

cd ~/build-agent-adk-toolbox-cloudsql
bash setup_verify_trial_project.sh && source .env

Przygotowywanie agenta do wdrożenia

Podczas tworzenia pakietu narzędzi skonfiguruj pliki wdrożenia agenta.

Utwórz plik Dockerfile w katalogu głównym projektu. Otwórz plik Dockerfile w edytorze Cloud Shell:

cloudshell edit Dockerfile

Następnie skopiuj tę treść:

# Dockerfile
FROM ghcr.io/astral-sh/uv:python3.12-trixie-slim
WORKDIR /app
COPY pyproject.toml ./
COPY uv.lock ./
RUN uv sync --no-dev
COPY jobs_agent/ jobs_agent/
EXPOSE 8080
CMD ["uv", "run", "adk", "web", "--host", "0.0.0.0", "--port", "8080"]

Ten plik Dockerfile używa obrazu podstawowego ghcr.io/astral-sh/uv, który zawiera wstępnie zainstalowane Pythona i uv. Nie musisz więc instalować uv osobno za pomocą pip.

Utwórz plik .dockerignore, aby wykluczyć niepotrzebne pliki z obrazu kontenera:

cloudshell edit .dockerignore

Następnie skopiuj do niego ten skrypt:

# .dockerignore
.venv/
__pycache__/
*.pyc
.env
jobs_agent/.env
toolbox
tools.yaml
seed.sql
deploy-toolbox/

Wdróż usługę agenta

Poczekaj na zakończenie wdrażania Toolboxa. Pobierz adres URL Cloud Run za pomocą tego polecenia:

TOOLBOX_URL=$(gcloud run services describe toolbox-service \
  --region=$REGION \
  --format='value(status.url)')
echo "Toolbox URL: $TOOLBOX_URL"

Zobaczysz dane wyjściowe podobne do tych:

Toolbox URL: https://toolbox-service-xxxxxx-xx.a.run.app

Następnie sprawdźmy, czy wdrożony zestaw narzędzi działa:

curl -s "$TOOLBOX_URL/api/toolset" | python3 -m json.tool | head -5

Jeśli wynik jest podobny do tego przykładu, wdrożenie zostało już zakończone.

{
    "serverVersion": "0.27.0+binary.linux.amd64.c5524d3",
    "tools": {
        "add-job": {
            "description": "Add a new job listing to the platform. Use this tool when a user asks to post a job that is not currently listed.",

Następnie wdróżmy agenta, przekazując adres URL zestawu narzędzi jako zmienną środowiskową:

cd ~/build-agent-adk-toolbox-cloudsql
gcloud run deploy jobs-agent \
  --source . \
  --region $REGION \
  --set-env-vars "TOOLBOX_URL=$TOOLBOX_URL,GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT,GOOGLE_CLOUD_LOCATION=$GOOGLE_CLOUD_LOCATION,GOOGLE_GENAI_USE_VERTEXAI=TRUE" \
  --allow-unauthenticated \
  --quiet

Kod agenta odczytuje wartość TOOLBOX_URL ze środowiska (zostało to wcześniej skonfigurowane). Lokalnie wskazuje http://127.0.0.1:5000, a w Cloud Run wskazuje adres URL usługi Toolbox. Nie wymaga to żadnych zmian w kodzie.

Testowanie wdrożonego agenta

Pobierz adres URL Cloud Run agenta:

AGENT_URL=$(gcloud run services describe jobs-agent \
  --region=$REGION \
  --format='value(status.url)')
echo "Agent URL: $AGENT_URL"

Otwórz adres URL w przeglądarce. Załaduje się interfejs programistyczny ADK – ten sam interfejs, którego używasz lokalnie, ale teraz działający w Cloud Run.

W menu wybierz jobs_agent i przetestuj:

What backend engineering jobs do you have?
I want a remote job working on AI and machine learning

Oba zapytania działają za pomocą wdrożonych usług: agent w Cloud Run wywołuje Toolbox w Cloud Run, który wysyła zapytanie do Cloud SQL.

9. Gratulacje / Czyszczenie

Masz utworzonego i wdrożonego inteligentnego asystenta do wyszukiwania ofert pracy, który korzysta z MCP Toolbox for Databases, aby połączyć agenta ADK z Cloud SQL PostgreSQL – zarówno za pomocą standardowych zapytań SQL, jak i semantycznego wyszukiwania wektorowego.

Czego się nauczysz

  • Jak MCP standaryzuje dostęp do narzędzi dla agentów AI i jak MCP Toolbox for Databases stosuje to w przypadku operacji na bazach danych – zastępowanie niestandardowego kodu bazy danych deklaratywną konfiguracją YAML.
  • Jak skonfigurować Cloud SQL PostgreSQL jako źródło danych w Toolboxie za pomocą typu źródła cloud-sql-postgres
  • Jak zdefiniować standardowe narzędzia do zapytań SQL z instrukcjami sparametryzowanymi, które zapobiegają wstrzykiwaniu kodu SQL
  • Jak włączyć wyszukiwanie wektorowe za pomocą pgvector i gemini-embedding-001 z parametrem embeddedBy do automatycznego osadzania zapytań
  • Jak valueFromParam umożliwia automatyczne wczytywanie wektorów – LLM podaje opis tekstowy, a Toolbox w tle kopiuje, osadza i przechowuje wektor obok tekstu.
  • Jak ADKToolboxToolset wczytuje narzędzia z działającego serwera Toolbox, dzięki czemu kod agenta jest minimalny, a logika bazy danych jest w pełni odseparowana
  • Jak wdrożyć serwer MCP Toolbox i agenta ADK w Cloud Run jako osobne usługi

Czyszczenie danych

Aby uniknąć obciążenia konta Google Cloud opłatami za zasoby utworzone w tym ćwiczeniu, możesz usunąć poszczególne zasoby lub cały projekt.

Najprostszym sposobem na wyczyszczenie danych jest usunięcie projektu. Spowoduje to usunięcie wszystkich zasobów powiązanych z projektem.

gcloud projects delete $GOOGLE_CLOUD_PROJECT

Opcja 2. Usuwanie poszczególnych zasobów

Jeśli chcesz zachować projekt, ale usunąć tylko zasoby utworzone w tym laboratorium:

gcloud run services delete jobs-agent --region=$REGION --quiet
gcloud run services delete toolbox-service --region=$REGION --quiet
gcloud sql instances delete jobs-instance --quiet
gcloud artifacts repositories delete cloud-run-source-deploy --location=$REGION --quiet 2>/dev/null