Cymbal Transit: Một hệ thống đa tác nhân sử dụng LangChain4J và MCP Toolbox Java SDK

1. Tổng quan

Khách du lịch ngày nay mong đợi có được trải nghiệm đàm thoại. Thay vì sử dụng các bộ lọc phức tạp trên giao diện người dùng, họ muốn hỏi: "Tôi có thể mang theo chó lên xe buýt 9 giờ sáng đến Boston không?" Điều này đòi hỏi một tác nhân có thể suy luận dựa trên dữ liệu không có cấu trúc (chính sách PDF) và dữ liệu có cấu trúc (lịch biểu SQL).

Trong phòng thí nghiệm này, chúng ta sẽ tạo Cymbal Transit Agent bằng cách sử dụng:

  • LangChain4j: Khung Java hàng đầu để điều phối AI.
  • AlloyDB: Một cơ sở dữ liệu hiệu suất cao, tương thích với PostgreSQL.
  • MCP Toolbox Java SDK: Một cách tiêu chuẩn hoá để kết nối các tác nhân Java với các công cụ và nguồn dữ liệu bên ngoài.

Sản phẩm bạn sẽ tạo ra

e68388d533c9997e.png

Cymbal Bus Agent, một ứng dụng Java Spring Boot bao gồm:

  1. Cơ sở dữ liệu AlloyDB và MCP Toolbox Java SDK để điều phối công cụ với các tác nhân.
  2. Cloud Run để triển khai và ứng dụng Toolbox (triển khai tác nhân).
  3. Thư viện LangChain4J cho khung tác nhân và LLM trong Ứng dụng Spring Boot bằng Java 17.

Kiến thức bạn sẽ học được

  • Cách sử dụng LangChain4J để tạo các tác nhân và tác nhân phụ chuyên biệt được điều phối bằng MCP Toolbox cho SDK Java về cơ sở dữ liệu
  • Cách thiết lập và sử dụng AlloyDB cho dữ liệu và AI.
  • Cách sử dụng MCP Toolbox để kết nối các tác nhân với công cụ dữ liệu AlloyDB.
  • Cách triển khai giải pháp bằng Cloud Run hoặc kích hoạt giải pháp cục bộ.

Kiến trúc

  1. AlloyDB cho PostgreSQL: Đóng vai trò là cơ sở dữ liệu vận hành hiệu suất cao, lưu giữ các bản ghi về tuyến đường, chính sách và lượt đặt chỗ của chúng tôi. Công cụ này hỗ trợ tính năng tìm kiếm và truy xuất vectơ.
  2. MCP Toolbox for Databases Java SDK: Đóng vai trò là "Nhạc trưởng điều phối", cung cấp dữ liệu AlloyDB dưới dạng các công cụ có thể thực thi mà các tác nhân có thể gọi.

MCP Toolbox Java SDK giúp bạn dễ dàng điều phối các tác nhân bằng các công cụ cơ sở dữ liệu cho các ứng dụng cấp doanh nghiệp.

  1. LangChain4J: Một thư viện Java nguồn mở giúp đơn giản hoá việc tích hợp Mô hình ngôn ngữ lớn (LLM) vào các ứng dụng Java. Khung này cung cấp các công cụ và thành phần trừu tượng để xây dựng các ứng dụng dựa trên AI, bao gồm cả chatbot, tác nhân và hệ thống Tạo sinh tăng cường truy xuất (RAG).
  2. Cloud Run: Một nền tảng KHÔNG CẦN MÁY CHỦ được quản lý toàn bộ, cho phép bạn dễ dàng tạo và triển khai ứng dụng hoặc trang web một cách nhanh chóng bằng mọi ngôn ngữ, mọi thư viện, mọi tệp nhị phân. Bạn có thể viết mã bằng ngôn ngữ, khung và thư viện yêu thích, đóng gói mã đó dưới dạng một vùng chứa, chạy "gcloud run deploy" và ứng dụng của bạn sẽ hoạt động – được cung cấp mọi thứ cần thiết để chạy trong quá trình phát hành công khai. Bạn không bắt buộc phải tạo vùng chứa. Nếu đang dùng Go, Node.js, Python, Java, .NET Core hoặc Ruby, bạn có thể dùng lựa chọn triển khai dựa trên nguồn để tạo vùng chứa cho bạn, theo các phương pháp hay nhất cho ngôn ngữ mà bạn đang dùng.

Yêu cầu

  • Một trình duyệt, chẳng hạn như Chrome hoặc Firefox.
  • Một dự án trên Google Cloud đã bật tính năng thanh toán.
  • Có kiến thức cơ bản về SQL và Java.

2. Trước khi bắt đầu

Tạo dự án

  1. Trong Google Cloud Console, trên trang chọn dự án, hãy chọn hoặc tạo một dự án trên Google Cloud.
  2. Đảm bảo rằng bạn đã bật tính năng thanh toán cho dự án trên đám mây của bạn. Tìm hiểu cách kiểm tra xem tính năng thanh toán có được bật trên một dự án hay không.
  1. Bạn sẽ sử dụng Cloud Shell, một môi trường dòng lệnh chạy trong Google Cloud. Nhấp vào Kích hoạt Cloud Shell ở đầu bảng điều khiển Google Cloud.

Hình ảnh nút Kích hoạt Cloud Shell

  1. Sau khi kết nối với Cloud Shell, bạn có thể kiểm tra để đảm bảo rằng bạn đã được xác thực và dự án được đặt thành mã dự án của bạn bằng lệnh sau:
gcloud auth list
  1. Chạy lệnh sau trong Cloud Shell để xác nhận rằng lệnh gcloud biết về dự án của bạn.
gcloud config list project
  1. Nếu bạn chưa đặt dự án, hãy dùng lệnh sau để đặt:
gcloud config set project <YOUR_PROJECT_ID>
  1. Bật các API bắt buộc: Truy cập vào đường liên kết rồi bật các API.

Ngoài ra, bạn có thể dùng lệnh gcloud cho việc này. Tham khảo tài liệu để biết các lệnh và cách sử dụng gcloud.

Các lỗi thường gặp và cách khắc phục

Hội chứng "Dự án ma"

Bạn đã chạy gcloud config set project, nhưng thực ra bạn đang xem một dự án khác trong giao diện người dùng Console. Kiểm tra mã dự án trong trình đơn thả xuống ở trên cùng bên trái!

Rào chắn thanh toán

Bạn đã bật dự án nhưng quên tài khoản thanh toán. AlloyDB là một công cụ hiệu suất cao; công cụ này sẽ không khởi động nếu "bình xăng" (thanh toán) trống.

Độ trễ truyền API

Bạn đã nhấp vào "Bật API", nhưng dòng lệnh vẫn hiển thị Service Not Enabled. Chờ 60 giây. Đám mây cần một chút thời gian để kích hoạt các nơ-ron.

Hạn mức Quags

Nếu đang sử dụng tài khoản dùng thử hoàn toàn mới, bạn có thể đạt đến hạn mức theo khu vực cho các phiên bản AlloyDB. Nếu us-central1 không thành công, hãy thử us-east1.

Nhân viên hỗ trợ dịch vụ"bị ẩn"

Đôi khi, AlloyDB Service Agent không được tự động cấp vai trò aiplatform.user. Nếu các truy vấn SQL của bạn không thể tương tác với Gemini sau này, thì đây thường là nguyên nhân.

3. Thiết lập cơ sở dữ liệu

Ứng dụng của chúng tôi dựa trên AlloyDB cho PostgreSQL. Chúng tôi đã tận dụng các chức năng vectơ mạnh mẽ và tích hợp công cụ theo cột của cơ sở dữ liệu này để tạo các mục nhúng cho hơn 50.000 bản ghi SCM. Điều này giúp phân tích vectơ gần với thời gian thực, cho phép các nhân viên của chúng tôi xác định điểm bất thường về khoảng không quảng cáo hoặc rủi ro về hậu cần trên các tập dữ liệu khổng lồ trong vài mili giây.

Trong phòng thí nghiệm này, chúng ta sẽ sử dụng AlloyDB làm cơ sở dữ liệu cho dữ liệu kiểm thử. Nó sử dụng cụm để lưu giữ tất cả các tài nguyên, chẳng hạn như cơ sở dữ liệu và nhật ký. Mỗi cụm có một phiên bản chính cung cấp một điểm truy cập vào dữ liệu. Các bảng sẽ chứa dữ liệu thực tế.

Hãy tạo một cụm, phiên bản và bảng AlloyDB nơi tập dữ liệu kiểm thử sẽ được tải.

  1. Nhấp vào nút hoặc Sao chép đường liên kết bên dưới vào trình duyệt mà bạn đã đăng nhập người dùng Google Cloud Console.

Ngoài ra, bạn có thể chuyển đến Cloud Shell Terminal trong dự án mà bạn đã đổi tài khoản thanh toán, rồi sao chép kho lưu trữ github và chuyển đến dự án bằng các lệnh bên dưới:

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

cd easy-alloydb-setup
  1. Sau khi hoàn tất bước này, kho lưu trữ sẽ được sao chép vào trình chỉnh sửa Cloud Shell cục bộ và bạn có thể chạy lệnh bên dưới từ thư mục dự án (bạn cần đảm bảo rằng bạn đang ở trong thư mục dự án):
sh run.sh
  1. Bây giờ, hãy sử dụng giao diện người dùng (nhấp vào đường liên kết trong thiết bị đầu cuối hoặc nhấp vào đường liên kết "xem trước trên web" trong thiết bị đầu cuối.
  2. Nhập thông tin chi tiết về mã dự án, tên cụm và tên phiên bản để bắt đầu.
  3. Hãy đi lấy một tách cà phê trong khi nhật ký cuộn và bạn có thể đọc về cách nhật ký thực hiện việc này ở chế độ nền tại đây.

Các lỗi thường gặp và cách khắc phục

Vấn đề về "Tính kiên nhẫn"

Cụm cơ sở dữ liệu là cơ sở hạ tầng lớn. Nếu làm mới trang hoặc kết thúc phiên Cloud Shell vì phiên này "có vẻ bị treo", bạn có thể gặp phải một phiên bản "ảo" được cung cấp một phần và không thể xoá nếu không có sự can thiệp thủ công.

Khu vực không khớp

Nếu đã bật API trong us-central1 nhưng lại cố gắng cung cấp cụm trong asia-south1, bạn có thể gặp phải vấn đề về hạn mức hoặc sự chậm trễ về quyền của Tài khoản dịch vụ. Hãy chọn một khu vực duy nhất cho toàn bộ phòng thí nghiệm!

Nhóm Zombie

Nếu trước đây bạn đã dùng cùng một tên cho một cụm và chưa xoá cụm đó, thì tập lệnh có thể cho biết tên cụm đã tồn tại. Tên cụm phải là duy nhất trong một dự án.

Thời gian chờ của Cloud Shell

Nếu thời gian giải lao uống cà phê của bạn là 30 phút, Cloud Shell có thể chuyển sang chế độ ngủ và ngắt kết nối quy trình sh run.sh. Hãy giữ cho thẻ hoạt động!

4. Cấp phép giản đồ

Sau khi bạn chạy cụm và phiên bản AlloyDB, hãy chuyển đến trình chỉnh sửa SQL của AlloyDB Studio để bật các tiện ích AI và cung cấp giản đồ.

1e3ac974b18a8113.png

Bạn có thể phải đợi phiên bản của mình tạo xong. Sau khi tạo xong, hãy đăng nhập vào AlloyDB bằng thông tin đăng nhập mà bạn đã tạo khi tạo cụm. Sử dụng dữ liệu sau để xác thực với PostgreSQL:

  • Tên người dùng : "postgres"
  • Cơ sở dữ liệu : "postgres"
  • Mật khẩu : "alloydb" (hoặc mật khẩu bạn đặt tại thời điểm tạo)

Sau khi bạn xác thực thành công vào AlloyDB Studio, các lệnh SQL sẽ được nhập vào Trình chỉnh sửa. Bạn có thể thêm nhiều cửa sổ Trình chỉnh sửa bằng cách nhấp vào dấu cộng ở bên phải cửa sổ cuối cùng.

28cb9a8b6aa0789f.png

Bạn sẽ nhập các lệnh cho AlloyDB trong cửa sổ trình chỉnh sửa, sử dụng các lựa chọn Chạy, Định dạng và Xoá khi cần.

Bật tiện ích

Để tạo ứng dụng này, chúng ta sẽ sử dụng các tiện ích pgvectorgoogle_ml_integration. Tiện ích pgvector cho phép bạn lưu trữ và tìm kiếm các vectơ nhúng. Tiện ích google_ml_integration cung cấp các hàm mà bạn dùng để truy cập vào các điểm cuối dự đoán của Vertex AI nhằm nhận thông tin dự đoán bằng SQL. Bật các tiện ích này bằng cách chạy các DDL sau:

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

Cấp quyền

Chạy câu lệnh bên dưới để cấp quyền thực thi cho hàm "embedding":

GRANT EXECUTE ON FUNCTION embedding TO postgres;

Cấp vai trò Người dùng Vertex AI cho tài khoản dịch vụ AlloyDB

Trên bảng điều khiển IAM của Google Cloud, hãy cấp cho tài khoản dịch vụ AlloyDB (có dạng như sau: service-<<PROJECT_NUMBER>>@gcp-sa-alloydb.iam.gserviceaccount.com) quyền truy cập vào vai trò "Người dùng Vertex AI". PROJECT_NUMBER sẽ có số dự án của bạn.

Ngoài ra, bạn có thể chạy lệnh bên dưới từ Cloud Shell Terminal:

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"

Tạo bảng

Bạn có thể tạo một bảng bằng câu lệnh DDL bên dưới trong 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
);

Cột policy_embedding sẽ cho phép lưu trữ các giá trị vectơ của một số trường văn bản.

Nhập dữ liệu

Chạy tập hợp câu lệnh SQL bên dưới để chèn hàng loạt các bản ghi vào các bảng tương ứng:

  1. Chèn các chính sách không có cấu trúc và TẠO CÁC VÉC TƠ ĐẠI DIỆN THỰC TẾ một cách tự nhiên trong 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. Tạo hơn 200 lịch biểu thực tế trong 7 ngày bằng cách sử dụng 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!

Tạo vectơ nhúng

Các mục nhúng sẽ tự động được đưa vào câu lệnh chèn vào bảng transit_policies bằng cách sử dụng hàm "embedding('text-embedding-005', '<<policytext>>')".

Các lỗi thường gặp và cách khắc phục

Vòng lặp "Quên mật khẩu"

Nếu bạn sử dụng chế độ thiết lập "Một lần nhấp" và không nhớ mật khẩu, hãy chuyển đến trang Thông tin cơ bản về phiên bản trong bảng điều khiển rồi nhấp vào "Chỉnh sửa" để đặt lại mật khẩu postgres.

Lỗi "Không tìm thấy tiện ích"

Nếu CREATE EXTENSION không thành công, thì thường là do phiên bản vẫn ở trạng thái "Bảo trì" hoặc "Đang cập nhật" kể từ lần cấp phép ban đầu. Kiểm tra xem bước tạo phiên bản đã hoàn tất chưa và đợi vài giây nếu cần.

Vấn đề về việc truyền dữ liệu IAM

Bạn đã chạy lệnh IAM gcloud, nhưng SQL CALL vẫn gặp lỗi về quyền. Có thể mất một chút thời gian để các thay đổi về IAM được áp dụng thông qua cơ sở hạ tầng của Google. Hít một hơi thật sâu.***NGHIÊM TRỌNG:

  1. Đôi khi, tài khoản dịch vụ AlloyDB của bạn có thể khác với định dạng hiện có mà chúng tôi đã sử dụng trong bước cấp quyền. Để chắc chắn 100% rằng tài khoản dịch vụ AlloyDB có Vai trò người dùng Vertex AI: Truy cập vào trang Cụm AlloyDB trong Google Cloud Console. Nhấp vào cụm của bạn, rồi trong thẻ Tổng quan, hãy tìm trường có nhãn Tài khoản dịch vụ.
    Sao chép giá trị rồi chuyển đến IAM và thêm Vai trò người dùng Vertex AI.
  2. Ngoài ra, nếu bỏ qua bước "Bật API" trong phần "Trước khi bắt đầu", bạn sẽ gặp vấn đề khi truy cập vào các mục nhúng từ AlloyDB.

Vector Dimension Mismatch

Cột policy_embedding của bảng transit_policies được đặt thành VECTOR(768). Nếu sau này bạn cố gắng sử dụng một mô hình khác (chẳng hạn như mô hình 1536 chiều), các phần chèn của bạn sẽ bị nổ. Hãy tuân thủ text-embedding-005.

Lỗi chính tả mã dự án

Trong lệnh gọi create_model, nếu bạn bỏ dấu ngoặc « » hoặc nhập sai mã dự án, thì quá trình đăng ký mô hình sẽ có vẻ thành công nhưng lại thất bại trong truy vấn thực tế đầu tiên. Kiểm tra kỹ chuỗi của bạn!

5. Thiết lập công cụ và hộp công cụ

MCP Toolbox for Databases là một máy chủ MCP nguồn mở dành cho cơ sở dữ liệu. Nhờ đó, bạn có thể phát triển các công cụ cho nhà phát triển dễ dàng, nhanh chóng và an toàn hơn bằng cách xử lý các điểm phức tạp như nhóm kết nối, xác thực và nhiều điểm khác. Toolbox giúp bạn tạo các công cụ AI tạo sinh cho phép nhân viên hỗ trợ truy cập vào dữ liệu trong cơ sở dữ liệu của bạn.

Chúng tôi sử dụng Hộp công cụ Giao thức ngữ cảnh mô hình (MCP) cho cơ sở dữ liệu làm "nhạc trưởng". Đây là một phần mềm trung gian được chuẩn hoá giữa các tác nhân và AlloyDB. Bằng cách xác định cấu hình tools.yaml, hộp công cụ sẽ tự động hiển thị các thao tác phức tạp trên cơ sở dữ liệu dưới dạng các công cụ có thể thực thi và rõ ràng như find-bus-schedules and routes hoặc query-schedules for specific routes, đồng thời thực thi các hành động tự động như book-ticket. Điều này giúp bạn không cần phải gộp kết nối theo cách thủ công hoặc sử dụng SQL nguyên mẫu trong logic của tác nhân.

Cài đặt máy chủ Hộp công cụ

Trong Cloud Shell Terminal, hãy tạo một thư mục để lưu tệp yaml công cụ mới và tệp nhị phân của hộp công cụ:

mkdir cymbal-bus-toolbox

cd cymbal-bus-toolbox

Trong thư mục mới đó, hãy chạy tập hợp lệnh sau:

# 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

Tiếp theo, hãy tạo tệp tools.yaml bên trong thư mục mới đó bằng cách chuyển đến Cloud Shell Editor rồi sao chép nội dung của tệp repo này vào tệp 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;

Lưu ý:

  1. Trong chế độ thiết lập tools.yaml, đừng quên thêm ipType: "private" vào cấu hình nguồn alloydb.
  2. Ngoài ra, hãy nhớ thêm URL dịch vụ MCP Toolbox vào tham số clientId cho cấu hình authServices. Bạn có thể chỉ nhận được đường liên kết sau lần triển khai ban đầu. Vì vậy, bạn sẽ phải chạy các bước triển khai hai lần để đảm bảo trường hợp sử dụng công cụ được xác thực hoạt động.
  3. Các lựa chọn bên dưới để kiểm thử hộp công cụ cục bộ sẽ không hoạt động nếu bạn đặt kết nối AlloyDB ở chế độ riêng tư. Bạn phải đặt kết nối ở chế độ công khai để kiểm thử cục bộ hoặc sử dụng một proxy cho kết nối. Nhưng bạn không cần lo lắng về điều đó. Trong trường hợp này, chúng ta sẽ triển khai trực tiếp ứng dụng đó lên Cloud Run rồi kiểm thử.

Cách kiểm thử tệp tools.yaml trong máy chủ cục bộ:

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

Ngoài ra, bạn có thể kiểm thử trong giao diện người dùng:

./toolbox --ui

Hãy tiếp tục và triển khai ứng dụng này trong Cloud Run như sau.

Triển khai Cloud Run

  1. Đặt biến môi trường PROJECT_ID:
export PROJECT_ID="my-project-id"
  1. Khởi động gcloud CLI:
gcloud init
gcloud config set project $PROJECT_ID
  1. Bạn phải bật các API sau:
gcloud services enable run.googleapis.com \
                       cloudbuild.googleapis.com \
                       artifactregistry.googleapis.com \
                       iam.googleapis.com \
                       secretmanager.googleapis.com
  1. Tạo một tài khoản dịch vụ phụ trợ nếu bạn chưa có:
gcloud iam service-accounts create toolbox-identity
  1. Cấp quyền sử dụng trình quản lý bí mật:
gcloud projects add-iam-policy-binding $PROJECT_ID \
    --member serviceAccount:toolbox-identity@$PROJECT_ID.iam.gserviceaccount.com \
    --role roles/secretmanager.secretAccessor
  1. Cấp thêm các quyền cho tài khoản dịch vụ dành riêng cho nguồn AlloyDB của chúng tôi (roles/alloydb.client và 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. Tải tools.yaml lên dưới dạng một khoá bí mật:
gcloud secrets create tools-cymbal-transit --data-file=tools.yaml
  1. Nếu bạn đã có một khoá bí mật và muốn cập nhật phiên bản khoá bí mật, hãy thực thi lệnh sau:
gcloud secrets versions add tools-cymbal-transit --data-file=tools.yaml
  1. Đặt một biến môi trường cho hình ảnh vùng chứa mà bạn muốn dùng cho Cloud Run:
export IMAGE=us-central1-docker.pkg.dev/database-toolbox/toolbox/toolbox:latest
  1. Triển khai Toolbox lên Cloud Run bằng lệnh sau:

Nếu bạn đã bật quyền truy cập công khai trong phiên bản AlloyDB, hãy làm theo lệnh bên dưới để triển khai vào 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

Nếu bạn đang sử dụng mạng VPC, hãy dùng lệnh bên dưới:

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

Lưu ý: Sau khi triển khai, hãy chuyển đến danh sách dịch vụ Cloud Run và đảm bảo rằng trong thẻ bảo mật của dịch vụ đó, bạn đã chọn "Cho phép truy cập công khai".

6. Thiết lập ứng dụng tác nhân

Sao chép kho lưu trữ này vào dự án của bạn và hãy xem qua kho lưu trữ này.

Kho lưu trữ GitHub

Để sao chép dự án này, hãy chạy lệnh sau từ Cloud Shell Terminal (trong thư mục gốc hoặc từ bất cứ nơi nào bạn muốn tạo dự án này):

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

Lệnh trên thực sự sao chép toàn bộ mcp-toolbox-sdk-java. Chúng tôi chỉ cần dự án mẫu từ đó. Vì vậy, hãy chuyển đến thư mục gốc của dự án trong kho lưu trữ:

cd mcp-toolbox-sdk-java/demo-applications/cymbal-transit
  1. Thao tác này sẽ tạo dự án và bạn có thể xác minh dự án đó trong Cloud Shell Editor.

a494664032904c77.png

  1. Mở CymbalTransitController.java rồi đặt các biến môi trường:
  2. GCP_PROJECT_ID
  3. GCP_REGION
  4. GEMINI_MODEL_NAME
  5. MCP_TOOLBOX_URL

Ngoài ra (chỉ dành cho mục đích phát triển), bạn cũng có thể thay thế các phần giữ chỗ giá trị dự phòng tương ứng.

7. Hướng dẫn từng bước về mã

CymbalTransitController đóng vai trò là điểm truy cập cho dịch vụ Cloud Run của chúng tôi. Nó quản lý luồng trò chuyện và đảm bảo rằng trợ lý ảo có quyền truy cập vào yêu cầu hiện tại của người dùng.

Việc triển khai tuân theo một cấu trúc phân lớp tách biệt việc điều phối AI, kết nối công cụ và giao tiếp MCP cấp thấp.

1. Cấu hình tác nhân AI (AgentConfiguration)

Lớp này sử dụng @Configuration của Spring để khởi động các thành phần AI. Thao tác này khởi chạy VertexAiGeminiChatModel và liên kết mô hình này với giao diện Agent của chúng ta.

@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();
}

Ý nghĩa: AiServices liên kết giao diện với LLM. MessageWindowChatMemory đảm bảo rằng trợ lý ảo ghi nhớ các lựa chọn ưu tiên của người dùng (chẳng hạn như lồng vận chuyển thú cưng đã đề cập trước đó) cho tối đa 20 tin nhắn trong một phiên.

2. Giao diện tác nhân AI (TransitAgent)

Chú thích @SystemMessage xác định "Persona" và các hạn chế về hoạt động, cụ thể là Chiến lược định tuyến.

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

Ý nghĩa: Chiến lược này giảm thiểu độ trễ. Bằng cách tìm nạp dữ liệu chung trước, tác nhân có thể trả lời các câu hỏi chung về việc định tuyến bằng cách sử dụng ngữ cảnh nội bộ mà không cần thực hiện các lệnh gọi phụ trợ dư thừa.

3. Toolbox Bridge (TransitAgentTools)

Dịch vụ này đóng vai trò là "bàn tay" của nhân viên hỗ trợ, chuyển đổi các lệnh gọi công cụ LangChain4j thành logic thực thi.

@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();
}

Thực thi đồng bộ: Mặc dù các lệnh gọi MCP là không đồng bộ (trả về CompletableFuture), nhưng LLM cần có kết quả thì mới có thể tiếp tục quy trình "suy nghĩ". Chúng tôi sử dụng .join() để cung cấp kết quả đồng bộ cho tác nhân.

4. Dịch vụ Hộp công cụ MCP (McpToolboxService)

Đây là lớp giao tiếp sử dụng MCP Toolbox Java SDK để tương tác với phần phụ trợ 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(", ", "[", "]"));
    });
}

Ý nghĩa: McpToolboxClient xử lý phần lớn hoạt động giao tiếp JSON-RPC. Phương thức bookTicket minh hoạ cụ thể khả năng liên kết các tham số phức tạp một cách linh động của SDK.

5. Bộ điều khiển REST (TransitAgentController)

Điểm cuối cuối cùng được đơn giản hoá đáng kể vì LangChain4j quản lý trạng thái và logic.

@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);
}

Ý nghĩa: Bằng cách liên kết mã nhận dạng HttpSession với @MemoryId, chúng tôi đảm bảo rằng kế hoạch đi lại của những người dùng khác nhau không bị lẫn lộn, đồng thời giữ cho mã bộ điều khiển rõ ràng và dễ đọc.

8. Hộp công cụ MCP: Ý nghĩa và SDK Java

MCP là gì?

Hãy xem Giao thức ngữ cảnh mô hình (MCP) như một trình dịch phổ quát cho AI. Được tạo ra để chuẩn hoá cách các mô hình AI kết nối với các công cụ và tập dữ liệu bên ngoài, MCP thay thế các tập lệnh tích hợp tuỳ chỉnh, rời rạc bằng một giao thức bảo mật, phổ biến. Cho dù tác nhân của bạn cần thực thi một truy vấn SQL giao dịch, tìm kiếm trong hàng nghìn tài liệu chính sách hay kích hoạt một API REST, MCP đều cung cấp một giao diện duy nhất, hợp nhất.

Hộp công cụ MCP cho cơ sở dữ liệu

Các nhóm kỹ thuật đang chuyển từ chatbot đơn giản sang xây dựng các hệ thống tác nhân tương tác trực tiếp với cơ sở dữ liệu quan trọng. Tuy nhiên, việc xây dựng các tác nhân doanh nghiệp này thường có nghĩa là bạn sẽ gặp phải một rào cản tích hợp gồm mã kết dính tuỳ chỉnh, API dễ bị lỗi và logic cơ sở dữ liệu phức tạp.

Để thay thế những điểm tắc nghẽn được mã hoá cứng này bằng một mặt phẳng điều khiển hợp nhất, an toàn, chúng tôi rất vui mừng thông báo về Java SDK cho Hộp công cụ Giao thức bối cảnh mô hình (MCP) dành cho cơ sở dữ liệu. Bản phát hành này mang đến khả năng điều phối tác nhân an toàn về kiểu và đẳng cấp cho hệ sinh thái doanh nghiệp được áp dụng rộng rãi nhất trên thế giới. Cấu trúc hoàn chỉnh của Java được xây dựng cho những yêu cầu khắt khe này, mang lại khả năng xử lý đồng thời cao, tính toàn vẹn nghiêm ngặt của giao dịch và khả năng quản lý trạng thái mạnh mẽ cần thiết để mở rộng quy mô an toàn các tác nhân AI quan trọng trong quá trình sản xuất.

Tại sao nên dùng Java SDK?

MCP Toolbox Java SDK cho phép nhà phát triển Java:

  1. Công cụ sử dụng: Kết nối với một máy chủ MCP (chẳng hạn như MCP Toolbox cho AlloyDB) và tự động chuyển các chức năng của máy chủ đó thành các phương thức Java mà LangChain4j hiểu được.
  2. Độ an toàn của kiểu: Tận dụng tính năng nhập mạnh mẽ của Java cho các tham số công cụ, giảm lỗi "ảo giác" trong thời gian chạy trong các lệnh gọi công cụ.
  3. Sẵn sàng cho doanh nghiệp: Dễ dàng tích hợp với Spring Boot, Quarkus, Micronaut, v.v.
  4. Kết nối dễ dàng: Tránh viết mã JSON-RPC nguyên mẫu.
  5. Chuẩn hoá quy trình xác thực: Hỗ trợ gốc cho mã thông báo OIDC của Google Cloud giúp đảm bảo việc thực thi công cụ an toàn.

và nhiều tính năng khác.

Phần phụ thuộc: Cấu hình pom.xml

Thêm phần phụ thuộc sau vào dự án Maven để đưa MCP Toolbox Java SDK mới nhất vào:

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

Thêm phần phụ thuộc sau vào dự án Maven để đưa cấu phần phần mềm LangChain4j vào:

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

Vậy là xong!!! Chúng ta đã sao chép thành công dự án và xem xét chi tiết về tác nhân, MCP Toolbox Java SDK và bối cảnh.

9. Chạy cục bộ

Để kiểm thử tác nhân trên máy, bạn cần trỏ tác nhân đó đến máy chủ MCP Toolbox đã triển khai.

  1. Đặt các biến môi trường:
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. Chạy bằng Maven:
mvn compile

mvn spring-boot:run

Thao tác này sẽ khởi động nhân viên hỗ trợ của bạn trên thiết bị và bạn có thể kiểm thử nhân viên hỗ trợ đó.

10. Hãy triển khai ứng dụng này lên Cloud Run

Triển khai ứng dụng đó trên Cloud Run bằng cách chạy lệnh sau từ Cloud Shell Terminal (nơi dự án được sao chép) và đảm bảo bạn đang ở trong thư mục gốc của dự án.

NẾU BẠN KHÔNG Ở THƯ MỤC GỐC CỦA DỰ ÁN HIỆN TẠI, hãy chạy lệnh này trong thiết bị đầu cuối Cloud Shell:

cd cymbal-transit

Nếu bạn đã ở thư mục gốc cymbal-transit, hãy chạy lệnh bên dưới để triển khai trực tiếp ứng dụng trên 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

Thay thế các giá trị cho phần giữ chỗ <<YOUR_PROJECT>> and <<YOUR_MCP_TOOLBOX_URL>>

Sau khi hoàn tất, lệnh này sẽ xuất ra một URL dịch vụ. Sao chép.

Cấp vai trò AlloyDB Client (Máy khách AlloyDB) cho tài khoản dịch vụ Cloud Run.Điều này cho phép ứng dụng không dùng máy chủ của bạn tạo đường hầm an toàn vào cơ sở dữ liệu.

Chạy lệnh này trong thiết bị đầu cuối Cloud Shell:

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

Lưu ý: Sau khi triển khai, hãy chuyển đến danh sách dịch vụ Cloud Run và đảm bảo rằng trong thẻ bảo mật của dịch vụ đó, bạn đã chọn "Cho phép truy cập công khai".

Bây giờ, hãy dùng URL dịch vụ (điểm cuối Cloud Run mà bạn đã sao chép trước đó) và kiểm thử ứng dụng.

Lưu ý: Nếu bạn gặp phải vấn đề về dịch vụ và vấn đề đó có liên quan đến bộ nhớ, hãy thử tăng giới hạn bộ nhớ được phân bổ lên 1 GiB để kiểm tra.

11. Bản minh hoạ

Hỏi trợ lý ảo: "Tôi cần đi từ New York đến Boston vào sáng mai. Tôi có thể mang theo chú chó Golden Retriever của mình không?" Quan sát cách nhân viên hỗ trợ:

  1. Tìm kiếm chính sách về chó lớn.
  2. Tìm lịch biểu cụ thể.
  3. Tóm tắt chuyến đi nhanh nhất bằng mã chuyến đi.
  4. Đồng thời đặt vé nếu bạn thực hiện yêu cầu hành động đó.

aa0408a81074d0fc.png

12. Dọn dẹp

Sau khi hoàn tất bài thực hành này, đừng quên xoá cụm và phiên bản alloyDB.

Thao tác này sẽ dọn dẹp cụm cùng với(các) phiên bản của cụm.

13. Xin chúc mừng

Bạn đã tạo thành công một tác nhân vận chuyển tinh vi dựa trên Java. Bằng cách tận dụng LangChain4j để điều phối và MCP Toolbox Java SDK để kết nối dữ liệu, bạn đã tạo một hệ thống có thể suy luận trên nhiều tác nhân, công cụ và nguồn dữ liệu. Nếu bạn muốn bắt đầu điều phối các ứng dụng dựa trên tác nhân bằng MCP Toolbox for Databases trên nhiều cơ sở dữ liệu, ngay cả trên nhiều nền tảng, hãy bắt đầu bằng Java SDK ngay hôm nay! Đây là bài đăng thông báo ra mắt trên blog, cung cấp thông tin chi tiết hơn về thư viện. Nếu bạn muốn tự tay xây dựng thêm nhiều ứng dụng như vậy miễn phí theo tốc độ của riêng mình và có người hướng dẫn, hãy đăng ký Code Vipassana tại https://codevipassana.dev!!!