ฐานข้อมูลในฐานะเครื่องมือ: RAG แบบเอเจนต์ที่มี ADK, MCP Toolbox และ Cloud SQL

1. บทนำ

เอเจนต์ AI จะมีประโยชน์เพียงใดก็ขึ้นอยู่กับข้อมูลที่เข้าถึงได้ ข้อมูลในโลกแห่งความเป็นจริงส่วนใหญ่อยู่ในฐานข้อมูล และการเชื่อมต่อเอเจนต์กับฐานข้อมูลมักหมายถึงการเขียนการจัดการการเชื่อมต่อ ตรรกะการค้นหา และไปป์ไลน์การฝังภายในโค้ดของเอเจนต์ ตัวแทนทุกรายที่ต้องการเข้าถึงฐานข้อมูลจะต้องทำซ้ำงานนี้ และการเปลี่ยนแปลงการค้นหาทุกครั้งจะต้องมีการติดตั้งใช้งานตัวแทนอีกครั้ง

Codelab นี้แสดงแนวทางที่แตกต่างออกไป คุณประกาศเครื่องมือฐานข้อมูลในไฟล์ YAML ซึ่งได้แก่ การค้นหา SQL มาตรฐาน การค้นหาความคล้ายกันของเวกเตอร์ หรือแม้แต่การสร้างการฝังอัตโนมัติ และ MCP Toolbox for Databases จะจัดการการดำเนินการฐานข้อมูลทั้งหมดในฐานะเซิร์ฟเวอร์ MCP โค้ดของเอเจนต์จะยังคงมีขนาดเล็ก: โหลดเครื่องมือ แล้วปล่อยให้ Gemini ตัดสินใจว่าจะเรียกใช้เครื่องมือใด

สิ่งที่คุณจะสร้าง

ผู้ช่วยกระดานหางานอัจฉริยะสำหรับ "TechJobs" ซึ่งเป็นเอเจนต์ ADK ที่ทำงานด้วยระบบ Gemini ซึ่งช่วยให้นักพัฒนาซอฟต์แวร์เรียกดูประกาศรับสมัครงานด้านเทคโนโลยีโดยใช้ตัวกรองมาตรฐาน (บทบาท กลุ่มเทคโนโลยี) และค้นพบงานผ่านคำอธิบายภาษาธรรมชาติ เช่น "ฉันต้องการงานระยะไกลที่ทำงานเกี่ยวกับแชทบอท AI" เอเจนต์จะอ่านและเขียนไปยังฐานข้อมูล Cloud SQL PostgreSQL ผ่าน MCP Toolbox for Databases ทั้งหมด ซึ่งจะจัดการการเข้าถึงฐานข้อมูลทั้งหมด รวมถึงการสร้างการฝังอัตโนมัติสำหรับการค้นหาเวกเตอร์ ในท้ายที่สุด ทั้งกล่องเครื่องมือและเอเจนต์จะทำงานใน Cloud Run

eb6de681c40990c1.jpeg

สิ่งที่คุณจะได้เรียนรู้

  • วิธีที่ MCP (Model Context Protocol) สร้างมาตรฐานการเข้าถึงเครื่องมือสำหรับเอเจนต์ AI และวิธีที่ MCP Toolbox for Databases ใช้มาตรฐานนี้กับการดำเนินการฐานข้อมูล
  • ตั้งค่า MCP Toolbox for Databases เป็นมิดเดิลแวร์ระหว่างตัวแทน ADK กับ Cloud SQL PostgreSQL
  • กำหนดเครื่องมือฐานข้อมูลแบบประกาศใน tools.yaml โดยไม่ต้องมีโค้ดฐานข้อมูลใน Agent
  • สร้างเอเจนต์ ADK ที่โหลดเครื่องมือจากเซิร์ฟเวอร์กล่องเครื่องมือที่กําลังทํางานโดยใช้ ToolboxToolset
  • สร้างการฝังเวกเตอร์โดยใช้ฟังก์ชัน embedding() ในตัวของ Cloud SQL และเปิดใช้การค้นหาเชิงความหมายด้วย pgvector
  • ใช้ฟีเจอร์ valueFromParam เพื่อการนำเข้าเวกเตอร์อัตโนมัติในการดำเนินการเขียน
  • ทำให้ทั้งเซิร์ฟเวอร์ Toolbox และเอเจนต์ ADK ใช้งานได้ใน Cloud Run

ข้อกำหนดเบื้องต้น

  • บัญชี Google Cloud ที่มีบัญชีสำหรับการเรียกเก็บเงินเวอร์ชันทดลอง
  • มีความรู้พื้นฐานเกี่ยวกับ Python และ SQL
  • ไม่จำเป็นต้องมีประสบการณ์เกี่ยวกับ ADK, MCP Toolbox หรือ pgvector มาก่อน

2. ตั้งค่าสภาพแวดล้อม

ขั้นตอนนี้จะเตรียมสภาพแวดล้อม Cloud Shell กำหนดค่าโปรเจ็กต์ Google Cloud และโคลนที่เก็บข้อมูลอ้างอิง

เปิด Cloud Shell

เปิด Cloud Shell ในเบราว์เซอร์ Cloud Shell มีสภาพแวดล้อมที่กำหนดค่าไว้ล่วงหน้าพร้อมเครื่องมือทั้งหมดที่คุณต้องการสำหรับ Codelab นี้ คลิกให้สิทธิ์เมื่อมีข้อความแจ้งให้ทำ

จากนั้นคลิก "ดู" -> "เทอร์มินัล" เพื่อเปิดเทอร์มินัล อินเทอร์เฟซของคุณควรมีลักษณะคล้ายกับอินเทอร์เฟซนี้

86307fac5da2f077.png

นี่จะเป็นอินเทอร์เฟซหลักของเรา โดยมี IDE อยู่ด้านบนและเทอร์มินัลอยู่ด้านล่าง

ตั้งค่าไดเรกทอรีการทำงาน

สร้างไดเรกทอรีที่ใช้งานอยู่ โค้ดทั้งหมดที่คุณเขียนใน Codelab นี้จะอยู่ที่นี่

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

สร้างโปรเจ็กต์ Google Cloud

สร้างไฟล์ .env ที่มีตัวแปรสถานที่ตั้ง

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

ดาวน์โหลดสคริปต์การตั้งค่าโปรเจ็กต์ลงในไดเรกทอรีการทำงาน

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

เรียกใช้สคริปต์ โดยจะยืนยันบัญชีสำหรับการเรียกเก็บเงินของช่วงทดลองใช้ สร้างโปรเจ็กต์ใหม่ (หรือตรวจสอบโปรเจ็กต์ที่มีอยู่) บันทึกรหัสโปรเจ็กต์ลงในไฟล์ .env ในไดเรกทอรีปัจจุบัน และตั้งค่าโปรเจ็กต์ที่ใช้งานอยู่ใน gcloud

bash setup_verify_trial_project.sh && source .env

สคริปต์จะทำสิ่งต่อไปนี้

  1. ตรวจสอบว่าคุณมีบัญชีสำหรับการเรียกเก็บเงินสำหรับการทดลองใช้ที่ใช้งานอยู่
  2. ตรวจสอบโปรเจ็กต์ที่มีอยู่ใน .env (หากมี)
  3. สร้างโปรเจ็กต์ใหม่หรือใช้โปรเจ็กต์ที่มีอยู่
  4. ลิงก์บัญชีสำหรับการเรียกเก็บเงินของช่วงทดลองใช้กับโปรเจ็กต์
  5. บันทึกรหัสโปรเจ็กต์ไปยัง .env
  6. ตั้งค่าโปรเจ็กต์เป็นโปรเจ็กต์ gcloud ที่ใช้งานอยู่

ยืนยันว่าตั้งค่าโปรเจ็กต์ถูกต้องแล้วโดยตรวจสอบข้อความสีเหลืองข้างไดเรกทอรีการทำงานในพรอมต์เทอร์มินัลของ Cloud Shell โดยควรแสดงรหัสโปรเจ็กต์ของคุณ

dcba35ce1389f313.png

หากเซสชัน Cloud Shell รีเซ็ตเมื่อใดก็ตามในระหว่างการทำ Codelab นี้ ให้กลับไปที่ไดเรกทอรีการทำงานแล้วเรียกใช้ bash setup_verify_trial_project.sh && source .env อีกครั้งเพื่อกู้คืนการกำหนดค่าโปรเจ็กต์ ยืนยันว่าข้อความรหัสโปรเจ็กต์สีเหลืองปรากฏขึ้นอีกครั้งในพรอมต์ของเทอร์มินัล

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) - Agent ของคุณใช้โมเดล Gemini และกล่องเครื่องมือใช้ Embedding API สำหรับการค้นหาเวกเตอร์
  • Cloud SQL Admin API (sqladmin.googleapis.com) - คุณจัดสรรและจัดการอินสแตนซ์ PostgreSQL
  • Compute Engine API (compute.googleapis.com) — จำเป็นสำหรับการสร้างอินสแตนซ์ Cloud SQL
  • Cloud Run, Cloud Build, Artifact Registry - ใช้ในขั้นตอนการทำให้ใช้งานได้ในภายหลังในโค้ดแล็บนี้

3. สร้างอินสแตนซ์ฐานข้อมูล

ขั้นตอนนี้จะตั้งค่าการสร้างอินสแตนซ์ Cloud SQL ในเบื้องหลัง ซึ่งจะจัดสรรในขณะที่คุณทำตามบทแนะนำต่อ

เริ่มสร้างอินสแตนซ์

เพิ่มรหัสผ่านฐานข้อมูลลงในไฟล์ .env แล้วโหลดซ้ำ

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

เริ่มสร้างอินสแตนซ์ Cloud SQL โดยจะทำงานในเบื้องหลังเพื่อให้คุณทำงานต่อไปได้

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 คือระดับ Cloud SQL แบบคอร์เฉพาะที่เล็กที่สุด (1 vCPU, RAM 3.75 GB) ในรุ่น ENTERPRISE อ่านรายละเอียดเพิ่มเติมได้ที่นี่ ต้องใช้คอร์เฉพาะสำหรับการผสานรวม Vertex AI ML โดยที่ระดับคอร์ที่ใช้ร่วมกัน (db-f1-micro, db-g1-small) ไม่รองรับ
  • --root-password ตั้งค่ารหัสผ่านสำหรับผู้ใช้ postgres เริ่มต้น
  • --enable-google-ml-integration ช่วยให้การผสานรวมในตัวของ Cloud SQL กับ Vertex AI ทำงานได้ ซึ่งช่วยให้คุณเรียกใช้โมเดลการฝังจาก SQL ได้โดยตรงโดยใช้ฟังก์ชัน embedding()
  • & จะเรียกใช้คำสั่งในเบื้องหลัง

โดยจะทำงานในเบื้องหลัง จากนั้นให้ดาวน์โหลดไบนารีของ MCP Toolbox ซึ่งทำได้ในเทอร์มินัลเดียวกัน

ดาวน์โหลดไบนารีของกล่องเครื่องมือ

ในบทแนะนำนี้ เราจะใช้ MCP Toolbox ซึ่งมาพร้อมกับไบนารีที่สร้างไว้ล่วงหน้าซึ่งพร้อมใช้งานในสภาพแวดล้อม Linux มาดาวน์โหลดในเบื้องหลังกันเลยเพราะอาจใช้เวลานาน

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

ปล่อยให้กระบวนการนี้ทำงานในแท็บปัจจุบัน (เราได้เรียกใช้กระบวนการนี้ในเบื้องหลังแล้ว แต่อินพุตจะยังคงแสดงอยู่) มาเปิดแท็บเทอร์มินัลใหม่ใน Cloud Shell (คลิกไอคอน +) เพื่อให้เราโฟกัสได้มากขึ้น

b01e3fbd89f17332.png

ไปที่ไดเรกทอรีการทำงานอีกครั้งและเปิดใช้งานโปรเจ็กต์โดยใช้สคริปต์การตั้งค่าก่อนหน้า

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

ขั้นตอนนี้จะตั้งค่าโปรเจ็กต์ Python ติดตั้งการอ้างอิง และสร้างโครงสร้างไดเรกทอรีของตัวแทน ADK

4. เริ่มต้นโปรเจ็กต์ Agent

ตั้งค่าโปรเจ็กต์ Python

uv เป็นเครื่องมือจัดการแพ็กเกจและโปรเจ็กต์ Python ที่รวดเร็วซึ่งเขียนด้วย Rust ( เอกสารประกอบของ uv ) Codelab นี้ใช้เพื่อความเร็วและความเรียบง่าย

เริ่มต้นโปรเจ็กต์ Python และเพิ่มการอ้างอิงที่จำเป็น

uv init
uv add google-adk==1.25.0 toolbox-adk==0.6.0
  • google-adk - ชุดพัฒนาเอเจนต์ของ Google ซึ่งรวมถึง Gemini SDK
  • toolbox-adk — การผสานรวม ADK สำหรับกล่องเครื่องมือ MCP สำหรับฐานข้อมูล

สร้างโครงสร้างไดเรกทอรีของเอเจนต์

ADK คาดหวังเลย์เอาต์โฟลเดอร์ที่เฉพาะเจาะจง ได้แก่ ไดเรกทอรีที่มีชื่อตามเอเจนต์ของคุณซึ่งมี __init__.py, agent.py และ .env โดยมีคำสั่งในตัวเพื่อสร้างโครงสร้างได้อย่างรวดเร็ว ดังนี้

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

ตอนนี้ไดเรกทอรีควรมีลักษณะดังนี้

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

5. เริ่มต้นฐานข้อมูลข้อมูลงาน

ขั้นตอนนี้จะเขียนข้อมูลเริ่มต้น รอให้อินสแตนซ์ Cloud SQL จัดสรรเสร็จสมบูรณ์ และโหลดตาราง jobs ที่มีประกาศรับสมัครงาน 15 รายการและการฝังคำอธิบาย

เขียน SQL เริ่มต้น

เราจะสร้างไฟล์ชื่อ seed.sql ใน Cloud Shell Editor โดยมีเนื้อหารายการงาน ซึ่งจะสร้างjobsตารางที่มีpgvectorการสนับสนุนและแทรกประกาศรับสมัครงาน 15 รายการที่บริษัทเทคโนโลยี

ก่อนอื่นให้สร้างไฟล์ seed.sql โดยใช้คำสั่งต่อไปนี้

cloudshell edit seed.sql

จากนั้นคัดลอกสคริปต์เหล่านี้ลงในไฟล์

-- 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.');

สคริปต์เริ่มต้นจะติดตั้งส่วนขยาย PostgreSQL 2 รายการ ได้แก่

  • google_ml_integration — มีฟังก์ชัน SQL ของ embedding() ซึ่งเรียกใช้โมเดลการฝังของ Vertex AI จาก SQL โดยตรง ส่วนขยายนี้เป็นส่วนขยายระดับฐานข้อมูลที่ทำให้ฟังก์ชัน ML พร้อมใช้งานภายใน jobs_db แฟล็กระดับอินสแตนซ์ (--enable-google-ml-integration) ที่คุณตั้งค่าในระหว่างการสร้างอินสแตนซ์จะอนุญาตให้ VM ของ Cloud SQL เข้าถึง Vertex AI ได้ ส่วนการขยายจะทำให้ฟังก์ชัน SQL พร้อมใช้งานภายในฐานข้อมูลที่เฉพาะเจาะจงนี้
  • vector (pgvector) — เพิ่มประเภทข้อมูล vector และตัวดำเนินการระยะทางสำหรับการจัดเก็บและค้นหาการฝัง

คอลัมน์ description_embedding คือ vector(3072) ซึ่งเป็นคอลัมน์ pgvector ที่จัดเก็บเวกเตอร์ 3072 มิติ ตอนนี้ค่าจะเป็น NULL คุณจะสร้างและป้อนข้อมูลการฝังในขั้นตอนถัดไปโดยใช้ฟังก์ชัน embedding()

ตั้งค่าฐานข้อมูลให้เสร็จ

การสร้างอินสแตนซ์ Cloud SQL ที่คุณเริ่มในขั้นตอนก่อนหน้าอาจยังทำงานอยู่และยังไม่เสร็จ ตรวจสอบว่าอินสแตนซ์พร้อมใช้งานแล้ว

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

คุณควรเห็นเอาต์พุตต่อไปนี้

RUNNABLE

34f5b48006b4cb3a.png

จากนั้นให้สิทธิ์บัญชีบริการของอินสแตนซ์ Cloud SQL ในการเรียกใช้ Vertex AI คุณต้องระบุข้อมูลนี้สำหรับฟังก์ชัน embedding() ในตัวที่จะใช้ในขั้นตอนถัดไป

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

หลังจากนั้น ให้สร้างฐานข้อมูลเฉพาะสำหรับข้อมูลงาน โดยทำดังนี้

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

คุณควรเห็นเอาต์พุตที่ยืนยันว่าสร้างฐานข้อมูลแล้ว

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

เชื่อมต่อและเริ่มต้นฐานข้อมูล

เริ่มพร็อกซีการตรวจสอบสิทธิ์ Cloud SQL (cloud-sql-proxy ติดตั้งไว้ล่วงหน้าใน Cloud Shell) ซึ่งจะช่วยให้การเชื่อมต่อจาก Cloud Shell ไปยังอินสแตนซ์ Cloud SQL ของคุณมีความปลอดภัยและมีการตรวจสอบสิทธิ์

d72e56478b517b5c.jpeg

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

หากพร็อกซีเริ่มทำงาน คุณควรเห็นเอาต์พุตต่อไปนี้ในเทอร์มินัล

... 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!

ตอนนี้เทอร์มินัลปัจจุบันจะแสดงบันทึกของ Cloud SQL Proxy อย่างต่อเนื่อง มาเปิดแท็บเทอร์มินัลใหม่ใน Cloud Shell (คลิกไอคอน +) เพื่อให้เราโฟกัสได้มากขึ้น

b01e3fbd89f17332.png

ไปที่ไดเรกทอรีการทำงานอีกครั้งและเปิดใช้งานโปรเจ็กต์โดยใช้สคริปต์การตั้งค่าก่อนหน้า

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

จากนั้นเรียกใช้สคริปต์เริ่มต้น

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

คุณจะเห็นเอาต์พุตของเทอร์มินัลดังนี้

CREATE EXTENSION
CREATE EXTENSION
CREATE TABLE
INSERT 0 15

มาตรวจสอบข้อมูลกัน

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

คุณควรเห็นประกาศรับสมัครงาน 15 รายการในหลายบทบาท ดังนี้

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

สร้างการฝังสำหรับรายละเอียดงาน

ขณะนี้ description_embedding คอลัมน์ในตาราง jobs เป็น NULL google_ml_integrationส่วนขยายในตัวของ Cloud SQL มีembedding()ฟังก์ชันที่เรียกใช้ Vertex AI จาก SQL ได้โดยตรง โดยไม่ต้องใช้สคริปต์ Python หรือ SDK ภายนอก

เริ่มสร้างการฝังในเบื้องหลัง คำสั่งนี้เรียกใช้ Vertex AI เพื่อสร้างเวกเตอร์ 3072 มิติโดยใช้โมเดล gemini-embedding-001 สำหรับคำอธิบายงานทั้ง 15 รายการ

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;" &

สคริปต์นี้จะทำสิ่งต่อไปนี้

  • embedding('gemini-embedding-001', description) — เรียกใช้โมเดลการฝัง Gemini ของ Vertex AI โดยตรงจาก SQL โดยส่งdescriptionข้อความของแต่ละงาน นี่คือส่วนขยาย google_ml_integration ที่คุณติดตั้งในสคริปต์เริ่มต้น
  • ::vector — แปลงอาร์เรย์ของค่าทศนิยมที่ส่งคืนเป็นประเภท vector ของ pgvector เพื่อให้จัดเก็บและค้นหาด้วยโอเปอเรเตอร์ระยะทางได้
  • UPDATE จะทำงานในทั้ง 15 แถว โดยสร้างการฝังมิติ 3072 จำนวน 1 รายการต่อคำอธิบายงาน
  • & จะเรียกใช้คำสั่งในเบื้องหลังเพื่อให้คุณทำงานต่อไปได้ในขณะที่ Vertex AI ประมวลผลการฝัง

เช่นเดียวกับการดำเนินการกระบวนการเบื้องหลังก่อนหน้านี้ เทอร์มินัลปัจจุบันจะแสดงบันทึกของกระบวนการ มาเปิดแท็บเทอร์มินัลใหม่ใน Cloud Shell (คลิกไอคอน +) เพื่อให้เราโฟกัสได้มากขึ้น

b01e3fbd89f17332.png

ไปที่ไดเรกทอรีการทำงานอีกครั้งและเปิดใช้งานโปรเจ็กต์โดยใช้สคริปต์การตั้งค่าก่อนหน้า

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

จากนั้นเราจะดำเนินการในกระบวนการถัดไปได้

6. กำหนดค่ากล่องเครื่องมือ MCP สำหรับฐานข้อมูล

ขั้นตอนนี้จะแนะนำกล่องเครื่องมือ MCP สำหรับฐานข้อมูล กำหนดค่าให้เชื่อมต่อกับอินสแตนซ์ Cloud SQL และกำหนดเครื่องมือค้นหา SQL มาตรฐาน 2 รายการ

MCP คืออะไรและเหตุใดจึงควรใช้กล่องเครื่องมือ

e7b9be2e1c98b4db.png

MCP (Model Context Protocol) เป็นโปรโตคอลแบบเปิดที่กำหนดมาตรฐานวิธีที่ AI Agent ค้นพบและโต้ตอบกับเครื่องมือภายนอก โดยจะกำหนดรูปแบบไคลเอ็นต์-เซิร์ฟเวอร์ ซึ่งเอเจนต์จะโฮสต์ไคลเอ็นต์ MCP และเซิร์ฟเวอร์ MCP จะแสดงเครื่องมือ ไคลเอ็นต์ที่เข้ากันได้กับ MCP สามารถใช้เซิร์ฟเวอร์ที่เข้ากันได้กับ MCP ได้ โดยเอเจนต์ไม่จำเป็นต้องใช้โค้ดการผสานรวมที่กำหนดเองสำหรับแต่ละเครื่องมือ

d5baa77423f0f465.png

กล่องเครื่องมือ MCP สำหรับฐานข้อมูลคือเซิร์ฟเวอร์ MCP แบบโอเพนซอร์สที่สร้างขึ้นเพื่อการเข้าถึงฐานข้อมูลโดยเฉพาะ หากไม่มีฟีเจอร์นี้ คุณจะต้องเขียนฟังก์ชัน Python ที่เปิดการเชื่อมต่อฐานข้อมูล จัดการกลุ่มการเชื่อมต่อ สร้างการค้นหาที่มีพารามิเตอร์เพื่อป้องกันการแทรก SQL จัดการข้อผิดพลาด และฝังโค้ดทั้งหมดนั้นไว้ใน Agent ตัวแทนทุกคนที่ต้องการเข้าถึงฐานข้อมูลจะต้องทำซ้ำ การเปลี่ยนคำค้นหาหมายถึงการติดตั้งใช้งาน Agent อีกครั้ง

โดยคุณจะเขียนไฟล์ YAML ด้วยกล่องเครื่องมือ เครื่องมือแต่ละอย่างจะแมปกับคำสั่ง SQL ที่มีพารามิเตอร์ กล่องเครื่องมือจะจัดการการจัดกลุ่มการเชื่อมต่อ คำค้นที่มีพารามิเตอร์ การตรวจสอบสิทธิ์ และการสังเกตการณ์ เครื่องมือจะแยกออกจากเอเจนต์ โดยคุณสามารถอัปเดตคําค้นหาได้โดยการแก้ไข tools.yaml และรีสตาร์ทกล่องเครื่องมือโดยไม่ต้องแตะต้องโค้ดเอเจนต์ เครื่องมือเดียวกันนี้ใช้ได้กับ ADK, LangGraph, LlamaIndex หรือเฟรมเวิร์กที่เข้ากันได้กับ MCP

เขียนการกำหนดค่าเครื่องมือ

ตอนนี้เราต้องสร้างไฟล์ชื่อ tools.yaml ใน Cloud Shell Editor เพื่อตั้งค่าเครื่องมือ

cloudshell edit tools.yaml

ไฟล์ใช้ YAML แบบหลายเอกสาร โดยแต่ละบล็อกที่คั่นด้วย --- จะเป็นทรัพยากรแบบสแตนด์อโลน ทรัพยากรทุกรายการมี kind ที่ประกาศว่าทรัพยากรนั้นคืออะไร (sources สำหรับการเชื่อมต่อฐานข้อมูล tools สำหรับการดำเนินการที่เรียกใช้ได้ของเอเจนต์) และ type ที่ระบุแบ็กเอนด์ (cloud-sql-postgres สำหรับแหล่งที่มา postgres-sql สำหรับเครื่องมือที่ใช้ SQL) เครื่องมือจะอ้างอิงแหล่งที่มาโดยใช้ name ซึ่งเป็นวิธีที่กล่องเครื่องมือทราบว่าควรใช้ Connection Pool ใด ตัวแปรสภาพแวดล้อมใช้ไวยากรณ์ ${VAR_NAME} และจะได้รับการแก้ไขเมื่อเริ่มต้นระบบ

ตอนนี้มาคัดลอกสคริปต์ต่อไปนี้ลงในไฟล์ 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}

---

สคริปต์นี้จะกำหนดทรัพยากรต่อไปนี้

  • แหล่งที่มา (jobs-db) — บอกกล่องเครื่องมือวิธีกำหนดค่าการเชื่อมต่อกับอินสแตนซ์ Cloud SQL PostgreSQL cloud-sql-postgres ประเภทนี้ใช้เครื่องมือเชื่อมต่อ Cloud SQL ภายใน โดยจะจัดการการตรวจสอบสิทธิ์และการเชื่อมต่อที่ปลอดภัยโดยอัตโนมัติ ระบบจะแก้ไขตัวยึดตำแหน่ง ${GOOGLE_CLOUD_PROJECT} , ${REGION} และ ${DB_PASSWORD} จากตัวแปรสภาพแวดล้อมเมื่อเริ่มต้น

จากนั้น ให้ต่อท้ายสคริปต์ต่อไปนี้ใต้สัญลักษณ์ --- ใน 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)."

---

สคริปต์นี้จะกำหนดทรัพยากรต่อไปนี้

  • เครื่องมือ 1 และ 2 (search-jobs, get-job-details) - เครื่องมือค้นหา SQL มาตรฐาน แต่ละรายการจะแมปชื่อเครื่องมือ (สิ่งที่เอเจนต์เห็น) กับคำสั่ง SQL ที่กำหนดพารามิเตอร์ (สิ่งที่ฐานข้อมูลดำเนินการ) พารามิเตอร์ใช้ตัวยึดตำแหน่งเชิงตำแหน่ง $1, $2 กล่องเครื่องมือจะดำเนินการคำสั่งเหล่านี้เป็นคำสั่งที่เตรียมไว้ ซึ่งจะป้องกันการแทรก SQL

มาต่อกันเลย เพิ่มสคริปต์ต่อไปนี้ใต้สัญลักษณ์ --- ใน tools.yaml

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

---

สคริปต์นี้จะกำหนดทรัพยากรต่อไปนี้

  • โมเดลการฝัง (gemini-embedding) - กำหนดค่ากล่องเครื่องมือให้เรียกใช้โมเดล gemini-embedding-001 ของ Gemini เพื่อสร้างการฝังข้อความแบบ 3072 มิติ กล่องเครื่องมือใช้ข้อมูลเข้าสู่ระบบเริ่มต้นของแอปพลิเคชัน (ADC) เพื่อตรวจสอบสิทธิ์ โดยไม่จำเป็นต้องใช้คีย์ API ใน Cloud Shell หรือ Cloud Run โปรดทราบว่า dimension ที่กำหนดค่าไว้ที่นี่ต้องเหมือนกับที่เรากำหนดค่าไว้ก่อนหน้านี้เพื่อเริ่มต้นฐานข้อมูล

มาต่อกันเลย เพิ่มสคริปต์ต่อไปนี้ใต้สัญลักษณ์ --- ใน 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

---

สคริปต์นี้จะกำหนดทรัพยากรต่อไปนี้

  • เครื่องมือ 3 (search-jobs-by-description) - เครื่องมือค้นหาเวกเตอร์ พารามิเตอร์ search_query มี embeddedBy: gemini-embedding ซึ่งจะบอกกล่องเครื่องมือให้สกัดกั้นข้อความดิบ ส่งไปยังโมเดลการฝัง และใช้เวกเตอร์ผลลัพธ์ในคำสั่ง SQL โอเปอเรเตอร์ <=> คือระยะทางโคไซน์ของ pgvector ซึ่งค่าที่น้อยกว่าหมายถึงคำอธิบายที่คล้ายกันมากขึ้น

สุดท้าย ให้เพิ่มเครื่องมือสุดท้ายภายใต้สัญลักษณ์ --- ใน 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

สคริปต์นี้จะกำหนดทรัพยากรต่อไปนี้

  • เครื่องมือ 4 (add-job) - แสดงการนำเข้าเวกเตอร์ พารามิเตอร์ description_vector มีฟิลด์พิเศษ 2 รายการ ดังนี้
  • valueFromParam: description — กล่องเครื่องมือจะคัดลอกค่าจากพารามิเตอร์ description ไปยังพารามิเตอร์นี้ LLM จะไม่เห็นพารามิเตอร์นี้
  • embeddedBy: gemini-embedding — กล่องเครื่องมือจะฝังข้อความที่คัดลอกลงในเวกเตอร์ก่อนส่งไปยัง SQL

ผลลัพธ์คือการเรียกใช้เครื่องมือเดียวจะจัดเก็บทั้งข้อความคำอธิบายดิบและการฝังเวกเตอร์ของข้อความนั้น โดยที่เอเจนต์ไม่ต้องรู้เรื่องการฝังเลย

รูปแบบ YAML แบบหลายเอกสารจะแยกแต่ละทรัพยากรด้วย --- เอกสารแต่ละฉบับมีฟิลด์ kind, name และ type ที่กำหนดว่าเอกสารนั้นคืออะไร โดยสรุปคือเราได้กำหนดค่าสิ่งต่อไปนี้ทั้งหมดแล้ว

  • กำหนดฐานข้อมูลต้นทาง
  • กำหนดเครื่องมือ ( tool 1 และ 2 ) เพื่อค้นหาฐานข้อมูลด้วยตัวกรองมาตรฐาน
  • กำหนดโมเดลการฝัง
  • กำหนดเครื่องมือเพื่อทำการค้นหาเวกเตอร์ ( tool 3 ) ไปยังฐานข้อมูล
  • กำหนดเครื่องมือเพื่อทำการนำเข้าข้อมูลเวกเตอร์ ( เครื่องมือ 4) ไปยังฐานข้อมูล

ยืนยันการฝัง

ก่อนเริ่มใช้กล่องเครื่องมือ ให้ตรวจสอบว่าการสร้างการฝังพื้นหลังเสร็จสมบูรณ์แล้ว ตรวจสอบว่าตอนนี้งานทั้งหมดมี Embedding แล้ว

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

ทุกแถวควรแสดง t (จริง) ในคอลัมน์ has_embedding หากไม่ต้องการ คุณสามารถเลือกที่จะรอจนกว่ากระบวนการสร้างการฝังแถวทั้งหมดจะเสร็จสิ้น

           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

เริ่มเซิร์ฟเวอร์กล่องเครื่องมือ

ในขั้นตอนการตั้งค่า เราได้ดาวน์โหลดไฟล์ที่เรียกใช้งานได้ของ toolbox แล้ว ตรวจสอบว่ามีไฟล์ไบนารีนี้และดาวน์โหลดสำเร็จ หากไม่มี ให้ดาวน์โหลดและรอจนกว่าจะเสร็จสิ้น

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

ส่งออกตัวแปรสภาพแวดล้อมที่จำเป็นและเริ่ม Toolbox ต้องระบุตัวแปร GOOGLE_CLOUD_LOCATION และ GOOGLE_GENAI_USE_VERTEXAI เนื่องจากค่ากำหนดมีการฝังโมเดล GOOGLE_GENAI_USE_VERTEXAI จะบอกให้ Gemini SDK กำหนดเส้นทางผ่าน Vertex AI (แทนที่จะใช้ Gemini API สำหรับผู้บริโภค) และ GOOGLE_CLOUD_LOCATION จะบอกว่าต้องใช้ปลายทางระดับภูมิภาคใด

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 &

คุณควรเห็นเอาต์พุตที่ยืนยันว่าเซิร์ฟเวอร์พร้อมแล้วดังที่แสดงด้านล่าง

... 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!"

เช่นเดียวกับขั้นตอนก่อนหน้า ขั้นตอนนี้จะสร้างกระบวนการอื่นและแสดงเอาต์พุต มาเปิดแท็บเทอร์มินัลใหม่ใน Cloud Shell (คลิกไอคอน +) เพื่อให้เราโฟกัสได้มากขึ้น

b01e3fbd89f17332.png

ไปที่ไดเรกทอรีการทำงานอีกครั้งและเปิดใช้งานโปรเจ็กต์โดยใช้สคริปต์การตั้งค่าก่อนหน้า

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

ยืนยันเครื่องมือ

ส่งคำค้นหาไปยัง Toolbox API เพื่อแสดงรายการเครื่องมือที่ลงทะเบียนทั้งหมด

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

คุณควรเห็นเครื่องมือพร้อมคำอธิบายและพารามิเตอร์ ดังที่แสดงด้านล่าง

...
       
"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": []
        }
...

ทดสอบsearch-jobsโดยตรง

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'

คำตอบควรมีงานวิศวกรแบ็กเอนด์ 2 งานจากข้อมูลเริ่มต้น

[
  {
    "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. สร้าง ADK Agent

ขั้นตอนนี้จะเชื่อมต่อ Agent ของ ADK กับเซิร์ฟเวอร์กล่องเครื่องมือที่ทำงานอยู่ และทดสอบเครื่องมือทั้ง 4 รายการ ได้แก่ การค้นหามาตรฐาน การค้นหาเชิงความหมาย และการนำเข้าเวกเตอร์ โค้ดของ Agent มีขนาดเล็กมาก เนื่องจากตรรกะของฐานข้อมูลทั้งหมดอยู่ใน tools.yaml

กำหนดค่าสภาพแวดล้อมของ Agent

ADK จะอ่าน GOOGLE_GENAI_USE_VERTEXAI, GOOGLE_CLOUD_PROJECT และ GOOGLE_CLOUD_LOCATION จากสภาพแวดล้อมของเชลล์ ซึ่งคุณได้ตั้งค่าไว้แล้วในขั้นตอนก่อนหน้า ตัวแปรเฉพาะตัวแทนมีเพียง TOOLBOX_URL เท่านั้น ให้ต่อท้ายตัวแปรนี้ในไฟล์ .env ของตัวแทน

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

อัปเดตโมดูลตัวแทน

เปิด jobs_agent/agent.py ใน Cloud Shell Editor

cloudshell edit jobs_agent/agent.py

และเขียนทับเนื้อหาด้วยโค้ดต่อไปนี้

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

โปรดทราบว่าไม่มีโค้ดฐานข้อมูลที่นี่ ToolboxToolset จะเชื่อมต่อกับเซิร์ฟเวอร์ Toolbox เมื่อเริ่มต้นและโหลดเครื่องมือทั้งหมดที่พร้อมใช้งาน เอเจนต์จะเรียกใช้เครื่องมือตามชื่อ ส่วนกล่องเครื่องมือจะแปลการเรียกเหล่านั้นเป็นการค้นหา SQL กับ Cloud SQL

ตัวแปรสภาพแวดล้อม TOOLBOX_URL จะมีค่าเริ่มต้นเป็น http://127.0.0.1:5000 สำหรับการพัฒนาในเครื่อง เมื่อคุณทําการติดตั้งใช้งานใน Cloud Run ในภายหลัง คุณจะลบล้างการตั้งค่านี้ด้วย URL ของ Cloud Run ของบริการกล่องเครื่องมือ โดยไม่ต้องเปลี่ยนแปลงโค้ด

ปัจจุบันคำสั่งอ้างอิงเฉพาะเครื่องมือมาตรฐาน 2 รายการ (search-jobs และ get-job-details) คุณจะขยายคำสั่งในขั้นตอนถัดไปเมื่อเพิ่มเครื่องมือการค้นหาเชิงความหมายและการนำเข้า

ทดสอบ Agent

เปิด UI สำหรับนักพัฒนาแอป ADK โดยทำดังนี้

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

เปิด URL ที่แสดงในเทอร์มินัล (โดยปกติคือ http://localhost:8000) โดยใช้ฟีเจอร์การแสดงตัวอย่างเว็บของ Cloud Shell หรือ Ctrl + คลิก URL ที่แสดงในเทอร์มินัล เลือก jobs_agent จากเมนูแบบเลื่อนลงของเอเจนต์ที่มุมซ้ายบน

ทดสอบคำค้นหามาตรฐาน

ลองใช้พรอมต์ต่อไปนี้เพื่อยืนยันเครื่องมือ SQL มาตรฐาน

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

93ac33e7f73aa0b9.png 240c53376042a916.png

ลองใช้คำอธิบายภาษาธรรมชาติที่ไม่ได้เชื่อมโยงกับบทบาทหรือเทคโนโลยีเฉพาะ

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

เอเจนต์จะพยายามเลือกเครื่องมือที่เหมาะสมตามประเภทคำค้นหา โดยตัวกรองที่มีโครงสร้างจะผ่าน search-jobs ส่วนคำอธิบายภาษาธรรมชาติจะผ่าน search-jobs-by-description

b0ea629f5c9b4c26.png

ทดสอบการส่งผ่านข้อมูลเวกเตอร์

ขอให้ตัวแทนเพิ่มงานใหม่โดยทำดังนี้

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

ตอนนี้ลองค้นหาโดยใช้คำต่อไปนี้

Find me jobs involving autonomous systems and working with physical hardware

ระบบสร้างการฝังโดยอัตโนมัติระหว่าง INSERT จึงไม่จำเป็นต้องมีขั้นตอนแยกต่างหาก

5a3d8e6f523dc18b.png

ตอนนี้คุณมีแอปพลิเคชัน Agentic RAG ที่ใช้งานได้อย่างเต็มรูปแบบซึ่งใช้ ADK, MCP Toolbox และ CloudSQL อยู่แล้ว ยินดีด้วย มาดูขั้นตอนเพิ่มเติมในการทำให้แอปเหล่านี้ใช้งานได้กับ Cloud Run กัน

ตอนนี้มาหยุด UI สำหรับนักพัฒนาซอฟต์แวร์โดยการสิ้นสุดกระบวนการด้วยการกด Ctrl+C 2 ครั้งก่อนดำเนินการต่อ

8. ทำให้ใช้งานได้กับ Cloud Run

เอเจนต์และกล่องเครื่องมือจะทำงานในเครื่อง ขั้นตอนนี้จะทำให้ทั้ง 2 อย่างใช้งานได้เป็นบริการ Cloud Run เพื่อให้เข้าถึงได้ผ่านอินเทอร์เน็ต บริการกล่องเครื่องมือจะทำงานเป็นเซิร์ฟเวอร์ MCP ใน Cloud Run และบริการตัวแทนจะเชื่อมต่อกับเซิร์ฟเวอร์ดังกล่าว

เตรียมกล่องเครื่องมือสำหรับการติดตั้งใช้งาน

สร้างไดเรกทอรีการติดตั้งใช้งานสำหรับบริการกล่องเครื่องมือ

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

สร้าง Dockerfile สำหรับกล่องเครื่องมือ เปิด deploy-toolbox/Dockerfile ใน Cloud Shell Editor โดยทำดังนี้

cloudshell edit deploy-toolbox/Dockerfile

แล้วคัดลอกสคริปต์ต่อไปนี้ลงในสเปรดชีต

# 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"]

ไบนารีของกล่องเครื่องมือและ tools.yaml จะรวมอยู่ในอิมเมจ Debian ขนาดเล็ก Cloud Run จะกำหนดเส้นทางการรับส่งข้อมูลไปยังพอร์ต 8080

ติดตั้งใช้งานบริการกล่องเครื่องมือ

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

คำสั่งนี้จะส่งซอร์สไปยัง Cloud Build สร้างอิมเมจคอนเทนเนอร์ พุชไปยัง Artifact Registry และทำให้ใช้งานได้กับ Cloud Run ซึ่งใช้เวลาเพียงไม่กี่นาที มาเปิดแท็บเทอร์มินัลใหม่ใน Cloud Shell (คลิกไอคอน +) เพื่อให้เราโฟกัสได้มากขึ้น

b01e3fbd89f17332.png

ไปที่ไดเรกทอรีการทำงานอีกครั้งและเปิดใช้งานโปรเจ็กต์โดยใช้สคริปต์การตั้งค่าก่อนหน้า

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

เตรียมตัวแทนสำหรับการติดตั้งใช้งาน

ขณะที่กล่องเครื่องมือสร้าง ให้ตั้งค่าไฟล์การติดตั้งใช้งานของ Agent

สร้าง Dockerfile ในรูทของโปรเจ็กต์ เปิด Dockerfile ใน Cloud Shell Editor โดยทำดังนี้

cloudshell edit Dockerfile

จากนั้นคัดลอกเนื้อหาต่อไปนี้

# 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"]

Dockerfile นี้ใช้ ghcr.io/astral-sh/uv เป็นอิมเมจพื้นฐาน ซึ่งมีทั้ง Python และ uv ที่ติดตั้งไว้ล่วงหน้าแล้ว จึงไม่จำเป็นต้องติดตั้ง uv แยกต่างหากผ่าน pip

สร้างไฟล์ .dockerignore เพื่อยกเว้นไฟล์ที่ไม่จำเป็นจากอิมเมจคอนเทนเนอร์

cloudshell edit .dockerignore

จากนั้นคัดลอกสคริปต์ต่อไปนี้ลงในไฟล์

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

ติดตั้งใช้งานบริการของ Agent

รอให้การติดตั้งใช้งานกล่องเครื่องมือเสร็จสมบูรณ์ เรียกข้อมูล URL ของ Cloud Run โดยใช้คำสั่งต่อไปนี้

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

คุณจะเห็นเอาต์พุตที่คล้ายกันดังนี้

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

จากนั้นมาตรวจสอบว่ากล่องเครื่องมือที่ติดตั้งใช้งานทำงานได้หรือไม่

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

หากเอาต์พุตแสดงเหมือนตัวอย่างนี้ แสดงว่าการติดตั้งใช้งานสำเร็จแล้ว

{
    "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.",

จากนั้นมาติดตั้งใช้งานเอเจนต์โดยส่งผ่าน URL ของกล่องเครื่องมือเป็นตัวแปรสภาพแวดล้อมกัน

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

รหัสตัวแทนจะอ่าน TOOLBOX_URL จากสภาพแวดล้อม (คุณตั้งค่านี้ไว้ก่อนหน้านี้) ในเครื่องจะชี้ไปยัง http://127.0.0.1:5000 แต่ใน Cloud Run จะชี้ไปยัง URL ของบริการกล่องเครื่องมือ โดยไม่ต้องเปลี่ยนแปลงโค้ดใดๆ

ทดสอบ Agent ที่ติดตั้งใช้งาน

เรียกข้อมูล URL ของ Cloud Run ของ Agent โดยทำดังนี้

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

เปิด URL ในเบราว์เซอร์ UI สำหรับนักพัฒนาซอฟต์แวร์ ADK จะโหลดขึ้นมา ซึ่งเป็นอินเทอร์เฟซเดียวกันกับที่คุณใช้ในเครื่อง แต่ตอนนี้ทำงานบน Cloud Run

เลือก jobs_agent จากเมนูแบบเลื่อนลง แล้วทดสอบ

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

ทั้ง 2 คำสั่งค้นหาจะทำงานผ่านบริการที่ทำให้ใช้งานได้ โดย Agent ใน Cloud Run จะเรียกใช้กล่องเครื่องมือใน Cloud Run ซึ่งจะค้นหา Cloud SQL

9. ขอแสดงความยินดี / ล้างข้อมูล

คุณได้สร้างและติดตั้งใช้งานผู้ช่วยกระดานรับสมัครงานอัจฉริยะที่ใช้กล่องเครื่องมือ MCP สำหรับฐานข้อมูลเพื่อเชื่อมต่อเอเจนต์ ADK กับ Cloud SQL PostgreSQL โดยใช้ทั้งการค้นหา SQL มาตรฐานและการค้นหาเวกเตอร์เชิงความหมาย

สิ่งที่คุณได้เรียนรู้

  • วิธีที่ MCP ทำให้การเข้าถึงเครื่องมือสำหรับเอเจนต์ AI เป็นมาตรฐาน และวิธีที่ MCP Toolbox for Databases ใช้การดำเนินการนี้กับการดำเนินการฐานข้อมูลโดยเฉพาะ ซึ่งแทนที่โค้ดฐานข้อมูลที่กำหนดเองด้วยการกำหนดค่า YAML ที่ประกาศ
  • วิธีกำหนดค่า Cloud SQL PostgreSQL เป็นแหล่งข้อมูลของกล่องเครื่องมือโดยใช้cloud-sql-postgresประเภทแหล่งที่มา
  • วิธีกำหนดเครื่องมือค้นหา SQL มาตรฐานด้วยคำสั่งที่มีพารามิเตอร์ซึ่งป้องกันการแทรก SQL
  • วิธีเปิดใช้การค้นหาเวกเตอร์โดยใช้ pgvector และ gemini-embedding-001 โดยมีพารามิเตอร์ embeddedBy สำหรับการฝังคำค้นหาอัตโนมัติ
  • วิธีที่ valueFromParam ช่วยให้การนำเข้าเวกเตอร์อัตโนมัติเป็นไปได้ - LLM จะให้คำอธิบายข้อความ และกล่องเครื่องมือจะคัดลอก ฝัง และจัดเก็บเวกเตอร์ควบคู่ไปกับข้อความโดยอัตโนมัติ
  • วิธีที่ ToolboxToolset ของ ADK โหลดเครื่องมือจากเซิร์ฟเวอร์ Toolbox ที่ทำงานอยู่ ทำให้โค้ดของเอเจนต์มีขนาดเล็กที่สุดและตรรกะของฐานข้อมูลแยกออกจากกันอย่างสมบูรณ์
  • วิธีติดตั้งใช้งานทั้งเซิร์ฟเวอร์ MCP ของกล่องเครื่องมือและตัวแทน ADK ใน Cloud Run เป็นบริการแยกต่างหาก

ล้างข้อมูล

หากต้องการหลีกเลี่ยงการเรียกเก็บเงินจากบัญชี Google Cloud สำหรับทรัพยากรที่สร้างขึ้นในโค้ดแล็บนี้ คุณสามารถลบทรัพยากรแต่ละรายการหรือลบทั้งโปรเจ็กต์ก็ได้

วิธีที่ง่ายที่สุดในการล้างข้อมูลคือการลบโปรเจ็กต์ ซึ่งจะเป็นการนำทรัพยากรทั้งหมดที่เชื่อมโยงกับโปรเจ็กต์ออก

gcloud projects delete $GOOGLE_CLOUD_PROJECT

ตัวเลือกที่ 2: ลบทรัพยากรแต่ละรายการ

หากต้องการเก็บโปรเจ็กต์ไว้แต่ต้องการนำเฉพาะทรัพยากรที่สร้างขึ้นในโค้ดแล็บนี้ออก ให้ทำดังนี้

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