Cymbal Transit: Sistem multi-agen yang menggunakan LangChain4J dan MCP Toolbox Java SDK

1. Ringkasan

Pelancong modern mengharapkan pengalaman percakapan. Daripada menavigasi filter UI yang kompleks, mereka ingin bertanya, "Bolehkah saya membawa saya di bus pukul 09.00 ke Boston?" Hal ini memerlukan agen yang dapat melakukan penalaran di seluruh data tidak terstruktur (kebijakan PDF) dan data terstruktur (jadwal SQL).

Dalam lab ini, kita akan membangun Cymbal Transit Agent menggunakan:

  • LangChain4j: Framework Java utama untuk orkestrasi AI.
  • AlloyDB: Database berperforma tinggi yang kompatibel dengan PostgreSQL.
  • MCP Toolbox Java SDK: Cara standar untuk menghubungkan agen Java ke alat dan sumber data eksternal.

Yang akan Anda build

e68388d533c9997e.png

Cymbal Bus Agent, aplikasi Java Spring Boot yang terdiri dari:

  1. Database AlloyDB dan MCP Toolbox Java SDK untuk orkestrasi alat dengan agen.
  2. Cloud Run untuk Deployment dan Aplikasi Toolbox (deployment agen).
  3. Library LangChain4J untuk framework agen dan LLM dalam Aplikasi Spring Boot dengan Java 17.

Yang akan Anda pelajari

  • Cara menggunakan LangChain4J untuk membuat agen dan sub-agen khusus yang diatur menggunakan MCP Toolbox for Databases Java SDK
  • Cara menyiapkan dan menggunakan AlloyDB untuk data dan AI.
  • Cara menggunakan MCP Toolbox untuk menghubungkan agen ke alat data AlloyDB.
  • Cara men-deploy solusi menggunakan Cloud Run atau menjalankannya secara lokal.

Arsitektur

  1. AlloyDB untuk PostgreSQL: Berfungsi sebagai database operasional berperforma tinggi yang menyimpan catatan rute, kebijakan, dan pemesanan kami. Fitur ini mendukung penelusuran dan pengambilan vektor.
  2. Java SDK MCP Toolbox for Databases: Bertindak sebagai "Orchestration Maestro", yang mengekspos data AlloyDB sebagai alat yang dapat dieksekusi yang dapat dipanggil oleh agen.

MCP Toolbox Java SDK memungkinkan orkestrasi agen dengan alat database Anda secara mudah untuk aplikasi tingkat perusahaan.

  1. LangChain4J: Library Java open source yang menyederhanakan integrasi Model Bahasa Besar (LLM) ke dalam aplikasi Java. Platform ini menyediakan alat dan abstraksi untuk membangun aplikasi berteknologi AI, termasuk chatbot, agen, dan sistem Retrieval-Augmented Generation (RAG).
  2. Cloud Run: Platform SERVERLESS terkelola sepenuhnya yang memungkinkan Anda membangun & men-deploy aplikasi atau situs dengan cepat dalam bahasa, library, biner apa pun. Anda dapat menulis kode menggunakan bahasa, framework, dan library favorit, mengemasnya sebagai container, menjalankan "gcloud run deploy," dan aplikasi Anda akan aktif—disediakan dengan semua yang diperlukan untuk berjalan dalam production. Membuat container sepenuhnya bersifat opsional. Jika menggunakan bahasa Go, Node.js, Python, Java, .NET Core, atau Ruby, Anda dapat menggunakan opsi deployment berbasis sumber yang dapat membantu membangun container untuk Anda, dengan menggunakan praktik terbaik untuk bahasa yang Anda gunakan.

Persyaratan

  • Browser, seperti Chrome atau Firefox.
  • Project Google Cloud yang mengaktifkan penagihan.
  • Pemahaman dasar tentang SQL dan Java.

2. Sebelum memulai

Membuat project

  1. Di Konsol Google Cloud, di halaman pemilih project, pilih atau buat project Google Cloud.
  2. Pastikan penagihan diaktifkan untuk project Cloud Anda. Pelajari cara memeriksa apakah penagihan telah diaktifkan pada suatu project.
  1. Anda akan menggunakan Cloud Shell, lingkungan command line yang berjalan di Google Cloud. Klik Activate Cloud Shell di bagian atas konsol Google Cloud.

Gambar tombol Activate Cloud Shell

  1. Setelah terhubung ke Cloud Shell, Anda dapat memeriksa bahwa Anda sudah diautentikasi dan project sudah ditetapkan ke project ID Anda menggunakan perintah berikut:
gcloud auth list
  1. Jalankan perintah berikut di Cloud Shell untuk mengonfirmasi bahwa perintah gcloud mengetahui project Anda.
gcloud config list project
  1. Jika project Anda belum ditetapkan, gunakan perintah berikut untuk menetapkannya:
gcloud config set project <YOUR_PROJECT_ID>
  1. Aktifkan API yang diperlukan: Ikuti link dan aktifkan API.

Atau, Anda dapat menggunakan perintah gcloud untuk melakukannya. Baca dokumentasi untuk mempelajari perintah gcloud dan penggunaannya.

Gotcha & Pemecahan Masalah

Sindrom "Project Hantu"

Anda menjalankan gcloud config set project, tetapi sebenarnya Anda melihat project lain di UI Konsol. Periksa project ID di dropdown kiri atas.

Penghalang Penagihan

Anda mengaktifkan project, tetapi lupa akun penagihan. AlloyDB adalah mesin berperforma tinggi; mesin ini tidak akan dimulai jika "tangki bahan bakar" (penagihan) kosong.

Keterlambatan Penyebaran API

Anda mengklik "Aktifkan API", tetapi command line masih menampilkan Service Not Enabled. Tunggu 60 detik. Cloud memerlukan waktu sejenak untuk mengaktifkan neuronnya.

Quota Quags

Jika menggunakan akun uji coba yang baru, Anda mungkin mencapai kuota regional untuk instance AlloyDB. Jika us-central1 gagal, coba us-east1.

Agen Layanan"Tersembunyi"

Terkadang, Agen Layanan AlloyDB tidak otomatis diberi peran aiplatform.user. Jika kueri SQL Anda tidak dapat berkomunikasi dengan Gemini di lain waktu, biasanya hal ini adalah penyebabnya.

3. Penyiapan database

Di inti aplikasi kami terdapat AlloyDB untuk PostgreSQL. Kami memanfaatkan kemampuan vektornya yang canggih dan mesin columnar terintegrasi untuk membuat sematan bagi lebih dari 50.000 catatan SCM. Hal ini memungkinkan analisis vektor hampir real-time, sehingga agen kami dapat mengidentifikasi anomali inventaris atau risiko logistik di seluruh set data besar dalam milidetik.

Di lab ini, kita akan menggunakan AlloyDB sebagai database untuk data pengujian. Cloud SQL menggunakan cluster untuk menyimpan semua resource, seperti database dan log. Setiap cluster memiliki instance utama yang menyediakan titik akses ke data. Tabel akan menyimpan data sebenarnya.

Mari kita buat cluster, instance, dan tabel AlloyDB tempat set data pengujian akan dimuat.

  1. Klik tombol atau Salin link di bawah ke browser tempat Anda login sebagai pengguna Konsol Google Cloud.

Atau, Anda dapat membuka Terminal Cloud Shell dari project tempat Anda menukarkan akun penagihan, lalu meng-clone repo github dan membuka project menggunakan perintah di bawah:

git clone https://github.com/AbiramiSukumaran/easy-alloydb-setup

cd easy-alloydb-setup
  1. Setelah langkah ini selesai, repo akan di-clone ke editor Cloud Shell lokal Anda dan Anda akan dapat menjalankan perintah di bawah dari folder project (penting untuk memastikan Anda berada di direktori project):
sh run.sh
  1. Sekarang gunakan UI (dengan mengklik link di terminal atau mengklik link "preview on web" di terminal.
  2. Masukkan detail Anda untuk project id, nama cluster, dan nama instance untuk memulai.
  3. Pergilah minum kopi sambil melihat log yang bergulir dan Anda dapat membaca tentang cara kerjanya di balik layar di sini.

Gotcha & Pemecahan Masalah

Masalah "Kesabaran"

Cluster database adalah infrastruktur yang berat. Jika Anda memuat ulang halaman atau menghentikan sesi Cloud Shell karena "tampaknya macet", Anda mungkin akan mendapatkan instance "hantu" yang disediakan sebagian dan tidak dapat dihapus tanpa intervensi manual.

Ketidakcocokan Region

Jika Anda mengaktifkan API di us-central1 tetapi mencoba menyediakan cluster di asia-south1, Anda mungkin mengalami masalah kuota atau penundaan izin Akun Layanan. Tetap gunakan satu region untuk seluruh lab.

Cluster Zombie

Jika sebelumnya Anda menggunakan nama yang sama untuk cluster dan tidak menghapusnya, skrip mungkin akan menyatakan bahwa nama cluster sudah ada. Nama cluster harus unik dalam project.

Waktu Tunggu Cloud Shell

Jika istirahat kopi Anda berlangsung selama 30 menit, Cloud Shell mungkin akan memasuki mode tidur dan menghentikan proses sh run.sh. Biarkan tab tetap aktif.

4. Penyediaan Skema

Setelah cluster dan instance AlloyDB Anda berjalan, buka editor SQL AlloyDB Studio untuk mengaktifkan ekstensi AI dan menyediakan skema.

1e3ac974b18a8113.png

Anda mungkin perlu menunggu hingga instance selesai dibuat. Setelah selesai, login ke AlloyDB menggunakan kredensial yang Anda buat saat membuat cluster. Gunakan data berikut untuk melakukan autentikasi ke PostgreSQL:

  • Nama pengguna : "postgres"
  • Database : "postgres"
  • Sandi : "alloydb" (atau apa pun yang Anda tetapkan pada saat pembuatan)

Setelah Anda berhasil diautentikasi ke AlloyDB Studio, perintah SQL dimasukkan di Editor. Anda dapat menambahkan beberapa jendela Editor menggunakan tanda plus di sebelah kanan jendela terakhir.

28cb9a8b6aa0789f.png

Anda akan memasukkan perintah untuk AlloyDB di jendela editor, menggunakan opsi Jalankan, Format, dan Hapus sesuai kebutuhan.

Mengaktifkan Ekstensi

Untuk membangun aplikasi ini, kita akan menggunakan ekstensi pgvector dan google_ml_integration. Ekstensi pgvector memungkinkan Anda menyimpan dan menelusuri embedding vektor. Ekstensi google_ml_integration menyediakan fungsi yang Anda gunakan untuk mengakses endpoint prediksi Vertex AI guna mendapatkan prediksi di SQL. Aktifkan ekstensi ini dengan menjalankan DDL berikut:

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

Berikan Izin

Jalankan pernyataan di bawah untuk memberikan izin eksekusi pada fungsi "embedding":

GRANT EXECUTE ON FUNCTION embedding TO postgres;

Memberikan PERAN Vertex AI User ke akun layanan AlloyDB

Dari konsol IAM Google Cloud, berikan akses akun layanan AlloyDB (yang terlihat seperti ini: service-<<PROJECT_NUMBER>>@gcp-sa-alloydb.iam.gserviceaccount.com) ke peran "Pengguna Vertex AI". PROJECT_NUMBER akan memiliki nomor project Anda.

Atau, Anda dapat menjalankan perintah di bawah dari Terminal Cloud Shell:

PROJECT_ID=$(gcloud config get-value project)


gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:service-$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")@gcp-sa-alloydb.iam.gserviceaccount.com" \
--role="roles/aiplatform.user"

Membuat tabel

Anda dapat membuat tabel menggunakan pernyataan DDL di bawah di AlloyDB Studio:

DROP TABLE IF EXISTS transit_policies;
DROP TABLE IF EXISTS bus_schedules;
DROP TABLE IF EXISTS bookings;

-- Table 1: Transit Policies (Unstructured Data for RAG)
CREATE TABLE transit_policies (
    policy_id SERIAL PRIMARY KEY,
    category VARCHAR(50),
    policy_text TEXT,
    policy_embedding vector(768) 
);

-- Table 2: Intercity Bus Schedules (Structured Data)
CREATE TABLE bus_schedules (
    trip_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    origin_city VARCHAR(100),
    destination_city VARCHAR(100),
    departure_time TIMESTAMP,
    arrival_time TIMESTAMP,
    available_seats INT DEFAULT 50,
    ticket_price DECIMAL(6,2)
);

-- Table 3: Booking Ledger (Transactional Action Data)
CREATE TABLE bookings (
    booking_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    trip_id UUID REFERENCES bus_schedules(trip_id),
    passenger_id VARCHAR(100),
    status VARCHAR(20) DEFAULT 'CONFIRMED',
    booking_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Kolom policy_embedding akan memungkinkan penyimpanan untuk nilai vektor beberapa kolom teks.

Penyerapan Data

Jalankan kumpulan pernyataan SQL di bawah untuk menyisipkan data secara massal di tabel masing-masing:

  1. Menyisipkan Kebijakan Tidak Terstruktur dan MEMBUAT EMBEDDING NYATA secara native di AlloyDB
-- 1. Insert Unstructured Policies and GENERATE REAL EMBEDDINGS natively in AlloyDB

INSERT INTO transit_policies (category, policy_text, policy_embedding) 
VALUES 
('Pets', 'Service animals are always welcome. Small pets (under 25 lbs) are allowed in secure carriers for a $25 fee. Large dogs are not permitted on standard coaches.', embedding('text-embedding-005', 'Service animals are always welcome. Small pets (under 25 lbs) are allowed in secure carriers for a $25 fee. Large dogs are not permitted on standard coaches.')),
('Luggage', 'Each passenger is allowed one carry-on (up to 15 lbs) and two stowed bags (up to 50 lbs each) free of charge. Additional bags cost $15 each.', embedding('text-embedding-005', 'Each passenger is allowed one carry-on (up to 15 lbs) and two stowed bags (up to 50 lbs each) free of charge. Additional bags cost $15 each.')),
('Refunds', 'Tickets are fully refundable up to 24 hours before departure. Within 24 hours, tickets can be exchanged for travel credit only.', embedding('text-embedding-005', 'Tickets are fully refundable up to 24 hours before departure. Within 24 hours, tickets can be exchanged for travel credit only.'));
  1. Membuat 200+ Jadwal Realistis untuk 7 Hari menggunakan generate_series
-- 2. Generate 200+ Realistic Schedules for the Next 7 Days using generate_series

INSERT INTO bus_schedules (origin_city, destination_city, departure_time, arrival_time, ticket_price, available_seats)
SELECT 
    origin,
    destination,
    -- Generate departures every 4 hours starting from tomorrow
    (CURRENT_DATE + 1) + (interval '4 hours' * seq) AS dep_time,
    (CURRENT_DATE + 1) + (interval '4 hours' * seq) + interval '4.5 hours' AS arr_time,
    ROUND((RANDOM() * 30 + 25)::numeric, 2) AS price, -- Random price between $25 and $55
    FLOOR(RANDOM() * 50 + 1) AS seats -- Random seats between 1 and 50
FROM 
    (VALUES 
        ('New York', 'Boston'), ('Boston', 'New York'),
        ('Philadelphia', 'Washington DC'), ('Washington DC', 'Philadelphia'),
        ('Seattle', 'Portland'), ('Portland', 'Seattle')
    ) AS routes(origin, destination)
CROSS JOIN generate_series(1, 40) AS seq; -- 6 routes * 40 time slots = 240 distinct trips ingested!

Membuat Embedding

Embedding otomatis tercakup dalam pernyataan penyisipan ke dalam tabel transit_policies menggunakan fungsi "embedding('text-embedding-005', '<<policytext>>')".

Gotcha & Pemecahan Masalah

Loop "Lupa Sandi"

Jika Anda menggunakan penyiapan "Satu Klik" dan tidak dapat mengingat sandi, buka halaman informasi dasar Instance di konsol dan klik "Edit" untuk mereset sandi postgres.

Error "Ekstensi Tidak Ditemukan"

Jika CREATE EXTENSION gagal, hal ini sering kali disebabkan karena instance masih dalam status "Pemeliharaan" atau "Memperbarui" dari penyediaan awal. Periksa apakah langkah pembuatan instance sudah selesai dan tunggu beberapa detik jika diperlukan.

Masalah Propagasi IAM

Anda menjalankan perintah IAM gcloud, tetapi SQL CALL masih gagal dengan error izin. Perubahan IAM mungkin memerlukan waktu beberapa saat untuk diterapkan melalui backbone Google. Tarik napas.***KRITIS:

  1. Terkadang, akun layanan AlloyDB Anda mungkin terlihat berbeda dari format yang ada yang telah kami gunakan dalam langkah pemberian izin. Jadi, untuk memastikan 100% bahwa akun layanan AlloyDB memiliki Peran Pengguna Vertex AI: Buka halaman AlloyDB Clusters di Konsol Google Cloud. Klik cluster Anda, dan di tab Overview, cari kolom berlabel Service Account.
    Salin nilainya, lalu buka IAM dan tambahkan Peran Pengguna Vertex AI.
  2. Selain itu, jika Anda melewati langkah "Aktifkan API" di bagian "Sebelum memulai", Anda akan mengalami masalah saat mengakses sematan dari AlloyDB.

Ketidakcocokan Dimensi Vektor

Kolom policy_embedding tabel transit_policies ditetapkan ke VECTOR(768). Jika Anda mencoba menggunakan model lain (seperti model 1536 dimensi) nanti, sisipan Anda akan meledak. Tetap gunakan text-embedding-005.

Kesalahan Pengetikan Project ID

Dalam panggilan create_model, jika Anda membiarkan tanda kurung « » atau salah mengetikkan ID project, pendaftaran model akan terlihat berhasil, tetapi gagal selama kueri pertama yang sebenarnya. Periksa kembali string Anda.

5. Penyiapan Alat & Toolbox

MCP Toolbox for Databases adalah server MCP open source untuk database. Hal ini memungkinkan Anda mengembangkan alat dengan lebih mudah, cepat, dan aman dengan menangani kompleksitas seperti penggabungan koneksi, autentikasi, dan lainnya. Toolbox membantu Anda membangun alat AI Generatif yang memungkinkan agen Anda mengakses data di database Anda.

Kita menggunakan Model Context Protocol (MCP) Toolbox for Databases sebagai "konduktor". Aplikasi ini berfungsi sebagai middleware standar antara agen kami dan AlloyDB. Dengan menentukan konfigurasi tools.yaml, toolbox akan otomatis mengekspos operasi database yang kompleks sebagai alat yang bersih dan dapat dieksekusi seperti find-bus-schedules and routes atau query-schedules for specific routes dan menjalankan tindakan otonom seperti book-ticket. Hal ini menghilangkan kebutuhan akan penggabungan koneksi manual atau SQL boilerplate dalam logika agen.

Menginstal server Toolbox

Dari Terminal Cloud Shell, buat folder untuk menyimpan file yaml alat baru dan biner toolbox:

mkdir cymbal-bus-toolbox

cd cymbal-bus-toolbox

Dari dalam folder baru tersebut, jalankan serangkaian perintah berikut:

# see releases page for other versions
export VERSION=0.27.0
curl -L -o toolbox https://storage.googleapis.com/genai-toolbox/v$VERSION/linux/amd64/toolbox
chmod +x toolbox

Selanjutnya, buat file tools.yaml di dalam folder baru tersebut dengan membuka Cloud Shell Editor dan menyalin konten file repo ini ke dalam file tools.yaml.

... (Refer to entire file in the repo)

tools:

   find-bus-schedules:
    kind: postgres-sql
    source: alloydb
    description: Find all available bus schedules.
    statement: |
      SELECT CAST(trip_id AS TEXT) trip_id, departure_time, arrival_time, ticket_price, available_seats , origin_city, destination_city 
      FROM bus_schedules;

   query-schedules:
    kind: postgres-sql
    source: alloydb
    description: Find available bus schedules between an origin and destination city.
    parameters:
      - name: origin
        type: string
        description: The departure city name.
      - name: destination
        type: string
        description: The arrival city name.
    statement: |
      SELECT CAST(trip_id AS TEXT) trip_id, departure_time, arrival_time, ticket_price, available_seats 
      FROM bus_schedules 
      WHERE lower(origin_city) = lower($1) 
        AND lower(destination_city) = lower($2) 
        AND available_seats > 0 
      ORDER BY departure_time ASC 
      LIMIT 5;

   book-ticket:
    kind: postgres-sql
    source: alloydb
    description: Books a ticket for a specific trip, decrementing available seats and generating a confirmed booking record.
    parameters:
      - name: trip_id
        type: string
        description: The UUID of the trip schedule to book.
      - name: passenger_name
        type: string
        description: Name or ID of the passenger (Bound securely via backend or AuthToken).
        authServices:
          - name: google_auth
            field: sub
    statement: |
      WITH updated_schedule AS (
          UPDATE bus_schedules 
          SET available_seats = available_seats - 1 
          WHERE trip_id = CAST($1 AS UUID) AND available_seats > 0
          RETURNING trip_id
      )
      INSERT INTO bookings (trip_id, passenger_id)
      SELECT trip_id, $2 
      FROM updated_schedule
      RETURNING CAST(booking_id as TEXT) as booking_id, trip_id, passenger_id, status, booking_time;

   search-policies:
    kind: postgres-sql
    source: alloydb
    description: Semantic search for transit policies regarding luggage, pets, refunds, and general rules.
    parameters:
      - name: search_query
        type: string
        description: The user's question about transit policies to be embedded and searched.
    statement: |
      SELECT category, policy_text 
      FROM transit_policies 
      ORDER BY policy_embedding <=> CAST(embedding('text-embedding-005', $1) AS vector(768))
      LIMIT 2;

Catatan:

  1. Dalam penyiapan tools.yaml, jangan lupa untuk menyertakan ipType: "private" dalam konfigurasi sumber AlloyDB.
  2. Jangan lupa juga untuk menyertakan URL layanan MCP Toolbox dalam parameter clientId untuk konfigurasi authServices. Anda mungkin mendapatkan link hanya setelah deployment awal - jadi ya, Anda harus menjalankan langkah-langkah deployment dua kali untuk memastikan kasus penggunaan alat yang diautentikasi berfungsi.
  3. Opsi di bawah untuk menguji toolbox secara lokal tidak akan berfungsi jika koneksi AlloyDB Anda disetel ke pribadi. Anda harus menyetelnya ke publik untuk mengujinya secara lokal atau menggunakan proxy untuk koneksi. Namun, jangan khawatir. Dalam kasus ini, kita akan langsung men-deploy-nya ke Cloud Run, lalu mengujinya.

Untuk menguji file tools.yaml di server lokal:

./toolbox --tools-file "tools.yaml"

Atau, Anda dapat mengujinya di UI:

./toolbox --ui

Lanjutkan dan deploy di Cloud Run sebagai berikut.

Deployment Cloud Run

  1. Tetapkan variabel lingkungan PROJECT_ID:
export PROJECT_ID="my-project-id"
  1. Lakukan inisialisasi gcloud CLI:
gcloud init
gcloud config set project $PROJECT_ID
  1. Anda harus mengaktifkan API berikut:
gcloud services enable run.googleapis.com \
                       cloudbuild.googleapis.com \
                       artifactregistry.googleapis.com \
                       iam.googleapis.com \
                       secretmanager.googleapis.com
  1. Buat akun layanan backend jika Anda belum memilikinya:
gcloud iam service-accounts create toolbox-identity
  1. Berikan izin untuk menggunakan Secret Manager:
gcloud projects add-iam-policy-binding $PROJECT_ID \
    --member serviceAccount:toolbox-identity@$PROJECT_ID.iam.gserviceaccount.com \
    --role roles/secretmanager.secretAccessor
  1. Berikan izin tambahan ke akun layanan yang khusus untuk sumber AlloyDB kami (roles/alloydb.client dan roles/serviceusage.serviceUsageConsumer)
gcloud projects add-iam-policy-binding $PROJECT_ID \
    --member serviceAccount:toolbox-identity@$PROJECT_ID.iam.gserviceaccount.com \
    --role roles/alloydb.client


gcloud projects add-iam-policy-binding $PROJECT_ID \
    --member serviceAccount:toolbox-identity@$PROJECT_ID.iam.gserviceaccount.com \
    --role roles/serviceusage.serviceUsageConsumer
  1. Upload tools.yaml sebagai secret:
gcloud secrets create tools-cymbal-transit --data-file=tools.yaml
  1. Jika Anda sudah memiliki secret dan ingin memperbarui versi secret, jalankan perintah berikut:
gcloud secrets versions add tools-cymbal-transit --data-file=tools.yaml
  1. Tetapkan variabel lingkungan ke image container yang ingin Anda gunakan untuk Cloud Run:
export IMAGE=us-central1-docker.pkg.dev/database-toolbox/toolbox/toolbox:latest
  1. Deploy Toolbox ke Cloud Run menggunakan perintah berikut:

Jika Anda telah mengaktifkan akses publik di instance AlloyDB, ikuti perintah di bawah untuk deployment ke Cloud Run:

gcloud run deploy toolbox-cymbal-transit \
    --image $IMAGE \
    --service-account toolbox-identity \
    --region us-central1 \
    --set-secrets "/app/tools.yaml=tools-cymbal-transit:latest" \
    --args="--tools-file=/app/tools.yaml","--address=0.0.0.0","--port=8080" \
    --allow-unauthenticated

Jika Anda menggunakan jaringan VPC, gunakan perintah di bawah:

gcloud run deploy toolbox-cymbal-transit \
    --image $IMAGE \
    --service-account toolbox-identity \
    --region us-central1 \
    --set-secrets "/app/tools.yaml=tools-cymbal-transit:latest" \
    --args="--tools-file=/app/tools.yaml","--address=0.0.0.0","--port=8080" \
    --network <<YOUR_NETWORK_NAME>> \
    --subnet <<YOUR_SUBNET_NAME>> \
    --allow-unauthenticated

Catatan: Setelah di-deploy, buka daftar layanan Cloud Run dan pastikan bahwa di tab keamanan layanan tersebut, "Izinkan akses publik" dipilih.

6. Penyiapan Aplikasi Agen

Clone repo ini ke project Anda dan mari kita bahas.

Repo GitHub

Untuk meng-clone-nya, dari Cloud Shell Terminal Anda (di direktori root atau dari mana pun Anda ingin membuat project ini), jalankan perintah berikut:

git clone https://github.com/googleapis/mcp-toolbox-sdk-java

Perintah di atas sebenarnya meng-clone seluruh mcp-toolbox-sdk-java. Kita hanya memerlukan project contoh dari sana. Jadi, buka direktori utama project di dalam repo:

cd mcp-toolbox-sdk-java/demo-applications/cymbal-transit
  1. Tindakan ini akan membuat project dan Anda dapat memverifikasinya di Cloud Shell Editor.

a494664032904c77.png

  1. Buka CymbalTransitController.java dan tetapkan variabel lingkungan:
  2. GCP_PROJECT_ID
  3. GCP_REGION
  4. GEMINI_MODEL_NAME
  5. MCP_TOOLBOX_URL

Atau (hanya untuk tujuan pengembangan), Anda juga dapat mengganti placeholder nilai penggantian masing-masing.

7. Panduan Kode

CymbalTransitController bertindak sebagai titik entri untuk layanan Cloud Run kita. Layanan ini mengelola alur percakapan dan memastikan agen memiliki akses ke permintaan pengguna saat ini.

Implementasi ini mengikuti arsitektur berlayer yang memisahkan orkestrasi AI, penghubungan alat, dan komunikasi MCP tingkat rendah.

1. Konfigurasi Agen AI (AgentConfiguration)

Class ini menggunakan @Configuration Spring untuk mem-bootstrap komponen AI. Tindakan ini akan melakukan inisialisasi VertexAiGeminiChatModel dan mengikatnya ke antarmuka Agen kami.

@Bean
ChatLanguageModel geminiChatModel() {
    return VertexAiGeminiChatModel.builder()
        .project(projectId)
        .location(region)
        .modelName(modelName)
        .build();
}

@Bean
TransitAgent transitAgent(ChatLanguageModel chatLanguageModel, TransitAgentTools tools) {
    return AiServices.builder(TransitAgent.class)
        .chatLanguageModel(chatLanguageModel)
        .chatMemoryProvider(memoryId -> MessageWindowChatMemory.withMaxMessages(20))
        .tools(tools) 
        .build();
}

Signifikansi: AiServices mengikat antarmuka ke LLM. MessageWindowChatMemory memastikan agen mengingat preferensi pengguna (seperti tas transportasi hewan peliharaan yang disebutkan sebelumnya) hingga 20 pesan dalam satu sesi.

2. Antarmuka Agen AI (TransitAgent)

Anotasi @SystemMessage menentukan "Persona" dan batasan operasional, khususnya Strategi Perutean.

@SystemMessage({
    "You are the Cymbal Transit Concierge.",
    "CRITICAL INSTRUCTION: On your very first interaction, you MUST use the 'findAllSchedules' tool to fetch and memorize the broad bus routes.",
    "ONLY if the user asks a specifically narrowed-down question... should you route to the specific tools like 'querySchedules', 'bookTicket', 'searchPolicies'.",
    "Don't show any asterisks while listing results. Keep it formatted and numbered or bulleted."
})
String chat(@MemoryId String sessionId, @UserMessage String userMessage);

Signifikansi: Strategi ini meminimalkan latensi. Dengan mengambil data yang luas terlebih dahulu, agen dapat menjawab pertanyaan perutean umum menggunakan konteks internalnya tanpa melakukan panggilan backend yang berlebihan.

3. Toolbox Bridge (TransitAgentTools)

Layanan ini bertindak sebagai "tangan" agen, menerjemahkan panggilan alat LangChain4j ke dalam logika eksekusi.

@Tool("Fetches the initial, broad dataset of all available bus schedules and routes.")
public String findAllSchedules() {
    return mcpService.findAllSchedules().join();
}


@Tool("Book a ticket for a passenger using a specific trip ID.")
public String bookTicket(String tripId, String passengerName) {
    return mcpService.bookTicket(tripId, passengerName).join();
}

Eksekusi Sinkron: Meskipun panggilan MCP bersifat asinkron (menampilkan CompletableFuture), LLM memerlukan hasil sebelum dapat melanjutkan proses "pemikirannya". Kami menggunakan .join() untuk memberikan hasil sinkron kembali ke agen.

4. Layanan MCP Toolbox (McpToolboxService)

Ini adalah lapisan komunikasi yang menggunakan MCP Toolbox Java SDK untuk berinteraksi dengan backend AlloyDB.

// Identity Management: Fetching OIDC ID Token for Auth
GoogleCredentials credentials = GoogleCredentials.getApplicationDefault();
this.idToken = ((IdTokenProvider) credentials)
    .idTokenWithAudience(targetUrl, Collections.emptyList())
    .getTokenValue();

// Dynamic Invocation: Executing a tool by name
public CompletableFuture<String> findAllSchedules() {
    return mcpClient.invokeTool("find-bus-schedules", Collections.emptyMap()).thenApply(result -> {
        return result.content().stream()
            .map(content -> content.text())
            .collect(Collectors.joining(", ", "[", "]"));
    });
}

Signifikansi: McpToolboxClient menangani komunikasi JSON-RPC yang berat. Metode bookTicket secara khusus menunjukkan kemampuan SDK untuk mengikat parameter kompleks secara dinamis.

5. Pengontrol REST (TransitAgentController)

Endpoint akhir disederhanakan secara radikal karena LangChain4j mengelola status dan logika.

@PostMapping("/chat")
public ResponseEntity<String> handleUserChat(@RequestBody String userMessage, HttpSession session) {
    String sessionId = session.getId();
    String agentResponse = transitAgent.chat(sessionId, userMessage);
    return ResponseEntity.ok(agentResponse);
}

Signifikansi: Dengan memetakan ID HttpSession ke @MemoryId, kita memastikan bahwa rencana perjalanan pengguna yang berbeda tidak tercampur, sekaligus menjaga kode pengontrol tetap bersih dan mudah dibaca.

8. MCP Toolbox: Signifikansi dan Java SDK

Apa itu MCP?

Anggap Model Context Protocol (MCP) sebagai penerjemah universal untuk AI. Dibuat untuk menstandarkan cara model AI terhubung ke alat dan set data eksternal, MCP menggantikan skrip integrasi kustom yang terfragmentasi dengan protokol universal yang aman. Baik agen Anda perlu mengeksekusi kueri SQL transaksional, menelusuri ribuan dokumen kebijakan, atau memicu REST API, MCP menyediakan antarmuka tunggal dan terpadu.

MCP Toolbox for Databases

Tim engineering tidak lagi hanya membangun chatbot sederhana, tetapi juga membangun sistem agentic yang berinteraksi langsung dengan database penting. Namun, membangun agen perusahaan ini sering kali berarti menghadapi hambatan integrasi berupa kode lem kustom, API yang tidak stabil, dan logika database yang kompleks.

Untuk menggantikan hambatan yang dikodekan secara permanen ini dengan bidang kontrol terpadu yang aman, dengan senang hati kami mengumumkan Java SDK untuk MCP Toolbox for Databases. Rilis ini menghadirkan orkestrasi agen yang aman untuk jenis di ekosistem perusahaan yang paling banyak digunakan di dunia. Arsitektur Java yang matang dibuat khusus untuk memenuhi tuntutan ketat ini, dengan menyediakan konkurensi tinggi, integritas transaksional yang ketat, dan pengelolaan status yang andal yang diperlukan untuk menskalakan agen AI yang sangat penting dalam produksi secara aman.

Mengapa Java SDK?

MCP Toolbox Java SDK memungkinkan developer Java untuk:

  1. Menggunakan Alat: Terhubung ke server MCP (seperti MCP Toolbox untuk AlloyDB) dan secara otomatis mengubah kemampuannya menjadi metode Java yang dipahami LangChain4j.
  2. Keamanan Jenis: Manfaatkan pengetikan kuat Java untuk parameter alat, sehingga mengurangi error "halusinasi" runtime dalam panggilan alat.
  3. Kesiapan Perusahaan: Integrasikan dengan mudah dengan Spring Boot, Quarkus, Micronaut, dll.
  4. Terhubung dengan Mudah: Hindari penulisan kode JSON-RPC boilerplate.
  5. Menstandardkan Autentikasi: Dukungan native untuk token OIDC Google Cloud memastikan eksekusi alat yang aman.

dan masih banyak lagi.

Dependensi: Konfigurasi pom.xml

Tambahkan dependensi berikut ke project Maven Anda untuk menyertakan MCP Toolbox Java SDK terbaru:

   <dependency>
        <groupId>com.google.cloud.mcp</groupId>
        <artifactId>mcp-toolbox-sdk-java</artifactId>
        <version>0.2.0</version>
    </dependency>

Tambahkan dependensi berikut ke project Maven Anda untuk menyertakan artefak LangChain4j:

     <!-- LangChain4j Core & Gemini -->
    <dependency>
        <groupId>dev.langchain4j</groupId>
        <artifactId>langchain4j</artifactId>
        <version>0.35.0</version>
    </dependency>

Selesai!!! Kita telah berhasil meng-clone project dan mempelajari detail agen, MCP Toolbox Java SDK, dan konteks.

9. Menjalankan Secara Lokal

Untuk menguji agen di mesin Anda, Anda harus mengarahkannya ke server MCP Toolbox yang di-deploy.

  1. Menetapkan variabel lingkungan:
export GCP_PROJECT_ID="<<YOUR_PROJECT_ID>>"
export GCP_REGION="us-central1"
export GEMINI_MODEL_NAME="gemini-2.5-flash"
export MCP_TOOLBOX_URL="<<YOUR_TOOLBOX_ENDPOINT_URL>>/mcp"
  1. Jalankan dengan Maven:
mvn compile

mvn spring-boot:run

Tindakan ini akan memulai agen Anda secara lokal dan Anda akan dapat mengujinya.

10. Mari kita deploy ke Cloud Run

Deploy di Cloud Run dengan menjalankan perintah berikut dari Cloud Shell Terminal tempat project di-clone dan pastikan Anda berada di dalam folder root project.

JIKA ANDA TIDAK BERADA DI FOLDER ROOT PROJECT SAAT INI, jalankan perintah ini di terminal Cloud Shell:

cd cymbal-transit

Jika Anda sudah berada di root cymbal-transit, jalankan perintah di bawah untuk men-deploy aplikasi secara langsung di Cloud Run:

gcloud run deploy cymbal-transit --source . --set-env-vars GCP_PROJECT_ID=<<YOUR_PROJECT_ID>>,GCP_REGION=us-central1,GEMINI_MODEL_NAME=gemini-2.5-flash,MCP_TOOLBOX_URL=<<YOUR_MCP_TOOLBOX_URL>> --allow-unauthenticated

Ganti nilai untuk placeholder <<YOUR_PROJECT>> and <<YOUR_MCP_TOOLBOX_URL>>

Setelah perintah selesai, URL Layanan akan ditampilkan. Salin.

Berikan peran Klien AlloyDB ke akun layanan Cloud Run.Hal ini memungkinkan aplikasi serverless Anda membuat tunnel ke database dengan aman.

Jalankan perintah ini di terminal Cloud Shell Anda:

# 1. Get your Project ID and Project Number
PROJECT_ID=$(gcloud config get-value project)
PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")

# 2. Grant the AlloyDB Client role
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com" \
--role="roles/alloydb.client"

Catatan: Setelah di-deploy, buka daftar layanan Cloud Run dan pastikan bahwa di tab keamanan layanan tersebut, "Izinkan akses publik" dipilih.

Sekarang gunakan URL layanan (endpoint Cloud Run yang Anda salin sebelumnya) dan uji aplikasi.

Catatan: Jika Anda mengalami masalah layanan, dan masalah tersebut menyebutkan memori sebagai penyebabnya, coba tingkatkan batas memori yang dialokasikan menjadi 1 GiB untuk mengujinya.

11. Demo

Tanyakan kepada agen: "Saya harus pergi dari New York ke Boston besok pagi. Bolehkah saya membawa Golden Retriever saya?" Perhatikan cara agen:

  1. Menelusuri kebijakan untuk besar.
  2. Menemukan jadwal tertentu.
  3. Merangkum perjalanan tercepat dengan ID Perjalanan.
  4. Juga memesan tiket jika Anda menindaklanjuti permintaan tindakan tersebut.

aa0408a81074d0fc.png

12. Pembersihan

Setelah lab ini selesai, jangan lupa untuk menghapus cluster dan instance AlloyDB.

Perintah ini akan membersihkan cluster beserta instance-nya.

13. Selamat

Anda telah berhasil membuat agen transit berbasis Java yang canggih. Dengan memanfaatkan LangChain4j untuk orkestrasi dan MCP Toolbox Java SDK untuk konektivitas data, Anda telah membuat sistem yang dapat melakukan penalaran di seluruh agen, alat, dan sumber data. Jika Anda ingin mulai mengatur aplikasi agentic dengan MCP Toolbox for Databases di beberapa database, bahkan di seluruh platform, mulai gunakan Java SDK sekarang. Berikut adalah blog pengumuman peluncuran yang memberikan informasi lebih mendetail tentang library. Jika Anda ingin membangun lebih banyak aplikasi seperti ini secara langsung, gratis dengan kecepatan Anda sendiri dan dipandu instruktur, daftar ke Code Vipassana di https://codevipassana.dev!!!